共用方式為


Sending Facebook invites from a Universal Windows app

In one of the previous posts published on this blog we’ve learned how to integrate Facebook in a Universal Windows app. Specifically, we’ve seen how to integrate the Facebook authentication, so that we are able to create a Universal Windows app where the user can login with his Facebook credentials, so that we can use the Graph APIs to interact with the social network and perform operations like retrieving the user’s profile or posting on his timeline.

For security reasons, there are some activities on Facebook (like sending invites for games or applications to a friend) that can’t be performed directly by calling some APIs, but they need to be managed with a web view that is offered by Facebook. The purpose of this approach is to avoid, for example, that an application could send automatically hundreds or thousands of invites without the explicit permission of the user. However, the developer has access to some tools to properly generate the web view and to receive the information about the outcome of the operation made by the user (like the list of friends that have been invited).

In this post we’re going to see how to integrate Facebook invites in a Universal Windows app, by reusing the knowledge we’ve acquired in the previous post about integrating the Facebook authentication mechanism.

Register the application on the Facebook developers’ portal

The first step, before writing some code, is to properly configure the Facebook application which we have created in the previous post and that it’s connected to the Windows application. It’s important to remember that every application (no matter if it’s a website, a mobile app or a desktop app) that needs to interact with the Facebook APIs needs to be properly registered in the developers’ portal provided by the social network. In this post we’re going to reuse the same application we’ve created in the previous post to support the authentication. In addition to the configuration we already did, we need to perform a few additional steps:. The trick to to integrate Facebook invites, in fact, is to treat the application like if it’s a web game, which has its own Facebook canvas (which is the area where Facebook renders the web application inside its pages). Every Facebook canvas is associated to a unique URL, which is invoked after that the procedure to send invites is completed: thanks to this URL, we’ll be able to determine the status of the operation and to retrieve the list of invited friends.

To configure the Facebook canvas we need to click, in the Settings section of our Facebook app, the Add platform button and add a new application, which type is Facebook Canvas. The only setting we need to setup is called Secure Canvas URL, which is the address that is invoked by Facebook when the operation is completed. We can use any custom URL; the only requirement is that it has to use the HTTPS protocol, like in the following sample.

Configuration of the Facebook Canvas

 

Now we are ready to write some code and to integrate invites in the Windows app.

Display the web view

To show the code that is needed to display the invites’ view we’re going to reuse the project we’ve created in the previous post. I’ll take for granted that you’re already familiar with the FacebookClient and WebAuthenticationBroker classes and that you’ve already used them to perform the authentication and to retrieve the access token, which is needed to perform any further interaction with the Graph APIs.

For our purposes we’re going to use again the FacebookClient class, which is included in the Facebook SDK that you can install in your project by using NuGet. It’s important to remember, at this point, that, in a Universal Windows app, the shared project is just a “placeholder” for all the files that are needed by the application and not a real class library. Consequently, you’ll have to add the Facebook SDK both to the Windows and Windows Phone projects.

The FacebookClient class offers a method called GetDialogUrl() which, given as parameter the kind of dialog we want to display, returns the URL we need to display inside a web view. Since we are in a Universal Windows app, we’re going to use the WebView control to achieve this goal.

The following sample shows how to use the GetDialogUrl() method:

 private void OnInviteFriendsClicked(object sender, RoutedEventArgs e)
{
    FacebookClient client = new FacebookClient(AccessToken);
    dynamic parameters = new ExpandoObject();
    parameters.app_id = ClientId;
    parameters.message = "Invite your friends";
    parameters.title = "Invite friends";
    parameters.redirect_uri = "https://wp.qmatteoq.com/";

    Uri dialogUrl = client.GetDialogUrl("apprequests", parameters);
    RequestView.Visibility = Visibility.Visible;
    RequestView.Navigate(dialogUrl);
}

The parameters to pass to the GetDialogUrl() method are managed with a dynamic object, which is defined with the following properties:

  • app_id is the identifier of the Facebook application, which you can retrieve from the Facebook developers’ portal and that we have already used, in the previous post, to perform the login. You can find it in the Settings page of the application; the field is called App ID.
  • message: it’s the message that explains to the user the purpose of the invites and it’s displayed in the web view.
  • title: it’s the title of the web view.
  • redirect_uri: it’s the Secure Canvas URL, which we have specified in the beginning of the post.

After we’ve properly configured the parameters, we can pass them to the GetDialogUrl() method, together with the kind of dialog we want do display. In this case, since we’re working with invites, we need to use the apprequests identifier. In return, we receive the URL of the view to display in a WebView control, which has been added to the page of our application, like in the following sample:

 <Grid>
    <WebView x:Name="RequestView" Visibility="Collapsed" Width="400" Height="800" NavigationCompleted="RequestView_OnNavigationCompleted"/>
    <StackPanel Margin="12, 20, 0, 0" x:Name="AppContent">
    <!-- the content of the page -->
    </StackPanel>
</Grid>

When we call the GetDialogUrl() method we also take care of displaying the WebView (which, by default, is hidden), by setting the Visibility property to Visible. Then, we call the Navigate() method of the WebView control, passing as parameter theURL returned by the GetDialogUrl() method. The application will display a view similar to the following one:

image

Process the invitations

In the web view the user will have the chance to select one of more his friends. After pressing the Send button, the operation will be completed and the invites will be sent. From the Facebook point of view, the operation is completed; however, as developers, we probably want to know more details about the outcome, like the list of friends that have been invited to use the application. We can achieve this goal by subscribing to the Navigation_Completed event of the WebView control, which is triggered when a web page is fully loaded.

After that the user has pressed the Send button, Facebook invokes the URL that we have defined as Secure Canvas URL in the app configuration. It’s the URL we need to intercept in the Navigation_Completed event to understand when the operation is completed. In this scenario, in fact, the URL will contain the list of all the friends that have been invited. Let’s take a look at the following sample code:

 private async void RequestView_OnNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
    if (args.Uri.DnsSafeHost == "wp.qmatteoq.com")
    {
        sender.Visibility = Visibility.Collapsed;
        AppContent.Visibility = Visibility.Visible;

        FacebookClient client = new FacebookClient(AccessToken);
        dynamic result = client.ParseDialogCallbackUrl(args.Uri);

        if (result.error_code == null)
        {
            var items = (IDictionary<string, object>) result;

            ObservableCollection<FacebookUser> invitedFriends = new ObservableCollection<FacebookUser>();

            foreach (KeyValuePair<string, object> value in items)
            {
                if (value.Key != "request")
                {
                    string query = string.Format("/{0}", value.Value);
                    dynamic user = await client.GetTaskAsync(query);
                    FacebookUser facebookUser = new FacebookUser();
                    facebookUser.FullName = user.name;
                    invitedFriends.Add(facebookUser);
                }
            }

            Friends.Visibility = Visibility.Visible;
            FriendsHeader.Visibility = Visibility.Visible;
            Friends.ItemsSource = invitedFriends;
        }
        else
        {
            MessageDialog dialog = new MessageDialog("The user has canceled the operation");
            await dialog.ShowAsync();
        }
    }
}

If the Uri of the page loaded by the WebView control is the same we have defined in the Facebook developers’ portal as Canvas Secure Url, it means that the operation is completed and we need to parse the result. The parsing procedure is simplified by a method offered by the FacebookClient class called ParseDialogCallbackUrl() , which requires as input parameter the full Uri of the page and returns a dynamic object (we use, again, the dynamic keyword to store the result). The first step is to check if the operation has completed successfully. In this case, the error_code property of the result will be empty, otherwise, it means that the operation has been cancelled by the user (the web view, in fact, offers also a Cancel button, which can be used to abort the operation). If it’s not the case, we can move on and retrieve the list of invited users. We are able, in fact, to manage the result as a Dictionary<string, object> collection, which contains:

  • As first value, an item identified by the request key, which contains the unique identifier of the request.
  • A series of numeric values: each of it is the unique Facebook identifier of the friends invited by the user.

In the sample code we process all the items of the collection with a foreach iterator; we discard the item identified by the request key (since we don’t need it for our purposes) and we use only the ones with the Facebook identifier. For all the friends that the user have invited, we issue a request to the Graph APIs to retrieve the friend’s profile. We use the GetTaskAsync() method of the FacebookClient class, passing as parameter the Graph API’s path (which is simply the symbol / followed by the identifier of the user, like /123456789).

In the end, it’s up to us to decide what we want to do with this information. In the previous sample, we create a new FacebookUser object (which is a custom class) for each friend and we store, in the FullName property, the name of the friend that we have retrieved using the Graph API. Here is a sample definition of the FacebookUser class:

 public class FacebookUser
{
    public string FullName { get; set; }
}

All these objects are included in a collection called invitedFriends, which type is ObservableCollection<FacebookUser>. This way, by using a ListView control, we can display to the user the list of the names of all the friends he has invited in the web view. The following code shows the simple template used for the ListView control:

 <ListView x:Name="Friends" Margin="0, 20, 0, 0" Visibility="Collapsed">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=FullName}" Style="{StaticResource BodyTextBlockStyle}" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Wrapping up

In this post we have seen how to integrate Facebook invites in our Universal Windows app. You can download the sample code we’ve seen in this post from the following repository on GitHub: https://github.com/qmatteoq/FacebookSample-Universal. It’s important to remember that, before using the sample, you’ll have to change the various Facebook parameters (like the App Id or the Canvas Secure URL) with the ones you have configured for your application in the Facebook developers’ portal.

Follow the Windows Store Developer Solutions team on Twitter @wsdevsol. Comments are welcome, both below and on twitter

Comments

  • Anonymous
    October 27, 2015
    Hey Bro, I do it follow this post. But my friend can't see these request, Whether my friend see these request when I run my app (Debug)