Facebook | Answers - A Django App

Over the holiday break I took 2 days to try my hand at writing a moderately complex, non-annoying, Facebook app. Facebook Answers is the result of this work. It’s a place where you can ask a question and let the community answer. People can vote other people’s up or down, and you can earn points by answering other folks’ questions.

fb_screen_cap.png

Django is a pleasure to work with. I quickly sketched out the app in a couple of hours, then set to work with Django from scratch. I had the entire app coded up in a day. The only snag was figuring out how to deal with Facebook and sessions. There are two ways your apps show up on a Facebook canvas page: either it is included via an iframe or it is accessed by the Facebook servers and then its content is rendered by Facebook. Courses on Facebook is a good example of the former. If you look at the source for that page you see that it includes content from coursesonfacebook.com with an iframe. In the latter method, the user never accesses your server directly unless you served some sort of media. Facebook|Answers uses the 2nd method. This poses a problem with sessions because, typically, a request is associated with a session based on a cookie stored in your browser. Facebook does not forward cookies to your app. Instead, the only session identifier you get is a request parameter. Django only uses cookies for session handling.

So, I had to write up my own session handling code. I was a bit scared to get into the django innards, but, I gave it a go. I had to code a FacebookSession model, a SessionWrapper, and a FacebookSessionMiddleware which overrode process_request. The details are kinda hairy there. There’s probably a better way to do it but I was going to leave town in a few days and I didn’t want to spend any more time trying to figure this out. I also used pyfacebook, a Python Facebook client library. It made it really easy to communicate with Facebook’s API and to get stuff out of requests.

Once I had it working I took another day to tweak the design and get it to really fit the Facebook look and feel. Facebook tag documentation was not too bad, the hard part is getting a hold of some sort of style guide or css guide for the Facebook design. This would have cut a significant amount of time from all the tweaking I had to do to get stuff to look just right. I think Facebook should provide developers a set of global css definitions we can use and a guide that shows what the definitions actually look like. Maybe this guide exists somewhere, but I couldn’t find it.

All in all I think developing for Facebook wasn’t that much different than developing any other web app. Some things are made even easier if you treat Facebook as a database where you can grab a bunch of data very quickly and figure out some interesting relationships. And fbml markup makes it easy to do stuff that would have taken me a couple of hours or even days to get ready on my own. For example, I can specify conditional view code based on if you have the app installed, if you are a friend of the person who wrote the question. All this is handled with simple fbml tags and I don’t have to do any database lookups on my end.

There’s still some work to do with integrating the app into your profile. I’d like it to show the latest question, if you have answers, and if your friends have questions. And I’d like to provide the user with a way to configure this. I’ll get around to that in a week or so.

Hope you enjoy the app. Tell all your friends about it. If you find any problems, let me know.

Here is the bit of code I wrote up to get the sessions working. I actually didn’t code much of it; I just took the existing session middleware code and modified it to use Facebook’s session id. Why did I not extend? I’m not sure. I must have had a good reason =p It probably won’t work right out of the box and it may not be the best way to do it. ymmv.

util.zip

Facebook | Answers

Django - The Web Framework for Perfectionists with Deadlines

pyfacebook - Python Facebook Library

Leave a Reply