How do I use Facebook’s restserver.php?
Facebook’s API is crap. I am integrating Facebook Connect into our website and I have struggled to no end on working out how to do it! So as per usual as soon as I work something new out I post it here.
So, you want to use Facebook’s API restserver?
Nowhere in the docs do I see it clearly state how to make a GET request to restserver.php and actually have it work! So here goes!
Wait, first.. There is a Rails plugin that will help you out. I tried it and it conflicted with the current sites Javascript libraries and I found it difficult to use. I didn’t need or want half of what it gave me and I didn’t have full control over it in regard to my site and how it integrated in. I am of course talking about Facebooker. I think this is probably a growing problem with more and more sites being crafted out of 20 different rails plugins. The developers job is heading more to integration rather than creation. Not a criticism, just an observation.
I created some methods to do the grunt work
def self.post(method, params)
add_facebook_defaults_and_method(method,params)
sorted_args = params.collect{|a|a[0].to_s+‘=’+a[1].to_s}.sort
sig = Digest::MD5.hexdigest(sorted_args.join+APP_SECRET)
sig_args = sorted_args.join(‘&’)+‘&sig=’+sig
res = Net::HTTP.get_response(URI.parse(“http://api.new.facebook.com/restserver.php?”+sig_args))
puts res.body
JSON.parse(res.body)
end
def self.add_facebook_defaults_and_method(method,params)
params[:method] = method
params[:call_id] = Time.now.to_f.to_s
params[:api_key] = APP_ID
params[:v] = “1.0”
params[:format] = “json”
params
end
def self.get_names(uids, session_key)
response = Facebook.post(“users.getinfo”,{:fields=>”name”,:uids=>uids.join(‘,’),:session_key=>session_key})
uids.each do |uid|
Rails.cache.write(“facebook_user_name/#{uid}”, response, :expires_in => 24.hours)
puts “Facebook #{uid} username cached”
end
response
end
The important bits are this.
Every GET request sent to http://api.new.facebook.com/restserver.php (changed from http://api.facebook.com/restserver.php) needs the following things
- method=<something.something> (method=User.getInfo)
- v=1.0
- api_key=<APP API_KEY> (api_key=3261d0c86fae5b363c2bfa872253887f)
- call_id=TimeStamp of NOW (call_id=1237760132) this is basically a number which always increments with each call, current time in milliseconds does fine.
- sig=MD5Hash (sig=8e719ba4d1506b2ac9551bfd2b0d42b3)
Which looks like the below
http://api.facebook.com/restserver.php?method=User.getInfo&api_key=3261d0c86fae5b363c2bfa872253887f&call_id=1237760132&fields=first_name&uids=705926010&v=1.0&sig=8e719ba4d1506b2ac9551bfd2b0d42b5
The sig needs to be computed in the same manner as in the Authentication.
- Put all params into an array, including the method=<whatever>
- Sort, join, add APP_SECRET to end, MD5Hash it
- Append that hash to end of params as sig=MD5Hash like below
http://api.facebook.com/restserver.php?method=User.getInfo&api_key=3261d0c86fae5b363c2bfa872253887f&call_id=1237760132&fields=first_name&uids=705926010&v=1.0&sig=8e719ba4d1506b2ac9551bfd2b0d42b5
The given example isn’t valid for the method it is calling, but it gives an idea. To make it valid it needs some more params, the uids and the session_key. When calling this method you should already have the session_key from the user via the cookies.
NOTE
Facebook Policy only allows you to keep user information for 24 hours.
To do this I am using memcached with a 24 hour timeout on it. It seems to be working fine and it doesn’t require the database to be hit at all.
Posted on March 24, 2009