After a long time I’m here to talk about Telegram bots. Lately, I discovered a nice PHP library for building Telegram Bots and I want now to show you it’s potential — BotMan.

BotMan is a framework agnostic PHP library that is designed to simplify the task of developing innovative bots for multiple messaging platforms, including Slack, Telegram, Microsoft Bot Framework, Nexmo, HipChat, Facebook Messenger, WeChat and many more.

The best part of this library is that you can integrate with Laravel, thus taking benefit of the vast ecosystem around it.

In this article, you are going to build a simple bot step by step, from the preparation to the actual development. I will not cover the deployment and testing as there are many possibilities.

Installation

If you ever used the Laravel installer, you will find this process familiar. You can require through Composer the BotManStudio installer using:

composer global require "botman/installer"

After that we can create a new Bot using:

botman new botname

By issuing the usual:

php artisan serve

You can test if everything went ok at /botman/tinker endpoint.

Tinker widget

Installing the driver

The library itself comes with the default web driver, to see which drivers are supported just run:

php artisan botman:list-drivers

To install the Telegram driver:

php artisan botman:install-driver telegram

To connect BotMan with your Telegram Bot, you first need to follow the official guide (or read my first blog post) to create your Telegram Bot and an access token.

Once we have obtained the access token, place it in your .env file using the TELEGRAM_TOKEN key.

TELEGRAM_TOKEN=yourkeyhere

Expose Our Bot To The World

Your bot needs to expose a public available endpoint to get updates and since the development of the bot happens on your local machine, to not deal with SSL certificates and port forwarding, we just use ngrok to expose it to the world. It will provide us a temporary SSL protected sub domain.

After installed, grab the port number shown by the command:

php artisan serve

http://127.0.0.1:8000 in my case is 8000

And run ngrok:

ngrok http 8000

Look at the “Forwarding” entry — this is our endpoint.

In our case, the endpoint is https://5e86b344.ngrok.io (Note that this changes!)

To link the both with the Telegram Bot API you can just copy paste this in your browser address bar:

https://api.telegram.org/bot<token>/setWebhook?url=https://5e86b344.ngrok.io/botman

Where <token> is the previously grabbed token from BotFather and https://5e86b344.ngrok.io changes according to the one given by ngork as explained above.

If everything went ok we can start chatting with your bot.

Example flow.

Our First Bot

In this section, I won’t describe what BotManStudio supports. For this, I recommending checking out the documentation (which is well written).

Your first bot will be an announcer bot. A sort of channel implemented within the bot. The idea is rather silly, but you can see how you can use existing features of Laravel such as Eloquent, Queue etc.

Subscribing Clients

Each bot user can subscribe to your bot. To implement this, we store each user id and username in a collection. This helps you to keep track who is subscribed.

$botman->hears('/subscribe', function ($bot) {

$users = \Cache::get('users', collect()); if ($users->has($bot->getUser()->getId())) {

$bot->reply('You are already subscribed');

} else {

$users->put($bot->getUser()->getId(), $bot->getUser()->getUsername());

\Cache::forever('users', $users);

$bot->reply('Subscribed, you will now receive notifications!');

}

});

For simplicity, I use the Cache component. On a real scenario, I would use Eloquent instead. The command is straightforward. It Checks if the user is the collection and adds it.

Subscribing Clients

If the user does not want to receive notifications anymore, he can unsubscribe.

$botman->hears('/unsubscribe', function ($bot) {

$users = \Cache::get('users', collect()); if ($users->has($bot->getUser()->getId())) {

$users->forget($bot->getUser()->getId());

\Cache::forever('users', $users);

$bot->reply('Unsubscribed, you will not receive notifications anymore!');

} else {

$bot->reply('You are not subscribed');

}

});

Broadcast

Naturally, you want to send messages to your subscribed users. To achieve this the bot needs to now every subscribed user id in order to be able to broadcast your message.

For this reason, we loop through the users collections and we broadcast the message.

$botman->group(['recipient' => 'id_number'], function ($bot) {

$bot->hears('/broadcast', function ($bot) {

$bot->ask('Send me the message to broadcast to your followers', function($answer) use ($bot) {

$users = \Cache::get('users', collect());

$users->each(function ($username, $id) use ($bot, $answer) {

$bot->sendRequest('sendMessage', [

'chat_id' => $id,

'text' => $answer->getText()

]);

});

$bot->reply('Sent the message to '.$users->count().' users');

});

});

});

Note how the library has a built-in mechanism that let you listen only for specific recipients. In this case, only a hypothetical “admin” can broadcast a message to the subscribers.

Also, the library lets you send low-level requests if a proper method is not built-in.

The final result.

How To Get The Recipient

While using ngrok go to http://127.0.0.1:4040/inspect/http and inspect any request that comes from you. The id is under from property (bold).

{

"update_id": 516450433,

"message": {

"message_id": 93,

"from": {

--> "id": id_number, <--

"is_bot": false,

"first_name": "unnikked",

"username": "unnikked",

"language_code": "it"

},

"chat": {

"id": id_number ,

"first_name": "unnikked",

"username": "unnikked",

"type": "private"

},

"date": 1504912542,

"text": "hi"

}

}

Conclusion

In my opinion, Laravel plus BotManStudio are one of the best tools available at the moment. They let you think about only your bot logic while offering maximum flexibility on integrating with other libraries.

With Laravel, you have at your disposal a vast community and packages. With BotMan you can design your bot logic platform independent (to some degree) and reuse it on various vendors. At the end of the story, it is your choice.