Friday, April 15, 2011

Tutorial - Post data on a Facebook Company Page as Admin

1 comments
Its been a while I have blogged about something.
Have been working on the Facebook API and one of the requirement is to post data into a Facebook company page from one's website.

Here is a step by step procedure on posting data to a company page(on which you have admin rights) using the Facebook API.
Feel free to skip the first two steps if you know how to set up a Facebook Application and to create pages in Facebook.

Step 1 - Creating a Facebook Application

Sign in to your Facebook Account and key in the following URL to your address bar

http://www.facebook.com/developers/createapp.php

Set Application Name as "My Demo Application"

Now I am adding the following data also to the Website tab of the core settings
(Lets come to that later)

Set Site URL as http://localhost/FacebookPost/

After entering, click on the Save Changes Button.
Now you will be re directed to a page where your App Settings are displayed.
Copy the values App ID, App Key and App Secret and store them securely.

Step 2 - Creating a Facebook Page

Now, key in the following URL to your address bar

http://www.facebook.com/pages/create.php

Now select the Page Type. Here is what I selected.

Type : Company, Organisation (Click on the type you want to create.
Category : Computers/Technology
Comapany Name: MyCompany

Now agree to the Facebook Pages Terms and click Get Started.
Your page is created by Facebook and you will be landed on a URL like that
http://www.facebook.com/pages//?created
Please copy the PageID and store it securely.

Step 3 - Create a website locally in your system

Open up your Visual Studio and Create an empty website.
Create a page "Default.aspx" and run the website and allow the web.config to be created.

(I have mapped my site to my IIS with the application name FacebookPost.
Please note that it is being done to match the Site URL I have set at the Facebook Application Page)

Step 4 - Pick a Facebook C# SDK to communicate with the Facebook Graph API.

My research came up with two options
1. Use the Facebook's own lesser used SDK found at GitHub ( link here )

2. Use the more widely used third party C# SDK hosted at Codeplex ( link here )

I preferred Facebook's own SDK. Actually, you can also write your own API if you want. Its set of simple WebRequest/WebResponse. So I went to GitHub where the SDK was hosted and downloaded the folder named facebook and changed it to Facebook ( :) Pascal Casing) and pasted it inside my App_Code

Step 5 - Modify your AppSettings at web.config

Remember those AppID, AppKey, AppSecret, PageID I asked you to keep securely?
Lets now store them at AppSettings of web.config.
(Ideally you would be much better of encrypting them, but details on encrypting is beyond the scope of this tutorial.)

<appSettings>
    <add key="AppID" value="Your App ID"/>
    <add key="AppKey" value="Your App Key"/>
    <add key="AppSecret" value="Your App Secret"/>
    <add key="PageID" value="Your Page ID"/>
  </appSettings>


Step 6 - Create a form for entering the data

Open up Default.aspx in Visual Studio and change Source like this.

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Codovations Demo - Posting to Facebook Company Page</title>
    <style type="text/css">
        .title {
            display:inline-block;
            vertical-align:top;
            width:100px;   
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <label class="title">Message</label><asp:TextBox ID="MessageText" runat="server" TextMode="MultiLine" Width="200px"></asp:TextBox><br />
    <label class="title">Name</label><asp:TextBox ID="NameText" runat="server" Width="200px"></asp:TextBox><br />
    <label class="title">Description</label><asp:TextBox ID="DescriptionText" runat="server" TextMode="MultiLine" Width="200px"></asp:TextBox><br />
    <label class="title">Picture(URL)</label><asp:TextBox ID="PictureText" runat="server" Width="200px"></asp:TextBox><br />
    <label class="title">Caption</label><asp:TextBox ID="CaptionText" runat="server" Width="200px"></asp:TextBox><br />
    <label class="title">Link</label><asp:TextBox ID="LinkText" runat="server" Width="200px"></asp:TextBox><br />
    <label class="title"></label>
        <asp:Button ID="PostToCompanyButton" runat="server" 
                Text="Post to Company Page" onclick="PostToCompanyButton_Click"/>
    </div>
    </form>
</body>
</html>


Step 7 - Posting data on the Company Page.

This is the trickiest part in this project. Facebook provides no straight forward way to post data to a company page. Here is how we achieve that.

First we will request oAuth from Facebook and on successful authorisation we get an access token.
Using the token we fetch "me/accounts" and will check in that account array, an account that matches the stored PageID. If found, we fetch the associated accesstoken for that page. When we get that we post the content to "me/feeds" using that accesstoken like this.

if (Request.Params["code"] != null)
{
    Status.Text = "";
    string accessToken = GetAccessToken(Request.Params["code"]);
    FacebookAPI api = new FacebookAPI(accessToken);

    JSONObject me = api.Get("me/accounts");
    Dictionary dictionary = me.Dictionary;
    JSONObject myPage = me.Dictionary["data"].Array
        .SingleOrDefault(d => d.Dictionary["id"].String.Equals(ConfigurationManager.AppSettings["PageID"].ToString()));
    if (myPage != null)
    {
        Dictionary parameters = Session["DataForFacebook"] as Dictionary;
        Session.Remove("DataForFacebook");
        string newToken = myPage.Dictionary["access_token"].String;
        var app = new FacebookAPI(newToken);
        var response = app.Post("me/feed", parameters);
        if (response != null && response.Dictionary[""] != null)
        {
            Status.Text = "Data posted successfully to company page.";
            ClearData();
        }
        else
        {
            Status.Text = "An error occured while posting.";
        }
    }
}

Two helper methods used are

private string GetAccessToken(string accessToken)
    {       
        Dictionary args = GetOauthTokens(accessToken);
        return args["access_token"];
    }

    private Dictionary GetOauthTokens(string accessToken)
    {
        Dictionary tokens = new Dictionary();
        try
        {
            string url = String.Format("{0}client_id={1}&redirect_uri={2}&client_secret={3}&code={4}&scope={5}",
                            "https://graph.facebook.com/oauth/access_token?",
                            ConfigurationManager.AppSettings["AppID"].ToString(),
                            "http://localhost/FacebookPost/Default.aspx",
                            ConfigurationManager.AppSettings["AppSecret"].ToString(),
                            accessToken,
                            "publish_stream,offline_access,manage_pages");

            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                StreamReader reader = new StreamReader(response.GetResponseStream());
                string retVal = reader.ReadToEnd();

                foreach (string token in retVal.Split('&'))
                {
                    tokens.Add(token.Substring(0, token.IndexOf("=")),
                        token.Substring(token.IndexOf("=") + 1, token.Length - token.IndexOf("=") - 1));
                }
            }
        }
        catch (Exception err)
        {

        }
        return tokens;
    }

Thats all to it. Happy coding.
Read more...