Making a Reminder Telegram bot with AWS Lambda and JS
Ayyo what’s good! Recently, my friends and I have been running a social media page that requires daily posting. However, as life is busy and we tend to forget our duty, we need some constant reminder. I, thus, realized a need to make a reminder Bot for my team.
After digging around a little bit, I have discovered AWS Lambda and its amazing FaaS (Function as a Service). In this article, I will be detailing the steps I have taken to write a Telegram bot that sends a message to a group chat everyday and deploy it to AWS Lambda.
Through this article, I hope to provide a basic understanding on how a Telegram bot works, as well as the service offered by AWS Lambda.
So the steps that we will be doing today are:
- Registering for a Telegram Bot
- Using
serverless
CLI tool to generate an AWS Lambda function - Write our code and deploy to AWS Lambda
Registering for a Telegram Bot
In order to make a Telegram Bot, we must first register for one. To do that, go to @BotFather
on Telegram and type /newbot
and follow the steps that follows:
Congrats! You now have a Telegram bot. You can now go to your bot and try typing some messages. You’d realize that your bot is nothing more than a shell at this point. It’s time to understand how Telegram bot works!
How does Telegram Bot works?
By registering for a Bot using BotFather, Telegram provides you with a token to call HTTP Requests, that will translates into the Bot’s performing some actions.
For example, in order for your bot to send a message, you’d be making this GET Request:
GET https://api.telegram.org/bot{{token}}/sendMessage?chat_id={{chat_id}}&text=Hello World
With variable token
to be the token provided to you by BotFather (as above), and the following params:
chat_id
: The ID of the chat that you’re trying to send totext
: The message that you are trying to send
For your bot to be able to reply to messages, you’d be needing your bot to constantly making API calls to Telegram’s server to get updates (or use long polling). In our use case, we only need our bot to send us messages every week, so we would only be using the above HTTP endpoint.
Getting chat_id
We need a chat_id of the chat that we are sending to. To do that, add your bot to your chat group and type /init @your_bot
. If you are only looking for your bot to send you messages, you can type the above to your own chat with the bot without adding it in any group.
Nothing happens. That’s ok. Now make this GET Request to get our chat_id:
GET https://api.telegram.org/bot{{token}}/getUpdates
And you’d be getting this result:
Now you can use this chat_id and the token obtained earlier to send your first message! Simply make a GET request to the /sendMessage
API shown above, with your token
, chat_id
, and text
!
At this juncture, you’d realize that making a Telegram bot that sends our group daily messages is simply calling this GET request daily. Our code simply just need to achieve this task.
While we can write a mini backend application (e.g with express
and node-cron
) and deploy it on a server (e.g DigitalOcean), there were a few things that turned me off with said approach:
- I have to pay money for a server (I’m thrifty)
- I have to manage the server myself and worry about fault tolerance, load balancing and a bunch of other things (this is a part time thing)
And this is where AWS Lambda come in.
AWS Lambda and the Serverless approach
What drew me to AWS Lambda was its Serverless architecture. Serverless doesn’t mean that there is no server involved. Serverless means that you don’t have to manage the server. In AWS Lambda’s case, it allows you to deploy functions to be ran, and then host it on AWS’ server (Function-as-a-Service).
Serverless doesn’t mean that there is no server involved. Serverless means that you don’t have to manage the server
AWS Lambda solves the 2 problems I highlighted above. With its serverless architecture, I don’t have to manage the server myself. AWS free tier comes with 1M free requests per month and 400,000 GB-seconds of compute time per month. Way more than enough for an average user.
If you don’t have already, create an AWS Console account. We would also be using the serverless
CLI tool to write and deploy our code. In your terminal, run npm install -g serverless
.
Once you have installed, let’s generate an AWS Lambda function that we could code and deploy! In this tutorial, I will be using Javascript. Thus, in your terminal, run serverless create -t aws-nodejs
. It will generate the following files:
Real simple! Ahandler.js
file that contains your logic and a serverless.yml
file that handles the settings of our AWS Lambda function.
To call an API, you’d need axios
. So run npm init
and initialize this project as an npm project. Then runnpm install --save axios
and put the following logic in handler.js
:
By this logic, everytime that this method is evoked, it would call Telegram’s /sendMessage
endpoint. You might be asking yourself now: Where is the scheduler? Let’s head over to serverless.yml
:
By default, our serverless.yml
looks like this. It is a little much, but we will not need a lot of it. This is all that we will need:
functions
lists out the list of functions that we are deployinghello
on line 8 is the name of our function. You can change it as you likehandler.hello
is the method name in ourhandler.js
. If you decide to changemodule.exports.hello
tomodule.exports.yourFunctionName
, you would need to update it herepath
is the endpoint that this method maps toschedule
denotes the frequency that this endpoint will be called. I am using acron
expression to denote how often that it will be called (everyday at 1pm GMT for the expression above). You can read more about cron expression here. Do note that time is in GMT so convert accordingly
Awesome! All that is left is to deploy it on AWS Lambda!
Deploying to AWS Lambda
First, we’ll need to connect our serverless
CLI tool to our AWS Lambda account. Head over to AWS Console and click on [User] > My Security Credentials like so:
Then click on Access keys > Create new access key like so:
Note that these keys have root access to your AWS Account. This is ok for now as there is only 1 person managing your account’s resources. For companies, it is better to create an IAm account with limited access rights.
After obtaining these keys, key this in your terminal:
serverless config credentials --provider aws --key your_access_key_id --secret your_secret_access_key
Great! Now just run serverless deploy
. Initial deployment should take about a minute, but subsequent deployment would take way less time!
Congrats! At this point, you have successfully:
- Made a Telegram Bot using BotFather
- Code a logic that calls a HTTP Request from Telegram to send a message to a group chat
- Deploy that logic on AWS Lambda and schedule that endpoint to be evoked everyday at 1pm GMT
You can test that deployment is successful by clicking on the endpoint under Service Information!
Managing on AWS Console UI
To see your deployed codes on AWS Console. Simply go to your AWS Console and search for Lambda. You would see your code have been deployed there!
You can also make changes to the code on AWS console itself, though I suggest making changes locally and then deploy so that your local version and the deployed version is in sync.
To see the scheduled calls, click on Services on the header and search for Cloudwatch. Then click on Rules under Event on the Sidebar. You would see your app’s run schedule. Click on it to see when it will be triggered.
Closing Remark
With this article, I hope you have learnt a little bit more about how Telegram bot works and how AWS Lambda works! I personally find AWS Lambda super useful for making small, stateless APIs that helps me with my daily automation.