Develop your first Facebook messenger bot in PHP

Facebook Messenger Bot - F8 Conference (Credit: Independent.co.uk)

Facebook recently announced a Bot platform for it’s Messenger which provides businesses and individuals another way to communicate with people.

What is a Chat bot?

A computer program designed to simulate conversation with human users, especially over the Internet.

Chat bot in PHP

When I heard of it, my very first thought was to a bot in PHP. I started to find some SDK in this regard released by Facebook but none was present. I headed over to documentation which provided good information for starters.

Ok! so without wasting further time, let’s build our first Bot

Timebot

In order to create an Fb bot you will need two things to host your bot: A Facebook Page which will be like Home of Bot, People will visit the page, click on Message option to Interact with your bot. For example, suppose Pizza Hut introduce a bot for order related operations. What could they do that they integrate or host their bot on their official page, a fan can just click on Message button and send messages to order a Pizza, get new deals etc and they will get messages as if some human representatives is responding to them. It all depends how efficient a bot is. Facebook puts no limitation in this regard.

I am going to create a Time bot which will tell you current time Time API that provides different options to retrieve time. For our bot, we are just fetching latest(NOW) time. I will go step by step:

 

Step 1: Create Facebook Page:

I am going to create Bot’s Page first, this page will actually be the entry point for communication for the bot to interact with your page fans/users. Do note that it is not necessary to create a separate page only for Bot purpose. You may use existing Fan page for this purpose.  For sake of this tutorial I am assuming that you never created a page before. Visit https://www.facebook.com/pages/create/ and you will see something like this(as of April, 2016):

Create Facebook Page

 

I picked Entertainment option. In next steps it asks different options which you can always skip.

Alright! so my page is ready and something like should be visible for you as well:

Facebook Fan page

 

 

 

Step 2: Create Facebook App:

Alright, go to https://developers.facebook.com/apps and click on Add a New App button. Make sure you have a developer account otherwise you will not be able to access developer dashboard. 

Facebook Create App

When you click on it it shows a window and asks you what kind of app are you going to make. I picked Basic Setup given at bottom. I entered required information; Display Name & Contact Email and hit Create App ID button.

Create Facebook App ID

After Captcha you will be redirected to your App Page where you will be seeing details.

Facebook App page

 

On left side bar you will see an option of Messenger. When you click on it, it shows introduction of Messenger Platform and why and how these bots will be helpful.

 

Messenger Platform

Click on Get Started and it will show a New Dashboard page related to your newly created app that’s going to be hooked with Messenger platform.

Messenger App Dashboard

Now we need to do a few things for setting up the bot. As you can see, you are being asked a few things; Access Token/Page Token so that Facebook can know where do you want to host bot, Webhooks, your script URL that will be receiving messages from your users and responding them. It will also be hold the logic of your bot and Permissions that is, what this bot should be able to perform when communicating with users. Ok first, set the page which you just created. I am selecting TimBot. Since I, as a normal Facebook User going to use this page very first time, it will ask for Permissions as it normally asks.

Once all goes well you would get your Page Token like this, save it somewhere as this will be used as access_token while sending messages.

Facebook Page Access Token

 

 

Now we have to set our Webhook. Facebook asks you to setup an https:// URL which means, you simply can’t use localhost while developing. You can either upload your script somewhere which allows SSL based requests or.. you can use some tunneling tool that will pass on your localhost message to outer world. Luckily such tools are available and they are FREE as well. I’d recommend nGrok for this purpose. Once it’s unzipped, go to the folder and run the command:

./ngrok http 80

As a free user you are not allowed to give your own subdomain. Once it starts working, it shows something like this:

nGrok in Action

As you can see, it gives you two forwarded URLs. Since we re interested about https one so we will focus on that. nGrok also provides you an interface to view requests on your newly created domain. It will help you to debug how your webhook page is being accessed by Messenger Platform. For that purpose, open a separate tab with the URL http://localhost:4040/inspect/http and here you can see all details related to that request.

nGrok Web Interface in action
Now I have the URL, all I have to do is to setup my Webhook for Time Bot. Click on Setup Webhooks option and you’d see something like that.

Facebook Messenger Webhook

 

 

Here I entered the nGrok based URL, Verify Token which could be ANY string and checked subscription fields. If you hit verify and save, you will get error:

 

 

What does it mean? Webhook when access the URL, it first verification token before doing anything further, if not present or incorrect, it gives the error you are seeing above.

It’s time to open IDE and write some code. Create a file, in my case it’s index.php, in your case it could be any other file. Write the code that verify your Webhook.

 

$access_token = "EAAH5qCyWCdcBAP0ddTZBNbVRdmqd43TZCnBJGFEwRZAmO76hlrXfWmVzBXO5xEsochEnlrQ88Tkrwm2B63KzXctLxXQ8RU6KKM9sWEFsGZAaBzmmMUoqVjfir1n5ufXgW8btvZAL41bNJ5S0IceHKUCioOLTqCLZCZCOOMlNz5fRAZDZD";
$verify_token = "fb_time_bot";
$hub_verify_token = null;

if(isset($_REQUEST['hub_challenge'])) {
    $challenge = $_REQUEST['hub_challenge'];
    $hub_verify_token = $_REQUEST['hub_verify_token'];
}


if ($hub_verify_token === $verify_token) {
    echo $challenge;
}

$verify_token holds the value you in Verify Token field.

Now all seems set, let’s try again! Hurray! if all goes well you would see something like this:


Now all seems set. How about we test our Webhook by sending message to our bot.

Step 3: Sending and Receiving Messages

Before you start sending/receiving messages, you need to subscribe your page. Go to Command prompt, assuming cURL is installed,run the following command.

curl -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=EAAH5qCyWCdcBAOGIHVjWL7TGTYHFYYTr1RZAxc0bXZCK9pBaqqFEJPn9ctdZCSgzbJbJIdTcEHScfIxJ2zWku2sn8AUSOEqktL5VmTqYhYrC0NXbJEMY3EpsshZAFCd484PEBcyK4hN3H2ZAaiQLowoZAbRSx5aNAihIVsjbCKggZDZD"

Where access_token is the code I got in earlier step for the page Time Bot Page which I asked you to save somewhere. If works perfectly you should success message on console:

{"success":true}

Now go to your bot page and send message.

 

 

If hooks and subscription works fine, on your nGrok Web Interface(http://localhost:4040/inspect/http), you should see a request hit:

Facebook Messenger Bot Message Structure

 

 

Now you will know the power of nGrok Web Interface, here we are receiving message from Bot in a structure. In next step we will convert this message structure by decoding JSON into array and fetch sender Id and message.

$input = json_decode(file_get_contents('php://input'), true);

$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
$message = $input['entry'][0]['messaging'][0]['message']['text'];

First line using to get message from Facebook and then convert the JSON into PHP Associative Array.

In next couple of lines I am getting senderID, the ID of the person messaging to bot and the message itself.

Wait.. while you are debugging requests on nGrok, you could find an error:

<br />
<b>Deprecated</b>:  Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in <b>Unknown</b> on line <b>0</b><br />
<br />
<b>Warning</b>:  Cannot modify header information - headers already sent in <b>Unknown</b> on line <b>0</b><br />
<br />
<b>Notice</b>:  Undefined variable: data in <b>/Applications/MAMP/htdocs/Facebook-Chat-Bot/index.php</b> on line <b>30</b><br />
Invalid

This issue arises if you are using PHP5.6. The best bet to create an .htaccess file with the content.

<IfModule mod_php5.c>
    php_value always_populate_raw_post_data -1
</IfModule>

Now the error should be gone away. This particular will not go away by using ini_set().

I am setting some basic rules for my bot. It should only tell if it contains certain words.

/**
 * Some Basic rules to validate incoming messages
 */
if(preg_match('[time|current time|now]', strtolower($message))) {

    // Make request to Time API
    ini_set('user_agent','Mozilla/4.0 (compatible; MSIE 6.0)');
    $result = file_get_contents("http://www.timeapi.org/utc/now?format=%25a%20%25b%20%25d%20%25I:%25M:%25S%20%25Y");
    if($result != '') {
        $message_to_reply = $result;
    }
} else {
    $message_to_reply = 'Huh! what do you mean?';
}
print $message_to_reply;

Jus to check all going well, the message going to be printed should be able to watch on nGrok debugger.

Ok, now we have to message back to user. We have sender’s Id, we prepared the message, it’s time to send.

//API Url
$url = 'https://graph.facebook.com/v2.6/me/messages?access_token='.$access_token;


//Initiate cURL.
$ch = curl_init($url);

//The JSON data.
$jsonData = '{
    "recipient":{
        "id":"'.$sender.'"
    },
    "message":{
        "text":"'.$message_to_reply.'"
    }
}';

//Encode the array into JSON.
$jsonDataEncoded = $jsonData;

//Tell cURL that we want to send a POST request.
curl_setopt($ch, CURLOPT_POST, 1);

//Attach our encoded JSON string to the POST fields.
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);

//Set the content type to application/json
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));

//Execute the request
if(!empty($input['entry'][0]['messaging'][0]['message'])){
    $result = curl_exec($ch);
}

First, we will create a JSON structure of the message as given by Facebook platform and then will make  POST call via cURL. If all things coded correctly, you should see bot in action!

As you can see it covers bot valid and invalid messages here as per our rules.

Facebook Bot in Action

 

Alright! It’s your time to show your creativity and create your first awesome bot. if you bot goes public you can add a little code on your Website to invite others. Check the documentation for that.

Code is available on Github

Do you have an existing Web app or Facebook page and wants to integrate a bot with it? Let me know and I could help you in this regard. Contact me at kadnan(at)gmail.com

If you like this post then you should subscribe to my blog for future updates.

* indicates required



100 Comments

  • tapos

    Hello, i have tried your code, i am not getting error but i am not getting response message from bot. if i print my $message_to_reply is ok, but i can’t get the reply message on messenger. Any idea can you suggest?

    • admin

      @tapos: Check nGrok Web Interface. You must be getting some error or warning. Most prolly, not a valid JSON format

    • bot-noob

      Hi tapos,

      did you manage to get it to work? I’m facing the same issue. The response prints on ngrok interface just fine but I don’t see the response on the Facebook messenger

  • Wei-Ting

    Hi 🙂
    what should I do with the index.php to verify the webhook? Upload the somewhere?
    Thank you!

    • admin

      Either you set it up locally via nGrok tool or put it up somewhere SSL is available. Webhooks don’t work without SSL

  • S Janarthanam

    Hi.

    Succeeded until setting up the webhook and getting request hits on nGROK. But I am not sure where the input message is to be processed. Should we decode the JSON in the index.php that we already created?

    Srini

  • ManuelH

    I do not get the answer. The line “$result = curl_exec($ch);” in var_dump es bool(false)

  • Richard Wing

    Thanks for taking the time to share your tutorial. I am wondering if you know if there is a way to trigger messages based on proximity. Either if they cross into a proximity with their device it activates a bot message or if when they interact with a bot it can know where they are at the time of asking the bot a question it could pull from an answer based on their proximity.

  • Christophe

    Hello !
    Nice tutorial, I tried to set up a simple bot following it.
    I can get the messages typed in Messenger but I cannot reply automatically.
    I tried to manually send the POST message to

    https://graph.facebook.com/v2.6/me/messages?access_token=%5Bmytoken%5D

    {
    “recipient”:{
    “id”:”1.01548XXXXX38E+16″
    },
    “message”:{
    “text”:”Hey! What do you want bro?”
    }
    }

    However I get the following error:

    {
    “error”: {
    “message”: “(#100) Invalid fbid.”,
    “type”: “OAuthException”,
    “code”: 100,
    “fbtrace_id”: “EezzpNnfYpk”
    }
    }

    I cannot find much documentation about this error message, any idea?

    • Christophe

      I found the problem: big numbers were encoded as powers of 10 and FB did not recognize them, i replaced the line as follows:

      $input = json_decode(file_get_contents(‘php://input’), true);

      by

      $raw_input = file_get_contents(‘php://input’);
      $input = json_decode($raw_input, true, 512, JSON_BIGINT_AS_STRING);

  • Luc

    Hi,

    You tutorial is awesome !!

    But I need “basic” help 😉

    So I created a MAMP Server on my MAC and created the index.php file on it with the code you provided.
    I updated the access Token & Verify Token in it.

    But I still can pass throught the Setup Webhooks, I still have the same error.

    If NGrok is a server ? If yes where do I put my file ?

    Thanks,

    Luc

    • admin

      If NGrok is a server ? If yes where do I put my file ?

      nGrok is providing tunnel to let your request broadcast to outerworld. For Ngrok you do need a local server anyway. You did not tell what kind of error?

  • Deepak

    Easy enough explanation and very detailed. I appreciate your help.

    Can we connect the bot on website page? If yes how, if not why not?

    • admin

      Thanks for liking.

      Yes you can add a button on your website which will let your users to connect with your bots. Check the documentation.

  • Christophe

    Hello,
    I have a follow-up question: I want to personalize the answer using the person’s first name, for instance:

    “Hello [Peter], the current time is [XXXXXX]”

    However the ID provided by the first query is not the profile ID. How would you modify your code to get the user’s first name in this case?

    I assume we should use
    https://graph.facebook.com/v2.6/?fields=first_name,last_name,profile_pic,locale,timezone,gender&access_token=

    But I don’t know how to get the actual

    Thanks,

    Christophe

  • Yak

    Hi, first of all, thanks a lot for this tutorial. Really simple to understand. I was having some issues which I think others might also have so I am sharing my solution.

    My problem was that everything looked to be fine but I was not getting any message back. Ngrok was reporting 200 OK status so I was clueless as to what was going on.

    I decided to check if there was something wrong with the curl_execute so I added

    if($result === FALSE) {
    die(curl_error($ch));
    }

    When I did that I saw ngrok also reporting a 200 OK but with the following:

    “SSL certificate problem: unable to get local issuer certificate”

    Solving this was a mess, but since I am on a dev environment and not the final one I simply added the following line right after “//Set the content type to application/json”

    The line to tell curl not to check for certificates (which is really a bad idea in terms of security) is:
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    Hope this helps!
    Thanks again!

  • Fauzan

    Hey! good tutorial but im stuck at “It’s time to open IDE and write some code. Create a file, in my case it’s index.php, in your case it could be any other file. Write the code that verify your Webhook.” So where should i put index.php? Im using windows

  • Copx

    Thanks for your tutorial,

    I have tried step by step but failed in step: setup webhooks
    $access_token = “EAAPBjt02ZAb4BAN0Hibm2tj7BJihWS7cgFWuZCO……”;
    $verify_token = “fb_time_bot”;
    $hub_verify_token = null;

    if(isset($_REQUEST[‘hub_challenge’])) {
    $challenge = $_REQUEST[‘hub_challenge’];
    $hub_verify_token = $_REQUEST[‘hub_verify_token’];
    }

    if ($hub_verify_token === $verify_token) {
    echo $challenge;
    }

    Above script was included in index.php as your suggestion, but after click on Verify an Save, error occurred:
    “The URL couldn’t be validated. Response does not match challenge, expected value=”1394911209”, received=’$access_token = “EAAPBj…'”.
    would you please have a look? Is there any other required script?
    sr I’m just newbie!

    Thanks

  • Isyraf Imran

    I want to create a bot for my business.I’m totally newbie with this,if you have a free time can you teach me…I’m really didn’t know how to make this…

  • Benke Smith

    I can receive messages, but can’t reply… the result of the CURL execution is 1.
    But there is no response from the bot… How can I check if the CURL is working?

  • Mota Narm

    Thanks for your tutorial.

    I followed all the step successfully until step 3.
    “Step 3: Sending and Receiving Messages”.
    I sent a message via curl and it was also succeeded.

    but after that i am failed here.

    “If hooks and subscription works fine, on your nGrok Web Interface(http://localhost:4040/inspect/http), you should see a request hit:”

    when I send message to my bot through my page nGork web interface doesn’t show it.

    where am I got wrong?

    Please leave a reply

    Thanks

    • niroshannipuna

      edit:
      looks like the problem was with the account I used to send the message. It was not my own account. When I send the message using my own facebook account there is no problem.

      then the next problem is how do I allow other people to use this bot?
      Do I need to submit this app to facebook for reviewing or something like that ??

  • Srini Vasan

    Hi,

    I get this error in ngrok (even though it reports “200 OK”):
    {“error”:{“message”:”(#100) No matching user found”,”type”:”OAuthException”,”code”:100,”fbtrace_id”:”Dkca+9nU7O5″}}

    I see the input in ngrok – but no replies in the message.

    What am I doing wrong?

    Thanks.

    Srini

      • Dhiraj

        Hi,
        I have already “Liked” my old page. But still facing same error. How do I subscribe the page ?

      • Pers

        Hi Adnan,

        I subscribed my page (I can see it in Messenger -> Settings – > Subscribed pages) and response messages from bot are delivered to FB.

        However, immediately after correctly delivering reply message, another POST appears on ngrok with summary: “{“error”:{“message”:”(#100) No matching user found”,” ….”

        So all is ok except this strange, not needed error message from FB. Do you know what could be the problem?

        Thank you.

  • venu

    curl_exec($ch); is not executing.

    Im running php file on XAMPP 5.6.23 server and hosting server using ngrok.

    Webhost is succesfully set and I’m able to send message succesfully from terminal using:
    curl -X POST -H “Content-Type: application/json” -d ‘{
    “recipient”:{
    “id”:”1234567890″
    },
    “message”:{
    “text”:”hello”
    }
    }’ “https://graph.facebook.com/v2.6/me/messages?access_token=ABCDEFG12345”

    But from php its not executing and server doesn’t throw any error also.

  • Neena

    Great tutorial but how to secure web hooks on production? To allow only traffic from Facebook message to get processed?

    • admin

      You may always implement some authentication scheme at your end. I can’t recommend referrer since bot scrapers can create a referrer while making an access.

  • Prashant kumar

    If bot has to send image in reply then how it will do ?
    can you help me in writing code for that in php .I have tried it using curl but instead of image bot shows image url from where bot has to fetch image.

    what to do help me out..!

  • Leandro Freitas

    Hello,

    Parabens by post.

    I doubt the next item
    “Efore you start sending / receiving messages, you need to subscribe your page. Go to Command prompt, assuming cURL is installed, run The Following command.”

    If I’m running on my remote server I have to run this command on it right?

    I am getting the following message from my bot:
    Sorry, I do not understand what you are trying to say.

  • Matias

    Hey man! Awesome tutorial, but… i can’t read the JSON.

    $input = json_decode(file_get_contents(‘php://input’), true);

    I get $input = null :/

  • Piyush

    i am getting an error while creating a webhook for my chatbot.

    {“error”:{“message”:”An active access token must be used to query information about the current user.”,”type”:”OAuthException”,”code”:2500,”fbtrace_id”:”CesCUkEavn+”}}

    can you help to resolve this.

  • Hassan

    Nice tutorial but I am facing an issue. The error is below that I got by enabling the debugging of curl.

    * Hostname graph.facebook.com was found in DNS cache
    * Trying 31.13.92.10…
    * Connected to graph.facebook.com (31.13.92.10) port 443 (#0)
    * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
    * NPN, negotiated HTTP1.1
    * SSL certificate problem: unable to get local issuer certificate
    * Closing connection 0

    Your help will be highly appreciated.

    Thanks

  • gil123

    First thanks for the tutorial! It really helped me and worked great.
    After finishing all the steps the bot is working, but only for me. I know I need to publish it and wait for approval, but there is a way to open it for another user? (co page admin)

      • gil123

        Thanks!
        Is there anyway to create one app and users can connect it to their page without knowing code or use facebook deveolpers? I want to make something basic for pepole to add to their page without my help just with a small tutrial. I want to make it as automatic as possible.

  • Shariff Elsheikh

    Great Article but i have a question, can I retrieve the user identity and answers whether video or voice, picture etc into my own application outside messenger so basically use it for chat and to feed my app with info that I will use outside Facebook.

  • tiptop

    Hi
    Thanks a lot for your code
    Everything works fine 🙂
    I need to create a json file with entries and messages to reply and place it in on my server
    Where I can find a sample json file working with your code ?
    Thanks for your help

  • Mousif Ahmed

    Hi,

    I am following this blog, every thing works fine. I found message on ngrok, but when i running my php script. It show below error. Please help me

    Array ( [error] => Array ( [message] => (#100) The parameter user_id is required [type] => OAuthException [code] => 100 [fbtrace_id] => BLJfJGBxts8 ) )

  • ahmed

    hi Adnan or anyone who could help
    i followed your tutorial then downloaded your code ,everything looks fine ..but when it comes to responding to messages ..the bot won’t reply.. i don’t understand where might the problem be . knowing that i changed the access_token and the verif_token .

  • Vikas Patil

    i am getting the following issue while sending the message

    {“error”:{“message”:”(#100) Parameter error: You cannot send messages to this id”,”type”:”OAuthException”,”code”:100,”fbtrace_id”:”BMaRC9tWxdJ”}}

    Can you suggest any solution for this issue

  • Bryant Gan

    I just need the SEND api part, but it didn’t work for me. Here is my PHP code.

    $pagetoken = “xxxxxxx”;

    $url = “https://graph.facebook.com/v2.6/me/messages?access_token=$pagetoken”;

    $jsonData = “{
    ‘recipient’:{
    ‘id’: $fbid
    },
    ‘message’:{
    ‘text’: $replymsg
    }
    }”;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTPHEADERS, “Content-Type: application/json”);
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
    $rst= curl_exec($ch);
    curl_close ($ch);

    **************
    I tried second piece of code below.. copy and paste the URL into browser, but i got the follow error.

    $message = json_encode(array(“text” => $replymsg));
    $recipient = json_encode(array(“id” => $fbid));

    $url = “https://graph.facebook.com/v2.6/me/messages?message=$message&recipient=$recipient&access_token=$pagetoken”;

    Error:

    {
    “error”: {
    “message”: “(#100) For field ‘messages’: The parameter user_id is required”,
    “type”: “OAuthException”,
    “code”: 100,
    “fbtrace_id”: “CvmuJ4zfH0s”
    }
    }