Serverless Telegram bot on AWS Lambda
In this article, I’ll show you how to create simple echo Telegram bot on webhooks written in Python 3 and deploy it to AWS Lambda using Serverless framework.
My name is Andrii Dvoiak and I’m a team lead and full-stack engineer at preply.com.
We are already using AWS Lambda in production so I decided to show how simple and hustle-free it can be. Relax, sit back and enjoy.
Here is a plan
- Setup Serverles framework
- Get AWS credentials
- Write backend of Telegram Bot on Python 3
- Deploy backend to Lambda
- Connect your backend to Telegram Bot
- Go live
Before we start
In order to go through this tutorial, make sure you have:
- Installed Python 3
- Installed Node.js
v6.5.0
or later - AWS account with admin rights (You can create one for free right here)
Step 1: Serverless framework
Let’s start from the beginning. In order to easily write and deploy our lambda we will use this awesome framework called Serverless. It’s written on NodeJS so we need npm
to install it. Let’s go:
npm install -g serverless
After this, let’s create a new project from template:
serverless create --template aws-python3 --path my-telegram-bot
It will create a new folder my-telegram-bot with two files:
- handler.py — a template for your Python code
- serverless.yml — configuration file
Step 2: AWS Credentials
This is the best part of this process, because once you’ve got credentials, you’ll never deal with AWS again. It’s super easy:
- Log in to your AWS Console, go to My Security Credentials > User and click on “Add User” blue button.
- Specify username (something like “serverless-admin”) and choose only “Programmatic access” checkbox.
- On the second page, choose “Attach existing policies directly” and look for “Administrator Access”.
- Once you created the user, copy your “Access key ID” and “Secret access key”. This is what you actually need to continue.
Congrats. You’ve got your keys. Open your terminal and execute:
export AWS_ACCESS_KEY_ID=<Access key ID>export AWS_SECRET_ACCESS_KEY=<Secret access key>
Step 3: Write Telegram Bot on Python 3
I’m not going to teach you how to write in Python, so just copy this code and paste to your `handler.py` file:
import json
import os
import syshere = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(here, "./vendored"))
import requests
TOKEN = os.environ['TELEGRAM_TOKEN']
BASE_URL = "https://api.telegram.org/bot{}".format(TOKEN)
def hello(event, context):
try:
data = json.loads(event["body"])
message = str(data["message"]["text"])
chat_id = data["message"]["chat"]["id"]
first_name = data["message"]["chat"]["first_name"]
response = "Please /start, {}".format(first_name)
if "start" in message:
response = "Hello {}".format(first_name)
data = {"text": response.encode("utf8"), "chat_id": chat_id}
url = BASE_URL + "/sendMessage"
requests.post(url, data)
except Exception as e:
print(e)
return {"statusCode": 200}
If you are lazy enought, just fork or clone it from my GitHub repo.
Also, you will need to create file requirements.txt
with only one line: “requests” and execute this command to install it locally:
pip install -r requirements.txt -t vendored
Step 4: Deploy to AWS Lambda
Pretty much like on Heroku, all you need is one configuration file “serverless.yml”. Go ahead and edit yours to make it look like this:
service: my-telegram-bot
provider:
name: aws
runtime: python3.6
stage: dev
region: us-east-1
environment:
TELEGRAM_TOKEN: ${env:TELEGRAM_TOKEN}
functions:
post:
handler: handler.hello
events:
- http:
path: my-custom-url
method: post
cors: true
And the magic happens once you execute this in your terminal:
serverless deploy
It will pack all your files into .zip archive and upload to AWS, then it will create AWS API Gateway and return API endpoint for you. You will receive something like this:
endpoints:POST - https://u3ir5tjcsf.execute-api.us-east-1.amazonaws.com/dev/my-custom-url
The serverless backend of your bot is ready to use. You will need this URL on the next step.
Step 5: Connect your backend to Telegram Bot
Lets create new Telegram Bot, using, of course, another bot for this. Go to web.telegram.org and write to this guy @BotFather. He will guide you through the process and you will end up with something like this:
Use this token to access the HTTP API:
459903168:APHruyw7ZFj5qOJmJGeYEmfFJxil-z5uLS8
First of all, set this as your environment variable:
export TELEGRAM_TOKEN="459903168:APHruyw7ZFj5qOJmJGeYEmfFJxil-z5uLS8"
Then, we need set up webhook (register API url of your backend). To do this, you need t send this payload :
{
"url": "<Your API Gateway endpoint>"
}
to this url:
https://api.telegram.org/bot<Your Telegram TOKEN>/setWebhook
go to your terminal again and execute this line (put your url and TOKEN):
curl --request POST --url https://api.telegram.org/bot459903168:APHruyw7ZFj5qOJmJGeYEmfFJxil-z5uLS8/setWebhook --header 'content-type: application/json' --data '{"url": "https://u3ir5tjcsf.execute-api.us-east-1.amazonaws.com/dev/my-custom-url"}'
If you did everything correct, you will receive something like this:
{
"ok": true,
"result": true,
"description": "Webhook was set"
}
Step 6: Go live
We are almost done, lets just deploy it one more time to propagate your secret telegram token into lambda:
serverless deploy
Now it’s live! Congratulations. You can start chatting with your bot.
P.S.
- Don’t forget to save all exported variables somewhere in
~/.bash_profile
- Never commit any api keys to your repository
- At the begining it will cost you nothing, because AWS Lambda has free tier of 100 000 invocations per month and API Gateway gives you 1 million API calls per month for free
- You can fork this example from GitHub repository
- You can find a planty examples of lambdas right here
Conclusion
Serverless approach is very convenient in some cases because it allows you to build very scalable solution. It also change your thinking paradigm about managing and paying for servers.
Serverless framework gives you very simple tool to deploy your function with no need to know AWS or any other cloud provider.
AWS gives you nice free tier period for services so you can build your MVPs totally for free, go live and start paying only if you reach a certain amount of users.
What’s next
The next article will write about chaining multiple lambdas using AWS Step Functions and connecting it to AWS DynamoDB.