Building a Telegram Bot With Firebase Cloud Functions and Telegraf.js
In this post, we will create a simple Telegram Echo bot and deploy it to Firebase within a function. We will use Firebase HTTPS Cloud Function as a webhook for Telegram Bot and will handle all Telegram updates within your function.
Prerequisites
To follow this tutorial you need to have these minimum requirements:
- Node v12.4.0
- NPM v6.9.0
- Telegraf.js v4.0
- Firebase CLI v9.2.0
- Firebase project with Blaze plan. I have already written about how to set Blaze plan on the Firebase platform
- Read more about how Telegram handle updates
- You should register your bot with @BotFather Bot and get the token
NOTE: Firebase requires us to set a Blaze plan in order to work with requests to other APIs (outside of Google Services). In this tutorial, we have to communicate with Telegram API from the Firebase Cloud Function. So, it’s important.
Set up Cloud Functions
We are starting from creating and setting up the Firebase Cloud Functions locally. We need to create a folder and initialize your project using the following command:
firebase init functions
For this setup, we can choose the default values.
On this step you can select to create or use an existing project:
We will go with an existing:
We will use Javascript as a default language:
Dependencies installation is a final step:
Install Telegraf.js
To leverage the work with Telegram API, let’s start using the Telegraf.js package. Telegraf.js is the most used library for developing Telegram Bots using Javascript or Typescript. This library has a large community of enthusiasts and probably the most powerful Telegram API wrapper for Node.js. BTW, you can discover other packages on the Telegram official site.
To install this library, we need to open the functions
folder:
cd functions
and use a simple command for installation:
npm install telegraf --save
NOTE: At the time this post was published, v4.0 was the latest version of Telegraf.js
Set Telegram Token as an environment variable
To avoid using the secret key (the Telegram token is a secret key) within our code we can set up the Telegram token as an environment variable for your Firebase project. Once you’ve got the token from the Botfather bot, we can add this value to the Firebase config:
firebase functions:config:set telegram token= "<telegram-token-string>"
It looks like this:
Later in this article, we will run the function in the Firebase Emulator Suite, so we have to export the Firebase config value to our local runtime configuration. You can do this within the functions
folder by running:
firebase functions:config:get > .runtimeconfig.json
Write Telegram bot and function
Add the following code to functions/index.js
:
All code before the exports.echoBot
line is Echo Bot — this is a sample bot implementation. The code is pretty straight-forward: We set the Telegram token, then implement a simple error-handler, configure a start
command and implement the logic of copying the message within the message
handler.
Then we implement the echoBot
HTTPS trigger function that handles all Telegram updates using the handleUpdate
method. We pass only the body
property of the request
object and response
as a second parameter.
In simple words, Telegram will send all updates to your function and the function will respond to these updates using the handleUpdate
method of the bot
entity. Basically, there is a logic of communicating with Telegram API behind the handleUpdate
.
NOTE: Sometimes Google can send the data to check whether your function is alive or not. This data is not an entity of Telegram update, but we need to respond to requests anyway. For this purpose, we can handle this case within
.then
block (bot.handleUpdate
returns aPromise
). If the Telegram update was handled successfully,rv
variable should betrue
and we will do nothing. Otherwise,rv
will beundefined
and we will respond withStatus Code: 🟢200
Prep work for testing locally
We can test the bot using the Firebase Emulator. But first of all, we need to create a public tunnel link for your bot. Telegram requires an HTTPS endpoint for the webhook value. The HTTPS trigger function will be it. In this section, we will create a public tunnel for your locally-launched function and set it as a webhook for the Telegram bot. Then we will register the public URL as a webhook for the Telegram Bot.
In this tutorial, we will use ngrok as a tool for creating a tunnel. Firebase Emulator runs the function on 5001
, so let's create a public tunnel for this port:
ngrok http 5001
Now we can run the emulator using the following:
firebase emulators:start
The emulator is accessible in the browser and we can check the logs:
After all these tunings, we can access the function from the outside. The pattern:
<ngrok-link>/<project-id>/<region>/<the-name-of-function>
Set the Cloud Function’s URL as a webhook for Telegram
To run the bot locally, we need this last step — register the webhook. We have done the prep work and already know the public URL, that we can use as a webhook.
To register the webhook, we need to use the setWebhook
Telegram API. We have to send the public URL as a query parameter. Use this URL pattern:
https://api.telegram.org/bot<bot-token>/setWebhook?url=<public-link>
You could send a POST
request with Postman or cURL:
TIP💡: Many Telegram APIs have this pattern:
https://api.telegram.org/bot<bot-token>/<method>
.
Telegram API should return a successful message. Now we need to be sure that Emulator is working and we can test the bot.
Example (video)
Let’s interact with the bot. Here is a video:
Deploy the function
After running locally we are ready to deploy this function including the bot functionality, scale it somewhere on Firebase servers and share with users :) We need to stop the local bot and we can deploy it within the functions
folder:
firebase deploy --only functions
You’ll get the function URL that should be used as a new webhook URL for Telegram (just update a webhook with it). Now, this is a real public link without any tunnels.
BTW, if you open the Firebase portal you could see the deployed function and check some real logs (only after the webhook was set):
Video:
TIP💡: To check an existing Webhook you can use the
getwebhookInfo
method:The response will be similar to the following:
Wrapping up
That was a lot of information about how to use Firebase HTTP trigger functions to handle Telegram updates and do Telegram Bot development. Firebase Cloud Functions are a cool solution for hosting multiple bots and scale them automatically.
TIP💡: You can add new cloud functions to extend your bot. For example, create your own proxy functions for setting Telegram tokens using Telegraf.js
TIP💡: Remember that Firebase Cloud Functions is a part of Google Cloud Platform and if your function requires more resources you are free to configure the memory, maximum instances, and timeout per function.