Streamline Telegram Bot Development on AWS Lambda with Telebot Framework

Rralf
Serverless Bots
Published in
4 min readJun 24, 2024

Telebot framework is a very popular for implementing Telegram bots. How can we use it in a Lambda?

Preparing libraries for further work.

In order to use external libraries in a Python lambda function, we need to pre-package these libraries into the lambda function layer.

Let’s create a layer that will include the requests and pyTelegramBotAPI libraries.

There are many articles on the internet how to do this. To do in on Windows machine, use following commands (should be execute in the command line):

mkdir telebot-layer
cd telebot-layer
python -m venv create_layer
.\create_layer\Scripts\activate

echo requests > requirements.txt
echo pyTelegramBotAPI >> requirements.txt
pip install -r requirements.txt

mkdir python\lib\python3.12
xcopy .\create_layer\Lib\*.* .\python\lib\python3.12 /s /e

7z a -r python3.12-telebot-layer.zip python

(If you are working on Windows, you will need 7zip for archiving. For other operating systems, the commands will be different.)

After executing these commands, a file named python3.12-telebot-layer.zip will appear in the telebot-layer folder, which we will use as a layer for our lambda function. Note that we created a layer for the Python 3.12 runtime.

Now let’s upload this layer to AWS.

After creating the layer in AWS, let’s create a function to verify that the libraries are indeed available in our layer.

Function code:

import json
import requests
import telebot

def lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}

Don’t forget to specify the telebot-python312 layer:

After we have added the layer to the function, we can check if it works…

The function executed without errors. This indicates that the libraries from the layer loaded correctly. We can continue exploring how to use telebot in a Lambda function.

Using the telebot framework.

In everyday usage, in all the examples on the internet, telebot framework is used either in infinite polling mode or in asynchronous mode — when the framework independently handles webhook requests from Telegram. But these modes do not suit us. We already know how to run bots in serverless mode (see Using AWS Lambda as Telegram bot backend). We need to somehow make Telebot to handle requests received by the Lambda function.

For this, the Telebot class has a method called process_new_updates. That method takes an Update object as an argument — the request sent by Telegram.

In stand-alone mode, the functionality of that method can be tested with the following code:

import json
import telebot

bot = telebot.TeleBot(
token = '<your-bot-token>',
threaded = False)

@bot.message_handler(commands=['start321'])
def startCommand(message):
bot.send_message(message.chat.id, 'Hi')


req_json = {
"update_id": 788190251,
"message": {
"message_id": 1333,
"from": {
"id": 87575599,
"is_bot": False,
"first_name": "N",
"last_name": "A",
"username": "nainarora",
"language_code": "en"
},
"chat": {
"id": <your-chat-id>,
"first_name": "N",
"last_name": "A",
"username": "nainarora",
"type": "private"
},
"date": 1633935457,
"text": "/start321",
"entities": [
{
"offset": 0,
"length": 5,
"type": "bot_command"
}
]
}
}

json_string = json.dumps(req_json)
update = telebot.types.Update.de_json(json_string)
bot.process_new_updates([update])
print("completed")

This code creates an instance of the Telebot class and calls the process_new_update method, passing it an Update object with a sample request from Telegram. Note that in this example, we are using telebot in single-threaded mode (the argument threaded=False in the object constructor). If you substitute the correct values in <your-bot-token> and <your-chat-id> in the example, you will see the message 'Hi' in your Telegram chat.

Let’s modify the latest version of the Lambda function from the previous article so that it can use telebot to handle commands. We will remove the sendReply method, which sent responses directly to the Telegram HTTP API, and add methods that handle Telegram commands. Binding methods to Telegram commands is done using decorators.

The text of the new version of the function can be as follows:

import json
import telebot

BOT_TOKEN="<your-bot-token>"

bot = telebot.TeleBot(
token = BOT_TOKEN,
threaded = False)


@bot.message_handler(commands=['helloTelebot'])
def startCommand(message):
username = message.chat.username
bot.send_message(message.chat.id, f"Hi, {username}")


def lambda_handler(event, context):
body = json.loads(event['body'])

json_string = json.dumps(body)
update = telebot.types.Update.de_json(json_string)
bot.process_new_updates([update])

return {
'statusCode': 200,
'body': json.dumps('Message processed successfully')
}

The function responds to the command /helloTelebot and replies to the command with 'Hi, <username>'.

You can either create a new Lambda function and register a new webhook URL for it in Telegram or change the code of the function from the previous article.

--

--