These days it goes without saying that social networking is a trend, with Facebook as one of the leaders in connecting people to the rest of the world. Facebook allows you to connect with people on so many different levels, giving you a portal to befriend people, let them know your likes and dislikes, show them the causes you believe in, show them what you are a fan of, and so much more. Facebook is also extensible; developers can create customized applications that load within the Facebook infrastructure, or outside of it. These applications are not explicitly created by Facebook developers, but by any developer who signs up.

There are two types of Facebook applications: The first type is within Facebook framework itself, on the same site. This application uses either the Facebook Markup Language (FBML) or JavaScript (or even both) to create an add-on of your own specific design that will run and operate within the www.facebook.com site.

The second type of application is the one that resides outside of the Facebook realm altogether. This is referred to as a Facebook Connect site. This site requires the use of a JavaScript API or XFBML (or a combination of the two). This type of site uses a REST API to connect to Facebook, extract information (such as logging in users and querying their profile), and much more.

You may wonder why integrate with Facebook? There can be several reasons. First, the world has changed with the creation of social networking sites, in the way we think and connect with other people. Facebook is a popular means of doing that and is another way to connect to an additional audience: by cross-connecting between Facebook and your custom website. Another reason you may want to use Facebook Connect is as an authentication store; a good portion of the world is on Facebook, and so you can use this site as a way to verify someone's identity or use them as an account. Whatever your reasons, it's helpful to understand what you need to be able to do to communicate with Facebook to get your ASP.NET website running.

What's the Difference?

You may be wondering about the differences between the Facebook API and the Connect API. The two APIs are very similar, actually. The difference, however, comes in the way that the applications are used. Facebook Connect is meant for applications being developed outside of the Facebook.com domain. These applications are commercial or personal applications using the Facebook API to embed social networking features into this application, the subject we'll talk about in this article. Facebook, however, uses a separate but similar API for creating applications within the site. I'll explain the differences between these APIs shortly. For now, know that development can take place in the realm of Facebook.com or outside for another personal site.

Understanding the Facebook Connect API

More and more sites are providing a REST-based API that creates the UI. The data gets returned as a JavaScript object, and some UI appears with this accompanying data. The primary means to creating the interface or communicating to a REST server is JavaScript. JavaScript has the ability to render HTML in the browser, so as to generate a UI on the fly. With Facebook, JavaScript is one of the solutions to rendering a UI. Facebook's script contains the necessary components to extract information from Facebook's servers about your application, its users, and their information. This is an important piece to the puzzle, but not the only means to access information. Some of the core components are:

  • FB: the namespace for all Facebook core components.
  • FB.Connect: represents the connect object or child objects that work with the connect API. We will be using some methods in this API.
  • FB.Facebook: the core object for Facebook applications, which contains some other useful features for Connect applications.
  • ApiClient: This is a core object for working with Facebook. This object provides method calls that communicate with the Facebook REST server, to extract information such as retrieving a user's list of friends, the groups they belong to, their events, and much more.

Every user who logs into Facebook has an ID. This ID is a numerical value (outside of username/password combination) that represents the user logged into the site. This ID is used to retrieve information about the user, and is very important to have. We'll illustrate how to get this later.

The next option is the FBML/XFBML languages. FBML stands for Facebook Markup Language and is a Facebook specific syntax for creating applications. FBML consists of a series of tags that are within the http://www.facebook.com/2008/fbml namespace. For Facebook Connect applications, the XFBML syntax is used, which consists of a smaller tagset than what is available for Facebook applications embedded into facebook.com. One of the more common examples of XFBML tags is the <fb:login-button /> element. This element renders a connect button as well as all the other required scripts to properly handle the login process. We'll explore some of the available tags later in the article.

Facebook Tools

All Facebook developers must first go to the developers' websiteat http://www.facebook.com/developers. Becoming a fan of the application gives you the ability to create your own application and have access to other useful resources. On the right side of the page is a button to create a new application. Create the application by clicking it. The wizard brings you to a page where you can enter the name of the application. Give the application a name and click the Save Changes button, as Figure 1 shows.

Figure 1: Creating the application

After the application is created, go to the application's main page. You'll see an Edit Application Name profile link. Click this link, followed by clicking the edit button for Application Settings. In the connect configuration settings, the main setting to establish is the connect callback URL. This URL is the main URL to your site. I've established a free domain for my personal testing (e.g., http://www.brinkster.net); make sure you point to the root folder structure and not to a specific file within your website. This URL is meant to point to the site that uses the Facebook application, so it spans across multiple files.

You only need to specify the connect URL at a minimum; however, feel free to provide other settings as well. Take a look at some of the Connect settings in Figure 2.

Figure 2: Facebook Connect settings

When you access this developers' application, there are some handy tools that Facebook has made available. The first is a form that allows you to enter FBML/XFBML markup, which Facebook translates into its HTML/JavaScript equivalents. This translation isn't a client to server rendering, but illustrates what happens under the scenes with each Facebook tag. Facebook also has a Wiki with useful information, along with a forum for you to ask questions to other developers.

Logging In

Facebook provides a couple of ways to log into your Facebook connect site. The process of connecting to a Facebook Connect site and extracting Facebook services begins when you connect to it. Let's begin by looking at the basic connect login page in Figure 3 below.

Figure 3: Basic Connect page
<fb:login-button onlogin="post_login();"></fb:login-button>
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/
FeatureLoader.js.php/en_US" type="text/javascript"></script>
<script type="text/javascript">
 var api_key = '1234567890abcdefghijklmnopq';
 var channel_path = 'xd_receiver.htm';
 FB_RequireFeatures(["XFBML"], function() {
   Create an ApiClient object, passing app's API key and
   a site relative URL to xd_receiver.htm
  FB.Facebook.init(api_key, channel_path);
 });
 function post_login() {
  window.location = 'profile.aspx';
 }
</script>

At the bare minimum, this is what Facebook Connect requires to log in to the page. This is a simple HTML page that embeds a static script from static.ak.connect.facebook.com in it, which contains all the necessary objects to setup the application. As I mentioned before, <fb:login-button> renders a button the user can use to login to the website. When the button is clicked, a connect screen appears asking you to log into this application and give it permission to use your information. An alternative to the login button would be to make a call to FB.Connect.requireSession, which performs a similar feature. Whether the button is used or the direct call, both options provide a valuable way to connect to Facebook.

In order for Facebook integration to work, some initialization information is needed, through the use of an API key and a channel path. The API key is the key that gets generated when you create a new application on the Facebook developers' site. The xd_receiver.htm file is a special file that Facebook requires for cross-domain communication. I am omitting it from this article due to time and space constraints; however, you may download it from the sample files I've provided with this article (click the Download link at the top of the article) or view it in the Wiki. It's pretty straightforward, and basically you copy the markup directly from the Wiki.

FB_RequireFeatures is the first Facebook method we'll examine here; it's a useful method that delays execution of scripts until those features are available to the developer (which may be delayed for multiple reasons). The first statement specifies that the initialization should be delayed until able to process XFBML script, accepting a callback that will run when script can run successfully.

FB.Facebook is a core object for using the Facebook API, but for Connect applications you will be interchanging FB.Facebook andFB.Connect. FB.Facebook has an init method that initializes the application, specifying the ID of the application and the path to the receiver file (in this case, xd_receiver.htm is in the root along with the ASP.NET page).

Upon clicking the login button and logging into the server, the onlogin code fires, triggering the post_login method. Any login code can run, and in this case, the user can now be redirected to the profile page, where most of the work occurs.

XFBML Tags

The profile page features a few new XFBML tags to introduce. Figure 4 shows the tags.

Figure 4: XFBML tags
<table cellspacing="0" border="0">
 <thead>
 </thead>
 <tbody>
  <tr>
   <td>
    <fb:profile-pic uid="loggedinuser" facebook-logo="true" size="normal"></fb:profile-pic>
    <br />
    <fb:name uid="loggedinuser" useyou="false"></fb:name>
    <br />
    <fb:share-button href="http://bmains/brinkster.net/AspNetPro/"></fb:share-button>
    <br />
   </td>
   <td>    
   </td>
   <td>
    <fb:prompt-permission perms="read_stream,publish_stream">Would you like our application to read from and post to your News Feed?</fb:prompt-permission>
    <fb:live-stream width="400" height="600"></fb:live-stream>
   </td>
  </tr>
 </tbody>
</table>

Each of these new tags has the following functions:

  • Fb:profile-pic: This tag displays the user's profile, in either a small, normal, or large image format.
  • Fb:name: displays the name of a user, including your name potentially. If useyou is set to true, if the user is you, you see the text "You" instead of your name (which would appear when the property is set to false).
  • Fb:share_button: renders a share button that allows users to share your application to other users.
  • Fb:prompt-permission: displays a prompt to the user allowing the application to perform some action. Facebook ensures that certain features require the application to prompt the user to allow that permission.
  • Fb:live-stream: displays the information on your wall to the user, as you see in Facebook.

These are only a few of the possible XFBML tags and are the only ones used in this example. The rest of the options available can be found in the Facebook developers' Wiki.

JavaScript API

Facebook has an extensive JavaScript API, too. Our first feature of the Facebook API will be to extract the current user's information and display it in the page. The core object to perform this feat is the ApiClient object, the object through which all of our REST-based, user-related data is retrieved. Figure 5 shows an example of our first use of this object.

Figure 5: Getting user information
FB_RequireFeatures(["XFBML"], function() {
        // Create an ApiClient object, passing app's API key and
        // a site relative URL to xd_receiver.htm
        FB.Facebook.init(api_key, channel_path);

        FB.Facebook.get_sessionState().waitUntilReady(function() {
                var api = FB.Facebook.apiClient;
                var userID = api.get_session().uid.toString();

                api.users_getInfo(userID, 'last_name, first_name, about_me, birthday, relationship_status, hometown_location', function(user, ex) {
                        if (ex != null) {
                                alert("An error occurred when loading the user:" + ex);
                                return;
                        }

                        loadUserInfo(user);
                });
        });
});

All the methods that retrieve data from the REST server use the callback approach, which takes the object returned from the method and a potential exception being thrown. Each REST-based method takes a different set of parameters. The getInfo method takes a reference to the user's ID (a long value) and a comma-separated list of the fields to download from the server. Most systems simply return the entire dataset for the user, but the users_getInfo method requires you to specify the fields to download, and only these fields will be accessible.

Let's take a look at some other REST-based methods, starting with the one in Figure 6.

Figure 6: Loading other resources
api.groups_get(userID, null, function(groups, ex) {
        if (ex != null) {
                alert("An error occurred when loading the groups:" + ex);
                return;
        }

        loadGroups(groups);
});

api.photos_getAlbums(userID, null, function(albums, ex) {
        if (ex != null) {
                alert("An error occurred when loading the albums:" + ex);
                return;
        }

        loadAlbums(albums, api);
});

The groups_get and photos_getAlbums  methods get the groups and albums that belong to the user. Both methods use the user ID and take a second parameter that accepts an array of IDs to use to include in the list. The callback methods return an array of group/album objects with a variety of useful parameters.

Some useful properties of the album object are:

  • cover_pid: references the ID of the photo for the album cover, in case you want to view the full photo. In order to get a photo by its ID, use the photos_get method from the ApiClient object.
  • link: the link to the album on Facebook. Clicking it redirects to the Facebook.com site.
  • edit_link: the link to go directly into editing the album in Facebook. Clicking it redirects to the Facebook.com site.
  • name: the name of the album.
  • owner: the user ID of the owner.

Groups, however, have a different set of properties:

  • description: the description of the group, as entered when creating the group.
  • gid: the unique identifier of the group.
  • group_type and group_subtype: the type and subtype of group as entered by the creator.
  • name: the name of the group.
  • pic, pic_big, and pic_small: the URL to the picture of the group in various sizes.
  • recent_news: recent news as entered by the creator of the group.

Most of the REST APIs are very similar to this approach. There are quite a few APIs, and I can't touch upon them all in one single article. I do, however, want to get to one last item regarding to the types of data available to developers: friends. Naturally, every user who connects to this application is bound to have registered friends. Let's look at the code in Figure 7, which illustrates the use of methods that will let your app access friends.

Figure 7: Displaying friends
api.friends_get(new Array(), function(users, ex) {
        if (ex != null) {
                alert("An error occurred when loading the groups:" + ex);
                return;
        }

        loadUsers(users);
});
function loadUsers(users) {
        var container = document.getElementById("friendspanel");
        var api = FB.Facebook.apiClient;

        api.users_getInfo(users.slice(0, 12), 'last_name, first_name, pic_square', function(usersToDisplay, ex) {
                if (ex != null) {
                        alert("An error occurred when loading the user:" + ex);
                        return;
                }

                for (var u = 0, ulen = usersToDisplay.length; u < ulen; u++) {
                        var user = usersToDisplay[u];
                       
                        var div = document.createElement("DIV");

                        var image = document.createElement("IMG");
                        image.src = user.pic_square;
                        div.appendChild(image);

                        var span = document.createElement("SPAN");
                        span.innerHTML = user.first_name + " " + user.last_name;
                        div.appendChild(span);

                        container.appendChild(div);
                }
        });
}

The friends_get method does the work of retrieving a user's friends. The loadUsers method does the actual work of displaying the users to the viewer of the web page. While I omitted the creation of the page using JavaScript for groups and albums, the process is pretty simple, so I'll illustrate both processes in one last example here.

The friends_get method works similarly to the previous methods. It takes as its input an array of user IDs to limit a result by. Although normally null is passed in this place, documentation on the Facebook Wiki recommends passing in an empty array.

The response returns in the format of an array list of user IDs (longs) that are a person's friends. Although that doesn't seem overly helpful, the users_getInfo REST method does the actual work of retrieving our friends' information. If I didn't state it before, the list of information that you can retrieve about your friends is pretty long, but here we only want first name, last name, and a URL to their image.

Rather than using the FBML approach to creating the UI, the data streamed from JSON is created via the JavaScript DOM. The DOM has the ability to create and append elements to it. Via a simple approach I used the DOM to create the user's image and display their name below that image. Each of these image/name pairings is grouped in a DIV, a very simplistic way to render the UI. Notice that the loadUsers method loads only 12 friends from the user's profile, rather than loading the entire list, which could be hundreds or more.

Strategic Options

So what does this enable us to do? These APIs allow you to get in touch with the people who use your application at a whole new level; you can see what their interests are. You can see if they are even interested in your group, product, or are your fan (or whatever the relationship may be between your application and your user).

There are so many opportunities to connect with your users. A good way to figure out what level to take your application is to see what other businesses are doing and try to get some ideas of what you can do with your product, business, or even general interest.

With what you've seen today, you can see how you can match users to preferences (groups) by name matching. You could even store a collection of groups that relate to your product and identify who may be interested in that group. These are just a few ideas, but the possibilities are endless.

Requesting Extended Permissions

Certain features in Facebook require some extended permissions. These permissions must be granted before the API call will succeed. One example is setting the user's status, as Figure 8 shows.

Figure 8: Updating status with extended permissions
$("#userstatusbutton").click(function() {
        FB.Connect.showPermissionDialog('status_update', function(result, ex) {
                var box = document.getElementById("userstatusbox");
                var api = FB.Facebook.apiClient;

                api.users_setStatus(box.value, false, false, function(status, ex) {
                        if (ex != null) {
                                alert("An error occurred when setting the status:" + ex);
                                return;
                        }

                        if (status)
                                setStatus(box.value);
                });
        });
});

jQuery attaches to the button click event, sends a call to submit the user's status, and displays their status in a label below the textbox (via the setStatus method call). One important note: If you call this method directly, the request will fail. The reason it will fail is due to permissions. We first must wrap the code with a showPermissionDialog request. The "status_update" extended permission will show an alert box, asking the user if this permission is OK. Setting the status will only work if the user agrees.

Facebook and ASP.NET

So what are the requirements with ASP.NET?  Not surprisingly, Facebook works in ASP.NET, too, since the by-product is essentially HTML. Although ASP.NET requires only one form, MVC is not limited to this, so you could say implementing this into MVC would be even easier than ASP.NET. The key to this is that it's a client-side solution; this solution isn't using the Facebook Toolkit or any other server-side solution to solve the problem. In this way, it meets the rich client needs of the user.

Facebook can work in both the past and future versions of ASP.NET. The great feature about the future with .NET 4.0 is that new client-side options for displaying data will come to light and make it easy for developers to work with the JavaScript API. While 4.0 won't directly affect the Facebook API, it will make how you use it easier and more manageable.

So now you've seen how Facebook integrates with an ASP.NET site, which does most of the work on the client. We've mixed in a little jQuery to liven it up, too. But the core emphasis is on XFBML tags and the JavaScript API, getting the developer to know the building blocks in order to take the application to the next level. As more and more people create Facebook profiles, a new era of key demographics may be at stake for your product or company, making the Facebook APIs an important addition to your developer toolkit.