Facebook REST-API — (Part2/2 — Erlang)
Monday, March 15th, 2010This is the second part of two minimal examples, on how to interact with the Facebook REST API. Last weeks part was in python, this time we do the exact same thing in erlang. (Note that there are python and erlang libs in various stages of completion, but my focus is on minimal examples and understanding here.)
The code below calls the function users.getinfo in the “call” method. The request send to the Facebook REST server has to be signed according to Facebook’s signing algorithm this is done in “get_rest_url”.
The result will be requested to be transmitted as JSON encoded text. I am using mochijson2 to decode the result.
-module(fb).
-export([call/1, test/0]).
-define(SECRET, "a1b1c1e1d1f1......"
-define(API_KEY, "a2b2c2e2d2f2......"
-define(REST_SERVER, "api.facebook.com").
-define(URL_START, "/restserver.php?").
get_rest_url(Args) ->
% this implements the the facebook signing recipe
% the link is in the text above
SortedArgs = lists:sort(Args),
Fun = fun({Key, Value}) -> Key ++ "=" ++ Value end,
StringArgs = lists:map(Fun, SortedArgs),
String = lists:flatten(StringArgs, ?SECRET),
<<M:128>> = erlang:md5(String),
Sig = lists:flatten(io_lib:format("~32.16.0b",[M])), % string rep of hexdigest
StringArgs2 = lists:map(fun(X) -> X ++ "&" end, StringArgs),
lists:flatten(["http://", ?REST_SERVER, ?URL_START, StringArgs2, "sig=", Sig]).
call(Args) ->
{Megaseconds,Seconds,Microseconds} = erlang:now(),
CallId = integer_to_list(Megaseconds)
++ integer_to_list(Seconds)
++ integer_to_list(Microseconds),
Args2 = lists:append(Args, [{"api_key", ?API_KEY}, % my application key
{"call_id", CallId}, % just any value that increases
{"format", "JSON"}]), % request JSON formatted reply
Url = fb:get_rest_url(Args2),
{ok, {{HttpVer, Code, Msg}, Headers, Body}} =
http:request(get, {Url, [{"User-Agent", "test "}]}, [], []),
mochijson2:decode(Body).
test() ->
call([{"method","users.getinfo"},
{"v","1.0"},
{"uids","1234567..."},
{"fields","first_name"}]).
you would run the above like this:
erl -pa /some/path/to/mochiweb/ebin/
Erlang R13B04 (erts-5.7.5) [source] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
Eshell V5.7.5 (abort with ^G)
1> inets:start().
ok
2> c(fb).
./fb.erl:28: Warning: variable 'Code' is unused
./fb.erl:28: Warning: variable 'Headers' is unused
./fb.erl:28: Warning: variable 'HttpVer' is unused
./fb.erl:28: Warning: variable 'Msg' is unused
{ok,fb}
3> fb:test().
[{struct,[{<<"first_name">>,<<"Joe">>},
{<<"uid">>,123456...}]}]
4>