Author's photo

How Do Telegram Bots Work

  • 3 Aug 2023
  • 1881 words
  • 9 min read

bot telegram

Figure 1. Telegram bot in cyberpunk universe
Figure 1. Telegram bot in cyberpunk universe

You may have heard about Telegram bots or even use them on a daily basis; however, for many people, they seem like small pieces of magic that somehow accomplish tasks. The goal of this post is to grasp the technical side of the Telegram system from a bot’s perspective, to examine how bots communicate with other system components, and to explore what is required to build one.

What is a Telegram bot?

A Telegram bot is a special account that can receive and respond to updates from real users, groups, or channels. It is a piece of software that runs on a remote server and processes received updates. A bot is a small program that can be embedded in Telegram chats and perform specific functions.

What are Telegram bots used for?

Telegram bots can be used for a wide range of purposes, limited only by common sense. Primarily, they help to automate routine tasks such as receiving updates about upcoming weather or your favorite RSS feed, as well as sending reminders for various activities. Big companies utilize bots to offer support features to their users.

Bots are also helpful in managing groups or channels with a large number of participants, as they can assist in removing spam messages and blocking troublesome users. Furthermore, you can even create small games and play with your friends, with the bot taking care of all the management tasks.

Telegram system components

Telegram is a centralized instant messaging service where clients need to communicate with Telegram servers to exchange messages with other clients. This communication occurs through the MTProto encryption protocol, which was designed and built by Telegram engineers.

Thankfully, you don’t have to learn the intricacies of this protocol to create a bot. The Telegram team has developed an intermediary server that conceals the complexity of MTProto and handles all encryption and communication with the Telegram API on your behalf. They named it Telegram Bot API, and it offers a straightforward REST API over HTTPS for receiving and sending updates to client applications.

Figure 2. Telegram system components
Figure 2. Telegram system components

Now, let’s explore the main Telegram components and their interactions as depicted in the figure above.

Telegram API vs Telegram Bot API

The Telegram API serves as the primary entry point for all Telegram clients. If you wish to develop a new client, you must grasp the MTProto protocol and utilize the Telegram API for communication. On the other hand, the Telegram Bot API offers a simplified version of the Telegram API specifically tailored for bots. In most cases, this Bot API should be the preferred choice for implementing bots.

Although it is not mandatory, you can choose to implement a bot using the MTProto API directly (option 1 in Figure 2) instead of going through the Bot API (option 2 in Figure 2). This approach offers certain advantages, such as the ability to retrieve a message by its ID, which the Bot API doesn’t allow. However, it may be overkilling for your use case and could lead to an increase in overall complexity. Additionally, using the MTProto API directly doesn’t provide access to many other features supported by the Bot API, such as webhooks and simpler message formatting.

Telegram Client

A Telegram client is any application approved by Telegram that engages in communication with servers and other clients. If you intend to create a new client, whether it’s for desktop or mobile, you need to obtain the api_id and api_hash and utilize the MTProto Telegram API to integrate with Telegram servers.

Bot Father

This is a super bot that serves as both the starting point for any new bot and a management tool for all your bots. If you wish to create a new bot, you must first contact Bot Father to register your bot and obtain a token, as shown in the figure below. This token is necessary for using the Bot API.

Figure 3. Registering a new bot and obtaining a token via Bot Father
Figure 3. Registering a new bot and obtaining a token via Bot Father

Telegram Bot

It’s the actual software you write and run. Essentially, it is code that interacts with the Telegram Bot API. The API provides a list of updates received from users, groups, or channels, and allows you to respond to users with messages as if the bot were a real user.

What are the main bot components?

To authenticate each request to the Bot API endpoint, a bot must use a token provided by the Bot Father. The endpoint URL follows the format https://api.telegram.org/bot<token>/METHOD_NAME.

Here’s an example of calling getMe to test a token and retrieve basic information about the bot:

# This is a fake token, use your own instead ;)
BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11

curl -s https://api.telegram.org/bot$BOT_TOKEN/getMe | jq '.'
{
  "ok": true,
  "result": {
    "id": 123456,
    "is_bot": true,
    "first_name": "Test",
    "username": "test_bot",
    "can_join_groups": true,
    "can_read_all_group_messages": false,
    "supports_inline_queries": false
  }
}

A bot receives a list of Update objects from Telegram users and responds to those updates by sending Message objects via the Telegram Bot API. These two objects are essential and will be used extensively in your bot development. Let’s execute a few requests and take a closer look at how these objects look like.

Here’s an example of retrieving an update from a test channel:

# Limit a number of updates to one
curl -s https://api.telegram.org/bot$BOT_TOKEN/getUpdates\?limit=1 | jq '.'
{
  "ok": true,
  "result": [
    {
      "update_id": 589880615,
      "channel_post": {
        "message_id": 200,
        "sender_chat": {
          "id": -1001870001123,
          "title": "Test channel",
          "type": "channel"
        },
        "chat": {
          "id": -1001870001123,
          "title": "Test channel",
          "type": "channel"
        },
        "date": 1690960211,
        "text": "Hey bot!"
      }
    }
  ]
}

And this is how we can send a message to a test channel:

curl -s -X POST \
  -H 'Content-Type: application/json' \
  -d '{"chat_id": "-1001870001123", "text": "Hey folks in the channel!"}' \
  https://api.telegram.org/bot$BOT_TOKEN/sendMessage | jq '.'
{
   "ok": true,
   "result": {
      "message_id": 205,
      "sender_chat": {
         "id": -1001870001123,
         "title": "Test channel",
         "type": "channel"
      },
      "chat": {
         "id": -1001870001123,
         "title": "Test channel",
         "type": "channel"
      },
      "date": 1691003950,
      "text": "Hey folks in the channel!"
   }
}

There are two approaches to obtaining updates from the Bot API. You can either use Webhooks or long polling, as described below. It’s not possible to use both simultaneously; if Webhook is set, no updates can be obtained via long polling.

Webhook

As shown in Figure 4, you must create a POST endpoint and request the Telegram server to register it using the setWebhook method. This setup only needs to be done once. The endpoint will be called each time there is a new update for a bot.

Figure 4. Bot receiving updates via registered Webhook
Figure 4. Bot receiving updates via registered Webhook

Upon receiving a POST request with an update, a bot can either:

  • Reply to this request, so the user will receive a reply message.
  • Ignore responding and send a message to the user via a separate API call.

Using Webhook is a good approach if you want to save some CPU resources and achieve a better response time compared to long polling. However, it’s important to note that Telegram only supports HTTPS hooks, so you’ll need a valid SSL certificate to make it work. Using this method for prototyping and running a bot on localhost can make it even more expensive.

Long polling

The alternative to Webhook is long polling, as shown in Figure 5. A bot initiates an HTTP request using the getUpdates method and waits for the server to respond. Whenever there is an update, the Telegram server responds with a list of new updates. The bot then reestablishes the connection, sends a new getUpdates request with the last update offset, and waits for new data.

Figure 5. Bot receiving updates via long polling
Figure 5. Bot receiving updates via long polling

This is what official documentation says about offset parameter of the getUpdates method:

Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will be forgotten.

To avoid receiving updates that the bot has already processed, it needs to keep track of the last seen update and request only new updates by providing a proper offset when calling getUpdates as follows: offset = update_id of the last processed update + 1.

Long polling is an excellent method that works best during the development phase. It doesn’t require any pre-setup like Webhook and a dedicated remote server. You can simply run your bot on localhost and test it right away.

Client libraries

You can use the Telegram Bot API directly; however, many client libraries have been built to simplify that interaction. There are multiple options available and actively supported for each mainstream programming language.

The beauty of such libraries is that they abstract the interaction part and provide you with methods and objects to work with. You don’t need to focus on how to properly implement long polling or parse received JSON; instead, you focus on the business logic of your bot.

Steps to create a bot

So, what do you need to create a bot? Here’s a checklist to follow:

  1. Register a new bot with the Bot Father by executing the /newbot command and providing a name and username for the bot.
  2. Bot Father will give you a token, which you’ll use for communication with the Telegram Bot API. Now you have two options to proceed:
    1. Call the Telegram Bot API directly.
    2. Use a bot client library to call the Bot API.
  3. Write the bot’s logic: process updates and respond with messages.
  4. Run and test the bot on localhost. Using long polling allows you to interact with real Telegram servers even while the bot is running locally.
  5. Deploy the bot to a remote server and set up a Webhook if needed. You may decide to continue using long polling, which is also fine for many use cases.
  6. Manage the bot via the Bot Father: set description, register commands, regenerate token, set up a payment provider, delete the bot, etc.
Figure 6. Steps to create a bot
Figure 6. Steps to create a bot

Bot limitations

There are a few limitations applied by Telegram that you should keep in mind when developing a bot:

  • 1 message per second when sending messages inside a particular chat.
  • 30 messages per second when sending bulk notifications to multiple users.
  • 20 messages per minute when sending messages to the same group.

However, these are considered soft limits rather than hard ones and may be subject to change in the future.

Summary

We have now examined the main components of the Telegram system and explored the role of bots, as well as how they function and interact with users. Bots are not magical entities; they are simply code running on the server, responding to user updates.

The next step in our journey is to delve into the Telegram Bot API, where we’ll create a small bot and gain hands-on experience by utilizing the features provided by Telegram. This will involve working with commands, callback queries, keyboards, and setting up a bot for a channel/group. So, stay tuned, and see you in the next post!