Facebook Chat bot (PHP webhook) sending multiple replies - facebook-graph-api

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

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);
}

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.

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
}

Related

Making a call to my webservice via curl doesn't work

I have a simple function to test my webservice via POST like this:
function service(){
$service_url = 'http://example.com/example_endpoint/user';
$curl = curl_init($service_url);
$header = array(
'Content-Type: application/x-www-form-urlencoded'
);
$curl_post_data = array(
"name" => "name_test",
"mail" => "name_test#example.com",
"pass" => "123",
);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
$curl_response = curl_exec($curl);
curl_close($curl);
$xml = new SimpleXMLElement($curl_response);
}
The webservice is specting the parameters on the array and the Content-Type is suppoused to be application/x-www-form-urlencoded but when I run the function in my browser and check the "Network" tab on "inspect element", there is a call to my webservice via GET despite of the fact that I'm setting the option to be POST
and the Content-Type keeps on text/html
This webservice allows to create users with the parameters inside the array $curl_post_data
I use the add-on "Poster" on Mozilla to call my webservice and it's succesfull, but when I call the function above, it doesn't work ¿How could I implement this function to make the correct call?
In Network tab on your browser you will not see POST as curl is posting this. Network tab shows activity from client side (Browser). Your data posting is happening by server through CURL.
Add this code to properly url encode data
$curl_post_data_string = '';
//url-ify the data for the POST
foreach($curl_post_data as $key => $value) {
$curl_post_data_string .= $key.'='.$value.'&';
}
rtrim($curl_post_data_string, '&');
And change this line
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
Keep in mind to see what you got after hitting a URL in CURL you need to print $curl_response
echo $curl_response;
This is a proper example of posting data using CURL
http://davidwalsh.name/curl-post

How to set webServiceURL and register successfully

I fill some parts of webserviceURL, but for deviceID, what do I put for it? This is the code I use to register device and pass for webservice. What do I need to change in order to register after adding pass ?
<?php
echo "<a href= 'genericPass.php'> Click here to add Generic Pass</a><br/>";
echo "<a href= 'couponPass.php'> Click here to add Coupon Pass</a>";
$url = 'https://192.168.1.105:8888/passesWebserver/v1/devices/{deviceID}/registrations/‌​pass.cam-mob.passbookpasstest/E5982H-I2';
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_POST, 1);
//curl_setopt( $ch, CURLOPT_POSTFIELDS, $myvars);
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec( $ch );
?>
When a pass is added to Passbook - the iPhone or iPod will call the webServiceURL to tell you it's device ID and push token. There is no way you can know what these are, so you need to set your web server up so that it can catch both the device ID and the push token.
The Device ID is sent as part of the URL and the token is posted as a JSON object.
On your web server, you need to set a rewrite rule to write all traffic from https://192.168.1.105:8888/passesWebserver/.... to https://192.168.1.105:8888/passesWebserver/index.php (search Google or SO on how to do this)
Then set up a index.php something like this:
// Transfer Request URL into array
$request = explode("/", substr(#$_SERVER['REQUEST_URI'], 1));
/**
* Register Device
*
* POST request to version/devices/<deviceLibraryIdentifier>/registrations/<passTypeIdentifier>/<serialNumber>
* Request will contain an Authorisation header with the value <ApplePass authenticationToken>, where
* authenticationToken equals the authenticationToken in the original voucher payload.
*/
if (strtoupper($_SERVER['REQUEST_METHOD']) === "POST"
&& isset($_SERVER['HTTP_AUTHORIZATION'])
&& strpos($_SERVER['HTTP_AUTHORIZATION'], 'ApplePass') === 0
&& $request[2] === "devices"
&& $request[4] === "registrations") {
$auth_key = str_replace('ApplePass ', '', $_SERVER['HTTP_AUTHORIZATION']);
$device_id = $request[3];
$pass_id = $request[5];
$serial = $request[6];
// Catch the JSON post and decode it
$dt = #file_get_contents('php://input');
$device_token = json_decode($dt);
$device_token = $device_token->pushToken;
if (!$device_token) die('No Token Found'); // Token wasn't found
// Add code to check the Auth Token against the serial number and add the
// device details to your database so you can use them later to push updates
// to the pass. This code should return a 200, 201 or other response depending
// on whether the auth is valid and the device is registered already or not
exit;
}
// Add other conditions to check for unregister, get serials, refresh and log.

How To Post Notification As Application

How to post a notification to users as application using facebook php sdk?
I have attached an image, in that picture we can see application from SongPop post a notification to me. I want to make something like this. I think this app post notification to their users, can I post a notification to a spesific user?
you have to a canvas page url set to in your app config then try with this code
$url = "https://graph.facebook.com/$user_id/notifications";
$notification_message = 'My Example Notification Message';
$app_access_token = $app_id . '|' . $app_secret;
$attachment = array(
'access_token' => $app_access_token, // access_token is a combination of the AppID & AppSecret combined
'href' => '', // Link within your Facebook App to be displayed when a user click on the notification
'template' => $notification_message, // Message to be displayed within the notification
);
// set the target url
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //to suppress the curl output
$result = curl_exec($ch);
curl_close ($ch);

facebook Graph API "/pageid/feed" returns blank

1) I got my facebook app setup.
2) I got my facebook page id, app_secret and access token.
function fetchUrl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$feedData = curl_exec($ch);
curl_close($ch);
return $feedData;
}
$profile_id = "288644066152";
//App Info, needed for Auth
$app_id = "appid";
$app_secret = "app_secret"; // do not expose app secret!
//Retrieve auth token
$authToken = fetchUrl("https://graph.facebook.com/oauth/access_token?type=client_cred&client_id={$app_id}&client_secret={$app_secret}");
$json_object = fetchUrl("https://graph.facebook.com/{$profile_id}/feed?{$authToken}");
print_r($json_object);
RETURNS:
{"data":[]}
Any help out there?
Thanks
There are 2 types of access tokens. The user access token, & the app access token.
Try something like:
https://www.facebook.com/dialog/oauth?client_id=******&redirect_uri=*************&scope=user_about_me,publish_stream,friends_about_me,****&state=SOMETHING

Cakephp post request to webservice

I have a web service that works fine with get requests but trying to use post it doesn't seem to work. I have this in my routes:
Router::connect("/products/service_add", array("controller"=>"products", "action" => "service_add", 'seller'=>true, "[method]" => "POST"));
Seller is like an admin. I also have ParseExtensions('xml'). My action is:
function seller_service_add() {
$this->log("hit", 'debug');
$hi = array("message"=>"hey");
$this->set(compact('hi'));
}
and the view is:
<product>
<?php echo $xml->serialize($hi); ?>
</product>
When I try to send a post to the API I just get a debug trace back with timer info. In the same script as I'm doing the post request I'm doing a get and when I run the script I can see the data passed by the API for the get but not for the post request.
The code I'm using to send the post is:
$ch = curl_init();
$data = array('Your' => 'Data');
curl_setopt($ch, CURLOPT_URL, "http://localhost/<project>/products/service_add.xml");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$result = curl_exec($ch);
curl_close($ch);
print_r($result);`
Any ideas on why this isn't working? Any help would be much appreciated.
Sorry if this is a bit verbose!
Update: I've added lines to spit stuff out to the cakephp debug log when actions are hit. I have one entry on the beforeFilter, this entry gets hit and I can see it in the log. The entry in the service_add action is not present in the log so I guess that the action is not being hit?
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
shouldn't this line be
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);