Archive

Posts Tagged ‘localhost’

Making a Facebook Wall Post using the new Graph API and C#

November 3, 2010 29 comments

One of the features coming up with Rate-It is the ability to post your ratings/reviews to your Facebook wall.  For this, we decided to go with the new Facebook Graph API.

There are quite a few tricks and obstacles in the way of you doing this, particularly because the documentation omits a few details and the documentation is very PHP- or Javascript-centric.  With this in mind, we’ve posted below some very detailed instructions on how to get the system going using Microsoft C#.

 

Debug your Facebook Application from localhost

One of the first problems you’ll have is trying to debug your application, and for this the easiest way is via localhost.  We have seen a few posts suggesting that this is not possible, but it is – and it is easy.  Simply setup a new application at www.facebook.com/developers and then enter your localhost information where a URL is required.  We’ve copied a screenshot of ours below:

image

 

Getting a user to Authorize your Application

Refer: http://developers.facebook.com/docs/authentication/

Facebook has a two-step approach for a user to authorize your application.  The first is to connect their Facebook account.  The second is to switch the Facebook account code with an OAuth account code.

The key to all this, and the most problems you’ll have is simply structuring your URLs.  There are three, and here they are:

        /// The callback page where the user is returned to after authorizing with FB

        /// </summary>

        /// <returns></returns>

        private string FacebookAfterAuthorize()

        {

            return SiteRoot + "services/facebook/canvas/afterauthorise.aspx";

        }


        /// <summary>

        /// Once FB returns a user code to us, we need to use the OAuth key in queries

        /// </summary>

        /// <param name="code"></param>

        /// <returns></returns>

        public string FacebookOAuthAccessTokenFromFacebookCode(string codeReturnedFromInitialFacebookRequest)

        {

            var url = "https://graph.facebook.com/oauth/access_token"

                .AppendQueryString("client_id", Configuration.Current.FacebookAPIKey)

                .AppendQueryString("client_secret", Configuration.Current.FacebookAPISecret)

                .AppendQueryString("code", codeReturnedFromInitialFacebookRequest)

                .AppendQueryString("redirect_uri", this.FacebookAfterAuthorize())

                ;


            return url;

        }


        /// <summary>

        /// The link the user clicks when they want to initialize their connection to FB

        /// </summary>

        /// <returns></returns>

        public string FacebookAuthorize()

        {

            var url = "https://graph.facebook.com/oauth/authorize"

                .AppendQueryString("client_id", Configuration.Current.FacebookAPIKey)

                .AppendQueryString("scope", "publish_stream,offline_access")

                .AppendQueryString("redirect_uri", this.FacebookAfterAuthorize())

                ;


            return url;

        }

Step 1 – Connect the Facebook Account

Simply create a hyperlink and present it to the user.  The hyperlink contains various GET parameters which tell Facebook who you are and what you want to do with the user’s account.  Here is our one:

var url = new LinkManager().FacebookAuthorize();

BtnFacebookAuthorize.NavigateUrl = url;

 

Pretty simple.  This redirects the user to a Facebook page where they are presented with something like this:

image

Assuming the user selects ‘Allow’, they are redirected to the redirect_url parameter you specified in the hyperlink.  In our case, this was /services/facebook/canvas/afterauthorize.aspx.  Let’s look at that now.

Step 2 – Switching the Facebook Code for the OAuth Code

The Graph API uses the OAuth system to authenticate users and at this point, we only have some kind of Facebook code.  We get the OAuth code by POSTing the Facebook code back up to Facebook.  I’ll let the code do the talking:

 

public void ProcessAfterAuthorization(HttpRequest request)

{

    // Facebook passes an empty code if the user declined

    string code = request.Params("code");

    if (string.IsNullOrEmpty(code)) throw new FacebookAuthorizationException("You have chosen not to proceed with Facebook integration.");


    // Facebook

    var url = new LinkManager().FacebookOAuthAccessTokenFromFacebookCode(code);

    var webRequest = WebRequest.Create(url);

    var webResponse = webRequest.GetResponse();

    StreamReader sr = null;

    string returnedKeyValuePairs = "";

    try

    {

        sr = new StreamReader(webResponse.GetResponseStream());

        returnedKeyValuePairs= sr.ReadToEnd();

    }finally

    {

        if (sr != null) sr.Close();

    }


    // Get the OAuth token from the returned querystring

    var authToken = returnedKeyValuePairs.GetQueryStringValue("access_token");


}

 

Save the authToken field against your user record – this is what you’ll pass later when you make a wall post.  It will look a little something like this:

108091332590110|a9fa8e86ed521818374c8733-100001367407858|vRR3VgTCPuBwgcsG4Kr2fUiw9A8

Writing to the User’s Wall

Refer: http://developers.facebook.com/docs/reference/api/post

Writing to a user’s wall is a lot more complicated, and the documentation linked above omits a very important point.  Here is what we came up with:

public class PostToWall

{

    public string Message = "";

    public string AccessToken = "";

    public string ArticleTitle = "";

    public string FacebookProfileID = "";


    public string ErrorMessage { get; private set; }

    public string PostID { get; private set; }


    /// <summary>

    /// Perform the post

    /// </summary>

    public void Post()

    {

        if (string.IsNullOrEmpty(this.Message)) return;


        // Append the user's access token to the URL

        var url = "https://graph.facebook.com/me/feed"

            .AppendQueryString("access_token", this.AccessToken);


        // The POST body is just a collection of key=value pairs, the same way a URL GET string might be formatted

        var parameters = ""

            .AppendQueryString("name", "name")

            .AppendQueryString("link", "http://link.com")

            .AppendQueryString("caption", "a test caption")

            .AppendQueryString("description", "a test description")

            .AppendQueryString("source", "http://blackballsoftware.com/images/whitetheme/headerwhite.png")

            .AppendQueryString("actions", "{\"name\": \"View on Rate-It\", \"link\": \"http://www.rate-it.co.nz\"}")

            .AppendQueryString("privacy", "{\"value\": \"EVERYONE\"}")

            .AppendQueryString("message", this.Message);



        // Mark this request as a POST, and write the parameters to the method body (as opposed to the query string for a GET)

        var webRequest = WebRequest.Create(url);

        webRequest.ContentType = "application/x-www-form-urlencoded";

        webRequest.Method = "POST";

        byte[] bytes = System.Text.Encoding.ASCII.GetBytes(parameters);

        webRequest.ContentLength = bytes.Length;

        System.IO.Stream os = webRequest.GetRequestStream();

        os.Write(bytes, 0, bytes.Length);

        os.Close();


        // Send the request to Facebook, and query the result to get the confirmation code

        try

        {

            var webResponse = webRequest.GetResponse();

            StreamReader sr = null;

            try

            {

                sr = new StreamReader(webResponse.GetResponseStream());

                this.PostID = sr.ReadToEnd();

            }

            finally

            {

                if (sr != null) sr.Close();

            }

        }catch(WebException ex)

        {

            // To help with debugging, we grab the exception stream to get full error details

            StreamReader errorStream = null;

            try

            {

                errorStream = new StreamReader(ex.Response.GetResponseStream());

                this.ErrorMessage = errorStream.ReadToEnd();

            }finally

            {

                if (errorStream != null) errorStream.Close();

            }

        }

    }

}

 

 

 

 

 

And to use, simply:

var post = new PostToWall();

post.Message = "Test message from Ben";

post.ArticleTitle = "A new rating has been posted";

post.AccessToken = "108091332590110|a9fa8e86ed521818374c8733-100001367407858|vRR3VgTCPuBwgcsG4Kr2fUiw9A8";

post.Post();

Response.Write("The Facebook post successed with ID: " + post.PostID);

Response.Write("<br/>");

Response.Write("The error message was: " + post.ErrorMessage);

 

Right – hopefully that is useful to somebody, it will be to us when we forget how we did it in a few months.

Apologies for the custom classes etc in the code like AppendQueryString() – I’m sure you can work them out.

Follow

Get every new post delivered to your Inbox.