shurillu / CTBot

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

Formatting options for text (Markdown or HTML) #68

Open hamster66 opened 3 years ago

hamster66 commented 3 years ago

Hi again :) Is it possible and how to use text formatting in a function sendMessage in version 3.0.0? In the old version I added the parse_mode parameter to the function, like:

bool sendMessage(int64_t id, String message, String keyboard = "", uint8_t parse_mode ); bool sendMessage(int64_t id, String message, CTBotInlineKeyboard &keyboard, uint8_t parse_mode); bool sendMessage(int64_t id, String message, CTBotReplyKeyboard &keyboard, uint8_t parse_mode); . . . if (parse_mode == 1) parameters += (String)F("&parse_mode=Markdown"); if (parse_mode == 2) parameters += (String)F("&parse_mode=HTML");

Do I need to modify the code in 3.0.0 as well, or is it already possible to do this normally?

shurillu commented 3 years ago

Hi Hamster66,

actually I forgot to add this functionality, sorry. I mark this issue as "thing to do"

Thanks!

Stefano

hamster66 commented 3 years ago

Excellent. Hopefully this will happen soon. Of course, it's better for a master to do this :)

hamster66 commented 3 years ago

Hi Stefano. In the form of a crutch, I temporarily solved the issue like this:

bool CTBot::editMessageTextEx(int64_t id, int32_t messageID, const char* message, const char* keyboard) {
    bool response;

#if ARDUINOJSON_VERSION_MAJOR == 5
#if CTBOT_BUFFER_SIZE > 0
    StaticJsonBuffer<CTBOT_JSON5_BUFFER_SIZE> jsonBuffer;
#else
    DynamicJsonBuffer jsonBuffer;
#endif
    JsonObject& root = jsonBuffer.createObject();
#elif ARDUINOJSON_VERSION_MAJOR == 6
    DynamicJsonDocument root(CTBOT_JSON6_BUFFER_SIZE);
#endif

    // payload
    root[FSTR("chat_id")]     = id;
    root[FSTR("text")]        = message;
        root[FSTR("parse_mode")]  = "Markdown";
    if (messageID != 0)
        root[FSTR("message_id")] = messageID;

But for some reason, in order for text selection to start working, for example - bold, three asterisks are needed

***It is bold***
**It is not bold**

Likewise, other formats require three control characters instead of two. Why it turns out this way I can't understand ... :(

shurillu commented 3 years ago

Hello hamster66,

I'm working on this new feature (v3.0.0). Just a little clarification: as the Telegram Bot API says, you need to use only one formatting character. Check this link.

So, I'm using the parse_mode=MarkdownV2 and sending a message with *bold*or _italic_ or ~stroke~ or __underline__ it seems to work simply ok (if placed directly as a text in a sendMessage() method)

They still work ok in a "echoBot" example except the __underline__ style... It act like something is parsing the __ characters... I have to investigate.

Stefano

shurillu commented 3 years ago

Hello hamster66,

I've just uploaded the changes to implement what you asked: calling the method CTBot::setParseMode(CTBotParseModeType parseMode) you can choose between MarkDown (V2) or HTML (or disable the parsing option). Take in mind what Telegram says about special characters here. Lastly, when you need to escape special characters, you need to use double backslash \\. In MarkDown parsing mode, for escaping the ! character, you need to write \\!

Please, let me know if it works as expected, as I can close this issue. Thanks, cheers.

Stefano

hamster66 commented 3 years ago

Hi Stefano. I'm sorry, but something wrong now. I set myBot.setParseMode(CTBotParseModeMarkdown); in setup section of my progect. And when I try to output, I get the following error:

--->sendCommand: Payload
{"chat_id":-xxxxxxxxxxxxx,"text":"*MyProgectName ver 1.2 221020 starting*\n Controller address is:     *192.168.1.243*\n","parse_mode":"MarkdownV2"}
--->receive: HTTPS response error:
--->receive: Content-Length size: 150
--->receive: start payload:
{"ok":false,"error_code":400,"description":"Bad Request: can't parse entities: Character '.' is reserved and must be escaped with the preceding '\\'"}
--->receive: end payload
--->parseResponse: response received
--->parseResponse: JSON error {
  "ok": false,
  "error_code": 400,
  "description": "Bad Request: can't parse entities: Character '.' is reserved and must be escaped with the preceding '\\'"

It looks like the error is caused by the presence of a dot in the text, but it is unrealistic to screen each dot through \\ :(

PS In case my little crutch (upper) I get no this error and text formatting work good Perhaps it makes sense to add another option - Markdown style (not V2), which does not require such escaped with the preceding character '\'.

shurillu commented 3 years ago

Hello hamster66, MarkDownV2 seems to be too "aggressive". I modify the parameter in order to choose the old MarkDown. Calling CTBot::setParseMode(CTBotParseModeMarkdown) now use the old (legacy) MarkDown.

Could you test it and let me know? Thanks,

Stefano

hamster66 commented 3 years ago

Stefano, this looks pretty good now! I checked the mode CTBotParseModeMarkdown and it work nice. Now we need to find testers for mode CTBotParseModeHTML and CTBotParseModeMarkdownV2 :) Thanks for your work! You are awesome! :)

shurillu commented 3 years ago

I'm very happy to hear that! Very good news.

Can we close this issue?

Stefano

hamster66 commented 3 years ago

Yes, apparently you can close