CTBot
CTBot copied to clipboard
CTBotInlineKeyboard addButton String param issue
Hi Stefano
I was modifying a bit my already working application code that uses CTBot, then my inline menu stopped working. Then I noted an interesting thing:
(Sorry I am not familiar with styling here): Working code:
CTBotInlineKeyboard kbd;
...
kbd.addButton("Act1", "Command1", CTBotKeyboardButtonQuery);
Then, since I was (am) replicating strings, decided to do:
String cmd1 = "Command1";
CTBotInlineKeyboard kbd;
...
kbd.addButton("Act1", cmd1, CTBotKeyboardButtonQuery);
Then, the menu stopped working, because I replaced explicit text parameters with String variables..
Well, the reference states clearly that one passes a STRING as parameter:
bool CTBotInlineKeyboard::addButton(String text, String command, CTBotInlineKeyboardButtonType buttonType)
But if I pass a String as a parameter, the menu does not mount, I need to pass a text (as the example above) for it to work. This way I get duplicated strings in the code.
Is this an implementation issue or documentation issue?
Best regards Lissandro
PS.:
I changed
kbd.addButton("Act1", cmd1, CTBotKeyboardButtonQuery);
to
kbd.addButton("Act1", cmd1.c_str(), CTBotKeyboardButtonQuery);
then it worked. I presume your code is working with something like that instead (did not check first parameter)
"bool CTBotInlineKeyboard::addButton(String text, C-style string command, CTBotInlineKeyboardButtonType buttonType)"
Hello Lissandro,
it's a very weird behavior! The two parameters are declared as String, so they must accept a string as input. BTW I try to modify the inline keyboard example just doing these simply changes:
//#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
String LIGHT_ON_CALLBACK = "lightON"; // callback data sent when "LIGHT ON" button is pressed
String LIGHT_OFF_CALLBACK = "lightOFF"; // callback data sent when "LIGHT OFF" button is pressed
Adding my WiFi credentials and my Telegram Bot Token the example just work.
I tested the code with an ESP8266 (NodeMCU) and the 2.1.3 library version. Are you using the same library version or are you using the v3.0.0 version? Finally I compile&run the example with the ArduinoJson library v5.13.5 and the v6.1.17.
Could you try the example?
Cheers,
Stefano
Hi.
Consider
String var = "button".
I tried previously as you made here when I pass the String variables the menu does not show on the client
i.e. var
.
If I pass a string literal i.e. "button"
then it works.
If I take var.c_str()
it works.
I am using the latest libs.
It is working with c_str()
though, I will let as this.
Hi Lissando,
finally I solved the riddle. One of the major changes in the v3.0.0 is the use of "C style string" only inside of the library: most of the issues related to random resets are dued to the String
class.
BTW, for backward compatibility, there are stub member functions that takes String
parameters as input but inside calls the "C style string" versions. So, the addButton
member function exist in two form:
bool addButton(const String& text, const String& command, CTBotInlineKeyboardButtonType buttonType);
bool addButton(const char* text, const char* command, CTBotInlineKeyboardButtonType buttonType);
When you use only String
type parameters, will be executed the first, when you use only "C style string", will be executed the second one.
By the other hand, when you mix the two types of string, there are two possibilities:
- First parameter
String
, second parameter "C style string": in this case, will be executed the first one and the second parameter will be converter inString
by the constructor. - First parameter "C style string", second parameter
String
: in this case will be executed the second one and you must force the string conversion of the second parameter by using theString
member functionc_str()
, because the "C style string" don't have a constructor (it is just a pointer, not a class).
So this is the explanation of the weird behavior.
Cheers,
Stefano