Writing a Telegram Bot Step by Step

Hi! This week I interacted myself and wrote my own telegram bot. It’s a brief instruction how to make this shit working.
Firstly - please care about valid SSL certificate. Yes, Telegram requires a valid SSL certificate for webhooks. Yes, for staging server too. If you found a way to avoid it - please tell me, it will make me happy and this post more useful.

I was thinking bot creation process is something complicated but fortunately, I had mistaken. Bot workflow if pretty simple, so I will separate this flow into section

  1. Ask @BotFather for a new bot. (It’s not a joke)
  2. Configure name and avatar of your bot
  3. Doing main steps to make backend working
  4. Writing commands. Why it’s a good idea to separate commands in separate entity.
  5. Test your bot

Visiting BotFather

“A friend should always underestimate your virtues and an enemy overestimate your faults”

― Mario Puzo, The Godfather
Actually, it’s just a bot creation step. Telegram meaning bots is a future of interfaces so the one way you can create a bot is … write one other bot. Just add @BotFater and ask him to a bot. Just type /newbot command to BotFather and He will answer you :) It would be simple answers which will lead you in bot creation process.

Do not forget to save API token, it’s the main result of this step and we will use this API key for all communications with telegram server. It allows us check webhooks from telegram and prevent unauthorized access and also will authorize us on telegram server when we will interact with its server.

Shit happens frequently and a lot of cool bot names already occupied. Including local Ukrainian! Be ready to spend a time looking for a nice name.

After bot creating let’s give him a bit humanity, so BotFather can help us with it:

/setname - set name to your bot. You have a name. Your parents have names. Your friends have names. Why your bot doesn’t has? :)

/setuserpic - I sure your bot already has any cool selfie for the avatar?

/setdescription and /setabouttext is absolutely different fields. /setdescription provide you possibility to set any greeting text which user will receive after adding conversation with your cute bot. /setabouttext - is responsible for the text which should be displayed in bot profile. Yes, the bot has a profile like any other telegram user.

All it was done? Great, we can proceed.

Bot settlement

“I’m gonna make him an offer he can’t refuse.”

― Mario Puzo, The Godfather
Great, we have a bot but it absolutely useless for a moment. I can compare it with “facebook developers application” which allows you to use OAuth API, for example.

We should prepare a server with a connected domain name and valid SSL key. Check is it working correctly before proceeding.

It’s a time to a little explanation. How it exactly work. Users can add your bot to the contact list and begin speaking with it. When user sends any command to your bot - telegram server send a POST request to your webhook URL. Depends on command name and arguments you can run commands and return a target information in response which would be passed to the user. And you can return media objects too, but I’ll explain it a bit later.

I’ll use PHP as the programming language for examples and Laravel 5.2 as the framework. I admit, it’s a little cheating - you can find working extensions for Laravel which simplifying Telegram API implementation. You can also try it. Just check its GitHub repository .

If you will write the client code from the scratch you can check official code listing here https://core.telegram.org/bots/samples/hellobot . As you can understand - it’s simple enough, so not requires any complicated implementation.

Let’s proceed with the telegram-bot-sdk extension which I using for example. Firstly it should be installed. If you familiar with Laravel and vendor extensions installation flow - you can skip next two paragraphs directly to the implementation of the code.

To start using telegram-bot-sdk you need to install it using composer, so add

"irazasyed/telegram-bot-sdk": "^2.0"

to your composer.json file and run

composer install

After a success message you will able to include this module in your laravel application, so let’s add sdk to your providers

Telegram\Bot\Laravel\TelegramServiceProvider::class

and facades

'Telegram'  => Telegram\Bot\Laravel\Facades\Telegram::class

and publish it

php artisan vendor:publish

Almost done. After publishing, you can find a telegram.php in the config folder. Just add your API Key there and enjoy.

Now you can start using API. The simplest way to check configuration - call the getMe method. I found a lot of examples with static calls to

Telegram\Bot\Laravel\TelegramServiceProvider::getMe()

but seems it’s added to documentation just to reducing an amount of sample code. I don’t found a way to use static calls, so one way you can interact with API - create a new instance of TelegramServiceProvider in each command. By the way - commands is something like actions in controllers, but the developer of the plugin is supposed to use commands as a separate entity in the form of separate files. Why not, actually.

I created a controller for handling Telegram functionality but I sure route description will be unnecessary in this post.

Controller looks like

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use Telegram\Bot\Api as Telegram;
use App\Helpers\TelegramResponse as Response;

class TelegramController extends Controller
{
    public function getHello() {
    	$api = new Telegram();

    	$response = $api-&gt;getMe();
    	return Response::handleResponse($response);
    }
}

TelegramResponse - isn’t a part of SDK, it’s just a little class written by me which wraps default response component and injects telegram response’s validation.

If getMe method returns your bot information - it’s working and we can proceed

Using components to handle webhooks

“Great men are not born great, they grow great . . .”

― Mario Puzo, The Godfather
Fine. Let’s talk about commands. You can define all commands you have in your telegram.php file. Also, you can ask @BotFather for it and do it when you eating in the car for example. As you understand - you should create command files with classes for each /command. You can place it anywhere, just add a folder to your autoloader and all will be fine.

Typical command skeleton will be similar to this listing:

<?php

namespace Vendor\App\Commands;

use Telegram\Bot\Actions;
use Telegram\Bot\Commands\Command;

class StartCommand extends Command
{

}

Commands extends Command class which implements Command interface. I will provide it here to explain which logic should command realize

<?php

namespace Telegram\Bot\Commands;

/**
 * Interface CommandInterface.
 */
interface CommandInterface
{
    /**
     * Process Inbound Command.
     *
     * @param $telegram
     * @param $arguments
     * @param $update
     *
     * @return mixed
     */
    public function make($telegram, $arguments, $update);

    /**
     * Process the command.
     *
     * @param $arguments
     *
     * @return mixed
     */
    public function handle($arguments);
}

Command class implements methods which describe chat functions and logic. Now you can do anything, just use methods of Command class like replyWithChatAction, replyWithMessage, triggerCommand and others. You can find the detailed description in documentation.

The text isn’t the one available option, so you can upload a photo, video, document or find location. These functions available as well in SDK. Just check actions and BaseObject class which implements adapter pattern for different response types.

Thanks for reading!