Community Post

Prerequisites for Symfony App Development

shahroz_nawaz

Over years, we humans have solved our problems by talking it out. Chatbots are the continuation of this tradition in the digital age.

Chatbots have become an important trend in customer service and support segment. Modern chatbots employ several important techniques including machine learning and Natural Language Processing. All popular websites use chatbots as the first stage of customer service process. The chatbots provide a basic level of service to the incoming queries and ensure that human CSRs are not engaged in low priority queries. Many brands use chatbots to receive incoming queries on social media channels.

In this article, I will show you how you could build your first Facebook chat bot using PHP. The process has several interconnected steps including:

  • Creation of a Facebook page.
  • Creation of a Facebook application and related webhook.
  • Creation of appropriate classes and and methods.
  • Additional message templates.

Roll up your sleeves and dive right into it!

Create the Facebook Page

The first step of the process is the creation of a Facebook page (requires an active Facebook account). Login and then create a page. Select the appropriate category and fill in the required information including the name of the page, address and contact information. For the purpose of this article, I have created a page named Cloudways School.

Create the Facebook Application

The second step is the creation of the a Facebook application that interfaces between the chatbot and the Facebook page chat. To create the app, go to Facebook Developers page and click Add New App. Add all required information and click Create App ID button. Facebook might ask you to verify a CAPTCHA code.

The app will appear in the Developer Dashboard. Open the application and add messenger platform to the app. Next, add the webhook that connects the app with the website. To add the webhook, generate the page access token.

Next, define the callback URL and the access token. Right below the token generation tab, goto the Webhook tab and click Setup Webhooks. Insert the URL. Note that, in order for this to work, the URL must be in https format.

At this point, the webhook has been setup and it is time to do some code!

Note: SSL based hosting is required for Facebook Messenger bot development. You can upload files to your preferred hosting provider such as Bluehost, Hostgator, Siteground. I have chosen Cloudways and installed Let’s Encrypt for SSL certification requirements. I have also used Filezilla to upload files using Master Credentials.

Create Required Class and Methods

In the development phase, I have used Guzzle instead of CURL as it is the latest standard for working with HTTP Requests. To install Guzzle, run the following command:

composer require guzzlehttp/guzzle

This command will create a vendor directory and install Guzzle in the project’s folder. Create two more files in the directory FbBot.php (for the main class) and bot.php (for handling messages via class methods).

I will start with the code of FbBot.php. Open the file in your editor and add the following code in it.


<?php
require 'vendor/autoload.php';

useGuzzleHttpClient;
useGuzzleHttpExceptionRequestException;
useGuzzleHttpPsr7Request;
class FbBot
{
    private $hubVerifyToken = null;
    private $accessToken = null;
    private $tokken = false;
    protected $client = null;
    function __construct()
    {
    }

    public function setHubVerifyToken($value)
    {
        $this->hubVerifyToken = $value;
    }

    public function setAccessToken($value)
    {
        $this->accessToken = $value;
    }

    public function verifyTokken($hub_verify_token, $challange)
    {
        try
        {
            if ($hub_verify_token === $this->hubVerifyToken)
            {
                return $challange;
            }
            else
            {
                throw new Exception("Tokken not verified");
            }
        }
        catch(Exception $ex)
        {
            return $ex->getMessage();
        }
    }

    public function readMessage($input)
    {
        try
        {
            $payloads = null;
            $senderId = $input['entry'][0]['messaging'][0]['sender']['id'];
            $messageText = $input['entry'][0]['messaging'][0]['message']['text'];
            $postback = $input['entry'][0]['messaging'][0]['postback'];
            $loctitle = $input['entry'][0]['messaging'][0]['message']['attachments'][0]['title'];
            if (!empty($postback))
            {
                $payloads = $input['entry'][0]['messaging'][0]['postback']['payload'];
                return ['senderid' => $senderId, 'message' => $payloads];
            }
            if (!empty($loctitle))
            {
                $payloads = $input['entry'][0]['messaging'][0]['postback']['payload'];
                return ['senderid' => $senderId, 'message' => $messageText, 'location' => $loctitle];
            }
            // file_put_contents('abc.txt', $payloads);
            // var_dump($senderId,$messageText,$payload);
            //   $payload_txt = $input['entry'][0]['messaging'][0]['message']['quick_reply']‌​['payload'];
            return ['senderid' => $senderId, 'message' => $messageText];
        }
        catch(Exception $ex)
        {
            return $ex->getMessage();
        }
    }

    public function sendMessage($input)
    {
        try
        {
            $client = new GuzzleHttpClient();
            $url = "https://graph.facebook.com/v2.6/me/messages";
            $messageText = strtolower($input['message']);
            $senderId = $input['senderid'];
            $msgarray = explode(' ', $messageText);

            $response = null;
            $header = array(
                'content-type' => 'application/json'
            );
            if (in_array('hi', $msgarray))
            {
                $answer = "Hello! how may I help you today?";
                $response = ['recipient' => ['id' => $senderId], 'message' => ['text' => $answer], 'access_token' => $this->accessToken];
            }
            elseif (in_array('blog', $msgarray))
            {
                $answer = ["attachment" => ["type" => "template", "payload" => ["template_type" => "generic", "elements" => [["title" => "Migrate your symfony application", "item_url" => "https://www.cloudways.com/blog/migrate-symfony-from-cpanel-to-cloud-hosting/", "image_url" => "https://www.cloudways.com/blog/wp-content/uploads/Migrating-Your-Symfony-Website-To-Cloudways-Banner.jpg", "subtitle" => "Migrate your symfony application from Cpanel to Cloud.", "buttons" => [["type" => "web_url", "url" => "www.cloudways.com", "title" => "View Website"], ["type" => "postback", "title" => "Start Chatting", "payload" => "get started"]]]]]]];
                $response = ['recipient' => ['id' => $senderId], 'message' => $answer, 'access_token' => $this->accessToken];

                // file_put_contents('abc.txt', print_r($response));
            }
            elseif (in_array('list', $msgarray))
            {
                $answer = ["attachment" => ["type" => "template", "payload" => ["template_type" => "list", "elements" => [["title" => "Welcome to Peter\'s Hats", "item_url" => "https://www.cloudways.com/blog/migrate-symfony-from-cpanel-to-cloud-hosting/", "image_url" => "https://www.cloudways.com/blog/wp-content/uploads/Migrating-Your-Symfony-Website-To-Cloudways-Banner.jpg", "subtitle" => "We\'ve got the right hat for everyone.", "buttons" => [["type" => "web_url", "url" => "https://cloudways.com", "title" => "View Website"], ]], ["title" => "Multipurpose Theme Design and Versatility", "item_url" => "https://www.cloudways.com/blog/multipurpose-wordpress-theme-for-agency/", "image_url" => "https://www.cloudways.com/blog/wp-content/uploads/How-a-multipurpose-WordPress-theme-can-help-your-agency-Banner.jpg", "subtitle" => "We've got the right theme for everyone.", "buttons" => [["type" => "web_url", "url" => "https://cloudways.com", "title" => "View Website"], ]], ["title" => "Add Custom Discount in Magento 2", "item_url" => "https://www.cloudways.com/blog/add-custom-discount-magento-2/", "image_url" => "https://www.cloudways.com/blog/wp-content/uploads/M2-Custom-Discount-Banner.jpg", "subtitle" => "Learn adding magento 2 custom discounts.", "buttons" => [["type" => "web_url", "url" => "https://cloudways.com", "title" => "View Website"], ]]]]]];
                $response = ['recipient' => ['id' => $senderId], 'message' => $answer, 'access_token' => $this->accessToken];
            }
            elseif ($messageText == 'get started')
            {
                $answer = ["text" => "Please share your location:", "quick_replies" => [["content_type" => "location", ]]];
                $response = ['recipient' => ['id' => $senderId], 'message' => $answer, 'access_token' => $this->accessToken];
            }
            elseif (!empty($input['location']))
            {
                $answer = ["text" => 'great you are at' . $input['location'], ];
                $response = ['recipient' => ['id' => $senderId], 'message' => $answer, 'access_token' => $this->accessToken];
            }
            elseif (!empty($messageText))
            {
                $answer = 'I can not Understand you ask me about blogs';
                $response = ['recipient' => ['id' => $senderId], 'message' => ['text' => $answer], 'access_token' => $this->accessToken];
            }
            $response = $client->post($url, ['query' => $response, 'headers' => $header]);

            // file_put_contents("payytorrrr.json", json_encode($response));
            return true;
        }
        catch(RequestException $e)
        {
            $response = json_decode($e->getResponse()->getBody(true)->getContents());
            file_put_contents("payytorrrre.json", json_encode($response));
            return $response;
        }
    }
}
?>

In the beginning of the code, I included Guzzle HTTP files to initiate Guzzle. After that , I made a class and declared appropriate variables because Messenger bot needs hub verify token and access token to match the requirements of the webhook and complete the challenge before replying to the message.

setHubVerifyToken(), setAccessToken() will set both tokens that will be made available in bot.php. verifyTokken() will completely verify the hub_verify_token and return the challenge.

readmessage() will receive the incoming message and return it to sendmessage() which then match the message (using if statements) and return the answer to the Messenger.

To complete the process, I will now create another file bot.php and add the following code in it.

<?php
include 'FbBot.php';

$tokken = $_REQUEST['hub_verify_token'];
$hubVerifyToken = 'cloudwaysschool';
$challange = $_REQUEST['hub_challenge'];
$accessToken = 'EAAa2ZCVTqQqgBADvZBxxxxxxxxxxxxX74M8uIQHCPC4f4tRjltXKcPxxxxxxxxxxxxxxxxBopP4FEYqF5guSshYdmxxxxxxxxxxxxxxxxxxxJGNaBiUWlGbihjZC6dwZDZD';
$bot = new FbBot();
$bot->setHubVerifyToken($hubVerifyToken);
$bot->setaccessToken($accessToken);
$bot->verifyTokken($tokken, $challange);
$message = $bot->readMessage($input);
$botmessage = $bot->sendMessage($message);

In this code, I first setup $hubVerifyToken which is exactly the same variable I had put in the webhook of the Messenger app. After the challenge, I initialized the class, set the tokens, read incoming message(s) and passed it as an argument to process, and finally sent the required reply to the Messenger.

The result of tall this activity is that when I go to the Facebook page and say Hi, the bot will reply Hello.

Now you can start talking to the chatbot! If you check sendMessage(), there is a condition that handles the response:

    if($messageText == 'hi') {
                    $answer = "Hello! How may I help you today ";
                     $response = [
                        'recipient' => [ 'id' => $senderId ],
                        'message' => [ 'text' => $answer ],
                        'access_token' => $this->accessToken
                     ]
   ;}

Additional Message Templates

To try out different messages, you could make change in the class.

I will now introduce a more structured replies for the chatbot. Suppose, there is a blog page on the Facebook and a visitor ask the bot about the latest blogs. In response, the blog will respond with the latest blog, as shown below:

You can extend the if structure to add customized responses for various situations. A sample logic is given below:

 elseif(strpos($messageText, 'blog')) {
                    $answer = ["attachment"=>[
      "type"=>"template",
      "payload"=>[
        "template_type"=>"generic",
        "elements"=>[
          [
            "title"=>"Migrate your symfony application",
            "item_url"=>"https://www.cloudways.com/blog/migrate-symfony-from-cpanel-to-cloud-hosting/",
            "image_url"=>"https://www.cloudways.com/blog/wp-content/uploads/Migrating-Your-Symfony-Website-To-Cloudways-Banner.jpg",
            "subtitle"=>"Migrate your symfony application from Cpanel to Cloud.",
            "buttons"=>[
              [
                "type"=>"web_url",
                "url"=>"www.cloudways.com",
                "title"=>"View Website"
              ],
              [
                "type"=>"postback",
                "title"=>"Start Chatting",
                "payload"=>"Even want some more? say me!"
              ]              
            ]
          ]
        ]
      ]
    ]];$response = [
                        'recipient' => [ 'id' => $senderId ],
                        'message' => $answer,
                        'access_token' => $this->accessToken
                     ];
                }

Now let’s suppose somebody ask the bot for a list of blogs, the bot could send something like:

This message can be sent using list template of Facebook Messenger. Use the following code to implement this functionality:

elseif (strpos($messageText, 'list')){
 $answer = ["attachment"=>[
      "type"=>"template",
      "payload"=>[
        "template_type"=>"list",
        "elements"=>[
            [
            "title"=>"Migrate symfony from cpanel",
            "item_url"=>"https://www.cloudways.com/blog/migrate-symfony-from-cpanel-to-cloud-hosting/",
            "image_url"=>"https://www.cloudways.com/blog/wp-content/uploads/Migrating-Your-Symfony-Website-To-Cloudways-Banner.jpg",
            "subtitle"=>"We've got the right hat for everyone.",
            "buttons"=>[
              [
                "type"=>"web_url",
                "url"=>"https://cloudways.com",
                "title"=>"View Website"
              ],
            ]
          ],
            [
            "title"=>"Multipurpose Theme Design and Versatility",
            "item_url"=>"https://www.cloudways.com/blog/multipurpose-wordpress-theme-for-agency/",
            "image_url"=>"https://www.cloudways.com/blog/wp-content/uploads/How-a-multipurpose-WordPress-theme-can-help-your-agency-Banner.jpg",
            "subtitle"=>"We've got the right theme for everyone.",
            "buttons"=>[
              [
                "type"=>"web_url",
                "url"=>"https://cloudways.com",
                "title"=>"View Website"
              ],
            ]
          ],
            [
            "title"=>"Add Custom Discount in Magento 2",
            "item_url"=>"https://www.cloudways.com/blog/add-custom-discount-magento-2/",
            "image_url"=>"https://www.cloudways.com/blog/wp-content/uploads/M2-Custom-Discount-Banner.jpg",
            "subtitle"=>"Learn adding magento 2 custom discounts.",
            "buttons"=>[
              [
                "type"=>"web_url",
                "url"=>"https://cloudways.com",
                "title"=>"View Website"
              ],
            ]
          ]
        ]
      ]
    ]];
 $response = ['recipient' => ['id' => $senderId], 'message' =>  $answer, 'access_token' => $this->accessToken];}

Conclusion

Developing a Facebook Messenger chat bot is a relatively straight forward process and much exciting. Using PHP and Facebook’s native tools, you could have a very functional chatbot up and running in no time. well this is not a drill you can do more with your chatbot. If you face a roadblock in the development of your chatbot or would like to add to the conversation, please leave a comment below.

shahroz_nawaz

Shahroze is always in search of new frameworks and methods to implement them. He is a big fan of PHP development and managed cloud hosting . Besides his coding life, he loves movies and playing soccer with friends.