Build a telegram bot using node.js and heroku

10 November 2015   Comments   nodejs heroku telegram

A little while ago I started using telegram as my messaging app (admittedly along-side dozen other apps). But it didn’t take long till I realized, there is something different about telegram which is really cool. It’s [almost] fully open-source and more importantly highly programmable, so much that they natively support bots! and quickly I found myself wanting to write my own bot.

In this article I will take you through the steps of how to write a very simple telegram bot that interacts with users on telegram and delivers a service. You can use this as a starting-point for building your more complex bots.

Register your bot

Like many other platforms, the first thing you need to do is to register your app. Doing so is amazingly simple in telegram and is done via… well… another bot on telegram!

@BotFather is the telegram’s designated robot for registering and managing your bots. Simply start chatting with it and you will see all of your options. – here we focus only on registering our new bot.

Simply type:

/newbot

and you will be asked to provide a name and identifier for your bot. Once done, BotFather will give you a token which is what you need to configure in your server component later in this article.

Problem domain

For the sake of this tutorial, let’s assume we need our bot to support the following two commands:

  • /say_hello <your-name> to reply Hello <your-name>
  • /sum <num1> <num2> ... to sum up any given numbers and reply with the result

Bot server

Next, we need to write a node.js program that listens to the incoming communications from bot users and responds to them.

For this we use node-telegram-bot-api which is a nicely-done wrapper around telegram’s bot api.

npm init
npm install --save node-telegram-bot-api

Now create bot.js file:

var token = '<token-from-bot-father>';

var Bot = require('node-telegram-bot-api'),
    bot = new Bot(token, { polling: true });

console.log('bot server started...');

This will instantiate a new instance of Bot in polling mode (i.e. an infinite loop that reads incoming messages as they come) using the token we obtained earlier.

Now, let’s write our first command listener:

bot.onText(/^\/say_hello (.+)$/, function (msg, match) {
  var name = match[1];
  bot.sendMessage(msg.chat.id, 'Hello ' + name + '!').then(function () {
    // reply sent!
  });
});

Above code registers a text-listener that calls our callback whenever a text message is received matching the given syntax. The reg-ex also extract the name segment out of the message and passes to the callback via the match parameter.

Then we send a text message back to the sender of the original message (msg.chat.id which may be a group or individual chat) with the result.

And similarly our sum command:

bot.onText(/^\/sum((\s+\d+)+)$/, function (msg, match) {
  var result = 0;
  match[1].trim().split(/\s+/).forEach(function (i) {
    result += (+i || 0);
  })
  bot.sendMessage(msg.chat.id, result).then(function () {
    // reply sent!
  });
});

This one has a slightly more complicated reg-ex which extracts all of the numbers given as the command parameter, then split the chunk, convert them to integer (+ prefix) and sum-up. Then similar to above, send the result back to the user.

Run!

Run the bot and bingo!

node ./bot.js

Your bot should now be responding to the messages:

screen

Http end-point

There are two reasons why we need to add an http end-point to our node.js bot server:

First of all to continue enjoying Heroku for free, we want our polling loop to run for-ever on a web role (as oppose to a paid Heroku scheduler add-on). Heroku shuts the web role process down, if no http port is listened from the process within 30 seconds.

Additionally I would like to set-up a web monitoring service (Uptime Robot provides this for free), to ensure my server is always up and running and never goes to sleep.

So I spin up a simple web server that simply returns app version number as json.

npm install --save express
var express = require('express');
var packageInfo = require('./package.json');

var app = express();

app.get('/', function (req, res) {
  res.json({ version: packageInfo.version });
});

var server = app.listen(process.env.PORT, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Web server started at http://%s:%s', host, port);
});

Finally we need to add an index.js file to start both bot and web servers:

require('./bot');
require('./web');

Now by starting the app (node .), you should get an output like this:

bot server started...
Web server started at http://0.0.0.0:64861

Deploy

Finally we need to create and deploy our Heroku app.

heroku create

This will create a new app in your heroku account (you will be asked to setup one if have no account setup) with a random name. To open the app in your browser simply run:

heroku open

Each time you need to deploy the app, simply run the following command and push your latest code to heroku remote repo, which then results in your node.js app to build and start on Heroku server.

git push heroku master

Conclusion

This is a minimalistic example to show you how easy and cool it is to create your own telegram bot in no time. You can keep adding more and more complexity and business logic to your server. For example remember users’ choice in a database to then report back to them in later commands, etc.

Telegram opens up a whole new ways of communicating with users, including sending audio, photo, location, etc. and even communicating with user chat groups. For more information see telegram bot API.

A complete source code of this tutorial can be found on the following GitHub repository:

https://github.com/mvalipour/telegram-bot-simple


blog comments powered by Disqus