Build an SMS-Based Bot in PHP with Laravel to Track COVID-19 Data

April 09, 2020
Written by
Brian Iyoha
Contributor
Opinions expressed by Twilio contributors are their own

Build an SMS-Based Bot in PHP to Track Covid-19 Data

It's no news that the Novel Coronavirus has spread around the world and recently been declared a pandemic by the World Health Organization (W.H.O). Luckily despite “stay-at-home” orders and full lockdowns, information concerning the virus can easily be found on the internet through a simple Google search or on social media platforms.

However, not everyone has easy, in-home access to the internet. In some third world countries like Nigeria, staying indoors to prevent the spread of the virus makes it difficult to get access to information via the internet. Fortunately, text messages are still a good form of communication because they don't rely on one having internet connectivity.

In this tutorial, you will build a simple SMS-based bot to help get information about the Novel Coronavirus cases in a country using Twilio Programmable SMS.

Prerequisites

To follow this tutorial, you will need the following:

Project setup

This tutorial will make use of Laravel to create our application and API endpoints. To get started building your bot, you need to first create a new Laravel project. Open up your terminal and run the following command to generate a new Laravel application using the Laravel installer:

$ laravel new covid19-bot

NOTE: The Laravel installer needs to be installed on your computer for the above command to work. If you don't have it installed, head over to the official Laravel documentation to see how to.

Next, point your terminal working directory to the newly created project, and run the following command to install the Twilio PHP SDK which will be used for sending out SMS from the application:

$ cd covid19-bot
$ composer require twilio/sdk

Now you need to get your Twilio credentials which will be used for authorizing requests made using the Twilio PHP SDK. Head over to your Twilio dashboard and copy your Account SID and Auth Token:

Twilio account dashboard

Next, head to the phone numbers section and copy your active Twilio phone number which will be used as the access point for the SMS bot:

Twilio Active Numbers

It’s important to keep these credentials safe in your application. To do this open up your .env file in the project root directory and add the following variables to store them as environment variables:

TWILIO_ACCOUNT_SID=YOUR ACCOUNT SID
TWILIO_AUTH_TOKEN=YOUR AUTH TOKEN
TWILIO_PHONE_NUMBER=YOUR TWILIO PHONE NUMBER

Building the Bot Logic

Now that you have successfully set up your Laravel project, let's jump into writing out the application logic. Start off by creating a Controller that will hold the application business logic. Open up a terminal in the project directory and run the following command to generate a new controller class:

$ php artisan make:controller BotController

Next, open up the newly created controller class app/Http/Controllers/BotController.php and make the following changes:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Twilio\Rest\Client;

class BotController extends Controller
{
    public function checkCountryStatus(Request $request)
    {
        $from = $request->input("From");
        $body = $request->input("Body");
        $response = Http::get("https://corona.lmao.ninja/countries/{$body}");
        $response = json_decode($response->body());
        if (isset($response->message)) {
            $this->sendMessage($response->message, $from);
            return;
        }

        $message = "👋 Here's the summary of the Covid-19 cases in " . Str::title($body) . " as at " . now()->toRfc850String() . "\n\n";
        $message .= "Today Cases: {$response->todayCases} \n";
        $message .= "Recovered Cases: {$response->recovered} \n";
        $message .= "Deaths Recorded: {$response->deaths} \n";
        $message .= "Total Cases: {$response->cases} \n";

        $this->sendMessage($message, $from);
        return;
    }

    /**
     * Sends sms to user using Twilio's programmable SMS client
     * @param string $message Body of sms
     * @param string $recipient string of phone number of recipient
     */
    private function sendMessage($message, $recipient)
    {
        $account_sid = getenv("TWILIO_ACCOUNT_SID");
        $auth_token = getenv("TWILIO_AUTH_TOKEN");
        $twilio_number = getenv("TWILIO_PHONE_NUMBER");
        $client = new Client($account_sid, $auth_token);
        return $client->messages->create($recipient, ['from' => $twilio_number, 'body' => $message]);
    }
}

Let's break down what’s happening in the code above. The checkCountryStatus() function is the main function here which handles what happens when a new message is sent to your Twilio number. The phone number of the sender is retrieved from the From property of the request body, followed by the Body property which is the name of a country the sender would like to get information about.

Next, using the new HTTP Client from Laravel, a GET request is made to https://github.com/novelcovid/api - an open-source API for tracking COVID-19:

$from = $request->input("From");
$body = $request->input("Body");
$response = Http::get("https://corona.lmao.ninja/countries/{$body}");

The country name $body is passed to the API URL as a path parameter. Next, using the PHP json_decode method, the response from the API is stored as a JSON object and a message is sent back to the user using the sendMessage() helper function depending on the response gotten from the request. The sendMessage() method takes in two arguments; the message and the recipient. In the sendMessage() function, a new instance of the Twilio Client is instantiated with the credentials retrieved from the environment variables, stored in an earlier section of this tutorial:

$account_sid = getenv("TWILIO_ACCOUNT_SID");
$auth_token = getenv("TWILIO_AUTH_TOKEN");

$client = new Client($account_sid, $auth_token);   

Next, using the instance of the Twilio Client, the messages->create() is called to actually send out an SMS to the recipient via the Twilio SMS API. The message->create() method takes in two arguments; recipient, the receiver of the message and an associative array containing the body and from properties:

$client->messages->create($recipient, ['from' => $twilio_number, 'body' => $message]);

In this case, the from number is your active Twilio phone number and the body is the response to be sent back to the initial sender of the message.

Creating the Route

Having written out the application logic, you need to create an entry point to your application. To do this, open up the routes/api.php file and make the following changes:

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Route::post('/bot','BotController@checkCountryStatus');

Setting up the Twilio Webhook

Before you can move on to testing the bot, you must first update your Twilio phone number webhook settings with a publicly accessible route to your application that enables Twilio to know what to do whenever a new message is received.

Making the application publicly accessible

To allow access to your Laravel project through a webhook, your application has to be accessible via the internet and this can easily be done using ngrok.

If you don’t have ngrok already set up on your computer, you can quickly do so by following the instructions on their official download page. If you already have it set up, then open up your terminal and run the following commands to start your Laravel application and expose it to the internet:

$ php artisan serve

Take note of the port your application is currently running on (usually 8000). Next, while still running the above command, open another instance of your terminal and run this command:

$ ngrok http 8000

After successful execution of the above command, you should see a screen like this:

ngrok output

NOTE:

  • Replace 8000 with the port your application is running on.
  • Take note of the forwarding URL as we will be making use of it next.

Updating the Twilio phone number configuration

Navigate to the active phone number section on your Twilio console and select the active phone number used for your application. Next, scroll down to the Messaging segment and update the webhook URL for the field labeled “A MESSAGE COMES IN” as shown below:

Twilio Active Number dashboard

NOTE: The URL path should be prefixed with /api.

Testing the bot

Now that your webhook has been updated, you are now ready to test your application. To do this, simply send a text with a country name to your active Twilio phone number. If successful,  you should receive a response shortly after with a summary of the coronavirus cases in the country or an error message if otherwise:

SMS bot on iphone

Conclusion

Now that you have finished this tutorial, you have successfully built an SMS based bot. You have also learned how to respond to SMS sent to your Twilio phone number from a Laravel application. If you will like to take a look at the complete source code for this tutorial, you can find it on Github.

Remember to stay safe, stay indoors, and always wash your hands. We will get through this together ❤️.

I’d love to answer any question(s) you might have concerning this tutorial. You can reach me via: