Building a serverless Telegram bot
With the arrival of FaaS and all the serverless infrastructure providers (AWS, Google Cloud, Azure, etc) now is easy to deploy our own Telegram bot.
A Webhook-based bot it's the perfect use case for serverless computing, using for example Google Cloud Functions we'll have all these advantages:
- Our function will be associated to a public endpoint (IPv4 and IPv6) over HTTPS (using a valid certificate provided by Google)
- Pay only for function invocations and its compute resources consumption, so it could be cheaper than paying for a server powered on all the time
- No server management
- Scales automatically
Requirements
Before start building your bot you'll need to:
- Register a new bot following these instructions core.telegram.org/bots in order to get an API token
- Using a Google Cloud account, register a new project, enable the Cloud Functions API and install the Cloud SDK following the official quickstart
Code
In a few lines of Python you can code a simple echo bot that will reply with the same message that it receives:
# main.py import os import telegram def webhook(request): bot = telegram.Bot(token=os.environ["TELEGRAM_TOKEN"]) if request.method == "POST": update = telegram.Update.de_json(request.get_json(force=True), bot) chat_id = update.message.chat.id # Reply with the same message bot.sendMessage(chat_id=chat_id, text=update.message.text) return "ok"
The only dependency needed is the amazing python-telegram-bot library:
# requirements.txt python-telegram-bot==11.1.0
So we just need these 2 files (main.py
and requirements.txt
) to deploy our bot. Google Cloud Functions will detect automatically your requirements file and it will install your dependencies in the environment of your function.
You can find the code and the requirements of this example in github.com/pabluk/serverless-telegram-bot.
Deploy
These are the steps to deploy the bot:
- Get the bot's code
- Create a Google Cloud Function
- Set a WebHook for the bot
- Test everything.
So for the step one you can clone this repository to get a basic example:
$ git clone https://github.com/pabluk/serverless-telegram-bot.git $ cd serverless-telegram-bot
Step two, create a Google Cloud Function running this command in the same line:
$ gcloud beta functions deploy webhook --set-env-vars "TELEGRAM_TOKEN=000:yyy" \ --runtime python37 --trigger-http
Some details:
- Here
webhook
is the name of the function in themain.py
file - You need to specify your Telegram token with the
--set-env-vars
option --runtime python37
describe the environment used by our function, Python 3.7 in this case--trigger-http
is the type of trigger associated to this function, you can find here the complete list of triggers
The above command will return something like this:
Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 128 entryPoint: webhook environmentVariables: TELEGRAM_TOKEN: 000:yyyy httpsTrigger: url: https://us-central1-<PROJECT_NAME>.cloudfunctions.net/webhook labels: deployment-tool: cli-gcloud name: projects/<PROJECT_NAME>/locations/us-central1/functions/webhook runtime: python37 serviceAccountEmail: <PROJECT_NAME>@appspot.gserviceaccount.com sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-xxxxxx/... status: ACTIVE timeout: 3s updateTime: '2018-09-03T16:18:32Z' versionId: '1'
The most important thing of that output is the URL in httpsTrigger because it will be the public endpoint of your bot used by Telegram to send him updates.
Security warning: to simplify this example I set up the Telegram's token via an environment variable but the recommended way to manage secrets on Google Cloud is to use Cloud KMS because the contents of environment variables may result for example being sent to logs.
Step three, you need to set up your Webhook URL using this API call:
$ curl "https://api.telegram.org/bot<TELEGRAM_TOKEN>/setWebhook?url=https://us-central1-<PROJECT-NAME>.cloudfunctions.net/webhook"
You must replace <TELEGRAM_TOKEN>
with your bot's token and <PROJECT_NAME>
with the ID of your Google Cloud project that was returned by the precedent command. If everything is good you'll see this response:
{ "description": "Webhook was set", "ok": true, "result": true }
And finally you can test and play with your bot via curl
:
$ curl "https://us-central1-<PROJECT-NAME>.cloudfunctions.net/webhook" ok
Or via the mobile app:
Next steps
A few considerations:
- Always keep your bot's token safe
- and don't share its Webhook URL to minimize the number of invocations
This a very basic example of what we can do using serverless computing to build a bot, then from here it could be easy to improve it using all the features provided by the python-telegram-bot.org library and by the Google Cloud platform (Storage, Observability, etc).