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.
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.
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.
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 + "&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:
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:
Clicking on the preview image then posts it into the main chat window:
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.
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
Buy Me A Coffee
If you found something useful above please say thanks by buying me a coffee here...
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