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..4db692d 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 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. + 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!")); @@ -375,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()); @@ -386,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(); @@ -415,20 +449,35 @@ int UniversalTelegramBot::getUpdates(long offset) { #endif } } else { // Parsing failed - if (response.length() < 2) { // Too short a message. Maybe a connection issue - #ifdef TELEGRAM_DEBUG + // 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 + + 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 +866,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..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 @@ -86,6 +87,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, @@ -126,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);