Member preview

How To Create Your First Telegram Bot

After more than two years the Telegram Bot Platform improved and offers more features.

Nowadays Telegram Bots can:

  • Interact with users
  • Interact with channels
  • Interact with groups
  • Can provide games
  • Can accept payments
  • Can interact with stickers

It’s been a long time since I’ve not practiced with Bot API, so let’s start again by reintroducing some basics.

You can user bots to enhance user experience on this platform. Run your business on top of Telegram ecosystem.

The Bot Platform provides an HTTP API, so it’s easy to interact with any programming language.

1. Get An API Token From BotFather

The first thing to get is the API token for interacting with the platform. You can get one token by talking with The BotFather.

Use the /newbot command to create a new bot. The BotFather will ask you for a name and username, then generate an authorization token for your new bot.

Use the /newbot command to create a new bot.

The name of your bot is displayed in contact details and elsewhere.

The name of your bot is displayed in contact details and elsewhere.

The Username is a short name, to be used in mentions and telegram.me links. Your bot’s username must end in ‘bot’, e.g. ‘tetris_bot’ or ‘TetrisBot’.

The Username is a short name, to be used in mentions and telegram.me links.

The token is a string like110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw that is required to allow your bot and send requests to the Bot API.

2. Build Your Bot

Now that you have the token, you need to build the logic for your bot.

There is no right programming language for that. Choose the one that you are proficient with and have fun!

But, I will choose Google App Script to host the examples. You can choose that too if you want to learn.

Google App Script

To create your first bot, go to script.google.com and give a name to your script.

Main page of Google App Script
Why Google App Script? Telegram bots require a valid SSL certificate for the bot endpoint. Renting and configuring a VPS with an SSL certificate can be expensive and time-consuming. If you are a beginner and you want to learn this is the quickest way to get started.

The Entry Point

The first thing to do is to paste this boilerplate code.

var token = 'xxxx';
function doPost(e) {
// Make sure to only reply to json requests
if(e.postData.type == "application/json") {

// Parse the update sent from Telegram
var update = JSON.parse(e.postData.contents);
// Instantiate the bot passing the update 
var bot = new Bot(token, update);

// If the update is valid, process it
if (update) {
bot.process();
}
}
}

This is your main entry point. Telegram servers posts updates to your script each time the bot receives a message.

What you need to do is to process the Update object according to your logic. There are no fixed rules.

Your First Bot

Using javascript you can build the bot you like. This is my approach.

Your first define e construction function, that way you can add features to your bot.

function Bot (token, update) {
this.token = token;
this.update = update;
this.handlers = [];
}

I defined a way to register handlers that are triggered by a given condition.

Bot.prototype.register = function (handler) {
this.handlers.push(handler);
}

The process method invokes only handlers that satisfy the given condition.

Bot.prototype.process = function () {  
for (var i in this.handlers) {
var event = this.handlers[i];
var result = event.condition(this);
if (result) {
return event.handle(this);
}
}
}

Command Handler

To process commands you construct an object that satisfies a simple interface:

  • condition(bot)
  • handle(bot)
function CommandBus() {
this.commands = [];
}

With the on method, you register commands that are only triggered when a specific regex matches the command.

CommandBus.prototype.on = function (regexp, callback) {
this.commands.push({'regexp': regexp, 'callback': callback});
}

Since you want to only process commands, this is the condition that you should put in place. Since commands usually start with ‘/’.

CommandBus.prototype.condition = function (bot) {
return bot.update.message.text.charAt(0) === '/';
}

The handle method detects whether the is a matching command. If a command is found it invokes the callback.

CommandBus.prototype.handle = function (bot) {  
for (var i in this.commands) {
var cmd = this.commands[i];
var tokens = cmd.regexp.exec(bot.update.message.text);
if (tokens != null) {
return cmd.callback.apply(bot, tokens.splice(1));
}
}

return bot.replyToSender("Invalid command");
}

Whit this rather strange line of javascript, you defined a rule. That is to pass the bot instance along the matches of the regex.

return cmd.callback.apply(bot, tokens.splice(1));
What is this apply thing? The apply() method calls a function with a given this value, and arguments provided as an array. To read more check the Function.prototype.apply() page on Mozilla Developer Network.

The request method handles the call to the Telegram Bot Platform. It sends each request as a serialized JSON object.

Bot.prototype.request = function (method, data) {
var options = {
'method' : 'post',
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
'payload' : JSON.stringify(data)
};

var response = UrlFetchApp.fetch('https://api.telegram.org/bot' + this.token + '/' + method, options);

if (response.getResponseCode() == 200) {
return JSON.parse(response.getContentText());
}
return false;
}

The replyToSender method is a utility function for your convenience.

Bot.prototype.replyToSender = function (text) {
return this.request('sendMessage', {
'chat_id': this.message.from.id,
'text': text
});
}

Registering The Handler

Since you have the handler for your commands, you need to register them. What you could do is to build first our CommandBus object, adding commands and then register it to the bot.

Place this after var bot = new Bot(token, update);

var bus = new CommandBus();

Your First Command

Respectable bots reply to the most popular command, /start. Is a convention to let your bot understand that someone wants to start a conversation.

It’s not mandatory to reply to the /start command, but it’s a good practice.

Place this after var bus = new CommandBus();

bus.on(/\/start/, function () {
this.replyToSender("Congratulations! It works!");
});

Finally, to register the CommandBus to the bot you use:

bot.register(bus);

3. Deploy And Test

Now that you have everything together you need to deploy the bot.

From Publish hit Deploy as a webapp…

Make sure to select those parameters.

  • Project version: new
  • Execute the app as: Me
  • Who has access to the app: Anyone, even anonymous
Hit Deploy

After hitting deploy you need to give the proper permission to the script. Hit Review Permissions.

Hit Review Permissions

Select your Google account.

Select your Google account.

And Allow the permission.

Hit Allow

Set the Webhook

Your bot will receive updates via the webhook method. To tell Telegram the HTTP endpoint of the bot, use this snippet of code.

function setWebhook() {
var bot = new Bot(token, {});
var result = bot.request('setWebhook', {
url: ScriptApp.getService().getUrl()
});

Logger.log(result);
}

Now select setWebhook from the drop down menù and hit play.

Select setWebhook and hit play.

From View -> Logs you will see this.

Log section.

If you get something like:

{result=true, description=Webhook was set, ok=true}

Everything is good.

Now you can test your bot by sending /start in the chat.

It works! :)

Bonus Command

As a bonus, I’ll show you how to add further commands and redeploy the changes.

The Internet Chuck Norris Database provides a simple API to fetch jokes.

We give to the user the /joke command and it can accept:

  • No parameters. It means that Chuck Norris is used as the name.
  • One parameter. It means that users Name Norris as the name of the joke.
  • Two parameters. It means that users Name Surname as the name of the joke.
function randomJoke(message, name, surname) {
var firstName = name || null;
var lastName = surname || null;

var url = 'http://api.icndb.com/jokes/random?escape=javascript';

if (firstName) url += '&firstName=' + firstName;
if (lastName) url += '&lastName=' + lastName;

var data = JSON.parse(UrlFetchApp.fetch(url).getContentText());
this.replyToSender(data.value.joke);
}

To register the command place this in your doGet method after the last defined command.

bus.on(/\/joke\s*([A-Za-z0–9_]+)?\s*([A-Za-z0–9_]+)?/, randomJoke);

Now deploy again the bot the same way you did in step 3.

So funny!

Conclusions and Takeaway

You learned:

  • How to get a token from BotFather
  • How to code a simple Telegram Bot that replies to the /start command
  • How to host your Telegram Bot on Google App Script
  • How to add a custom command to your Telegram Bot

The complete code is available in this Gist.

Now the limit is only your imagination!