From ab478d46cdbef37c033b5ddd2cbbf8ea6336f3dd Mon Sep 17 00:00:00 2001 From: franc Date: Wed, 21 Sep 2022 10:08:01 +0200 Subject: [PATCH 1/5] Fix von RobertGnz wg. zu langer Nachrichten deleteMessage Funktion README.md angepasst --- .gitignore | 1 + README.md | 10 +++-- src/UniversalTelegramBot.cpp | 76 ++++++++++++++++++++++++++++++++---- src/UniversalTelegramBot.h | 2 + 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 648f8cc..e4b99ca 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ .gcc-flags.json .pio/ .vscode/ +descript.ion diff --git a/README.md b/README.md index 8127696..c131c01 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,6 @@ An Arduino IDE library for using Telegram Bot API. It's designed to be used with Join the [Arduino Telegram Library Group Chat](https://t.me/arduino_telegram_library) if you have any questions/feedback or would just like to be kept up to date with the library's progress. -## Help support what I do! - -I have created a lot of different Arduino libraries that I hope people can make use of. [If you enjoy my work, please consider becoming a Github sponsor!](https://github.com/sponsors/witnessmenow/) - ## Introduction This library provides an interface for [Telegram Bot API](https://core.telegram.org/bots/api). @@ -24,6 +20,12 @@ Each library only supported a single type of Arduino and had different features ![alt text](https://imgs.xkcd.com/comics/standards.png "standards") +Finally I have forked this library, which is since years no more under development, from witnessmenow and I have implemented the fix of [issue #275](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/275) by glorious developer [RobertGnz](https://github.com/RobertGnz) (Thank you!). + +Furhter I have implemented a new API-Call deleteMessage (see UniversalTelegramBot::deleteMessage in the src), to easier ban a chat_id if some flooding attack would happen. + +There is still much work to do: the strings in the library will crash the ESP8266 after a while of running, because of memory issues, see: [Taming Arduino Strings -- How to Avoid Memory Issues](https://www.instructables.com/Taming-Arduino-Strings-How-to-Avoid-Memory-Issues/). J-Rios has already done good work here with his [fork](https://github.com/J-Rios/Universal-Arduino-Telegram-Bot) but it is back in commits (compared to witnessmenow's repo) a lot. Maybe it is possible to use some special string library, e.g. [SafeString](https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html). At the moment I do [daily reset](https://www.forward.com.au/pfod/ArduinoProgramming/ArduinoStrings/index.html#reboot) to avoid memory issues. + ## Installing The downloaded code can be included as a new library into the IDE selecting the menu: diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index fbb1ac7..7e7b900 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -37,6 +37,8 @@ #define ZERO_COPY(STR) ((char*)STR.c_str()) #define BOT_CMD(STR) buildCommand(F(STR)) +// fcw: 2022-07-13: DEBUG +// #define TELEGRAM_DEBUG UniversalTelegramBot::UniversalTelegramBot(const String& token, Client &client) { updateToken(token); @@ -368,6 +370,36 @@ int UniversalTelegramBot::getUpdates(long offset) { } String response = sendGetToTelegram(command); // receive reply from telegram.org +// fcw: 2022-07-13: Bug bei zu grossen Nachrichten, die werden immer wieder abgerufen und blockieren die Abfrage +// so gemacht mit einer 1500 Zeichen grossen Nachricht von Cat (5306541440), danach ging es nicht mehr. +// RobertGnz hat dazu schon einen issue geoeffnet, siehe: +// https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/275 +// Aenderungen sind mit // Robert und // End Robert gerahmt (hier und weiter unten noch eine Zeile). +// Nach der Aenderung von Robert ging es wieder. +// Siehe auch: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/266#issuecomment-985013894 + +// Robert: +// If deserializeJson happen to endup with an error for instance update to big for +// the buffer, then last_message_received will not be updated. +// Subsequent calls to getUpdates uses last_message_received + 1 for the offset value. +// But as last_message_received was not updated we will allways read the same message. +// Here we try to find the update_id and store it to update last_message_received if necessary. + char * pt1; char * pt2; long candidate; + candidate = -1; + pt1 = strstr_P( response.c_str(), (const char *) F("update_id")); + if ( pt1 != NULL ) { + pt1 = strstr_P( pt1, (const char *) F(":")); + if ( pt1 != NULL ) { + pt1++; + pt2 = strstr_P( pt1, (const char *) F(",")); + if ( pt2 != NULL ) { + if ( pt2 - pt1 < 12 ) { // for safety + sscanf( pt1, "%ld", &candidate ); + } + } + } + } +// End Robert if (response == "") { #ifdef TELEGRAM_DEBUG Serial.println(F("Received empty string in response!")); @@ -415,20 +447,24 @@ int UniversalTelegramBot::getUpdates(long offset) { #endif } } else { // Parsing failed - if (response.length() < 2) { // Too short a message. Maybe a connection issue - #ifdef TELEGRAM_DEBUG + // Robert: try to update last_message_received + if ( candidate != -1 ) last_message_received = candidate; + // End Robert + + if (response.length() < 2) { // Too short a message. Maybe a connection issue + #ifdef TELEGRAM_DEBUG Serial.println(F("Parsing error: Message too short")); - #endif - } else { + #endif + } else { // Buffer may not be big enough, increase buffer or reduce max number of // messages - #ifdef TELEGRAM_DEBUG + #ifdef TELEGRAM_DEBUG Serial.print(F("Failed to parse update, the message could be too " "big for the buffer. Error code: ")); Serial.println(error.c_str()); // debug print of parsing error - #endif + #endif + } } - } // Close the client as no response is to be given closeClient(); return 0; @@ -817,3 +853,29 @@ bool UniversalTelegramBot::answerCallbackQuery(const String &query_id, const Str closeClient(); return answer; } + +// fcw: 2022-09-19: um Nachrichten zu loeschen, kopiert und angepasst von sendSimpleMessage(...) +bool UniversalTelegramBot::deleteMessage(const String& chat_id, int message_id) { + bool sent = false; + #ifdef TELEGRAM_DEBUG + Serial.println(F("deleteMessage: DELETE Message")); + #endif + unsigned long sttime = millis(); + + if (chat_id != "" && message_id != 0) { + while (millis() - sttime < 8000ul) { // loop for a while to send the message + String command = BOT_CMD("deleteMessage?chat_id="); + command += chat_id; + command += F("&message_id="); + command += String(message_id); + String response = sendGetToTelegram(command); + #ifdef TELEGRAM_DEBUG + Serial.println(response); + #endif + sent = checkForOkResponse(response); + if (sent) break; + } + } + closeClient(); + return sent; +} \ No newline at end of file diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index 5fc97ee..36fcbeb 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -86,6 +86,8 @@ class UniversalTelegramBot { bool sendSimpleMessage(const String& chat_id, const String& text, const String& parse_mode); bool sendMessage(const String& chat_id, const String& text, const String& parse_mode = "", int message_id = 0); +// fcw: 2022-09-19: Nachrichten loeschen... + bool deleteMessage(const String& chat_id, int message_id); bool sendMessageWithReplyKeyboard(const String& chat_id, const String& text, const String& parse_mode, const String& keyboard, bool resize = false, bool oneTime = false, From c160d969faf3b572b048314ed89a933eefda90cc Mon Sep 17 00:00:00 2001 From: franc Date: Wed, 28 Sep 2022 11:00:13 +0200 Subject: [PATCH 2/5] New: maxResponseLength for too long commands, which are now just ignored --- src/UniversalTelegramBot.cpp | 21 +++++++++++++++++---- src/UniversalTelegramBot.h | 6 +++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 7e7b900..4db692d 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -379,7 +379,7 @@ int UniversalTelegramBot::getUpdates(long offset) { // Siehe auch: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/266#issuecomment-985013894 // Robert: -// If deserializeJson happen to endup with an error for instance update to big for +// If deserializeJson happen to endup with an error for instance update too big for // the buffer, then last_message_received will not be updated. // Subsequent calls to getUpdates uses last_message_received + 1 for the offset value. // But as last_message_received was not updated we will allways read the same message. @@ -407,7 +407,8 @@ int UniversalTelegramBot::getUpdates(long offset) { // close the client as there's nothing to do with an empty string closeClient(); return 0; - } else { + } + else { #ifdef TELEGRAM_DEBUG Serial.print(F("incoming message length ")); Serial.println(response.length()); @@ -418,11 +419,12 @@ int UniversalTelegramBot::getUpdates(long offset) { DynamicJsonDocument doc(maxMessageLength); DeserializationError error = deserializeJson(doc, ZERO_COPY(response)); - if (!error) { +// fcw: 2022-09-28: Hack. Nicht, wenn response zu lang (maxResponseLength in der Header Z135) + if ((!error) && (response.length() < maxResponseLength)) { #ifdef TELEGRAM_DEBUG Serial.print(F("GetUpdates parsed jsonObj: ")); serializeJson(doc, Serial); - Serial.println(); + Serial.println(); #endif if (doc.containsKey("result")) { int resultArrayLength = doc["result"].size(); @@ -447,6 +449,17 @@ int UniversalTelegramBot::getUpdates(long offset) { #endif } } else { // Parsing failed + // fcw: fuer Seriellen Debug + if (response.length() >= maxResponseLength) { + #ifdef TELEGRAM_DEBUG + Serial.print(F("Received too long string in response! response.length(): ")); + Serial.println(response.length()); + Serial.print(F("last_message_received: ")); + Serial.println(last_message_received); + Serial.print(F("candidate: ")); + Serial.println(candidate); + #endif + } // Robert: try to update last_message_received if ( candidate != -1 ) last_message_received = candidate; // End Robert diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index 36fcbeb..b23ad23 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -22,7 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ifndef UniversalTelegramBot_h #define UniversalTelegramBot_h -//#define TELEGRAM_DEBUG 1 +// fcw: hier wird der Bibliotheks Debug-Schalter gesetzt (entkommentiert fuer seriellen DEBUG) +// #define TELEGRAM_DEBUG 1 #define ARDUINOJSON_DECODE_UNICODE 1 #define ARDUINOJSON_USE_LONG_LONG 1 #include @@ -128,7 +129,10 @@ class UniversalTelegramBot { unsigned int waitForResponse = 1500; int _lastError; int last_sent_message_id = 0; +// fcw: 2022-09-27: wenn maxMessageLength kleiner geht es aber nicht mehr. int maxMessageLength = 1500; +// fcw: Antwort Laenge beschraenken, damit Flooding nicht auch noch zurueck gesendet wird. Laenge der Antwort: siehe response.length() Achtung: ohne Inhalt (text) ist die Laenge schon 356 gross. Maximaler Befehl (/open_with_supercode...) ist 391 Zeichen insgesamt +unsigned int maxResponseLength = 400; private: // JsonObject * parseUpdates(String response); From 47d83898d90caa896d414c200adb1dbf4028880e Mon Sep 17 00:00:00 2001 From: franc Date: Wed, 21 Sep 2022 10:08:01 +0200 Subject: [PATCH 3/5] Fix von RobertGnz wg. zu langer Nachrichten deleteMessage Funktion README.md angepasst --- .gitignore | 1 + README.md | 10 +++-- src/UniversalTelegramBot.cpp | 76 ++++++++++++++++++++++++++++++++---- src/UniversalTelegramBot.h | 2 + 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 648f8cc..e4b99ca 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ .gcc-flags.json .pio/ .vscode/ +descript.ion diff --git a/README.md b/README.md index 8127696..c131c01 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,6 @@ An Arduino IDE library for using Telegram Bot API. It's designed to be used with Join the [Arduino Telegram Library Group Chat](https://t.me/arduino_telegram_library) if you have any questions/feedback or would just like to be kept up to date with the library's progress. -## Help support what I do! - -I have created a lot of different Arduino libraries that I hope people can make use of. [If you enjoy my work, please consider becoming a Github sponsor!](https://github.com/sponsors/witnessmenow/) - ## Introduction This library provides an interface for [Telegram Bot API](https://core.telegram.org/bots/api). @@ -24,6 +20,12 @@ Each library only supported a single type of Arduino and had different features ![alt text](https://imgs.xkcd.com/comics/standards.png "standards") +Finally I have forked this library, which is since years no more under development, from witnessmenow and I have implemented the fix of [issue #275](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/275) by glorious developer [RobertGnz](https://github.com/RobertGnz) (Thank you!). + +Furhter I have implemented a new API-Call deleteMessage (see UniversalTelegramBot::deleteMessage in the src), to easier ban a chat_id if some flooding attack would happen. + +There is still much work to do: the strings in the library will crash the ESP8266 after a while of running, because of memory issues, see: [Taming Arduino Strings -- How to Avoid Memory Issues](https://www.instructables.com/Taming-Arduino-Strings-How-to-Avoid-Memory-Issues/). J-Rios has already done good work here with his [fork](https://github.com/J-Rios/Universal-Arduino-Telegram-Bot) but it is back in commits (compared to witnessmenow's repo) a lot. Maybe it is possible to use some special string library, e.g. [SafeString](https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html). At the moment I do [daily reset](https://www.forward.com.au/pfod/ArduinoProgramming/ArduinoStrings/index.html#reboot) to avoid memory issues. + ## Installing The downloaded code can be included as a new library into the IDE selecting the menu: diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 86cd747..bc805f6 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -37,6 +37,8 @@ #define ZERO_COPY(STR) ((char*)STR.c_str()) #define BOT_CMD(STR) buildCommand(F(STR)) +// fcw: 2022-07-13: DEBUG +// #define TELEGRAM_DEBUG UniversalTelegramBot::UniversalTelegramBot(const String& token, Client &client) { updateToken(token); @@ -368,6 +370,36 @@ int UniversalTelegramBot::getUpdates(long offset) { } String response = sendGetToTelegram(command); // receive reply from telegram.org +// fcw: 2022-07-13: Bug bei zu grossen Nachrichten, die werden immer wieder abgerufen und blockieren die Abfrage +// so gemacht mit einer 1500 Zeichen grossen Nachricht von Cat (5306541440), danach ging es nicht mehr. +// RobertGnz hat dazu schon einen issue geoeffnet, siehe: +// https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/275 +// Aenderungen sind mit // Robert und // End Robert gerahmt (hier und weiter unten noch eine Zeile). +// Nach der Aenderung von Robert ging es wieder. +// Siehe auch: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/266#issuecomment-985013894 + +// Robert: +// If deserializeJson happen to endup with an error for instance update to big for +// the buffer, then last_message_received will not be updated. +// Subsequent calls to getUpdates uses last_message_received + 1 for the offset value. +// But as last_message_received was not updated we will allways read the same message. +// Here we try to find the update_id and store it to update last_message_received if necessary. + char * pt1; char * pt2; long candidate; + candidate = -1; + pt1 = strstr_P( response.c_str(), (const char *) F("update_id")); + if ( pt1 != NULL ) { + pt1 = strstr_P( pt1, (const char *) F(":")); + if ( pt1 != NULL ) { + pt1++; + pt2 = strstr_P( pt1, (const char *) F(",")); + if ( pt2 != NULL ) { + if ( pt2 - pt1 < 12 ) { // for safety + sscanf( pt1, "%ld", &candidate ); + } + } + } + } +// End Robert if (response == "") { #ifdef TELEGRAM_DEBUG Serial.println(F("Received empty string in response!")); @@ -415,20 +447,24 @@ int UniversalTelegramBot::getUpdates(long offset) { #endif } } else { // Parsing failed - if (response.length() < 2) { // Too short a message. Maybe a connection issue - #ifdef TELEGRAM_DEBUG + // Robert: try to update last_message_received + if ( candidate != -1 ) last_message_received = candidate; + // End Robert + + if (response.length() < 2) { // Too short a message. Maybe a connection issue + #ifdef TELEGRAM_DEBUG Serial.println(F("Parsing error: Message too short")); - #endif - } else { + #endif + } else { // Buffer may not be big enough, increase buffer or reduce max number of // messages - #ifdef TELEGRAM_DEBUG + #ifdef TELEGRAM_DEBUG Serial.print(F("Failed to parse update, the message could be too " "big for the buffer. Error code: ")); Serial.println(error.c_str()); // debug print of parsing error - #endif + #endif + } } - } // Close the client as no response is to be given closeClient(); return 0; @@ -817,3 +853,29 @@ bool UniversalTelegramBot::answerCallbackQuery(const String &query_id, const Str closeClient(); return answer; } + +// fcw: 2022-09-19: um Nachrichten zu loeschen, kopiert und angepasst von sendSimpleMessage(...) +bool UniversalTelegramBot::deleteMessage(const String& chat_id, int message_id) { + bool sent = false; + #ifdef TELEGRAM_DEBUG + Serial.println(F("deleteMessage: DELETE Message")); + #endif + unsigned long sttime = millis(); + + if (chat_id != "" && message_id != 0) { + while (millis() - sttime < 8000ul) { // loop for a while to send the message + String command = BOT_CMD("deleteMessage?chat_id="); + command += chat_id; + command += F("&message_id="); + command += String(message_id); + String response = sendGetToTelegram(command); + #ifdef TELEGRAM_DEBUG + Serial.println(response); + #endif + sent = checkForOkResponse(response); + if (sent) break; + } + } + closeClient(); + return sent; +} \ No newline at end of file diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index 5fc97ee..36fcbeb 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -86,6 +86,8 @@ class UniversalTelegramBot { bool sendSimpleMessage(const String& chat_id, const String& text, const String& parse_mode); bool sendMessage(const String& chat_id, const String& text, const String& parse_mode = "", int message_id = 0); +// fcw: 2022-09-19: Nachrichten loeschen... + bool deleteMessage(const String& chat_id, int message_id); bool sendMessageWithReplyKeyboard(const String& chat_id, const String& text, const String& parse_mode, const String& keyboard, bool resize = false, bool oneTime = false, From 7058fd63d4b617e13599c5b4b49f277a7be5ed02 Mon Sep 17 00:00:00 2001 From: franc Date: Wed, 28 Sep 2022 11:00:13 +0200 Subject: [PATCH 4/5] New: maxResponseLength for too long commands, which are now just ignored --- src/UniversalTelegramBot.cpp | 21 +++++++++++++++++---- src/UniversalTelegramBot.h | 6 +++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index bc805f6..79079e0 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -379,7 +379,7 @@ int UniversalTelegramBot::getUpdates(long offset) { // Siehe auch: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/266#issuecomment-985013894 // Robert: -// If deserializeJson happen to endup with an error for instance update to big for +// If deserializeJson happen to endup with an error for instance update too big for // the buffer, then last_message_received will not be updated. // Subsequent calls to getUpdates uses last_message_received + 1 for the offset value. // But as last_message_received was not updated we will allways read the same message. @@ -407,7 +407,8 @@ int UniversalTelegramBot::getUpdates(long offset) { // close the client as there's nothing to do with an empty string closeClient(); return 0; - } else { + } + else { #ifdef TELEGRAM_DEBUG Serial.print(F("incoming message length ")); Serial.println(response.length()); @@ -418,11 +419,12 @@ int UniversalTelegramBot::getUpdates(long offset) { DynamicJsonDocument doc(maxMessageLength); DeserializationError error = deserializeJson(doc, ZERO_COPY(response)); - if (!error) { +// fcw: 2022-09-28: Hack. Nicht, wenn response zu lang (maxResponseLength in der Header Z135) + if ((!error) && (response.length() < maxResponseLength)) { #ifdef TELEGRAM_DEBUG Serial.print(F("GetUpdates parsed jsonObj: ")); serializeJson(doc, Serial); - Serial.println(); + Serial.println(); #endif if (doc.containsKey("result")) { int resultArrayLength = doc["result"].size(); @@ -447,6 +449,17 @@ int UniversalTelegramBot::getUpdates(long offset) { #endif } } else { // Parsing failed + // fcw: fuer Seriellen Debug + if (response.length() >= maxResponseLength) { + #ifdef TELEGRAM_DEBUG + Serial.print(F("Received too long string in response! response.length(): ")); + Serial.println(response.length()); + Serial.print(F("last_message_received: ")); + Serial.println(last_message_received); + Serial.print(F("candidate: ")); + Serial.println(candidate); + #endif + } // Robert: try to update last_message_received if ( candidate != -1 ) last_message_received = candidate; // End Robert diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index 36fcbeb..b23ad23 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -22,7 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ifndef UniversalTelegramBot_h #define UniversalTelegramBot_h -//#define TELEGRAM_DEBUG 1 +// fcw: hier wird der Bibliotheks Debug-Schalter gesetzt (entkommentiert fuer seriellen DEBUG) +// #define TELEGRAM_DEBUG 1 #define ARDUINOJSON_DECODE_UNICODE 1 #define ARDUINOJSON_USE_LONG_LONG 1 #include @@ -128,7 +129,10 @@ class UniversalTelegramBot { unsigned int waitForResponse = 1500; int _lastError; int last_sent_message_id = 0; +// fcw: 2022-09-27: wenn maxMessageLength kleiner geht es aber nicht mehr. int maxMessageLength = 1500; +// fcw: Antwort Laenge beschraenken, damit Flooding nicht auch noch zurueck gesendet wird. Laenge der Antwort: siehe response.length() Achtung: ohne Inhalt (text) ist die Laenge schon 356 gross. Maximaler Befehl (/open_with_supercode...) ist 391 Zeichen insgesamt +unsigned int maxResponseLength = 400; private: // JsonObject * parseUpdates(String response); From a9723a77322446fe08c22bc48206e2980c2201ce Mon Sep 17 00:00:00 2001 From: franc Date: Mon, 11 Mar 2024 18:05:27 +0100 Subject: [PATCH 5/5] Fix for too long messages (by RobertGnz), added deleteMessage, only one debug switch (#define TELEGRAM_DEBUG) --- README.md | 11 +++-- src/UniversalTelegramBot.cpp | 79 ++++++++++++++++++------------------ src/UniversalTelegramBot.h | 9 +--- 3 files changed, 46 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index c131c01..6dd56f7 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ An Arduino IDE library for using Telegram Bot API. It's designed to be used with Join the [Arduino Telegram Library Group Chat](https://t.me/arduino_telegram_library) if you have any questions/feedback or would just like to be kept up to date with the library's progress. +## Help support what I do! + +I have created a lot of different Arduino libraries that I hope people can make use of. [If you enjoy my work, please consider becoming a Github sponsor!](https://github.com/sponsors/witnessmenow/) + ## Introduction This library provides an interface for [Telegram Bot API](https://core.telegram.org/bots/api). @@ -20,12 +24,6 @@ Each library only supported a single type of Arduino and had different features ![alt text](https://imgs.xkcd.com/comics/standards.png "standards") -Finally I have forked this library, which is since years no more under development, from witnessmenow and I have implemented the fix of [issue #275](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/275) by glorious developer [RobertGnz](https://github.com/RobertGnz) (Thank you!). - -Furhter I have implemented a new API-Call deleteMessage (see UniversalTelegramBot::deleteMessage in the src), to easier ban a chat_id if some flooding attack would happen. - -There is still much work to do: the strings in the library will crash the ESP8266 after a while of running, because of memory issues, see: [Taming Arduino Strings -- How to Avoid Memory Issues](https://www.instructables.com/Taming-Arduino-Strings-How-to-Avoid-Memory-Issues/). J-Rios has already done good work here with his [fork](https://github.com/J-Rios/Universal-Arduino-Telegram-Bot) but it is back in commits (compared to witnessmenow's repo) a lot. Maybe it is possible to use some special string library, e.g. [SafeString](https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html). At the moment I do [daily reset](https://www.forward.com.au/pfod/ArduinoProgramming/ArduinoStrings/index.html#reboot) to avoid memory issues. - ## Installing The downloaded code can be included as a new library into the IDE selecting the menu: @@ -72,6 +70,7 @@ Here is a list of features that this library covers. (Note: The examples link to | _Long Poll_ | Set how long the bot will wait checking for a new message before returning now messages.

This will decrease the amount of requests and data used by the bot, but it will tie up the arduino while it waits for messages | `bot.longPoll = 60;`

Where 60 is the amount of seconds it should wait | [LongPoll](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/LongPoll/LongPoll.ino) | | _Update Firmware and SPIFFS_ | You can update firmware and spiffs area through send files as a normal file with a specific caption. | `update firmware`
or
`update spiffs`
These are captions for example. | [telegramOTA](https://github.com/solcer/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP32/telegramOTA/telegramOTA.ino) | ``` | | _Set bot's commands_ | You can set bot commands programmatically from your code. The commands will be shown in a special place in the text input area | `bot.setMyCommands("[{\"command\":\"help\", \"description\":\"get help\"},{\"command\":\"start\",\"description\":\"start conversation\"}]");`. See examples | [SetMyCommands](examples/ESP8266/SetMyCommands/SetMyCommands.ino) | +| _Deleting messages_ | Your bot can delete a message. This can be useful to delete unwanted messages from Spambots e.g. | `bool deleteMessage(String chat_id, int message_id)`

Deletes the message from chat_id with the message_id. Returns true if successful. | | The full Telegram Bot API documentation can be read [here](https://core.telegram.org/bots/api). If there is a feature you would like added to the library please either raise a Github issue or please feel free to raise a Pull Request. diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 79079e0..2f53da6 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -37,8 +37,6 @@ #define ZERO_COPY(STR) ((char*)STR.c_str()) #define BOT_CMD(STR) buildCommand(F(STR)) -// fcw: 2022-07-13: DEBUG -// #define TELEGRAM_DEBUG UniversalTelegramBot::UniversalTelegramBot(const String& token, Client &client) { updateToken(token); @@ -330,14 +328,14 @@ bool UniversalTelegramBot::setMyCommands(const String& commandArray) { payload["commands"] = serialized(commandArray); bool sent = false; String response = ""; - #if defined(_debug) + #ifdef TELEGRAM_DEBUG Serial.println(F("sendSetMyCommands: SEND Post /setMyCommands")); - #endif // defined(_debug) + #endif unsigned long sttime = millis(); while (millis() - sttime < 8000ul) { // loop for a while to send the message response = sendPostToTelegram(BOT_CMD("setMyCommands"), payload.as()); - #ifdef _debug + #ifdef TELEGRAM_DEBUG Serial.println("setMyCommands response" + response); #endif sent = checkForOkResponse(response); @@ -369,21 +367,13 @@ int UniversalTelegramBot::getUpdates(long offset) { command += String(longPoll); } String response = sendGetToTelegram(command); // receive reply from telegram.org - -// fcw: 2022-07-13: Bug bei zu grossen Nachrichten, die werden immer wieder abgerufen und blockieren die Abfrage -// so gemacht mit einer 1500 Zeichen grossen Nachricht von Cat (5306541440), danach ging es nicht mehr. -// RobertGnz hat dazu schon einen issue geoeffnet, siehe: -// https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/275 -// Aenderungen sind mit // Robert und // End Robert gerahmt (hier und weiter unten noch eine Zeile). -// Nach der Aenderung von Robert ging es wieder. -// Siehe auch: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/266#issuecomment-985013894 - -// Robert: -// If deserializeJson happen to endup with an error for instance update too big for +// RobertGnz: If deserializeJson happen to endup with an error for instance update too big for // the buffer, then last_message_received will not be updated. // Subsequent calls to getUpdates uses last_message_received + 1 for the offset value. // But as last_message_received was not updated we will allways read the same message. // Here we try to find the update_id and store it to update last_message_received if necessary. +// See: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/275 +// and: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/issues/266#issuecomment-985013894 char * pt1; char * pt2; long candidate; candidate = -1; pt1 = strstr_P( response.c_str(), (const char *) F("update_id")); @@ -419,7 +409,7 @@ int UniversalTelegramBot::getUpdates(long offset) { DynamicJsonDocument doc(maxMessageLength); DeserializationError error = deserializeJson(doc, ZERO_COPY(response)); -// fcw: 2022-09-28: Hack. Nicht, wenn response zu lang (maxResponseLength in der Header Z135) +// Not, if response is too long (maxResponseLength in UniversalTelegramBot.h in L135) if ((!error) && (response.length() < maxResponseLength)) { #ifdef TELEGRAM_DEBUG Serial.print(F("GetUpdates parsed jsonObj: ")); @@ -449,7 +439,7 @@ int UniversalTelegramBot::getUpdates(long offset) { #endif } } else { // Parsing failed - // fcw: fuer Seriellen Debug + // serial Debug if (response.length() >= maxResponseLength) { #ifdef TELEGRAM_DEBUG Serial.print(F("Received too long string in response! response.length(): ")); @@ -460,9 +450,9 @@ int UniversalTelegramBot::getUpdates(long offset) { Serial.println(candidate); #endif } - // Robert: try to update last_message_received + // RobertGnz: try to update last_message_received if ( candidate != -1 ) last_message_received = candidate; - // End Robert + // End RobertGnz if (response.length() < 2) { // Too short a message. Maybe a connection issue #ifdef TELEGRAM_DEBUG @@ -858,7 +848,7 @@ bool UniversalTelegramBot::answerCallbackQuery(const String &query_id, const Str if (url.length() > 0) payload["url"] = url; String response = sendPostToTelegram(BOT_CMD("answerCallbackQuery"), payload.as()); - #ifdef _debug + #ifdef TELEGRAM_DEBUG Serial.print(F("answerCallbackQuery response:")); Serial.println(response); #endif @@ -867,28 +857,37 @@ bool UniversalTelegramBot::answerCallbackQuery(const String &query_id, const Str return answer; } -// fcw: 2022-09-19: um Nachrichten zu loeschen, kopiert und angepasst von sendSimpleMessage(...) +/*********************************************************************** + * DeleteMessage - function to delete message by message_id * + * Function description and limitations: * + * https://core.telegram.org/bots/api#deletemessage * + ***********************************************************************/ bool UniversalTelegramBot::deleteMessage(const String& chat_id, int message_id) { - bool sent = false; - #ifdef TELEGRAM_DEBUG - Serial.println(F("deleteMessage: DELETE Message")); + if (message_id == 0) + { + #ifdef TELEGRAM_DEBUG + Serial.println(F("deleteMessage: message_id not passed for deletion")); + #endif + return false; + } + + DynamicJsonDocument payload(maxMessageLength); + payload["chat_id"] = chat_id; + payload["message_id"] = message_id; + + #ifdef TELEGRAM_DEBUG + Serial.print(F("deleteMessage: SEND Post Message: ")); + serializeJson(payload, Serial); + Serial.println(); #endif - unsigned long sttime = millis(); - if (chat_id != "" && message_id != 0) { - while (millis() - sttime < 8000ul) { // loop for a while to send the message - String command = BOT_CMD("deleteMessage?chat_id="); - command += chat_id; - command += F("&message_id="); - command += String(message_id); - String response = sendGetToTelegram(command); - #ifdef TELEGRAM_DEBUG - Serial.println(response); - #endif - sent = checkForOkResponse(response); - if (sent) break; - } - } + String response = sendPostToTelegram(BOT_CMD("deleteMessage"), payload.as()); + #ifdef TELEGRAM_DEBUG + Serial.print(F("deleteMessage response:")); + Serial.println(response); + #endif + + bool sent = checkForOkResponse(response); closeClient(); return sent; } \ No newline at end of file diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index b23ad23..f18e604 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -22,8 +22,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ifndef UniversalTelegramBot_h #define UniversalTelegramBot_h -// fcw: hier wird der Bibliotheks Debug-Schalter gesetzt (entkommentiert fuer seriellen DEBUG) -// #define TELEGRAM_DEBUG 1 #define ARDUINOJSON_DECODE_UNICODE 1 #define ARDUINOJSON_USE_LONG_LONG 1 #include @@ -36,7 +34,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define HANDLE_MESSAGES 1 //unmark following line to enable debug mode -//#define _debug +// #define TELEGRAM_DEBUG typedef bool (*MoreDataAvailable)(); typedef byte (*GetNextByte)(); @@ -87,7 +85,6 @@ class UniversalTelegramBot { bool sendSimpleMessage(const String& chat_id, const String& text, const String& parse_mode); bool sendMessage(const String& chat_id, const String& text, const String& parse_mode = "", int message_id = 0); -// fcw: 2022-09-19: Nachrichten loeschen... bool deleteMessage(const String& chat_id, int message_id); bool sendMessageWithReplyKeyboard(const String& chat_id, const String& text, const String& parse_mode, const String& keyboard, @@ -129,10 +126,8 @@ class UniversalTelegramBot { unsigned int waitForResponse = 1500; int _lastError; int last_sent_message_id = 0; -// fcw: 2022-09-27: wenn maxMessageLength kleiner geht es aber nicht mehr. int maxMessageLength = 1500; -// fcw: Antwort Laenge beschraenken, damit Flooding nicht auch noch zurueck gesendet wird. Laenge der Antwort: siehe response.length() Achtung: ohne Inhalt (text) ist die Laenge schon 356 gross. Maximaler Befehl (/open_with_supercode...) ist 391 Zeichen insgesamt -unsigned int maxResponseLength = 400; + unsigned int maxResponseLength = 1500; private: // JsonObject * parseUpdates(String response);