Building a Serverless Telegram Bot on AWS
Nowadays, chat bots are frequently used on instance messaging platforms to send notifications, host/play games, moderate groups, check for services etc. I’ve always wanted to try out to build a small notification bot myself. So, I decided to take a serverless approach to it.
I chose Telegram for this project as their Bot API was quite easy to understand. There are also very useful bot frameworks built around the API, so I could get started quickly.
Features Included
The goal of this project is to get the basics working and build more features as we go.
- Automatically setup an API endpoint (called a webhook) for Telegram to send updates (ie. whenever any message is sent to the bot).
- Have the bot respond to a few commands.
The project is available on Github if you wish you try it out yourself.
Create the Bot
Check out the guide from Telegram to create your bot. The instructions are straighforward. The important piece here is to get the token
which is used to make authorized requests to the Bot API.
Lambda Code Walkthrough
I’m using NodeJS for the the Lambda code here. I’m not going to dive in too much into the code detail, but I’ll highlight some of the important parts in this code.
The structure of the code is made up of 2 functions, that are triggered based on which API endpoint is called.
// handler.js
// setup the bot
// hello function handles updates(messages) sent from Telegram to the webhook API
module.exports.hello = async event => {
// using a try/catch block
try {
// process event data
const body = JSON.parse(event.body);
// bot handles processed data from the event body
await bot.handleUpdates(body);
// return an Ok response
} catch (err) {
// handle any errors
// return any Err responses
}
}
// setWebhook function handles initial webhook setup for Telegram
module.exports.setWebhook = async event => {
// using a try/catch block
try {
// process webhook url based on event data
let url = 'https://' + event.headers.Host + '/' + event.requestContext.stage
+ '/webhook';
// use bot methods to set the webhook url
await bot.telegram.setWebhook(url);
// return an Ok response
} catch (err) {
// handle any errors
// return any Err responses
}
}
Telegraf Bot Framework
Telegraf is a Telegram Bot Framework for NodeJS which has a good set of features and is easy to use. In this example I’m implementing a few commands that the bot will respond to using this framework.
// setup the bot
const { Telegraf } = require('telegraf');
const bot = new Telegraf(process.env.BOT_TOKEN);
// set a start command
bot.start((ctx) => {
return ctx.reply('Hello from Lambda! Use /help to view available commands.');
});
// bot handles processed data from the event body
await bot.handleUpdates(body);
Deploy using Serverless Framework
Using the Serverless Framework, we can define all the resources required in a .yml
file and it will go deploy the application on AWS.
I already talked about how I used it in an earlier post. But there are some important things to note in this setup highlighted below.
# set the BOT_TOKEN as an environment variable so that it
# is accessible to the function
# define env variables under provider section
provider:
name: aws
runtime: nodejs12.x
environment:
BOT_TOKEN: ${file(./serverless.env.yml):TELEGRAM_TOKEN, ''}
# define functions and their API endpoints
functions:
hello:
handler: handler.hello
events:
- http:
path: webhook
method: post
cors: true
set-webhook:
handler: handler.setWebhook
events:
- http:
path: setWebhook
method: post
cors: true
Deploy by running serverless deploy
on the terminal and that’s it. After a few minutes your application will be setup on AWS.
It’ll show the output of the configuration once completed.
Get Updates from Telegram via Webhook
There are 2 ways of getting updates from Telegram; polling and webhook. Since this is a serverless application and functions are triggered on events, we’ll be using the webhook method.
So, as the final step, register the bot’s webhook URL with Telegram by calling the setWebhook
API endpoint.
curl -X POST https://<api_gateway_url>/prod/setWebhook
And that’s about it!
Test the Bot
Send a few commands and check out the replies.
Final Thoughts
- Most of the time for this project was spent on figuring out how to use the bot framework and NodeJS as this is my first time using the language.
- I think I should have a separate file to implement the bot functionality and have the
handler
refer to it. That way it would be more modular and I can update parts of the application easily.
References
- Telegram notifications bot with Firebase Cloud Functions. Reading Maail’s article was how I got the general idea to build this.
- Serverless Telegram Bot - Python Example. This NodeJS port is based on the original Python code structure.
- Telegraf; Telegram Bot Framework
- Marvin’s Marvellous Guide to All Things Webhook. This guide is very useful to know the structure of the
JSON
updates sent by Telegram.