We have learned from our previous tutorial how to send Facebook application requests and store the resultant ids to our DB.

But how should your application act when the “receiver/invitee” accept a request? This will be explained in this tutorial along with an additional tips of how to maximize the use of this great feature.

 

Requirements

Back to top
 

Explanation

Before we start, let us revise our code from our previous tutorial and add the data field to the apprequests dialog (read the Facebook documentation):

<?php
// PATH TO THE FB-PHP-SDK
require_once '../src/facebook.php';
$facebook = new Facebook(array(
  'appId'  => 'APP_ID',
  'secret' => 'APP_SECRET'
));

$user = $facebook->getUser();
$loginUrl = $facebook->getLoginUrl();

if ( empty($user) ) {
    echo("<script> top.location.href='" . $loginUrl . "'</script>");
    exit();
}
?>
<!doctype html>
<html>
<head>
<title>How To: Send An Application Request Using The Facebook Graph API - MasteringAPI.com</title>
</head>
<body>
<div id="fb-root"></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
    window.fbAsyncInit = function() {
        FB.init({
            appId: 'APP_ID',
            status: true,
            cookie: true,
            oauth: true
        });
    };
 
    $('a').click(sendRequest);
    function sendRequest() {
        FB.ui({
            method: 'apprequests',
			message: 'I want to give you this flower!',
			title: 'Give a flower to some of your friends',
			data: '{"item_id":1254,"item_type":"plant"}'
        },
        function (response) {
            if (response.request && response.to) {
                var request_ids = [];
                for(i=0; i<response.to.length; i++) {
                    var temp = response.request + '_' + response.to[i];
                    request_ids.push(temp);
                }
                var requests = request_ids.join(',');
                $.post('handle_requests.php',{uid: <?php echo $user; ?>, request_ids: requests},function(resp) {
                    // callback after storing the requests
                });
            } else {
                alert('canceled');
            }
        });
        return false;
    }
 
      // Load the SDK Asynchronously
  (function(d){
     var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
     js = d.createElement('script'); js.id = id; js.async = true;
     js.src = "//connect.facebook.net/en_US/all.js";
     d.getElementsByTagName('head')[0].appendChild(js);
   }(document));
</script>
 
<a href="#">Send your friends a flower!</a>
 
</body>
</html>

UPDATE: The code above has been updated to use the latest PHP-SDK (v3.x) and the new Requests 2.0 Efficient implementation

To better understand the Facebook application requests, we are going to assume that you have an application that allows the users to send their friends gifts/items. In the code above, the user will send his friends an item.

This item has the an id = 1254 (the id of “flower“s in our application/system) and of type/category plant.
As you can see, we are using json format in the data field. This would allow us to send data along with the request in a more structured way.

Back to top
 

Handling the applications requests

From the Facebook documentation:

If a user clicks ‘Accept’ on a request, they will be sent to the canvas URL of the application that sent the request. This URL will contain an additional parameter, request_ids, which is a comma delimited list of Request IDs that a user is trying to act upon

But be aware if you are setting the Bookmark URL in your application settings, Facebook will send the user to that url instead.

Handling the requests can be done in various ways depending on your application and its functionality and here is a basic usage:

<?php
if(!empty($_REQUEST['request_ids'])) {
	$APPLICATION_ID = "APP_D";
	$APPLICATION_SECRET = "APP_SECRET";

	/*
	* Get the current user, you may use the PHP-SDK
	* or your own server-side flow implementation
	*/
	$user = getUserFromSignedRequest();
	
	$app_token = get_app_access($APPLICATION_ID,$APPLICATION_SECRET);

	// We may have more than one request, so it's better to loop
	$requests = explode(',',$_REQUEST['request_ids']);
    foreach($requests as $request_id) {
        // If we have an authenticated user, this would return a recipient specific request: <request_id>_<recipient_id>
		if($user) {
			$request_id = $request_id . "_{$user}";
		}
		
		// Get the request details using Graph API
        $request_content = json_decode(file_get_contents("https://graph.facebook.com/$request_id?$app_token"), TRUE);
		
		// An example of how to get info from the previous call
		$request_message = $request_content['message'];
		$from_id = $request_content['from']['id'];
		
		// An easier way to extract info from the data field
		extract(json_decode($request_content['data'], TRUE));
		// Now that we got the $item_id and the $item_type, process them
		// Or if the recevier is not yet a member, encourage him to claims his item (install your application)!
		echo $item_id;
		
		if($user) {
			/*
			* When all is done, delete the requests because Facebook will not do it for you!
			* But first make sure we have a user (OR access_token - not used here)
			* because you can't delete a "general" request, you can only delete a recipient specific request
			* <request_id>_<recipient_id>
			*/
			$deleted = file_get_contents("https://graph.facebook.com/$request_id?$app_token&method=delete"); // Should return true on success
		}
	}
}

function get_app_access($appId, $appSecret) {
	$token_url =    "https://graph.facebook.com/oauth/access_token?" .
                    "client_id=" . $appId .
                    "&client_secret=" . $appSecret .
                    "&grant_type=client_credentials";
    $token = file_get_contents($token_url);
	return $token;
}

function getUserFromSignedRequest() {
	if(!empty($_REQUEST['signed_request'])) {
		$signed_request = $_REQUEST["signed_request"];
		list($encoded_sig, $payload) = explode('.', $signed_request, 2);
		$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
		
		if( !empty($data['user_id']) )
			return $data['user_id'];
	}
	return null;
}
?>

Here, we are:

  • Getting an application access token
  • Looping through the request ids (if we have any)
  • Appending a recipient id if we have a user
  • And based on the data field, we can do various actions
  • After that, we are deleting the request as recommended by Facebook

As you can see, we are not using the PHP-SDK. But you can always use it like so:

Reading the request:

$facebook->api("/$request_id?$app_token");

Deleting the request:

<?php
    require_once('php-sdk/facebook.php');
    $config = array(
    'appId' => 'YOUR_APP_ID',
    'secret' => 'YOUR_APP_SECRET',
    );
   $facebook = new Facebook($config);

   //Assuming the user has already authenticated the app
   $user_id = $facebook->getUser();

   //get the request ids from the query parameter
   $request_ids = explode(',', $_REQUEST['request_ids']);

   //build the full_request_id from request_id and user_id 
   function build_full_request_id($request_id, $user_id) {
      return $request_id . '_' . $user_id; 
   }

   //for each request_id, build the full_request_id and delete request  
   foreach ($request_ids as $request_id)
   {
      echo ("reqeust_id=".$request_id."<br>");
      $full_request_id = build_full_request_id($request_id, $user_id);  
      echo ("full_reqeust_id=".$full_request_id."<br>");
  
      try {
         $delete_success = $facebook->api("/$full_request_id",'DELETE');
         if ($delete_success) {
            echo "Successfully deleted " . $full_request_id;}
         else {
           echo "Delete failed".$full_request_id;}
        }          
      catch (FacebookApiException $e) {
      echo "error";}
    }
?>
Back to top
 

Notes

  • It is always a good idea to set your Bookmark URL in your application settings so you have a separate script to handle the requests Bookmark URL is no longer in use
  • After deleting the request, it would be a good practice to update the DB record and set the outstanding field to zero (refer to the previous tutorial)
Back to top
  • http://www.facebook.com/profile.php?id=636774153 Ivan Kurnosov

    What about adding sample json-responses for both API methods? (normal and delete ones)

    • http://www.masteringapi.com Ibrahim Faour

      For the delete method, I clearly stated in the comment of the code that it should return “true” on success.

      As the retrieval call, the response is explained in the FB documentation and I was clear I’m not going to write everything back here. Also, I’ve provided two examples on how to retrieve the “to” and “from” ids, so with the structure in FB documentation in mind this should be straight forward for other fields.

      Any questions are welcome.

  • Pingback: How To: Send An Application Request Using The Facebook Graph API | API? Yes Master!

  • Diego Trigo

    I never comment on the net, but I loves you article..
    exactly what I was looking for..

    Thanks a lote…
    Diego Trigo

    • Ibrahim Faour

      You are welcome!

  • Wck930

    i put the second code in my server as php format, however, when i run it, just a blank page shown. Is this normal?

    • http://www.masteringapi.com Ibrahim Faour

      No it is not! This code is just an example of how to handle the application requests. I recommend you read the previous tutorial to understand what applications requests are all about. Also read the corresponding Facebook document.

  • stefan

    exactly what i needed … but when i try to us file_get_contents … i get an “Unsupported get request.” i provide the correct request_id and i have a valid token … and no idea what i’m doing wrong :(

  • http://profiles.google.com/merman.us Merlin W

    Does this work if I have not yet received or requested basic permissions? I’m sending requests without them- without getting user_id. How do I read or handle these requests?

    • http://www.masteringapi.com Ibrahim Faour

      You need to store the response ids returned from the response and then read the request as described above.

  • http://www.facebook.com/zerfl Daniel Martin

     Thanks for the tutorial. Very helpful. Unfortunately the custom data I sent with a request is not being retrieved. 

    $request = FB::api(‘/’.$request_id);

    $request simply holds no “data” key, whereas all the other info (from / to, message, created, etc) is there.

    The “data” I pass is a simple test string. The documentation isn’t really helpful either.

  • Cmaciasg

    First of all, great tutorial, bravo!!.
    Just one question, and if what I want is update the outstanding flag only when the recevied install the application? Would it be possible?

  • Gacasu

    Great job! You saved my day! Thanks!!

  • http://twitter.com/andyromero_ Andy Romero

    ok, very nice, but how we write if the invited acept on fb_requests table? please continue with the previos tutorial =)

  • Rahul Das

    There is an error with facebook.php

    When I am trying to use it, it is showing parse error at line number 18.

  • Asd

    thank you for your tutorials! it’s rather difficult to find tutorials about facebook api which aren’t outdated.
    i’ll visit your page from now on! keep up the excellent work!

    greetings from germany

  • Fatih Saki

    Good job. Thanx for this great tutorial.

    Here is our case.

    when a user removed app then we try to delete her/his requests which we stored in our DB.

    But in error log file we see so much warning like below because of deleting attempt.

    PHP Warning:  file_get_contents(https://graph.facebook.com/2405542262475?access_token=10xxxxxxxxxxxxx17|c3xxxxxxxxxxxGY&method=delete) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request
     in ……

    What do you think about this situation?

  • http://www.facebook.com/people/Pierre-Dechery/627692952 Pierre Dechery

    I know this is a old topic, but I really like to know how to implement this code in my app… I see there’s a function for dealing and removing the requests but I don’t think I can just put this in my app’s welcome page.

    Any help would be much appreciated..

  • Treed44

    Hi, thanks for this great tutorial! All works for me except when i want to delete the request, i only get this message error “App Request Recipient Must Be Specified: The recipient for this app request must be specified through a user-signed access token or the fully specified app request ID”  the token and the request id are correct inded if i remove  “&method=delete” i can get the request information complete, but i can delete. Any idea?

  • Jim Cricket

    So my understanding is that the handling requests PHP code above would reside in the canvas URL page, not the callback response from the sendRequest() function. Is that correct?

  • Ovaisrafiq

    Can we use this article as a response to the new changes for request part which facebook will reflect 1 Jan 2012 please let me know Reference is this:
    http://developers.facebook.com/blog/post/569/
    please inform me on email ovaisrafiq@gmail.com i am facing problem in getting the request_ids using their new feature.

    I am using the code something like this

    if (receiverUserIds.request) {
                        var ids = receiverUserIds.request;

                        var _batch = [];
                        for (var i = 0; i 0) {
                            FB.api(‘/’, ‘POST’, { batch: _batch }, function (res) {
                                // var obj = eval(‘(‘ + res + ‘)’);

                                for (var j = 0; j < res.length; j++) {
                                    body = res[j].body;
                                    var myObject = eval('(' + body + ')');
                                    //console.log("IDS2 : " + myObject);
                                    friendID = myObject.to;
                                       var friend=friend+friendID+'|';
                                    //console.log("friend : " + friend);
                                    //alert(friendID);
                                   // here you have every friendID

                                }

    then in $.post  i add the array of friend but i am not getting more then one request ids i want to get all the request id which i have invited so that i can get friend id on behalf of that.I am trying myObject.to to get all the friend request ids.

    Thanks
    Ovais

  • http://www.facebook.com/eze.lauria Ezequiel Lauria

    Nice documentation, but I have a question.

    Don’t you have to be connected to the app if you want to read the notification?

  • http://twitter.com/SpirytSista Nnenna

    thanks so much! i couldn’t find anything in the documentation about handling requests

  • http://twitter.com/RyanWhyGordon Ryan Gordon

    Awesome article, so much help. (always a but :P )

    Could all these errors be because in your getUserFromSignedRequest(), the decoded querystring from $_REQUEST['signed_request'] no longer supports the return param for $data['user_id']??

    My return is this and I cant’t seem to find [ 'user_id ']
    array(3) { ["algorithm"]=> string(11) “*************” ["issued_at"]=> int(**********) ["user"]=> array(3) { ["country"]=> string(2) “**” ["locale"]=> string(5) “en_US” ["age"]=> array(1) { ["min"]=> int(21) } } }  

    Has the API been updated?

    [UPDATE] – I believe this is a permissions and OAuth issue for the app if anyone is experiencing the same problems…

    • Alberto

      I have the same issue.
      Any idea?

  • sujan

    Is there any new idea for the handling application request using facebook sdk cause this code doesn’t work any more. can anybody help me for this. and can you help me the code in codeigniter