Cutting Edge

Essential Facebook Programming: Widgets and Timeline

Dino Esposito

 

Dino EspositoAfter covering some basic aspects of Facebook programming in previous columns, I’ll now discuss tools and techniques to view and retrieve content from a Facebook wall in order to share it through other means and catalog it for something else, such as business intelligence (BI) analysis.

Not all companies have the same level of interest in the world of social communities as does Facebook. One lesson I’ve learned, however, is that in all companies, periodically an internal department—usually marketing—ends up with a strong interest in getting closer to customers and, maybe more important, in having customers get closer to the company. A Facebook fan page is one of the tools to attract contacts, and the number of Likes and the level of activity on the page can measure the success of the initiative.

Where does programming fit in? To keep a Facebook page alive and kicking and to stimulate user activity that increases the number of “people talking about this,” you need to post interesting content—and frequently. Sometimes the company can afford a staff of people just researching and creating content for the Facebook page. Sometimes, instead, good content for the Facebook page comes straight from the regular flow of company business. In this case, it would be a bit problematic for employees doing their regular jobs to reserve extra time to report on a Facebook page what they’re doing. Imagine, for example, that news is posted to the Web site. The internal workflow might entail preparing the text, getting it approved, publishing it in the internal system and waiting for the content management system to make it live on the site. If the same news should be published to Facebook, too, most of the time the same person opens the Facebook page as an admin and just posts content manually. It often works this way today, but it’s not an approach that scales. This is just where Facebook programming fits in.

Beyond Posting

In recent installments of this column, I addressed the main topic of posting to a Facebook wall and the basics of building a Web site and a desktop application that can interact with the Facebook account of the user (you can see all my columns at bit.ly/hBNZA0). For an enterprise scenario where the target wall is the company’s fan page, the approach isn’t really different. All that changes is the account that receives posts.

So the first step toward Facebook programming is definitely finding a way to post content to specific walls in an automated way under the control of your software.

Over time, the content shared to the company’s fan page, which typically includes marketing communications, becomes a useful resource for the company. It becomes valuable information that the company might want to retrieve and further share or analyze. And this is another great fit for Facebook programming.

The Like Box Widget

A quick and simple way to add some Facebook content to your site is through the Like Box widget. The widget lists recent posts made on a Facebook page as well as an optional list of users who like the page. For Web sites interested in using content published to Facebook, this is the first step to accomplish. It’s important to note that the Facebook Like Box social plug-in is only intended to be used with Facebook fan pages and won’t work if you connect it to a personal Facebook account.

Also, note that Facebook differentiates between fan pages and profile pages. The bottom line is that fan pages are for businesses, whereas profile pages are for individuals. There are some differences between the two as far as the allowed actions are concerned. First and foremost, a team of people can have admin rights on a fan page. In addition, posts from a fan page can be specifically targeted by language and location so they reach followers (well, fans, actually) who can best receive them. Fan pages support additional features and can be promoted via ads and sponsored articles.

Conversely, profile pages are intended to let owners stay in touch with friends and family. Being a friend becomes a mandatory condition to get updates, even though through the subscription mechanism you can allow non-friends to get your updates as well.

Configuring the Like Box for a Web page couldn’t be easier. You can preview the content being displayed and grab related HTML directly from the Facebook developers site. Go to bit.ly/hFvo7y for a live demo. In the end, it’s all about arranging a long URL to set on an iframe element. Figure 1 lists the parameters you can use in the URL.

Figure 1 Parameters to Configure the Facebook Like Box

ParametersDescription
hrefIndicates the URL of the Facebook fan page to feature in the Like Box.
widthIndicates the desired width in pixels for the plug-in. The default width is 300 pixels.
heightIndicates the desired height in pixels of the plug-in. The default height is not fixed and depends on whether faces and streams are to be displayed. In general, you should allow 500 pixels for it if you intend to have a stream of news.
colorschemeIndicates the color scheme for the plug-in. You have only two options: light or dark.
show_facesIndicates whether the plug-in should display profile photos. The default is true.
streamIndicates whether the plug-in should display the latest posts from the page’s wall.
headerBoolean parameter, hides or displays the default Facebook header at the top of the plug-in.
border_colorIndicates the border color of the plug-in.
force_wallIf the page refers to a place, then this parameter indicates whether the stream should contain posts from the place’s wall or just check-ins from friends. The default is false.

All you do is arrange a URL and bind it to an iframe, as shown in Figure 2.

Figure 2 Binding a URL to an Iframe

<iframe src="//www.facebook.com/plug-ins/likebox.php
  ?href=http://www.facebook.com/etennisnetpage
    &width=292&height=490
    &colorscheme=light
    &show_faces=false
    &stream=true
    &header=true
    &appId=xxxxxxxxxxxxxxx"
  scrolling="no"
  frameborder="0"
  style="border:none; overflow:hidden; width:292px; height:590px;"
  allowTransparency="true">
</iframe>

It goes without saying that you can also embed the Like Box in a desktop application (for example, a Windows Presentation Foundation—or WPF— application) through a WebBrowser control.

As you can see, the plug-in allows for some quick styling that works most of the time. However, if you want to apply your own CSS (to the extent that it’s possible and documented) you should embed the Like Box via JavaScript and HTML5. Figure 3 shows the output of a Like Box for a sample site with custom and regular (light) style.

Sample Like Box
Figure 3 Sample Like Box

The Activity Plug-In

Another quick way to incorporate existing specific Facebook content in Web pages or desktop applications (via Web-browser components) is the Activity plug-in.

This plug-in aggregates stories resulting from the interaction that users have with your site through Facebook. Notice that the target here isn’t a Facebook page but rather an external site. Example actions that generate such feeds are liking content on the site, watching videos, commenting and sharing content from the site. The plug-in is also able to detect whether the current user of the site that contains the Activity plug-in is logged in to Facebook or not. If so, the displayed feed is restricted to friends of the user. Otherwise, the plug-in shows recommendations from across the site, while giving the user the option to log in to Facebook and receive more-targeted feedback. Here’s the markup you need (note that the Activity plug-in can only be consumed through HTML5 markup):

<div class="fb-activity"
  data-site="www.yoursite.com"
  data-app-id="xxxxxxxxxxxxx"
  data-width="300"
  data-height="300"
  data-header="true"
  data-recommendations="true">
</div>

You must incorporate the JavaScript SDK in the page in order for this markup to produce what’s in Figure 4.

The Activity Plug-in in Action
Figure 4 The Activity Plug-in in Action

Accessing the Timeline

In past columns, I used the Facebook C# SDK to post to the wall both plain text and attachments. Once the post is made, friends and fans can interact with it by liking it, sharing it and commenting on it. Let’s see what it takes to read the timeline of a given user.

Facebook assigns a unique and fairly long ID to any account, whether profile or fan page. Users, however, don’t use this ID to identify pages. So the first thing to do in order to read a timeline is match the public name of the page (or user) to the underlying Facebook ID. As a mere exercise, you can type the following into the address bar of any browser: https://graph.facebook.com/your-page-name.

The placeholder “your-page-name” is just the name of the account as you would type it to reach the page. Getting the ID of the account for which you intend to read the timeline is only the first step. You also need to be authenticated to access the feed. The bottom line is that any operation that goes directly against the underlying Facebook Graph API requires OAuth authentication. This means that the same preliminary steps discussed in past columns must also be done here:

  • Create a Facebook app to deal with the Facebook back end.
  • Have the user authorize the Facebook app to operate on behalf of the account. This step delivers an access token that binds together (for a limited time) the user and Facebook app.
  • Use the access token as the key to operate against the Graph API from within the host application (for example, an ASP.NET MVC application).

Once acquired, the access token can be saved to a cookie and used for every further operation until it expires. Here’s the required code to get the raw feed from the Facebook server:

var name = "name-of-the-user"; 
  // For example, joedummy
  var client =
    new FacebookClient(access_token);
  dynamic user = client.Get(name); 
  dynamic feed =
    client.Get(name + "/feed");

The first call to the Facebook client doesn’t strictly require the access token, as it’s expected to return only public information about the user. The user variable exposes properties such as first_name, last_name, id and location. Depending on your intentions, you might not need to place this call. The second call to the Facebook client is what really does the trick. It takes a string that denotes the path to the user’s feed. You build the path concatenating the account’s name with the /feed string. In return, you get a dynamic C# object built out of an underlying JSON stream. Figure 5 shows the structure of the JSON stream as captured by Fiddler.

The JSON Structure of a Timeline Item in Facebook
Figure 5 The JSON Structure of a Timeline Item in Facebook

It shows that the selected post got two types of actions—it has been liked and commented upon. It also currently counts 14 likes. More details about people who commented on it or liked it are available as you expand nodes. Finally, you find the content of the post. At the JSON level, the content of the post is the message field.

It’s important to note that not all posts have the same structure; this is the reason why the Facebook C# SDK doesn’t use plain, statically defined classes as data transfer objects (DTOs). A common snag is that the post lacks a message, link and picture, but includes a story field. This is the case, for example, when the admin adds a collection of photos.

The Facebook C# SDK just hands you a dynamic C# object. Parsing that into more defined data types—or deciding that the object is good as is to trickle down to the view—is your call. Figure 6 shows some code that attempts to parse the dynamic object into a classic C# class.

Figure 6 Parsing a Dynamic Object into a Classic C# Class

public class FacebookPost
{
  public String PostId { get; set; }
  public String Author { get; set; }
  public String Picture { get; set; }
  public String Link { get; set; }
  public String Published { get; set; }
  public String ContentHtml { get; set; }
  private delegate String ExtractDelegate();
  public static IList<FacebookPost> Import(dynamic data)
  {
    var posts = new List<FacebookPost>();
    foreach (var item in data)
    {
      var tempItem = item;
      var fb = new FacebookPost
      {
        PostId = Extract(() => tempItem["id"]),
        Published = Extract(() => tempItem["created_time"]),
        Picture = Extract(() => tempItem["picture"]),
        Link = Extract(() => tempItem["link"]),
        Author = Extract(() => tempItem["from"]["name"])
      };
      try
      {
        fb.ContentHtml = Extract(() => tempItem["message"]);
      }
      catch
      {
      }
      if (!String.IsNullOrEmpty(fb.ContentHtml))
        posts.Add(fb);
      }
      return posts;
    }
  private static String Extract(ExtractDelegate func)
  {
    try {
      return func();
    } catch {
        return null;
      }
  }
}

The most annoying part of this code is finding an effective way to check whether a given property is defined on the dynamic object you parse. Quite a few stackoverflow.com users agree on the approach shown in Figure 6, based on a delegate.

Dealing with social networks opens up a whole new world of possibilities, which become opportunities for developers to think of and realize new creative applications. As a .NET developer, you should be a friend of the Facebook C# SDK.


Dino Esposito is the author of “Architecting Mobile Solutions for the Enterprise” (Microsoft Press, 2012) and “Programming ASP.NET MVC 3” (Microsoft Press, 2011), and coauthor of “Microsoft .NET: Architecting Applications for the Enterprise” (Microsoft Press, 2008). Based in Italy, Esposito is a frequent speaker at industry events worldwide. Follow him on Twitter at twitter.com/despos.

Thanks to the following technical expert for reviewing this article: Scott Densmore (Microsoft)
Scott Densmore is a a senior development lead at Microsoft working on features in Visual Studio. He has worked on agile development teams for the last 10 years at large corporate environments and small startups. His primary interests are cloud computing, mobile device computing and social computing. You can find him on Twitter at @scottdensmore.

 

Rate: