shurillu / CTBot

A simple (and easy to use) Arduino Telegram BOT Library for ESP8266/ESP32
MIT License
147 stars 34 forks source link

double action when esp8266 is restarted #101

Closed mjtrini closed 1 year ago

mjtrini commented 1 year ago

I want to thank you for your fantastic library for telegram. I noticed an issue when my esp8266 setup responds to a telegram chat command; if the esp is restarted within 5 seconds of responding to the last command, upon reboot and reconnection to the internet, the esp will repeat the same response. If the esp is restarted more than 5 seconds after it's response to the telegram chat command, there will be no repeated response.

Is there any means to prevent the CTBot library from checking new messages upon boot of the esp8266?

Much thanks and appreciation, Michael.

shurillu commented 1 year ago

Hello Michael, thank you for using the library. The issue that you are pointing out is dued to a "not marked as read the last received message". In other word, every time you got a new message, if you want to mark it as "read" you must execute a new getNewMessage(). Moreover, the standard getNewMessage() is not blocking, so you must call the blocking version to be sure that the last message is marked as read. To do that, as detailed in the CTBot.h file:

    // get the first unread message from the queue (text and query from inline keyboard). 
    // This is a destructive operation: once read, the message will be marked as read
    // so a new getMessage will read the next message (if any).
    // params
    //   message : the data structure that will contains the data retrieved
    //   blocking: false -> execute the member function only every CTBOT_GET_UPDATE_TIMEOUT milliseconds
    //                      with this trick the Telegram Server responds very quickly
    //             true  -> the old method, blocking the execution for aroun 3-4 second
    // returns
    //   CTBotMessageNoData: an error has occurred
    //   CTBotMessageText  : the received message is a text
    //   CTBotMessageQuery : the received message is a query (from inline keyboards)
    CTBotMessageType getNewMessage(TBMessage &message, bool blocking = false);

So call the getNewMessage() method with the second parameter set to true before the reboot.

I found the same issue when I implemented a bot with a remote reboot command: when a reboot command was sent to the bot, it starts a reboot loop because the last message before the reboot (the reboot command) was not acknowledged. This mean that the bot get the command (reboot), do the reboot, check for a new message and found the same message (reboot), do another time the reboot and so on. To solve this issue, I added a blocking getNewMessage() before the reboot. doing that, I have acknowledged the last message (reboot) and the bot don't enter in the reboot loop as before. Take in mind that the new message retrieved by the blocking getNewMessage() is not lost: after the reboot you can download it because it was not acknowledged.

Here you can find how updates works (check offset parameter)

Hoping that helps.

Cheers

Stefano

mjtrini commented 1 year ago

Thank you for the fast reply!

I tried adding the following line at the end of my telegram code in void loop(). getNewMessage(TBMessage &message, bool blocking = true) However an error of "expected primary-expression before '&' token" is being given by arduino ide.

Can you give an example sketch using the blocking getNewMessage()?

shurillu commented 1 year ago

You can try that code.

If you send a message with the word restart, the bot will reboot (you can check it in the serial console). Any other word will be sent back (like the echobot).

If you comment the the sentence myBot.getNewMessage(msg, true); the bot will be in a reboot loop.

Remember: if you use the locking version of the getNewMessage() method, the program will wait (i.e. block!) until the Telegram Server respond.

#include "CTBot.h"

#define WIFI_SSID "YOUR WIFI SSID"
#define WIFI_PASS "YOUR WIFI PASSWORD"
#define TOKEN     "YOUR TELEGRAM TOKEN"
CTBot myBot;

void setup() {
    Serial.begin(115200); // initialize the serial
    delay(1000);

    Serial.println("\n\nInitializing bot...");

    myBot.wifiConnect(WIFI_SSID, WIFI_PASS); // connect to the WiFi Network
    myBot.setTelegramToken(TOKEN); // set the telegram bot token

    if (!myBot.testConnection()) {
        Serial.println("TestConnection error");
        for (;;);
    }
    Serial.println("Bot ready");
}

void loop() {

    TBMessage msg;
    bool response;

    response = myBot.getNewMessage(msg);

    if (response) {
        if (msg.messageType == CTBotMessageText) {
            // message

            if (msg.text.equalsIgnoreCase("restart")) {
                Serial.println("Restarting bot...");
                myBot.getNewMessage(msg, true);
                ESP.restart();
            }
            else {
                // generic message
                myBot.sendMessage(msg.sender.id, msg.text);
            }
        }
    }
}
mjtrini commented 1 year ago

You Sir are a super genuis! I thank you again for all your efforts!

Much respect, Michael.