Building a bot using BotMan for Slack and Telegram

building-bot-using-botman-slack-telegram-header.png

In this tutorial, learn how to build a chat bot for Slack and Telegram using BotMan and PHP.

Introduction

In this tutorial, I will be showing you how to build a bot for Slack and Telegram using 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.

What we’ll be building

We’ll be building a bot that compares top cryptocurrencies through the https://coinmarketcap.com API. We’ll call the bot cryptocompare. Below are screenshots of how the bot works on both Slack and Telegram:


Prerequisites

This tutorial assumes you have the following setup:
– PHP >= 7.0.0
– Composer

Let’s get started!

Install BotMan Installer

For the purpose of this tutorial, we’ll be using BotMan Studio which is BotMan bundled with the Laravel framework. The most straightforward way to get started with BotMan is with BotMan Studio. We’ll start by installing BotMan installer:

1composer global require "botman/installer"

Create a BotMan Studio Project

Once installed, we can use the botman new command to create a new BotMan Studio installation:

1botman new cryptocompare

Note: Make sure you have at least botman/botman 2.0.3 (as at the time of this tutorial) installed. This is important due to a bugfix.

This will create a cryptocompare directory containing a fresh BotMan Studio installation with all of BotMan’s dependencies already installed. If you are familiar with the Laravel framework you will feel comfortable looking at this directory. To make sure everything is working, run:

1php artisan serve

You’ll see the BotMan Studio welcome page:

We can also test the sample chatbot that came with BotMan Studio. Click on the Tinker link and type Hi and you will get a reply.

With everything working so far, let’s start writing the logic of comparing cryptocurrencies. Luckily for us, https://coinmarketcap.com does not require any kind of authentication or setup. We just make calls to the necessary endpoints. Open app/Http/Controllers/BotManController.php and update the hears() call within the handle() method as below:

1// app/Http/Controllers/BotManController.php
2
3    $botman->hears('cryptocompare {limit}', function ($bot, $limit) {
4        $result = $this->compareCryptocurrencies($limit);
5        $bot->reply($result);
6    });

BotMan has a hears() method which will listen for certain commands. In our case, we care about listening for the cryptocompare command. When the bot receives this command, it will execute the closure. Because we want users to supply the number of cryptocurrencies they want to compare (the limit), we add a limit parameter to the command. This way we can capture user’s input. Next, we call compareCryptocurrencies``() (which we’ll create shortly) passing the limit captured from the user. Finally, we reply to the user with the result.

Create the compareCrytocurrencies method

From the snippet above, we called a method called compareCryptocurrencies``() which we’ll create now. The method accepts the limit of cryptocurrencies we want to compare as a single parameter. Still in BotManController.php, paste the snippet below:

1// app/Http/Controllers/BotManController.php
2
3    // Remember to include this at the top of the file
4    use GuzzleHttp\Client;
5
6    protected function compareCryptocurrencies($limit)
7    {
8        $client = new Client(['base_uri' => 'https://api.coinmarketcap.com/v1/ticker/']);
9
10        $response = $client->get('?limit=' . $limit);
11        $results = json_decode($response->getBody()->getContents());
12
13        $data = "Here's the comparison of the top $limit cryptocurrencies: " . PHP_EOL;
14
15        foreach ($results as $result) {
16            $data .= '> ' . $result->name . ' | ' . $result->symbol . ' | ' . '$' . $result->price_usd . ' | ' . '$' . $result->market_cap_usd . PHP_EOL;
17        }
18
19        return $data;
20    }

We are using Guzzle to make HTTP calls to the API endpoint. We also pass the limit specified in the command as a query parameter to the API endpoint. This will limit the number of cryptocurrencies that will be compared. Then we loop through the response returned from the API call and format them the way we want them to be displayed. Lastly, we return the formatted response.

Adding Fallbacks

There are times users will type something different from our command. Let’s add a little interaction to our bot by adding a fallback method that tells users possible command(s) they can enter. The fallback method will be executed whenever a user types something different from our command. Within the handle() method, add the snippet below just before we call listen():

1// app/Http/Controllers/BotManController.php
2
3    $botman->fallback(function ($bot) {
4        $bot->reply("Sorry, I did not understand these commands. Try: `crytocompare 5`");
5    });

The complete handle() method should be as below:

1// app/Http/Controllers/BotManController.php
2
3    public function handle()
4    {
5        $botman = app('botman');
6
7        $botman->hears('cryptocompare {limit}', function ($bot, $limit) {
8            $result = $this->compareCryptocurrencies($limit);
9            $bot->reply($result);
10        });
11
12        // Fallback in case of wrong command
13        $botman->fallback(function ($bot) {
14            $bot->reply("Sorry, I did not understand these commands. Try: `cryptocompare 5`");
15        });
16
17        $botman->listen();
18    }

That’s all for the logic of our bot. Once again, let’s test to make sure everything is working locally before we move on to creating bots for our targeted platforms (Slack and Telegram).

Create Slack app

To test out our bot, we need to create a Slack app. Before we create the app, let’s quickly install the Slack driver. Within the project directory, run:

1php artisan botman:install-driver slack

Now let’s create the Slack app. Visit the Slack API website to do this.

Once the app is created, configure the app for the following:

Bot Users
We need a bot user to communicate with BotMan in your Slack team. Give the bot a display name and username.

Event Subscriptions
Provide the URL that points to your BotMan logic/controller (that is, the route that points to handle() eg. https://address.com/botman) in the Request URL field. Then subscribe for these bot events:
message.channels – A message was posted to a channel
message.im – A message was posted in a direct message channel

Tip: You might want to use ngrok or Laravel Valet to get a public URL to your BotMan app

Install the app
Lastly, we need to install the app:

Upon installation of the app, we’ll get some tokens as displayed in the image below:

**Bot User OAuth Access Token** is what we need. Copy this token and add it to the .env file as below:

1// .env
2
3    SLACK_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Now we can test the bot in our Slack team. Below is a screenshot of how the bot works in Slack:

Create a Telegram Bot

Follow the official guide to create a Telegram bot. We’ll use the @botFather bot to create our own.

To create the bot, click on /newbot then you will be prompted to provide a name for the bot:

Once the bot is created, we’ll see the access token for the bot. Note this token as we’ll be using it shortly.

Next, just as we did for Slack, we also need to install the Telegram driver:

1php artisan botman:install-driver telegram

Next, let’s add the API token to the .env file as below:

1// .env
2
3    TELEGRAM_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Next, we need to connect the bot with BotMan. We have to register the URL where BotMan is running with Telegram. We can do this by sending a POST request to https://api.telegram.org/bot<YOUR-TELEGRAM-TOKEN-HERE>/setWebhook and pass one parameter called url which holds the URL to your BotMan logic/controller (that is, the route that points to handle()).

We can use Postman for that:

Note: This driver requires a valid and secure URL in order to set up webhooks and receive events and information from the chat users. This means your application should be accessible through an HTTPS URL.
Tip: You might want to use ngrok or Laravel Valet to get a public URL to your BotMan app

With that done, we can now test out the bot. Below is a screenshot of how the bot works in Telegram:

The complete code is available on GitHub.

Conclusion

There you have it. You have seen how to build a Slack and Telegram bot using BotMan. Now, go forth and build really awesome bots. Also, do check out the BotMan documentation to learn more.