Serverless Telegram bot on AWS Lambda and Python 3
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.
In order to go through this tutorial, make sure you have:
v6.5.0
or laterLet’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:
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:
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>
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 jsonimport osimport sys
here = 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
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: awsruntime: python3.6stage: devregion: us-east-1environment:TELEGRAM_TOKEN: ${env:TELEGRAM_TOKEN}
functions:post:handler: handler.helloevents: - http:path: my-custom-urlmethod: postcors: 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.
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](https://api.telegram.org/botAPHruyw7ZFj5qOJmJGeYEmfFJxil-z5uLS8/setWebhook)
/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"}
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.
~/.bash_profile
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.
The next article will write about chaining multiple lambdas using AWS Step Functions and connecting it to AWS DynamoDB.