Telegram Bot Projects on the ESP32

Inline-ESP32-Telegram-Bots.png

Various Telegram Bot projects for the ESP32 such as sending a photo at set intervals, inline stickers and inline articles for sensor readings.

If you don’t have a Telegram account or need help setting up a bot, please see the first part of this tutorial: Running a Telegram Bot on the ESP32-CAM

Bots in Telegram have two modes of interaction. Normal and Inline

Normal Mode

In ‘normal’ mode you can open a chat with the bot and send it messages or, if the bot is a member of a group, you can issue commands to it. This works best if you want a single chat that people can go to to interact with your bot or you have added it to a group and the members know how to issue commands to it. You can’t access the bot outside of the chat or group.

Telegram Bot Chat
Basic chat interaction with the bot
Telegram Bot Command Hint
Command(s) hint for a bot in group
Telegram Bot Command Entry
Issuing a command using the /command syntax

Code for the basic chat interaction is very similar to the echo example. Something like this:

in_name = (bot.messages[i].from_name);
last_chat_id = bot.messages[i].chat_id;
bot.sendMessage(last_chat_id, "Hello " + in_name, "");

Code for the command example above where the user requests that the bot says ‘hello’ every 60 seconds looks something like this:

    
in_command = (bot.messages[i].text);
in_command.remove(0, 1); // remove /
in_name = (bot.messages[i].from_name);
last_chat_id = bot.messages[i].chat_id;
bot.sendMessage(last_chat_id, "Saying hello every " + in_command + " seconds", "");

loop - 
    bot.sendMessage(last_chat_id, "Hello " + in_name, "");
    delay(in_command * 1000); // need to make in_command int for this to work

Inline Mode

In inline mode you can ‘summon’ the bot in any chat or group by typing @username_bot. When these bots are summoned they show options that you can select to add to the chat. The bot is available to use anywhere but the options are normally files stored at Telegram or at a URL so sending something that has been created by a microcontroller on-the-fly is more difficult.

Telegram Bot Inline Request
Summoning a bot using the @botname syntax
Telegram Bot Inline Response
Bot responding with a pre-set selection of stickers
Telegram Bot Response Sticker Posted
Selected sticker posted to chat

The code for the sticker example above looks like this.

    if (bot.messages[i].type == "inline_query") {
      String sticker_json = "["
      "{\"type\": \"sticker\", \"id\": \"klsjfdsgkfjdg1\", \"sticker_file_id\": \"CAACAgIAAxkBAAIEGF5ZAu8QOdzQwuVRC8bx1RzCiYmFAAIVAAPANk8TzVamO2GeZOcYBA\"},"
      "{\"type\": \"sticker\", \"id\": \"klsjfdsgkfjdg2\", \"sticker_file_id\": \"CAACAgIAAxkBAAIEl15aieJNgLyeZBIWIEY9dtLD_DmIAAKjAQACVp29CrgdFd218xk9GAQ\"},"
      "{\"type\": \"sticker\", \"id\": \"klsjfdsgkfjdg3\", \"sticker_file_id\": \"CAACAgIAAxkBAAIEml5ailRBIGearS6ZYit_DQPYe0ypAAILAwAC8-O-CwVcfQRNCcKwGAQ\"},"
      "{\"type\": \"sticker\", \"id\": \"klsjfdsgkfjdg4\", \"sticker_file_id\": \"CAACAgIAAxkBAAIEm15ail7AkPKmb9IXAydc_MlJ4Lb-AAJUCAACYyviCTfLtlzTZ0XfGAQ\"},"
      "{\"type\": \"sticker\", \"id\": \"klsjfdsgkfjdg5\", \"sticker_file_id\": \"CAACAgIAAxkBAAIEnF5ail8XyYPkm0Uh725Vyx-jXXwpAAKPAQACVp29CpMEvY4OJJHGGAQ\"}"
      "]";
      String thing = "/bot" + token + "/answerInlineQuery?inline_query_id=" + bot.messages[i].inline_query_id + "&results=" + sticker_json;
      bot.sendGetToTelegram(thing);
    } else {....

The full inline sticker sketch is here: https://github.com/robotzero1/esp32cam-telegram/blob/master/esp32InlineStickerBot.ino. Remember to use the /setinline command in the BotFather to enable inline mode.

Inline Photos

The previous tutorial covered setting a basic ESP32-CAM based chatbot that would send a photo as a reply in a normal bot chat. It’s possible to use an inline bot to show a new photo from the ESP32 but it’s complicated and prone to timeouts.

You can’t directly send a photo using inline mode because a photo has to be stored at Telegram or be at a URL. To get around this you can send the photo to a private channel, find the photo id in the response and then send this as part of the bots answer to the request. The diagram below shows how to use a private channel to save photos to use in an inline bot.

Diagram for Storing Photos for Inline Chats

The code for this is something like this:

void take_send_photo(String chat_id, String inline_query_id)
{
....

  // send the photo to the private channel
  String response = bot.sendPhotoByBinary(chat_id, "image/jpeg", fb->len, isMoreDataAvailable, photoNextByte, nullptr, nullptr);

  // get the new photo id from the response
  DynamicJsonDocument doc(1200); // guestimated size
  DeserializationError error = deserializeJson(doc, response);
  String photoID = doc["result"]["photo"][0]["file_id"].as<String>();

  // quick and dirty random filename
  long randNumber = random(3000);
  String numberString = String(randNumber);

  String cache_photo_json = "[{\"type\": \"photo\", \"id\": \"" + numberString + "\", \"photo_file_id\": \"" + photoID + "\", \"caption\": \"Post Robot to Chat!\"}]";

  // inline request answer
  String thing = "/bot" + token + "/answerInlineQuery?inline_query_id=" + inline_query_id + "&amp;results=" + cache_photo_json;
  bot.sendGetToTelegram(thing);
...
}

void loop() {
....
if (bot.messages[i].type == "inline_query") {       // inline request to bot
    take_send_photo("-100111111111", bot.messages[i].inline_query_id); // private channel 'chat id'
} else {
    // 
}
....
}

In the chat window when you start typing the @name_bot you will see the name appear:

Inline Start Typing

Click on the bot name. A photo is taken and sent to the private channel and the image id is returned. If this happens fast enough, you see the preview image:

Inline Preview Appears

Clicking on the preview image then posts it into the main chat window:

Inline Image Posted

Inline Sensor Values

You can use a Telegram Bot running on an ESP32 to show the readings from sensors and then insert them into any chat.

Nukey Bot Start Typing
Summoning bot with @bot syntax
Nukey Bot Full
Bot responds inline with sensor readings. Choosing one…
Nukey Bot Inserted
.. adds it to the group

Normally in this scenario you would have the bot automatically push the values into a chat when they reach a certain threshold. The example above just demonstrates how Inline Bots can function.

A better example might be a beach bot that has the sea conditions at various beaches. Someone would request the bot to collect the data, display it inline and then this could be posted into the group with one click as the destination for the day.

Inline sensor code is here: https://github.com/robotzero1/esp32cam-telegram/blob/master/esp32InlineArticleBot.ino

References

Various ESP32 Telegram Sketches : https://github.com/robotzero1/esp32cam-telegram
Universal Arduino Telegram Bot Library: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/V1.2.0

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

scroll to top