Friday, April 8, 2011

How to customize Facebook pages - step by step guide (different content for fans, different content by language)

Objective:
To create a landing tab on a Facebook page which displays content in user language, plus different content if the user is a fan, meaning the he or she clicked the like button on the Facebook page.
This is a detailed tutorial, but the actual code is pretty simple, is uses the signed_request parameter sent by Facebook to the IFrame containing a simple application (download the .Net code).

What you need before starting:
  • A Facebook account
  • Access to a hosted URL address which will contain a Facebook application code
  • Optionally a HTTPS address needed for people having secured connection configured on their Facebook accounts
  • The example in this tutorial is using .Net Framework 3.5 and Visual Studio 2008, but the same technique works for any other language (PHP, Python, Java etc.)
  • The example is this tutorial is using English and French as languages, but the same technique works for any number of languages

Step by step guide:
  • Create your Facebook page (skip this step if the page already exists)
  • Create a website for the future Facebook application
    • Using Visual Studio create a new website on your computer
    • Create an App_Code folder
    • In the App_Code folder, create a new file (class), named Facebook.cs
    • Copy and paste the Facebook.cs code (see Code section below)
    • If the website contains a Default.aspx page, delete it
    • Create a new Default.aspx page
      • Choose Visual C# as language
      • Uncheck Place code in separate file
      • Uncheck Select master page
    • Copy and paste the Default.aspx code (see Code section below)
    • From Visual Studio, right click on Default.aspx and choose View in browser from the context menu
    • The website will open in your default browser
    • You’ll need the address of the website displayed in the browser address bar for Facebook configuration
  • Create a Facebook application – this application will be displayed on a tab in your page
    • Go to http://developers.facebook.com/
    • Click on My Apps
    • Click on Set Up New App button
    • Follow the steps to create the application (in this example we’ll call it my_new_fb_app)
  • Configure the Facebook application to work with the test code on your machine
    • Go to http://developers.facebook.com/
    • Click on My Apps
    • Click on the application previously created (my_new_fb_app)
    • Click on Edit Settings
    • Personalize your application: name, description, icon, logo etc.
    • Click on Facebook integration
    • Choose a name for your page on the Canvas Page field
    • Put the address of the page previously created and displayed on the browser (yes, it will work fine with a localhost address)
    • If Facebook complains about the address, just add a parameter to the URL (doesn’t matter what, ex. http://localhost:3219/facebookapp/default.aspx?par=val)
    • In the Canvas section, choose IFrame for Canvas Type (FBML is now deprecated)
    • In the Page Tabs section, choose IFrame for Page Tab Type
    • Click on Save Changes
    • Your app is now ready to test
  • Add the Facebook application to the Facebook page
    • Click on Back to My Apps
    • If you have more than one app, make sure that my_new_fb_app is selected
    • Click on Application Profile Page
    • Click Add to My Page
    • From the pop-up list displayed, choose my_new_fb_page, click on Add to Page
    • Click on Close
    • The app is now added to the page
  • Test and debug the test code
    • Go to Facebook home page
    • From the section starting with App Requests, click on More
    • Click on Ads and Pages
    • Click on my_new_fb_page
    • At left you will see a link to my_new_fb_app, click on it
    • The app will be displayed (by default in English and Not fan)
    • If there is a .Net error Post Verb is not accepted, go to the application settings (previous section), and add a parameter after the URL (doesn’t matter what, ex. http://localhost:3219/facebookapp/default.aspx?par=val)
    • At this point, everything should work fine, you can click on like button on the page in order to display fan content and you can change you Facebook language (from Account, Account Settings)
  • Deploy the code to the production environment
    • Deploy the website code to the production environment
    • Test the production address (you should see the defaults, English not fan)
    • If possible, activate HTTPS on the production environment and test the secure website (strongly recommended for the page to be displayed correctly for users using SSL connections)
  • Change Facebook application settings to point to the production code
    • Go to http://developers.facebook.com/
    • Click on My Apps
    • Click on the application previously created (my_new_fb_app)
    • Click on Edit Settings
    • Click on Facebook Integration
    • On the Canvas section, put the production URLs (Canvas URL and Secure Canvas URL)
    • On the Page Tabs section, put the production URLs (Tab URL and Secure Tab URL)
    • Click on Save Changes
    • Changes may take several minutes to propagate to all servers
  • Configure the Facebook page
    • Go to Facebook home page
    • From the section starting with App Requests, click on More
    • Click on Ads and Pages
    • Choose my_new_fb_page, click on Edit Page
    • From Manage Permissions, on Default Landing Tab, you can choose the newly created tab as default (please note that since you are an admin of the page, your landing page will always be the wall, but everything will work as expected for other users)
    • From Apps, you’ll find my_new_fb_app at the bottom, you can click on Edit Settings if you want to customize the tab name displayed on the page
  • Finalize and test
    • If possible, use another Facebook account (not admin of the page)
    • Click on View Page
    • Test all scenarios (English/French, fan/not fan)
    • All done; hope everything worked well, if not you can leave a comment and I’ll try to help you

Code used in this tutorial:
Download the code (facebook_page.zip)



Facebook.cs

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public class FacebookData
{
    public string algorithm { get; set; }
    public long issued_at { get; set; }
    public long expires { get; set; }
    public string oauth_token { get; set; }
    public string app_data { get; set; }
    public string user_id { get; set; }
    public FacebookPage page { get; set; }
    public FacebookUser user { get; set; }
    public FacebookData() { }
}
public class FacebookPage
{
    public long id { get; set; }
    public bool liked { get; set; }
    public bool admin { get; set; }
    public FacebookPage() { }
}
public class FacebookUser
{
    public string country { get; set; }
    public string locale { get; set; }
    public FacebookUserAge age { get; set; }
    public FacebookUser() { }
    public string culture
    {
        get { return String.IsNullOrEmpty(locale) ? null : locale.Substring(0, 2); }
    }
}
public class FacebookUserAge
{
    public int min { get; set; }
    public int max { get; set; }
    public FacebookUserAge() { }
}

Default.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    protected override void OnLoad(EventArgs e)
    {
        string culture = "en";
        string fan = "not_fan";
        string signed_request_encoded = Request["signed_request"];
        if (signed_request_encoded != null && signed_request_encoded.Contains("."))
        {
            byte[] buffer = Base64UrlDecode(signed_request_encoded.Split('.')[1]);
            string signed_request = Encoding.UTF8.GetString(buffer);
            FacebookData facebookData = new JavaScriptSerializer().Deserialize<FacebookData>(signed_request);
            if (facebookData.user.culture != null)
                culture = facebookData.user.culture;
            fan = facebookData.page.liked ? "fan" : "not_fan";
        }
        Page.FindControl(String.Format("{0}_{1}", culture, fan)).Visible = true;
    }
    byte[] Base64UrlDecode(string arg)
    {
        string s = arg;
        s = s.Replace('-', '+'); // 62nd char of encoding
        s = s.Replace('_', '/'); // 63rd char of encoding
        switch (s.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: s += "=="; break; // Two pad chars
            case 3: s += "="; break; // One pad char
            default: throw new System.Exception(
              "Illegal base64url string!");
        }
        return Convert.FromBase64String(s); // Standard base64 decoder
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Facebook Application</title>
</head>
<body>

<asp:PlaceHolder ID="en_fan" runat="server" Visible="false">
    Current user is fan <!-- insert your HTML here -->
</asp:PlaceHolder>
<asp:PlaceHolder ID="en_not_fan" runat="server" Visible="false">
    Current user is not fan <!-- insert your HTML here -->
</asp:PlaceHolder>
<asp:PlaceHolder ID="fr_fan" runat="server" Visible="false">
    L'usager est fan <!-- insert your HTML here -->
</asp:PlaceHolder>
<asp:PlaceHolder ID="fr_not_fan" runat="server" Visible="false">
    L'usager n'est pas fan <!-- insert your HTML here -->
</asp:PlaceHolder>

</body>
</html>

The simplest way to customize Facebook pages

Display different content for fans, plus localize your page using the user language

Very often people want their Facebook pages to display pages in visitor language (Facebook configured language). Also, they want to display some content only if the current user is a fan (clicked the Like button).
There are a lot of solutions for localization and personalization on the Web, using Facebook applications, using FBML (now deprecated by Facebook since March 11th, 2011) and so on. These are interesting but I've found a better way to achieve all this.
In my article about Facebook pages localization I've talked about the signed_request parameter send by Facebook to an iframe application. The documentation was not so clear on the Facebook website, but seems that they did a much better job now: https://developers.facebook.com/docs/authentication/signed_request/
So if you read the value of the signed_request parameter and decode it, you will get a json string containing all the info needed to localize the content, plus some information about the page hosting the application, including a boolean value which tells if the current user liked the page or not. All this without for an application not requesting any additional permission from the user, so it will act like a regular tab on the page.
I'll get back soon with a step by step procedure to achieve Facebook pages customization.

UPDATE: Here is the step by step guide: http://www.marianborca.com/2011/04/how-to-customize-facebook-pages-step-by.html