3

My Facebook chat bot is working but it's sending back multiple messages after my initial message to it. This is my webhook script (i appreciate it's a very rough working example):

$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];

if ($verify_token === 'MY_VERIFICATION_TOKEN') {
  echo $challenge;
}

$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'];


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

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

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

//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'));

//Execute the request
$result = curl_exec($ch);
dmulter
  • 2,608
  • 3
  • 15
  • 24
Lee Woodman
  • 1,319
  • 2
  • 16
  • 30

3 Answers3

9

FB hits your webhook url with the original incoming message and you process it. You are then sending a response back to the user and the script ends. Then, once the message is delivered to the user, FB sends a delivery confirmation to the webhook url. Since your script is always set to send "Hey Lee!" any time that it is called, the delivery callback is actually triggering another message to be sent, and then another delivery confirmation comes in, and then that process is repeating it self. To fix this, put an if statement around your code to send a message. Here's an example.

$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];

if ($verify_token === 'MY_VERIFICATION_TOKEN') {
  echo $challenge;
}

$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'];


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

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

if($message=="hello")
{
        //The JSON data.
        $jsonData = '{
        "recipient":{
                "id":"'.$sender.'"
        },
        "message":{
                "text":"Hey Lee!"
        }
        }';
}

//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'));

//Execute the request
$result = curl_exec($ch);

Hope that helps.

Drew Smith
  • 91
  • 1
  • I am using the example. Webhook got verified, When i try to message my bot, it returns nothing. I don't know either how to debug Webhooked page – Volatil3 Apr 21 '16 at 18:34
  • I had the challenge of debugging too but because Drupal (the backend platform for my Chatbot) rocks it has a function called Watchdog which is a logging module so you can send everything to Watchdog to debug. Makes the process very very easy. Like this: $input = json_decode(file_get_contents('php://input'), true); watchdog("Webhook Data Received", '
    ' . print_r( $input, true) . '
    ');
    – Lee Woodman May 06 '16 at 10:00
  • The fact that a webhook is posted for delivery confirmation got me. Thanks a bunch @Drew. – nikk wong Jun 15 '16 at 19:14
  • awesome explanation. makes perfect sense. – lilsizzo Sep 14 '16 at 07:23
9

I think it's because you don't verify if the messages sent are empty :

try this instead :

$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];

if ($verify_token === 'MY_VERIFICATION_TOKEN') {
  echo $challenge;
}

$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'];


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

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

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

//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'));

//Execute the request
if(!empty($input['entry'][0]['messaging'][0]['message'])){
$result = curl_exec($ch);
}
  • Getting these weird errors instead: `
    Deprecated: 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 Unknown on line 0

    Warning: Cannot modify header information - headers already sent in Unknown on line 0
    {"error":{"message":"Invalid OAuth access token.","type":"OAuthException","code":190,"fbtrace_id":"BsNG\/mJVYem"}} ^As
    – Volatil3 Apr 21 '16 at 19:30
  • You need to put exit(); after echo $challenge; line – mileusna May 17 '16 at 13:03
  • I'm also facing similar problem, but I have added a check for empty message (delivery). When I checked the webhook URL, seems it's being hit twice. I'm using ngrok with local server as webhook and I can clearly see that the webhook url is being accessed twice with message field populated both the times. Any idea?? – thekosmix Jun 16 '16 at 15:21
  • 1
    Thank you for this answer! It works! Strange bug... :) – Seishin Aug 23 '16 at 09:59
0

Tried the same, the first request holds the actual user message, the other requests not. I just send an answer if the
$message = $input['entry'][0]['messaging'][0]['message']['text']; is not null:

if ($message){
//send your message here
}
  • How to send multiple response to a single message , if Someone Says Hi , Bot Should reply Hi (1st Message) , What is your name (2nd message) .. – Srinivas08 Mar 01 '18 at 01:23