shurillu / CTBot

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

Inline keyboard callback queries not received? #72

Closed MicDG closed 3 years ago

MicDG commented 3 years ago

Hello, I am trying to use the inline keyboard but I am not getting any callback query. Notably, using the example included in the library, the inline keyboard is successfully sent to the chat but if I try to click a button I don't get any callback query message on my ESP32. I can receive normal text messages, though.

Could you please help me?

I am using v2.1.3 on an ESP32 DevKit C (i tried both on PlatformIO and on the Arduino APP)(i also tried with v3.0.0).

I also include the code I used though it's the example one plus a few prints.

#include "CTBot.h"

#define LIGHT_ON_CALLBACK "lightON"  // callback data sent when "LIGHT ON" button is pressed
#define LIGHT_OFF_CALLBACK "lightOFF" // callback data sent when "LIGHT OFF" button is pressed

CTBot myBot;
CTBotInlineKeyboard myKbd;  // custom inline keyboard object helper

String ssid = "omitted";     // REPLACE mySSID WITH YOUR WIFI SSID
String pass = "omitted"; // REPLACE myPassword YOUR WIFI PASSWORD, IF ANY
String token = "omitted";   // REPLACE myToken WITH YOUR TELEGRAM BOT TOKEN

void setup() {
  // initialize the Serial
  delay(5000);
  Serial.begin(115200);
  Serial.println("Starting TelegramBot...");

  // connect the ESP8266 to the desired access point
  myBot.wifiConnect(ssid, pass);

  // set the telegram bot token
  myBot.setTelegramToken(token);

  // check if all things are ok
  if (myBot.testConnection())
    Serial.println("\ntestConnection OK");
  else
    Serial.println("\ntestConnection NOK");

  // inline keyboard customization
  // add a query button to the first row of the inline keyboard
  myKbd.addButton("LIGHT ON", LIGHT_ON_CALLBACK, CTBotKeyboardButtonQuery);
  // add another query button to the first row of the inline keyboard
  myKbd.addButton("LIGHT OFF", LIGHT_OFF_CALLBACK, CTBotKeyboardButtonQuery);
  // add a new empty button row
  myKbd.addRow();
  // add a URL button to the second row of the inline keyboard
  myKbd.addButton("see docs", "https://github.com/shurillu/CTBot", CTBotKeyboardButtonURL);
}

void loop() {
  // a variable to store telegram message data
  TBMessage msg;

  // if there is an incoming message...
  if (myBot.getNewMessage(msg)) {
    Serial.print("Received message type: "); Serial.println(msg.messageType);
    // check what kind of message I received
    if (msg.messageType == CTBotMessageText) {
      // received a text message
      if (msg.text.equalsIgnoreCase("show keyboard")) {
        // the user is asking to show the inline keyboard --> show it
        myBot.sendMessage(msg.group.id, "Inline Keyboard", myKbd);
      }
      else {
        // the user write anithing else --> show a hint message
        myBot.sendMessage(msg.group.id, "Try 'show keyboard'");
      }
    } else if (msg.messageType == CTBotMessageQuery) {
      // received a callback query message
      if (msg.callbackQueryData.equals(LIGHT_ON_CALLBACK)) {
        // pushed "LIGHT ON" button...
        Serial.println("Query Light ON received");
        // terminate the callback with an alert message
        myBot.endQuery(msg.callbackQueryID, "Light on", true);
      } else if (msg.callbackQueryData.equals(LIGHT_OFF_CALLBACK)) {
        // pushed "LIGHT OFF" button...
        Serial.println("Query Light OFF received");
        // terminate the callback with a popup message
        myBot.endQuery(msg.callbackQueryID, "Light off");
      }
    }
  }
  // wait 500 milliseconds
  delay(500);
}
MicDG commented 3 years ago

Sooo..

After some digging I actually managed to get the callbacks in v3.0.0 working by changing root[FSTR("allowed_updates")] = FSTR("message,callback_query"); to root[FSTR("allowed_updates")] = FSTR("[\"message\",\"callback_query\"]"); in CTBot::getUpdates()

I see in the Telegram Bot API that "allowed_updates" should be an array of string so maybe that should be fixed?

I wouldn't know how to change it in v2.1.3 though

shurillu commented 3 years ago

Hi MicDG,

first of all, thank you for using the library and for all the effort spent for finding the issue/solution. Today I'm a bit crowded with the work, I'll check ASAP (maybe this late evening) and I'll answer. Briefly, as you pointed out, Telegram seems to have changed/updated the rules to defines which updates you want to subscribe.

Cheers,

Stefano

shurillu commented 3 years ago

Here me again, In my lunch break I checked your code and compiled with:

...and it just work, here the serial output:

VMDPR_Starting TelegramBot...

testConnection OK
Received message type: 1
Received message type: 2
Query Light ON received
Received message type: 2
Query Light OFF received

Now, according with the Telegram docs that you pointed out, I modify the file CTBot.cpp, line 182 parameters = FSTR("?limit=1&allowed_updates=message,callback_query"); with this one parameters = FSTR("?limit=1&allowed_updates=[\"message\",\"callback_query\"]"); and the sketch/code still work.

In order to check if this changes works (here it works in any case!) could you try it please? If it is confirmed to work, I'll make a new release.

Again, thank you for your effort!

Cheers,

Stefano

MicDG commented 3 years ago

Hello Stefano,

I checked again and I think I found the culprit. After reading what you wrote, I tried testing again and, in fact, everything was working and I received the callbacks with both options... this confused me, though, because it didn't work before! So I tried having another read at the Telegram API and I found THIS (which was in plain view, actually, but didn't strike me at first 😇):

Specify an empty list to receive all updates regardless of type (default). If not specified, the previous setting will be used.

And I came to the conclusion that this:

parameters = FSTR("?limit=1&allowed_updates=message,callback_query");

is probably not parsed correctly on Telegram's side which therefore reverts to the previous setting. To test this, I tried to edit the request by removing the callback_query, like this:

parameters = FSTR("?limit=1&allowed_updates=message");

but I still received the callbacks. Using this worked, though:

parameters = FSTR("?limit=1&allowed_updates=[\"message\"]");

Same thing going the other way. This happens both in v2.1.3 and v3.0.0.

So probably my bot's last setting was to not receive the callback queries (how did it get there anyway? 🤔), while yours received them, explaining the different behaviour we got at first.

Yours truly,

Michele

P.S. Thank YOU for the great library!

shurillu commented 3 years ago

Michele, very good job, really!

Thank you, I'm drafting a new release in the two branches with your changes, thanks a lot!

A presto!

Stefano