fix: fix telegram sent error in cron task.
Signed-off-by: Bo <boironic@gmail.com>
This commit is contained in:
@@ -2,9 +2,12 @@
|
||||
#include "mimi_config.h"
|
||||
#include "bus/message_bus.h"
|
||||
#include "proxy/http_proxy.h"
|
||||
#include "display/display.h"
|
||||
#include "ui/config_screen.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_crt_bundle.h"
|
||||
@@ -167,6 +170,37 @@ static char *tg_api_call(const char *method, const char *post_data)
|
||||
return tg_api_call_direct(method, post_data);
|
||||
}
|
||||
|
||||
static bool tg_response_is_ok(const char *resp, const char **out_desc)
|
||||
{
|
||||
if (out_desc) {
|
||||
*out_desc = NULL;
|
||||
}
|
||||
if (!resp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cJSON *root = cJSON_Parse(resp);
|
||||
if (root) {
|
||||
cJSON *ok_field = cJSON_GetObjectItem(root, "ok");
|
||||
bool ok = cJSON_IsTrue(ok_field);
|
||||
if (!ok && out_desc) {
|
||||
cJSON *desc = cJSON_GetObjectItem(root, "description");
|
||||
if (desc && cJSON_IsString(desc)) {
|
||||
*out_desc = desc->valuestring;
|
||||
}
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Proxy or gateway can occasionally return non-standard payload framing. */
|
||||
if (strstr(resp, "\"ok\":true") != NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void process_updates(const char *json_str)
|
||||
{
|
||||
cJSON *root = cJSON_Parse(json_str);
|
||||
@@ -186,13 +220,17 @@ static void process_updates(const char *json_str)
|
||||
|
||||
cJSON *update;
|
||||
cJSON_ArrayForEach(update, result) {
|
||||
/* Track offset */
|
||||
/* Track offset and skip stale/duplicate updates */
|
||||
cJSON *update_id = cJSON_GetObjectItem(update, "update_id");
|
||||
int64_t uid = -1;
|
||||
if (cJSON_IsNumber(update_id)) {
|
||||
int64_t uid = (int64_t)update_id->valuedouble;
|
||||
if (uid >= s_update_offset) {
|
||||
s_update_offset = uid + 1;
|
||||
uid = (int64_t)update_id->valuedouble;
|
||||
}
|
||||
if (uid >= 0) {
|
||||
if (uid < s_update_offset) {
|
||||
continue;
|
||||
}
|
||||
s_update_offset = uid + 1;
|
||||
}
|
||||
|
||||
/* Extract message */
|
||||
@@ -209,17 +247,34 @@ static void process_updates(const char *json_str)
|
||||
if (!chat_id) continue;
|
||||
|
||||
char chat_id_str[32];
|
||||
snprintf(chat_id_str, sizeof(chat_id_str), "%.0f", chat_id->valuedouble);
|
||||
if (cJSON_IsString(chat_id) && chat_id->valuestring) {
|
||||
strncpy(chat_id_str, chat_id->valuestring, sizeof(chat_id_str) - 1);
|
||||
chat_id_str[sizeof(chat_id_str) - 1] = '\0';
|
||||
} else if (cJSON_IsNumber(chat_id)) {
|
||||
snprintf(chat_id_str, sizeof(chat_id_str), "%.0f", chat_id->valuedouble);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Message from chat %s: %.40s...", chat_id_str, text->valuestring);
|
||||
|
||||
if (config_screen_is_active()) {
|
||||
config_screen_toggle();
|
||||
}
|
||||
char title[48];
|
||||
snprintf(title, sizeof(title), "TG IN %s", chat_id_str);
|
||||
display_show_message_card(title, text->valuestring);
|
||||
|
||||
/* Push to inbound bus */
|
||||
mimi_msg_t msg = {0};
|
||||
strncpy(msg.channel, MIMI_CHAN_TELEGRAM, sizeof(msg.channel) - 1);
|
||||
strncpy(msg.chat_id, chat_id_str, sizeof(msg.chat_id) - 1);
|
||||
msg.content = strdup(text->valuestring);
|
||||
if (msg.content) {
|
||||
message_bus_push_inbound(&msg);
|
||||
if (message_bus_push_inbound(&msg) != ESP_OK) {
|
||||
ESP_LOGW(TAG, "Inbound queue full, drop telegram message");
|
||||
free(msg.content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +353,7 @@ esp_err_t telegram_send_message(const char *chat_id, const char *text)
|
||||
/* Split long messages at 4096-char boundary */
|
||||
size_t text_len = strlen(text);
|
||||
size_t offset = 0;
|
||||
int all_ok = 1;
|
||||
|
||||
while (offset < text_len) {
|
||||
size_t chunk = text_len - offset;
|
||||
@@ -325,50 +381,68 @@ esp_err_t telegram_send_message(const char *chat_id, const char *text)
|
||||
cJSON_Delete(body);
|
||||
free(segment);
|
||||
|
||||
if (json_str) {
|
||||
char *resp = tg_api_call("sendMessage", json_str);
|
||||
free(json_str);
|
||||
if (resp) {
|
||||
/* Check for Markdown parse error, retry as plain text */
|
||||
cJSON *root = cJSON_Parse(resp);
|
||||
if (root) {
|
||||
cJSON *ok_field = cJSON_GetObjectItem(root, "ok");
|
||||
if (!cJSON_IsTrue(ok_field)) {
|
||||
ESP_LOGW(TAG, "Markdown send failed, retrying plain");
|
||||
cJSON_Delete(root);
|
||||
free(resp);
|
||||
if (!json_str) {
|
||||
all_ok = 0;
|
||||
offset += chunk;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Retry without parse_mode */
|
||||
cJSON *body2 = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(body2, "chat_id", chat_id);
|
||||
char *seg2 = malloc(chunk + 1);
|
||||
if (seg2) {
|
||||
memcpy(seg2, text + offset, chunk);
|
||||
seg2[chunk] = '\0';
|
||||
cJSON_AddStringToObject(body2, "text", seg2);
|
||||
free(seg2);
|
||||
}
|
||||
char *json2 = cJSON_PrintUnformatted(body2);
|
||||
cJSON_Delete(body2);
|
||||
if (json2) {
|
||||
char *resp2 = tg_api_call("sendMessage", json2);
|
||||
free(json2);
|
||||
free(resp2);
|
||||
}
|
||||
} else {
|
||||
cJSON_Delete(root);
|
||||
free(resp);
|
||||
}
|
||||
} else {
|
||||
free(resp);
|
||||
}
|
||||
ESP_LOGI(TAG, "Sending telegram chunk to %s (%d bytes)", chat_id, (int)chunk);
|
||||
char *resp = tg_api_call("sendMessage", json_str);
|
||||
free(json_str);
|
||||
|
||||
int sent_ok = 0;
|
||||
if (resp) {
|
||||
const char *desc = NULL;
|
||||
sent_ok = tg_response_is_ok(resp, &desc);
|
||||
if (!sent_ok) {
|
||||
ESP_LOGW(TAG, "Markdown send failed: %s", desc ? desc : "unknown");
|
||||
}
|
||||
}
|
||||
|
||||
if (!sent_ok) {
|
||||
/* Retry without parse_mode */
|
||||
cJSON *body2 = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(body2, "chat_id", chat_id);
|
||||
char *seg2 = malloc(chunk + 1);
|
||||
if (seg2) {
|
||||
memcpy(seg2, text + offset, chunk);
|
||||
seg2[chunk] = '\0';
|
||||
cJSON_AddStringToObject(body2, "text", seg2);
|
||||
free(seg2);
|
||||
}
|
||||
char *json2 = cJSON_PrintUnformatted(body2);
|
||||
cJSON_Delete(body2);
|
||||
if (json2) {
|
||||
char *resp2 = tg_api_call("sendMessage", json2);
|
||||
free(json2);
|
||||
if (resp2) {
|
||||
const char *desc2 = NULL;
|
||||
sent_ok = tg_response_is_ok(resp2, &desc2);
|
||||
if (!sent_ok) {
|
||||
ESP_LOGE(TAG, "Plain send failed: %s", desc2 ? desc2 : "unknown");
|
||||
ESP_LOGE(TAG, "Telegram raw response: %.300s", resp2);
|
||||
}
|
||||
free(resp2);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Plain send failed: no HTTP response");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Plain send failed: no JSON body");
|
||||
}
|
||||
}
|
||||
|
||||
if (!sent_ok) {
|
||||
all_ok = 0;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Telegram send success to %s (%d bytes)", chat_id, (int)chunk);
|
||||
}
|
||||
|
||||
free(resp);
|
||||
offset += chunk;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
return all_ok ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t telegram_set_token(const char *token)
|
||||
|
||||
Reference in New Issue
Block a user