Step by step: Telegram Bot with Heroku and NodeJs

A bit of background:

Adrian Gesto
6 min readMay 9, 2021

I’m renting an office as a home extension, and since some of my workshop needs to be there I didn’t feel very safe without having an “eye” on it.
So besides getting a comercial solution I thought this was a good idea for a project.

In a nutshell, I need automated video survelliance with motion detection and notifications to my cellphone in the case of a breach. This involves some interesting technologies, and looks like a fun project too.

This article will cover some parts of the project, namely a Telegram bot to send notifications to us, an app that talks to the bot, and how to host this.

Let’s start by creating a bot:

For this part of the system I need an app that can send an image to Telegram via a bot, and I decided that I’d like to host it on Heroku.

Fortunately for us Telegram’s documentation is really good, but even so I’ll just summarize the steps here:

We first start by messaging BotFather /start

Then we message again with /newbot and follow the instructions:

After selecting an username and a bot name you’ll be presented by a token,
keep it in a safe place, we will need it later.

That’s it. Congratulations!! you just created a bot

Let’s talk to it with NodeJs:

We have now our bot set up, but we still need an app to interact with it, and for that we will use the token we got on the previous step and node-telegram-bot-api

Let’s start with something simple, here’s a sample app that talks to our bot whenver we say bot or we input /help the bot will respond to us, and if we want to know the current chat Id (we will need it later) we can use /chatid

You’ll need to change the first param on TelegramBot constructor with your api token.

Note I’m using es6 modules so you may require to adjust package.json with "type"="module" in order to run this gist, alternatively save the file as .mjs

And now we can run the app and test our bot.

Our bot is now replying to our messages!

But with this example we can only have the bot react to our input, since bots cannot directly talk to us, we need to create a group and invite the bot:

And now we can have our bot send some messages to our group, but for that we need to first know the chat id.
This is easy to achieve since our code is responding to the chat id of the message originator, and we have set a listener for Bot.onText that responds to us with it:

Now we can have our bot talk to us without us having to initiate the conversation, which is very useful for our project since we want to be notified from an external event (motion detection), and we’d also like to receive an image from the camera originating the event.

For this we’ll need an endpoint that we can hit with an image and also some sort of validation so not anyone can post a picture to this endpoint.

For this we’ll do a very small express app that exposes such endpoint and we’ll ensure to only act on requests with a valid JWT.

So here’s the code:

It may seem a bit overwhelming when looking at all of it at once, but if you go slowly through it you’ll see that it’s pretty much the same code as before, just that now we also have an express server expecting post requests on /pic endpoint which expects a valid token (JWT), and a multipart-encoded picture under the field snap

Now we can use cURL to test our endpoint, note that @debugging.jpgis the image we’re sending, and $AUTH_TOKEN is an env variable that holds a valid JWT:

$ curl -X POST -H "Content-Type: multipart/form-data" -H "token: $AUTH_TOKEN" -F "snap=@debugging.jpg" localhost:3000/pic

And here’s the result of that request:

By sending an image to our endpoint we get an image on our Telegram client!

And that’s it, now we have an app that by exposing a single endpoint can receive an image and relay it to us via a bot on Telegram.

Next we’ll need to host this app somewhere, and Heroku just seems perfect for it.

Enter Heroku

Heroku is a cloud platform that allows us to run our applications on “Dynos”, which are basically a form of containerization for our app and associated services. I won’t go much into detail on Dynos, but if you’re interested you can check Heroku’s documentation.

Since this falls under the category of personal/hobby project we’ll use this tier

If you don’t already have an account on Heroku, go create one! it will be needed for this step:

Log in to Heroku and on your dashboard create a new app:

IMPORTANT NOTE:

Our server must run on the same port as specified by the env var PORT , see https://devcenter.heroku.com/articles/deploying-nodejs#specifying-a-start-script

In order to execute a NodeJs app in Heroku we must set a start script on our package.json as well as an engine:

You can get the source code for all of this project here

For the next part I’ll use Heroku’s cli, you can install it via NPM and login to it:

$ npm install -g heroku$ heroku login

We’ll create a git repository with our project so we can deploy, if you already have your project in a git repo you can skip this part:

$ cd sample-telegram-bot
$ git init

We’ll add heroku’s git remote to our repo:

$ heroku git:remote -a sample-telegram-bot

Now it’s just a matter of pushing our code to the remote we just set

$ git add .
$ git commit
$ git push heroku master

And now if we go back to our admin panel at Heroku, on our application’s overview tab we’ll be able to see something like this:

Our application has been deployed

We’re almost set, but wait we still need to configure our app, so go to settings tab and expand the config vars section. We’ll input our token, secret and chat id.

Once we change our environment varialbes our Dyno will automatically restart.

We’re set and done, now we can send a cURL post request to our app running on the URL provided by Heroku, which in our case is `https://sample-telegram-bot.herokuapp.com`

curl -X POST -H "Content-Type: multipart/form-data" -H "token: $AUTH_TOKEN" -F "snap=@johnny.jpg" https://sample-telegram-bot.herokuapp.com:/pic

Remember to provision the AUTH_TOKEN env var with your JWT

Success!

That’s all for now, we have an idea of how to talk to a bot, get it replying to us and how to get the bot to talk to us whenver a request arrives to our app.

Hope you enjoyed this article, and happy coding!

Source code can be found here

--

--