Talk:Fb:request-form

From Facebook Developer Wiki

Jump to: navigation, search

is it true that the example: <fb:fbml> <fb:request-form action="index.php" method="POST" invite="true" type="YOUR APP NAME" content="Your text goes here. <?php echo htmlentities("<fb:req-choice url=\"YOUR CANVAS URL\" label=\"Authorize My Application\"") ?>" > <fb:multi-friend-selector showborder="false" actiontext="Invite your friends to use YOUR APP NAME."> </fb:request-form> </fb:fbml>

there is no closing "/>" for <fb:req-choice


Contents

[edit] Who's responsible

From what i can gather it is totally down to the developer to track who has been sent invites and has then accepted/declined/undecided and if the developer does not choose to do this and other users invite the same person, the developer is penalised, by having the number of invites they are allowed cut? No surely if facebook choose to implement such drastic measures, and it means so much to them, should they not sort it out them selves? if evryone has to do it why make evryone do it kind of thing? its like making a variable that has to be set to a certain value, no matter what? so why have the variable? it seems pointless and i am not sure why facebook are reluctant to adopt such a seemingly simple and highly requested feature into their own markup language (which may i say i think is quite good despite) so...what do you think? should it be down to the developer? should facebook intergrate it? am i being naive? you choose

lkcl: from what i can gather, tracking of friend information - exactly as is required - contravenes the facebook developer "Terms of Service". you are allowed to cache information for periods of up to 24 hours, and so by the time the "invite friends" restriction is lifted (24 hours), you're supposed to destroy the very information that you need!

in short, yes, absolutely, facebook should be cacheing invites and sending them out at the rate that _they_ want to restrict applications to. it's not like the application can record the invites and perform them itself (20 or so at a time or whatever) because the invites are entirely in facebook's hands, not the applications.

[edit] Max number of recipients

I created a new app and it only allows me to send to 4 people "total", not even at a time. How can I expand on this number? My app is intended for teachers to send to their students. I was just ready to publish my app and I ran into this horrible flaw!


Seeing as how Facebook controls this component, please get rid of the "add up to 15 of your friends" part of the component, at least as far as having it be a user-facing feature is concerned. What I mean is, since Facebook is now handling everything from recieving the list of users that the friend selects all the way through to actually sending the invites, there's no reason to tell the user that they can only "select up to 15 friends". Instead, the user should be able to select as many as they want, and then Facebook should cache the list, and then send out the invites at a rate of 15 per day until all the friends in the list have been invited. That way, the user is not needlessly bothered with having to pick a subset of 15 friends every time they want to invite people, and also it solves the problem of users having to visit the "invite friends" page several times over multiple days to invite all of their friends, as well as the problem of the user sending multiple invites to the same friend(s) because they forget who they have previously invited.

So what I'm saying is, collect the entire list of all the friends that the user wants to invite, all at once, and then internally cache that list, and send out the invites at whatever rate is deemed to be most appropriate. The user should not have to be bothered with the "only 15 will be sent per day" policy, it should now be handled entirely on Facebook's end, and transparent to the end users.

  • The reason for the limit is not some kind of technical reason - it's because we don't want users spamming huge numbers of friends. We're hoping that the standard interface may enable us to increase the limit, but just spreading the invites out across multiple days won't help the situation.
    • I'm not sure I follow your logic. You don't want users spamming lots of friends, so you impose a limit of x invites at a time. However, there is nothing to stop a determined user from visiting the page multiple times, and nothing to stop determined app developers from tracking the time at which a user was directed to the invite page, and then sending them back there again as soon as they are able to send more invites. Nothing has been gained by limiting the number of people the user can select at once, it just creates a greater level of hassle for users who actually want to invite all of their friends (and if that's what an end user wants to do, they should be able to do so). What if you collected the list all at once, and then did some pattern matching against the invite content to make sure that the same user could never send the same invite to the same friend more than once? That's really how it should work anyways, and that should also be far less spammy then allowing the user to visit the invite page multiple times, and potentially send the same invite to the same people over and over.
    • Note that the dynamic has changed as well, as it is no longer the case that app developers are saying who the invites should be sent to, it is now the end user who decides this. If an end user decides they want to send something to all their friends, then they should be able to do so, and it is not "spam" in the same sense as it is if a developer has just invoked the 'sendRequest' API call on behalf of a user and just passed all of that user's friends because it is what the developer wants. The use-case has now shifted such that it is entirely the end user deciding who they want to invite, and as such they should be able to select as few or as many people at once as they please.
    • If the limit has been genuinely imposed to prevent users spamming their friends, it should apply to Facebook's own applications too. Why is it that a facebook user can create an event using facebook events, or a group using facebook groups and invite ALL their friends, yet if they create a survey using my application, they cannot invite all their friends to answer the survey? This does not make sense - if this limit is intended to reduce spam it should apply equally to facebooks own applications or not at all. Alternatively, the limit needs to be removed completely on a per-application basis for those applications such as my 'surveys, petitions, polls, votes and quizzes' application, where the user has a genuine need to invite all their friends. If user A has 500 friends and wants to carry out a legitimate survey of all their friends, it is impossible at a rate of 20 per day. If a user thinks their friend is spamming out lots of invites, they should be able to block that specific friend from sending them any invites, there is no need or reason for a daily limit per application.


Alternatively...

The suggestion above would be *great* if implemented. But at the least, we developers need to know which users were invited each time this interface is invoked, so we can mark those users in our app UIs as already invited. We also need some way to omit previously invited users from the list presented by Facebook's new invite list interface, or to flag them as already invited and sort them to the bottom, so users can invite new people.

This should be made to work with the upcoming IFRAME version as well.

  • You already have access to this. The list of selected users is included in the form submission. Think of <fb:request-form> as a normal HTML form tag - you can include method="POST" and action="submit.php" or whatever you want. Then the <fb:multi-friend-selector> is a special form element that results in an array of ids[] being passed to your page. You can exclude people via the exclude_ids attribute.

[edit] IFrame Based Applications

So, basically, does this mean that iframe applications are SOL?

I think there needs to be an iframe equivalent.

-- I agree. This change unfairly makes IFRAME applications second-class on Facebook. There needs to be some way for us to call the old invite/request mechanism or a new version similar to the new FBML version.

Is there a confirmed version of an IFRAME compatible add friend method? Is 2-3 weeks a bit of a short timeframe? Is it not better just to deprecate the notifications API method? Sorry a lot of questions; nobody expects the Spanish Inquisition :)

I really hope there is an option for iframe apps that becomes available *before* the sendRequest API is completely removed.

For iframe apps, you can use XFBML and the fb:serverfbml tag to render fb:request-form. -- Pete (563683308 11:47, 25 March 2009 (PDT))

Pete, we've tried this but IE8 Final blocks the request-form from rendering due to XSS warning. Anyone have any thoughts?

The solution I used was to put the invite form on an fbml page with Fb_force_mode (www.domain.com/invite.php?fb_force_mode=fbml) Everything else in my app is in the iFrame, but that one page is not.

[edit] Working sample of Multi Friend Selector for IFRAME applications

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 encounteed 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 aguments 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.

So here is the code that works. Like I said, adding calls to htmlentites() and urlencide() can caue the verfication 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 userids 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 . ' />';
       $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=$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,

I tried this code and the only thing that I am getting is the blank page. Can you please advice what I am doing wrong. Application is http://apps.facebook.com/bezisfriends/

Thanx, Bez

[edit] IFrame Based Applications - Followup

As a follow up the iframe issue - what are the impacts and/or accomodations for desktop-only applications?

Also, what about Flash apps that are in IFRAMEs? I am developing a Flash app and was planning on using sendRequest to invite users to the app. It will be extremely klunky to redirect them to a little FBML page just for this one case. My UI for 'invite a friend' is already built, so this was painful news for me!

[edit] Troubleshooting

How do you pass a URL to return for "Skip this step"?

Make sure to declare an action attribute in the fb:request-form tag

In the beta parser, what's the deal with the required image attribute for fb:request-form ? --25700704 12:20, 8 September 2007 (PDT)

  • oops, the beta tier was (ironically) out of date for this request form stuff. should work now without the image attribute.

How do you remove the "Skip This Step" button? This will most definitely deter uptake of new users...

I am defining an "action" url in the fb:request-form tag, but I still get redirected to the app's canvas page after the invite is sent (or skipped).

[edit] Invites

Some applications are using single friend selector to challenge a friend to do something. And if a friend has already installed the application the notification is sent, and if not, an invitation. How it can be done now? And are there any daily limits for single app user to invite his friends?

  • There is no way to dynamically decide which to send. We believe you should use the mechanism that is appropriate for the type of action that the user is taking - if it requires a response from the recipient, use a request, while if it simply notifies the recipient that something has happened that they might be interested in, use a notification.

But if a user hasn't installed the application, will he get a notification from the application?

I'd like to second this concern and ask for Facebook to clarify. A number of applications will be badly affected by this change. If a user wants to perform an action with respect to a friend, why should they have to know whether or not their friend has already added the app? The app should just send an invitation or a notification as appropriate. Requiring the use of an invitation-specific page means that either (1) the user must know whether or not their friend already has the application installed, (2) the user must be given a page with two sections for choosing a friend who has added the application or one who does not, or (3) if the user selects a friend who has not already added the app they must go through another page confirming their selection, and then yet another confirming the sending of the invitation. All of these possibilities are really ugly. Please retain the current API functionality, even if it only allows invitations to be sent to one user at a time (each with one-step confirmation). --662630184

Third the concern; Don't remove features of your API that will restrict desirable user flows. Make request-form an alternative to sendRequest. --19223529

Fourth this concern; This change completely disables my application. It makes no sense to me. This form makes invitations extremely impersonal and ironically just gives app users an attractive bit of spammy UI. Come on Facebook.

  • In multi-friend-selector you allow exclude_ids, why not allow this for fb:request-form? That way we can throw in a list of app users on the form level so when they Challenge their friend (or something equivalent using friend-selector or other FBML tags) the request-form will invite users that need inviting but still pass the other IDs in the ids post list so we can keep the end-user experience less confusing and allow those of us who loved the versatility of sendRequest to continue to take advantage of it. --1414620016 21:25, 9 September 2007 (PDT)

New Limits

Are there any limits on the number of invites the user can send now?

  • We've increased the limit on the new tool to 20 per user per day for now. We may be adjusting this later (hopefully, if we feel that the new tool is being used in a more effective manner, we'll be able to increase the limit).

Custom Text

Is it me or is their no way for users to send a custom invitation, as we like all of ours to be personalised if possible?

  • Good point. We'll definitely add in a standardized way for users to include a custom message with their request.

Exclude Current App Users

Is there a way to exclude current application users from the list of users we want to send invites to?

  • You can use the exclude_ids attribute. But keep in mind that in general, we encourage you to use this not just to send invitations to your application but to invite people to something within your application (e.g. to invite someone to attend an event or join a group).

Track what invites were sent

In our app we try to track which invites where actually sent so that our users don't see the same users each time. This is also useful to track the success rate of invites. Could we have the action URL be called with some query parameters that list the people invited? That would even be an improvement from the current '&sent=1' provided after notifications.sendRequest redirect.

Exclude Current App Users List Too Long

There have been instances where the user has more than 500 friends. In such a scenario, if 500 has added the application, the exclude list is extremely long. Is there an easier/more efficient way to tackle this?

[edit] Specifying an existing list of recipients

I have an application that is like an extended version of Relationship Status, and I use sendRequest to notify someone that someone else added them to a relationship. So I already have the form to specify the other people, and when it's submitted the relationship goes into my database and the request is sent. Am I correct in that in order to replicate this functionality, I need to direct the user to another page containing <fb:request-form> after updating the database? If so, is there a way to use the existing list of people to send the request to? I really need to be able to specify the recipients without using friend selectors. Or can I just replace the whole form with <fb:request-form>, and my database will be updated? -- 6415618 07:53, 8 September 2007 (PDT)

  • One of the ideas behind the new FBML tags is that you can't prefill in the list of recipients, since too many apps were pre-selecting random people that the user probably didn't intend to send the request to. That said, we're considering adding the ability to preselect a single person in an fb:multi-friend-input or fb:friend-selector tag. You would not be able to insert multiple pre-selected people in a single request-form. Would this help?
    • Not really, since multiple people may be involved. If I replace my <form> tag with <fb:request-form>, and keep the method, action, etc. the same, would that work? Would it redirect to my action URL after sending the request, with all the post variables intact? -- 6415618 17:02, 8 September 2007 (PDT)
    • Upon implementing <fb:request-form> in my application, I've determined that yes, this would help.
      • Seconded by 4813235 02:44, 14 September 2007 (PDT). Please add the ability to auto-hilite a certain friend id.
        • User: 564137914 This feature would also be very helpful to my application.
        • I agree, this would be useful. -David
        • I also really really need this.. and I bet there are hundreds out there who will too once sendRequest is gone. Please add this ASAP. 525336368 17:08, 25 September 2007 (PDT)
        • Most certainly needed. A way to pass one or more ids to be preselected is of utmost importance =). Also, if it'd be possible to not display the <fb:friend-selector> at all but, instead to have the value in a hidden field, this would be ideal. The reason for this is that in my app, the user chooses the person to send the invite on one page, and then i pop-up a dialog to confirm actions and would like to send the app invite from this dialog, with the uid passed in.

[edit] Please select some friends first.

I just put together an invitation system modeled by the one on this page. I've been trying to test it by inviting a single friend. However, when I select him and hit "Send Invitation", the selector rebuffs me with "Please select some friends first" even when he's clearly selected (will show up if I hit the "selected" tab, etc). Facebook bug, or bug in my code? --24407958 12:05, 9 September 2007 (PDT)

  • Never mind, I found the problem. The test account had my app blocked for some ungodly reason. --24407958 12:55, 9 September 2007 (PDT)


[edit] Desired Functionality

  • A way to pass in a list of ids to preselect people
  • A way for the app to track which invites were sent
  • A way to send 'reminders'. My apps let you send an additional invitation after one week.
  • A way to visually differentiate between the following three states: [a] not an app user, never invited; [b] not an app user, but has been invited; [c] already an app user.

I second the need for passing in a list of IDs. Since the user has to confirm to whom they are sending the invites anyway, why not let them pre-select??

-->I believe that the implementation of an attribute like 'selected_ids' is not a big deal but it will be very very helpful.

[edit] Aesthetics

Based on the example, list all aesthetic nit-picks, quibbles, and comments below.

  • Photos should be optional. They are too small to be used to pick people out of a crowd. Without photos you could fit more people on the page.
  • Paging should be optional. If the app developer wants to display 100 friends in a scrollable div they should have that option.
  • The number of characters permitted for the name is too short. Works fine for US and Canada but longer international names would get truncated (as do hyphonated surnames).
  • Sorting: should allow the app developer to specify sorting by first name, last name, network name, gender, or potentially other properties.
  • The truncating of the network name is not helpful. It's almost better not to show it at all.
  • If using photos, the dimensions of the grid should be able to be modified by the app developer. 5x4 is a fine default but more or less col/rows should be allowed.
  • The pager should be inside the "View All" box: if you have 200 friends, you will have 10 pages in "View All". Let's say you have selected 35, which would mean 2 pages within the "Selected" tab. Since the pager changes when you change tabs, it belongs WITHIN the tab container IMHO.
  • Drop the "up to <max> of" when the number of friends to select among are less than the maximum.

There appears to be an error with the "Send Request" button. In Firefox 2 the envelope image sits on top of the button's text, rather than next to it. It displays correctly in IE7

[edit] Skip This Step

Clearly you must see that there is a need to get rid of the 'Skip This Step' button. I understand the reasoning behind it. To many apps requiring people to send invites before they could use the actual application. I understand that. But what about all the apps that don't do that, and just have an invite button on the menu and it's a separate page altogether that the user has to navigate to themselves? The 'Skip This Step' button won't make sense on that page. It's really bad UI. Please please please, figure out a way to save the rest of us! Thanks.

Suggestion: The problem here is that the invite form can be invoked in two contexts: as an initialization step to using the app, and as a user-initiated action. The solution is to label the button so that it makes sense in both contexts. I suggest renaming it from "Skip This Step" to "Don't Send." Then the buttons will be "Send App Invitation" and "Don't Send." Works well for all contexts.

Partial Solution: Actually, you can hide these buttons using this style:

<style type="text/css">
/* Removing the Skip Buttons */
.inputaux, 
.skip_top{
 display: none;
 visibility: collapse;
}
</style>

[edit] More control over the invitee list

I have just successfully examined the new system (on perl!).

The main problem I have is that my application's invite list isn't a random or alphabetic sample of the user's friends like most apps, the list of recommended invitees is selected according to application specific logic/invitee attributes - which I want the invitor to see so they can make an informed decision.

E.g.

The following friends have the most to gain from using this app
Name          Score
FriendA       30      
FriendB       28
FriendC       25

This would involve being able to

  • Control the membership and sort order of the list
  • Add some personalised content for each entry

I also need (already mentioned by others in this topic) to be able to

  • Personalise the content of the invitation that the invitee receives

[edit] Allowed and possible to use standard HTML form elementes within fb:request-form?

As I understand it the sendrequest api call is being decommissioned in favour of the fb:request-form. And there are four special fbml form controls designed for this.

However I believe I can still place standard HTML controls within an fb:request-form. So is it allowed and possible for developers to engineer their own invitation pages using standard HTML form controls within a fb:request-form?

  • Yes, definitely! The only catch is that people can only be invited through Facebook-controlled widgets such as fb:friend-selector, fb:multi-friend-selector and fb:multi-friend-input, and the button used to submit the form must be an fb:request-form-submit. But you're welcome and even encouraged to include your own set of controls in the form in addition to these - they will get submitted when the user sends the confirmation.

[edit] Use case for (single-recipient) requests between app users?

I have a use case where User A needs to send a request to User B, both of whom already have the application installed. In context, this is basically from a 'community library' app where people can borrow books from each other:

- Precondition: user Alice is viewing screen "Books of user Bob", and sees a book she wants to borrow
- Action: Alice clicks on "Ask Bob if I can borrow this book"
- Result: a request is sent to Bob, with text "Alice would like to borrow <book>", and buttons "Yes, sure" and "No, sorry".

In this context, using the new request mechanism, I'd have two options:

(a) redirect the user to a request page (with the username pre-filled if possible)
 - this is unpleasant because Alice already knows the content of the request and the person he wants to send it to
 - it increases the number of clicks required to do something, therefore decreases the usability of the app
(b) send a notification instead of a request, containing links for "Yes" and "No"
 - Using GET, and links would be clickable multiple times
 - The user can easily forget about it, since it requires no action to be cleared from the side-bar on the homepage
 - The notification request buttons are POSTed and can be clicked only once, meaning I don't have to worry about idempotence so much

I understand the above concerns about spam, but in this case, it's for user-to-user communication when both of them already have the app installed. I can work around it with (b) if necessary, but it's not the best solution. My question: could you leave the current notifications.sendRequest effective for communication between users who already have the calling app installed? This new API seems far more oriented towards invites, but there are many other uses for the original notifications.sendRequest API. --604295671 12:57, 12 September 2007 (PDT)

  • Thanks, this is a great writeup...I definitely see where you're coming from. I think your proposal to keep the API function for communication between app users is a reasonable one, will definitely consider it.

I'm in a similar position to the poster above. Users of the app can challenge others to a game, and those "others" may either be their friends (who may or may not have the app installed), or non-friends that are using the app (e.g. players on the leaderboard.) It's important to the app users that they can challenge non-friends to a game, and of course they want to be able to invite their friends to join them. With the notifications.sendRequest API I can handle this, but using the new FBML system there's no way to implement it.

I realise unwanted notifications are definitely an issue, but this kind of functionality seems to me to be critical if you want complex applications hosted on the FB platform. --731206808 05:45, 18 September 2007 (PDT)

Another point to make about these legitimate uses of real requests and not just this new application-invite oriented API is is that numeric limits don't really make sense. If you are asking friends to borrow a book, it would be somewhat lame if you could only send some small number (10, 15, whatever) of such per day. "I'm sorry, you can't borrow that book today, you've already asked too many people to borrow books." The user, if they are anything like me, is likely to use the app every now and then in a large session, not every day for one thing.

Here's a more concrete example of an existing app that would be crippled with these restrictions: Photos. When I start finding people and tagging them in albums, I tend to sit around for a half an hour and do it seriously. I might go through the last few weeks of pictures from my friends, tagging people who are in the background. This generates a _large_ number of requests (I have a bunch of friends that use Photos), all of which are legitimate.

You might argue that someone might not want me to generate that many requests, but that's a problem between them and me, not a problem with the application. We are both users of this application, we should expect that kind of traffic. If we don't, then we should unfriend the spammer. Remember that applications _can't_ spam people with the "accept this request" paradigm. _People_ spam people, by _knowingly_ choosing to allow large numbers of invitations.

My application lets you manage things your friends have said somewhat similar to Photos manages pictures of them. You can tag people and things in quotes, and I'd _like_ users to be able to tag each other's quotes. This is likely to generate even _more_ tag requests per capita than Photos, because you aren't just viewing your friend's quotes, you are viewing everyone's (most people contribute their quotes to a massive, shared database). Still, however, this is expected use case, would be difficult to be abuse, and wouldn't really generate many incoming requests per person. Jay Freeman (saurik) 16:54, 19 September 2007 (PDT)

[edit] URL with parameters

Trying to validate a form with a <fb:multi-friend-input> and other options like radio buttons, inside a <fb:request-form> with a <fb:request-form-submit> button. I can't validate before send request, and I can't customize url redirected when receiver accepts request. In particular I need customize this url, with params coming from form.

Solutions I found to avoid this problem imply bad problems in application usability.

sendRequest function gave me more flexibility.

  • I don't quite understand. You should be able to set the form's action URL to anything, just as you would normally. The <fb:request-form> does not prevent you from using any other types of form elements like radio buttons or hidden input fields. Am I misunderstanding?


Example:

<fb:request-form action="verifyForm.php" method="POST" invite="false" type="whatever" content="<? echo htmlentities($fbml_request); ?>">

   <fb:multi-friend-input/>
   
    <input type="radio" name="param1" value="item1"/> item1
    <input type="radio" name="param1" value="item2"/> item2
   <fb:request-form-submit/>

</fb>

Are there caveats about which friend selectors you can use additional form inputs with?

Trying to add hidden form fields to a fb:request-form with a fb:multi-friend-selector in it caused sendRequest() to be called without a reference to the request_form. For me at least.


I don't want to send a request if no friend chosen or param1 is empty. When I submit form, request confirmation appears. If no friend choosen, automtic error message appears. Good! but how can I check param1 value? I want to do it in form's action URL VerifyForm.php. If I accept request then I am redirected to verifyForm.php. The problem is that request is already sent if I have chosen a friend. I would like to process form input in verifyForm.php before send request. That is a limitation.

[edit] Send Request to Particular Friend

Currently (with the API), it is possible to make a button which initiates a request to a particular user. My app makes use of this, placing such a button next to images of each the current user's friends. It seems like there is no way to do this with the fb:request-form, and that when the API becomes deprecated, this functionality will no longer be possible. It would be nice to be able to use the fb:request-form and fb:request-form-submit tags, but specify the recipient's uid in a prefilled field. Can this be added? -David


In my canvas app, I work around this by dynamically loading the request form from a cgi url that fills in the fb:request-form-submit tag. But I'm not sure if this will work for my iframe version, I'm wrestling with this issue now.

<fb:request-form-submit id="le_friend_uid" uid=[|FRIEND_UID|] label="Send to %N" /> </fb:request-form> --Golda

[edit] fb:request-form sequence flow

As a new developer on FB, it was not very obvious how the sequence of page requests would flow, for request-form. Could you add something like this to the article page:

fb:request-form is a multi stage process. When this form submits, it causes a) a popup for the submitter to confirm the appearance of a FB Request msg (which will appear on the target users home page), and b) a callout to the application server occurs, providing the list of user ids who receive the FB Request-on-home-page, in the context of the user submitting this form, and c) eventually a target user notices the Request and clicks confirm (or ignore). If confirm, then the application gets a callout in the context of this requestee.

This means request-form has to be given two target urls, for b) and c). The c) case is the reason for the encoding of fb:req-choice, using htmlentities to fit this c) url into the content tag of request-form. The c) URL has to be of the form: http://apps.facebook.com/projectxx/your-file.php The b) url is in the action tag of request-form.

If I had advice, I would say FBML should accept the req-choice tag as simply an entry following the request-form tag. And FBML processing would compress as needed. Not that different from requiring the button request-form-submit.

The b) callout is specified in request-form action tag. The b) callout to the application server provides user ids encoded differently depending upon use of fb:multi-friend-input or fb:friend-selector, or fb:multi-friend-selector. It is convenient to use the same target url for b) and c), but then discriminate them by adding different GET variables to each URL.

The b) callout target URL needs to finish with a fb:redirect. For debugging, leave out the redirect and display the $_REQUEST array to see what FB is sending.

The c) callout is harder to debug. FB ignores the return from this page, since it is just performing the Request confirm on a user home page. If you set your php pages to log errors to a file on your application server, such as adding to dbappinclude.php:

 error_reporting(E_ALL);
 ini_set("error_log", "../errors/error-log.txt"); 
 ini_set("log_errors", "1"); //be sure errors will go to above log file.
 $GLOBALS['facebook_config']['debug'] = false;

then you can add to c) callout target url file, following the include of dbappinclude.php, something like: trigger_error("Called with: " . print_r($_REQUEST, TRUE), E_USER_NOTICE); for a nice message in error-log.txt.

[edit] sendRequest vs. MultiFriendSelector for iFrame apps

Just spent the morning implementing and testing MultiFriendSelector in a .NET iFrame app. I posted some code here for anyone interested: http://www.codeplex.com/FacebookToolkit/Thread/View.aspx?ThreadId=15597

MultiFriendSelector is not at all a suitable replacement for sendRequest. The reasons why have already been stated in this wiki: you can't pass in a list of users to select and you can't get a list of users back out who were actually invited. I know the whole idea of MultiFriendSelector was to give the user more control over the invite process but there has got to be a better way. One thing I saw was an improved confirmation dialog that lets the user see exactly who is being invited and remove people as they see fit; this is great, why not put that into the sendRequest flow?

[edit] Lists and MultiFriendSelector

One thing to add to my previous post: one big problem with the MFS is that it looks like a list/group selection control but isn't. For applications, like mine, that rely on creating personal groups/lists on behalf of users and then allowing them to interact with those groups/lists, the MFS ends up looking redundant to the UI that we have already built. I have read elseswhere that FB plans to add some sort of personal group/list functionality to the Platform. Some combination of lists/groups combined with a tweaked MFS would do the trick for my app at least.

I hope the the solution to this problem is well thought out for iFrame apps as well as FBML. It appears that the changes to sendRequest were instituted with FBML in mind then retrofitted to iFrame. This is probably just my perspective and I am sure that there are many more FBML apps to accomodate than iFrame. But if I may digress from the topic at hand for a moment and climb on my soapbox:

<fb:soapbox> The first wave of FB apps were almost exclusively FBML and many of these rode the initial wave of excitement plus a few generous features (which have since been removed) of the FBML controls to unbelievable user adoption. This is behind us now and I believe the next wave of apps are going to feature a lot more iFrame and a stronger focus on solving business problems than the first wave. Not to disparage, mind you, I think SuperPoke is an outstanding business tool. ;-) My point is that removing sendRequest without giving iFrame app developers a real solution to the problem we are trying to solve -- fair, sustainable, natural growth of our applications -- is slamming the door just when we are ready to walk through it. </fb:soapbox>

[edit] Customizing the friend selector

I have several apps that "analyze" names in some fashion (etymology, displaying the name in foreign writing systems, numerology and so on). In these apps users are more likely to invite their friends if they are able to see what the analysis results would look like already in the invite form, as seen below.

customizing_invite_form.gif

Could such customization still be possible with the new system? I feel that simply using the default invite widget would significantly hurt the apps' appeal.

[edit] Flash applications sending single requests / invitations from Flash

Our app lets you pick a friend in a highly interactive Flash game. It then triggers an invitation via notification.sendRequest today if the user does not already have the application (otherwise it sends a notification, which is fine).

Without this, we would have to (somehow) leave the Flash game, go to a FBML page out of context, and then jump back into the Flash game.

Today, the user clicks on a friend in context, and immediately goes back to game play without any page refreshes.

Is there another solution to this use case? It seems like fb:request-form would make our user experience much more sub-optimal.

We're not doing anything tricky here, in our use case, we're only selecting a single friend -- multiple invites can easily happen outside with a Share tab and use fb:request-form with no problem. But in this particular use-case, the context the user is selecting a friend in is very important to maintain context and an optimal user flow.

Any ideas or solutions would be great. We've considered a FBJS bridge, but Flash to JS bridges are already fragile as it is.

Thanks, Charles from PixVerse

[edit] Can we remove Skip This Step?

I'm not having this as part of initial app-adding, and so this is not needed. I'm passing a variable in my request form action so that I can display a friendly "invites sent" message but not only do I not need to show Skip, but when someone clicks Skip, the "invites sent" message is displayed... can we at least have a different URL for that? --Angela 09:25, 14 October 2007 (PDT)

[edit] PHP Example

The PHP example does not work (atleast in PHP 4) because the array of uids is buried three deep in the $rs. Adding the following line after $arFriends = ""; (line 8) fixes the problem:

 $rs= $rs["fql_query_response"]["user"];

[edit] fb_sig_* fields missing

Unlike any normal form, a fb:request-form doesn't include the fb_sig, fb_sig_user, etc... fields. This makes it a bit difficult to verify who is submitting the form. Can these be added, please?

  • YES I second this! This really should be signed somehow, otherwise it's totally untrusted data coming from Facebook. Adding it to fb_sig would break too many apps, but what if there is just an additional param "ids_sig" that signs the ids against your app's secret key? -- 2008-02-29

[edit] "ids" isn't part of the POST variables

Instead, there is a variable called "ids[]" being posted. Given that lots of people are using this already, this probably can't be fixed, but can documentation mention the actual variable name then?

  • ids[] just mean it adds one "ids" parameter for each selected friend. in php, you can get those in the form of an array... foreach ($ids as $id) { // do some stuff }

ThaNerd 17:56, 21 March 2009 (PDT)

[edit] Bug? POST sometimes is empty

Sometimes when using the fb:request-form and just an fb:friend-selector it sends a request, but the $_POST is empty when it hits my PHP. Here's my request, it's pretty simple:

 <fb:request-form method="post"
 	action="http://strd6.com/apps/mcgriff/postmessage.php"
 	content="<fb:if-user-has-added-app>
 		<a href='<?=$appcallbackurl?>'> View your McGriff-o-Gram!</a>
 		<fb:else><a href='<?=$facebook->get_add_url()?>'> View your McGriff-o-Gram!</a></fb:else>
 	</fb:if-user-has-added-app>"
 	type="Barkblast">
 	<LABEL for="message">Message: </LABEL>
<TEXTAREA name="message" rows="4" cols="43" ></TEXTAREA>

Send the message to: <fb:friend-selector include_me="true" />

<fb:request-form-submit /> </fb:request-form>

The strange thing is that it works most of the time (80%) but it happens frequently enough to be a problem. Also, the request is sent even though the POST data never makes it. Any one else have this problem or any suggestions?

[edit] re: POST sometimes empty

Hi, I checked with the bugs team and we think you are seeing another manifestation of bug 459 (http://bugs.developers.facebook.com/show_bug.cgi?id=459). You can CC yourself on it or maybe try the workaround and see if that helps.

[edit] Lowercase Type attribute

Apparantly the 'type' attribute is always converted to lower case. eg an invite sent with 'type="Test App"' will arrive as "You have a test app invitation". This should be documented or changed.

It also gets truncated to only 20 characters, which is a major inconvenience.

[edit] Example FBML Invite Page Broken (Fixed Attached)

First sample is wrong, it should be:

Example FBML Invite Page

<fb:fbml> <fb:request-form action="index.php" method="POST" invite="true" type="YOUR APP NAME" content="Your text goes here. <?php echo htmlentities("<fb:req-choice url=\"YOUR CANVAS URL\" label=\"Add My Application\"/>") ?> "> <fb:multi-friend-selector showborder="false" actiontext="Invite your friends to use YOUR APP NAME."> </fb:request-form> </fb:fbml>

[edit] Prevent page refresh

I'd like to use the multi-friend selector to send invitations for my application, but I dont want to force a page refresh. setting the action to '#' still seems to cause a page refresh. for pages built mostly on Ajax this will cause the user to lose whatever the current state. with the original method I could create an Ajax call to a PHP script that would send the request and the user would not have to do a page refresh. is there any way to preserve this functionality?

the only workaround I've found is to send regular notifications with a link to the app, but without the a proper button since that method only allows for text and text links.

[edit] Custom form parameters

I am trying to use "fb-protected" feature to be able to add bunch of form fields to the request form. Sometimes it goes through, but most of the times I don't get the parameters in the request. I have tried both GET and POST. I have also tried using fb_protected instead of fb-protected as used in the example.

Not sure, if this feature has been removed. I'll appreciate any help.

[edit] What does fb_protected actually DO?

I find myself befuddled by fb_protected.

What does it actually DO?

Where is it documented?

In this page, at least, it's just some "magic constant" you have to have for a form element to "work"

I know it blocks JS from altering the form element, but why?

So another rogue app can't hack it?

If I'm validating server-side and don't care, can I leave it out and still get the INPUT?

I'm even more confused today than I was then...

The PHP example shows fb_protected="true", the docs say fb-protected="true"

And neither one of them seems to do anything at all -- The FORM built up doesn't have any of my INPUTs at all.

I'm giving up on this silly thing, and just stuffing my data into $_SESSION and moving on with life.

I'm majorly having problems with this too. The "Skip" button often works, but if the user sends any invites, none of my input variables are sent to my file pointed by my action. GET or POST don't seem to matter. Instead I get a bunch of fb_sig and typeahead crap. To make it worse, the ?fb_force_mode=fbml tag isn't working, either as a hidden variable or as a GET variable, breaking everything.

Example 1: method="GET" action=addtoprofile.php <input id="fb_force_mode" type="hidden" fb_protected="true" value="fbml" name="fb_force_mode"/> Example 2: method="GET" action=addtoprofile.php?fb_force_mode=fbml In BOTH cases after an invite, it goes to an iframe with no fb_force_mode. 527235316 05:29, 27 October 2009 (PDT)

[edit] php example about htmlentities

If there is Chinese in your $app_name , you should use htmlentities this way:

<fb:request-form action="invite.php" method="POST" invite="true" type="<?PHP print $app_name; ?>" content="<?PHP print htmlentities($content, ENT_COMPAT , "utf-8");?>"

as utf-8 is the default page code.

[edit] Disable the redirect?

I've been mucking with this for a week, and can't get there. I'd like to stop the automatic redirect of the form when the user closes it. I've been able to do this for the 'cancel' buttons, but can't get it to stop on the 'submit button. I added event listeners to the div that holds the buttons, and close the friend invite. I also set the action url as "#", which works with cancel. All of the applications interaction is within a swf, so I don't want to reload the entire page after inviting friends. The other workaround I'm toying with is placing the invite in an iframe within a div, then setting the action url to page that closes the div, if possible. Any thoughts would be great.

Here's an example of what I've done:

// Render the friend invite in a div

\
\<fb:request-form method="POST" 
 action="#"
 type="Play \<%=strGameTitle%\>" 
 invite="false"
 content='Please allow <%=strGameTitle%> access, so we can play together!
  <fb:req-choice url="http://www.facebook.com/add.php?api_key=<%=strFacebookApiKey%>" label="Confirm"/>'>
  <fb:req-choice url="http://www.facebook.com/add.php?api_key=<%=strFacebookApiKey%>" label="Send Request"/>
  <fb:multi-friend-selector showborder="false" actiontext="Select friends that would enjoy playing <%=strGameTitle%>." bypass="cancel" exclude_ids="<%=friendsWithoutApp%>"/\>
</fb:request-form>
\
"

// The swf lives in this div

<script> // The top right hand cancel button document.getElementById('friend_invite').getFirstChild().getFirstChild( ).getFirstChild( ).getFirstChild( ).addEventListener( 'click', HideFriendInvite );

// The button div for the bottom submit and cancel buttons document.getElementById('friend_invite').getFirstChild().getFirstChild( ).getFirstChild( ).getLastChild( ).addEventListener( 'click', HideFriendInvite );

// Show the friend invite form function ShowFriendInvite( ) {

document.getElementById('friend_invite').setStyle( 'visibility', 'visible' );
document.getElementById('friend_invite').setStyle( 'display', 'inline' );
document.getElementById('friend_invite').setStyle( 'left', '0px'  );
document.getElementById('friend_invite').setStyle( 'top', ( document.getElementById('swfDiv').getAbsoluteTop( ) - 50 ) + "px" );
console.log( "ShowFriendInvite" );

}

//Hide the friend invite function HideFriendInvite( ) {

document.getElementById('friend_invite').setStyle( 'visibility', 'hidden' );
document.getElementById('friend_invite').setStyle( 'display', 'none' );
console.log( "HideFriendInvite" );

} </script>


[edit] IE8 Final (iframe)

We have an iframe app and added the request-from inside an iframe to that app. In other browsers (and pre-release IE8) everything works well, without page refreshes! But when the final version of IE8 was released, the iframe (request-form) is blocked from rendering due to XSS.

We've tried to add the X-XSS-Protection: 0 http header. It didn't work.

Any thoughts?

[edit] i18n

Note that for applications using the FB i18n services, in order to translate the content attribute correctly, include an empty content attribute and specify the value in an fb:fbml-attribute tag as normal. Leaving out the content attribute will cause this error:

fb:request-form: Required attribute "content" not found in node fb:request-form

To avoid it, do something like this:

<fb:request-form invite="true" type="blah" action="blah" content=""> <fb:fbml-attribute name="content"> <fb:intl>Content string that will be translated</fb:intl> </fb:fbml-attribute>