Multi friend selector

From Facebook Developer Wiki

Jump to: navigation, search

Facebook is modifying the way you can use the multi-friend selectors. Details will follow soon.

For more information, please read the Developer Roadmap, specifically, the sections on requests and invites.

How you render a multi-friend selector depends upon whether you have an FBML or iframe application.

FBML applications can easily embed a selector on your application's canvas pages using the fb:request-form and fb:multi-friend-selector tags.

IFrame applications can render a multi-friend selector by wrapping the multi-friend selector in fb:serverfbml tags. Facebook Connect sites can use this tag, or use fb:connect-form. IFrame applications can also construct an HTML form that submits either a GET or POST (preferred) request to http://www.facebook.com/multi_friend_selector.php, a full frame Facebook page that functions similarly to fb:multi-friend-selector, passing in the following parameters listed below.

See below and Talk:Multi_friend_selector for information on how to use it.

Contents

[edit] Parameters

You can pass these parameters in via GET or POST. Since you will be passing in a lot of information, we recommend that you use POST if at all possible to avoid issues. If you use GET and your query string winds up too long, your user might see a weird error message, so use it with caution. Whichever method you choose, the parameters are similar to a combination of the attributes for fb:request-form and fb:multi-friend-selector.

[edit] Required Parameters

General parameters
  • string api_key - Your API key.
  • string sig - A signature generated based on the rest of the parameters and using your secret key. See below.
fb:request-form parameters
  • string content - The contents of the request/invitation that will be sent. This should be FBML containing only links and the special tag <fb:req-choice url="" label="" /> to specify the buttons to be included in the request.
  • string type - The type of request/invitation to generate. This corresponds to the word that is displayed on the home page, e.g. "event".
  • string action - The URL to submit the form results to (or to go to if a user presses "skip").
fb:multi-friend-selector parameters
  • string actiontext - An instructional message to display to users at the top of the multi-friend selector.

[edit] Optional Parameters

fb:request-form parameters
  • bool invite - Set this to true if you want to send an invitation, or false (default) if you want to send a request. The only difference is in the language that is displayed to the user.
fb:multi-friend-selector parameters
  • bool showborder - You can choose to put a border around the outside of the multi-friend selector.
  • int rows - The number of rows of friends to show in the multi-friend selector. Default is 5, must be between 3 and 10.
  • int max - The maximum number of users who can be selected. Defaults to 15, can currently range from 5 to 20.
  • array exclude_ids - A list of user IDs to exclude from the multi-friend selector. (This should be passed in as a comma-separated list.)

[edit] Signing the Request (the Sig Parameter)

To sign the request, you can use the same function you use to sign normal API requests, and one that's similar to the way fb_sig_ parameters are calculated. Check out How Facebook Authenticates Your Application for more details, but the basic idea is to take an array of all the parameters you're going to be passing in, sort them alphabetically (using the parameters names to sort them), concatenate them all together, and then append your secret key and take the md5 checksum of the resulting string.

[edit] Resulting Values

If the user agrees to send the request, your action URL will receive an ids parameter containing an array of the IDs chosen by the user. If the user clicks Cancel, no IDs will get passed to the action URL.

If you passed in your parameters using POST to multi_friend_selector.php, then the resulting values will POST to your action URL. Otherwise, the result will do a GET to your action URL and the parameters are appended to the URL as a query string.

[edit] Errors

If you mess up somehow in passing the parameters, most users of your application will be sent to their Facebook home pages, away from your application. On the other hand, if you as a developer of an application are testing out the application, we'll try to print out some error messages that will hopefully help you debug. If you don't include the api_key parameter or pass in the wrong value, we'll be unable to tell whether you are the developer of the application and thus we'll send you home.

[edit] Working Multi-Friend Selector Example for IFrame Applications (PHP)

It was a bit of a struggle, but here is working PHP code that uses the new multi_friend_selector.php approach to initiating invites to your application. I am also including the code for the old style approach - the soon to be deprecated approach using $facebook->api_client->notifications_sendRequest.

The biggest challenge I encountered is the URL signing process. It is very easy to get signing errors when trying to redirect to the multi_friend_selector.php page, due to URL and HTML encoding. In order to discover the source of the verification issues, I literally had to start with a minimalist set of arguments to the multi_friend_selector.php page, and build them up in a trial and error fashion. I discovered that using PHP functions like htmlentities() and urlencode() on the arguments and/or the URL can cause the final URL to differ from the raw arguments passed to the signature generator. If the URL passed to $facebook->redirect() is encoded in any way, it will appear to not pass the signature verification.

I discovered that the parameters should not be encoded before signing, but urlencoded after signing. I fixed the demo below - if it doesn't work for you, change the example.

So here is the code that works. Like I said, adding calls to htmlentities() and urlencode() can cause the verification to break down. I also discovered that using double quotes in the $content string also throws things off the verification.

Hopefully this article will help others out there make the switch from $facebook->api_client->notifications_sendRequest to multi_friend_selector.php.

define( 'FB_API_KEY', 'abcdabcdabcdabcdabcdabcdabcdabcd' ); define( 'FB_SECRET', 'abcdabcdabcdabcdabcdabcdabcdabcd' ); define( 'FB_APPID', '0123456789' ); define( 'FB_CANVAS_URL', 'http://apps.facebook.com/myapp/' ); define( 'FB_APP_HOME_URL', 'http://www.mycompany.com/myapp/' ); // Call this function to send an invitation // $to - a comma-separated list of Facebook user ids to invite. It can be null for the NewStyle case. // $bNewSytle - a bool indicating whether the new style mechanism should be used (multi_friend_selector.php) function SendStandardInvitation($to, $bNewStyle = false) { $typeword = FB_APP_NAME; // Warning: double quotes in the content string will screw up the invite signature process $content = FB_APP_NAME . ' let\'s you blah blah blah. You can even blah blah blah!'; $content .= '<fb:req-choice url=\' ' . FB_CANVAS_URL . 'Home.php\' label=\'Check out ' . FB_APP_NAME . ' />'; // if your have post add routines take them to that add app URL instead. $actionText = 'Spread the word! Help your friends discover ' . FB_APP_NAME . '.'; if ($bNewStyle) $bOK = SendNewRequest($to, $typeword, $content, $actionText); else $bOK = SendRequest($to, $typeword, $content); return $bOK; } // The new style invite approach using multi_friend_selector.php function SendNewRequest($to, $typeword, $content, $actionText, $bInvitation = true) { global $facebook; $bInviteAll = (!$to || $to == "" ? true : false); $excludeFriends = null; if (!$bInviteAll) // Get all friends $excludeFriends = $facebook->api_client->friends_get(); else // Get all friends with the app $excludeFriends = $facebook->api_client->friends_getAppUsers(); $excludeFriendsStr = null; foreach ($excludeFriends as $userid) { $pos = strpos($to, (string)$userid); if ($pos !== false) continue; if ($excludeFriendsStr) $excludeFriendsStr .= ','; $excludeFriendsStr .= $userid; } $params = array(); $params['api_key'] = FB_API_KEY; $params['content'] = $content; // Don't use htmlentities() or urlencode() here $params['type'] = $typeword; $params['action'] = FB_CANVAS_URL . 'Mobilize'; $params['actiontext'] = $actionText; $params['invite'] = ($bInvitation ? 'true' : 'false'); $params['rows'] = '5'; $params['max'] = '20'; $params['exclude_ids'] = $excludeFriendsStr; $params['sig'] = $facebook->generate_sig($params, FB_SECRET); $qstring = null; foreach ($params as $key => $value) { if ($qstring) $qstring .= '&'; $qstring .= "$key=".urlencode($value); } $inviteUrl = 'http://www.facebook.com/multi_friend_selector.php?'; $facebook->redirect($inviteUrl . $qstring); return true; } // The old style invite approach using $facebook->api_client->notifications_sendRequest function SendRequest($to, $typeword, $content, $bInvitation = true) { global $facebook; $image = FB_APP_HOME_URL . 'logo.gif'; // To be shown beside the invite; resized to be 100 pixels wide $result = $facebook->api_client->notifications_sendRequest($to, $typeword, $content, $image, $bInvitation); $url = $result; if (isset($url) && $url) { $facebook->redirect($url . '&canvas=1&next=Home.php'); return true; } $bOK = ($result && $result != ""); return $bOK; }


I hope this helps.

Jim McCurdy Face To Face Software


Hi Jim,

thanx for your help but this code is not working in my case.

1. I copied your code invite2.php file.

2. Changed the FB_API, FB_Secret, FB_APPID, FB_CANVAS_URL, FB_APP_HOME_URL

3. Put everything in the test application http://apps.facebook.com/bezisfriends/

But am still getting the blank page.

Is there any other simple solution to call from an iframe application?

Thank you so much for your help. Bez


I am experiencing the same exact problem. It seems like it's the php code posted...

[edit] Working Multi-Friend Selector Example for IFrame Applications (Python -- TurboGears)

This is my version of the multi-friend selector that does work with Python's TurboGears as the server. This relies on the following:

  • minifb is the library used to interact with Facebook
  • it uses Python cgi library to escape the content needed to embed within the XFBML
  • A known problem with this approach is that it leaves the user in a nested frame
  • constants for the app id, key, and other required things are declared elsewhere
@expose() def invite(self, *args, **kwargs): """ returns fbinvite, but directly as a string... """ from cgi import escape uid=identity.current.user.id signed = minifb.validate(_FbSecret, kwargs) list_o_friends = minime._getAppFriends(signed['session_key']) excludeIds = ",".join([str(i) for i in list_o_friends]) content = """ <fb:name uid="%s" firstnameonly="true" shownetwork="false" /> wants to invite you create and share top ten lists, <fb:req-choice url="%s" label="Add MY APPLICATION." /> """ % (uid, _canvas_url) invitation_content = escape(content,True) reqform = """ <fb:serverfbml> <script type="text/fbml"> <fb:request-form action="%s" method="POST" invite="true" type=" MY APPLICATION" content="%s" > <fb:multi-friend-selector max="20" actiontext="Invite your friends to help improve MY APPLICATION." showborder="true" rows="5" exclude_ids="%s" /> </fb:request-form> </fb:fbml> </script> </fb:serverfbml> """ % (_canvas_url,invitation_content,excludeIds) return """ <html xmlns=http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" > <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/> <title> MY APPLICATION Invitation</title> <script src="http://static.ak.facebook.com/js/api_lib/FacebookApi.debug.js" type="text/javascript"></script> </head> <body> <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"> </script> %s <script type="text/javascript"> //<![CDATA[ FB_RequireFeatures(["XFBML"], function(){ FB.Facebook.init("%s", "/static/xd_receiver.html"); ;}); //]]> </script> </body> </html> """ % (reqform, _FbApiKey)

I hope this help. --Mickey Hadick

reference