Since Facebook has rolled out realtime updates it has been easier to gather information. Instead of hitting the API on a set time interval, we can just wait for Facebook to ping us and go grab the information we need. This all sounds good in theory but as I had to integrate realtime updates for an application I am working on, there were quite a few pitfalls and I wish I knew some of these before hand.
Setting up a Facebook application
I am not going to walk you through creating a Facebook application, Ryan Bates already does a good job with it. Once you have that setup and the permissions you need for this application head over to your Facebook applications dashboard. Over here select the application in which you would like to enable realtime updates and hit the edit button on the top right. This should take you to a page with the basic information of your application, and on the right under settings there should be ‘realtime updates’.
As you can see I have a user object and the fields I want to follow. I have selected all the fields for the demo. You should only select the fields your app has permissions for, otherwise it would be pointless as you won’t be able to get the information. For the callback URL you should point it to the route of the realtime action, but you must be thinking how will I test this locally? That’s where Ngrok comes in. Ngrok creates a tunnel from the public internet to a port on your local machine. This is perfect for a situation like this where Facebook has to verify that you are authorized. The information on the site is self explanatory, once installed have it listen to the same port as your server.
1 2 3 |
|
Ngrok will give you a URL which you can paste in to the callback section followed by the route to the realtime action. For the verify token any random string will do.
Setting up the controller
Now create a facebook controller with the real_time method.
1 2 3 4 5 6 7 8 9 10 11 |
|
And the routes should look like this:
1 2 3 |
|
Now that we have the route set up for both GET&POST, when we click on test on the realtime updates page Facebook will make a get request to this route ensuring we are authorized. The default hub.mode set by Facebook is subscribe and you must make sure that the verify_token matches what you have entered on Facebook. If all went well Facebook will prompt you with the following message:
And we are done…not really.
Your application is running, realtime updates are setup and you have a test account to play around with. On every change the user makes to the field you have subscribed to, Facebook will ping your servers. However it will only do so with the Facebook ID, the fields that have changed and a timestamp. This means that we still have to query the API and this can be quite a pain when it comes to things like comments or photos. The good thing is I have banged my head on this for the past week and should be able to alleviate a lot of your troubles.
Facebook example response for relationship change:
1
|
|
Now in order to actually grab the change we have to make a call to the Facebook API requesting this information. You will only be able to get this information if you have the right permissions.
1 2 |
|
This gives the information for the relationship status. This seems and is straight forward and these are the building pieces for every change. However there are some caveats. Below are snippets in order to get events,friends,posts,photos&comments.
Events
Facebook example response for events change:
1
|
|
And the query to get all event ID’s and the respective information:
1 2 3 4 5 |
|
Friends
Facebook example response for friends change:
1
|
|
And the query to get all friend’s related information:
1 2 3 4 5 |
|
Posts,Photos&Comments
Now this is where things start to get complicated. As you can see Facebook sends ‘feed’ as a changed field with every column.With every change to anything on Facebook it needs to update the feed and in order to get the photos,posts and comments we must query the feed or stream in the Facebook Query Language. Despite being able to get posts on the ‘status’ changed field and photos on the ‘photos’ changed field, I found it best to look for the feed change and make a query.
One great thing with the Facebook Query Language is that you can add conditions to your queries.When making a query after a realtime update, you can put a conditional for updated time to be just before the timestamp given by Facebook.That’s what I thought too, but after a lot of digging Facebook doesn’t give you the right information. The only way around this is to get all the posts, sort them by updated time and then use ruby’s built in methods to select the posts before a certain time.
Facebook example response for feed:
1 2 |
|
And the query to get the latest posts:
1 2 3 |
|
What’s going on here? In the first query, I find all the posts of the user limit them to 100, order them by updated time and make sure that either message or attachment(photo) is present. In the next line I take only the posts that have an updated time 30 seconds(approximate time it takes Facebook to ping your servers) before the timestamp. And select the ones that either have a message or photos. Now we have a bunch of posts, time to decipher whether it is a status update, photo or comment.
1 2 3 4 5 6 7 8 |
|
The post is fairly simple from here, we already have the attributes we need. Now in order to get comments for post, we can do the following query:
1 2 |
|
The use case for me is to update all the comments for the posts and add the new ones, hence I query for all of them. Facebook gives you the flexibility with the query language for any use case possible. Posts,and comments done and now time for photos. After rigourous testing, Facebook gives only 9 photos. Let’s say a user added an album, added 50 photos to this with normal queries that I am about to display Facebook will only give 9 photos back. The worst part is there’s no way to decipher if there are more photos. One trick I found is, if Facebook gives you 9 photos that means there are more photos. Hence I find all the photos in the album.
1 2 3 4 5 6 7 8 9 10 11 |
|
I get the photo_ids from the first line, and if there are 9 which means more photos I get all photo IDs from the album. Iterating over all the photo ID’s to get the related informaton:
1 2 3 4 5 6 7 8 9 |
|
As you can see there’s a lot of edge cases here, so you must test thoroughly. Both manually and with automated tests. One good thing about the photo query is that it gives you comment information too. The following takes care of status updates, comments on them, photos posted on the wall, comments to those and if the user posts an album. The only part I haven’t been able to get is realtime comment on a photo which is inside an album. I am currently working on that, and will update this post if I find a way.
Wrapping it all up.
Despite it’s limitations Facebook has done a great job with the realtime updates and Facebook Query Language. I can’t stress this point enough, test thoroughly. Manually and with automated testing such as Rspec. I have written tests for this and might showcase it in a later blog post. Whenever you get stuck, instead of searching StackOverflow which at times can help, the best approach I found is to use the Graph Explorer.
Hope that was useful, let me know if you have any questions.