Facebook REST-API — (Part2/2 — Erlang)

This 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>

Tags: , , , , , , , , ,

7 Responses to “Facebook REST-API — (Part2/2 — Erlang)”

  1. Hynek (Pichi) Vychodil Says:

    Your blog engine ate <>. You overuse lists:flatten in your code little bit. erlang:md5 accepts io_lists for example. Almost all your usage of ++ can be done by | and lists:flatten can be called only once for get_rest_url return value because http:request doesn’t accept io_list if memory serves me right.

  2. Hynek (Pichi) Vychodil Says:

    Hmm, and comment engine too :( So second attempt <<M:128>>

  3. snies Says:

    Thanks Hynek, i will try your suggestions. I fixed the bracket issue.

  4. Chandra Arnot Says:

    Sweet, that’s exactly what I was looking for! You just saved me alot of work :)

  5. Jonathan Reyes Says:

    First thank you for this documentation.
    A ran into a few things when I tried your code.
    I noted that when you are writing code provided for
    a user I typically
    I am running/testing on Erlang 14B
    ALSO where do u find
    mochijson2:decode(Body)
    I had to remove this from my code.
    Any chance writing a new tutorial for the new FB graph API?

    Compilation failed:
    -define(SECRET, “a1b1c1e1d1f1……”
    -define(API_KEY, “a2b2c2e2d2f2……”
    ….
    Url = fb:get_rest_url(Args2),

    {“uids”,”1234567…”},

    Modifications to consider:
    -define(SECRET, “”).
    -define(API_KEY, “”).

    Url = get_rest_url(Args2),

    {“uids”,”"},

    Thanks,
    Jonathan

  6. snies Says:

    the mochijson2:decode function is part of the mochiweb package
    http://code.google.com/p/mochiweb/source/browse/trunk/src/mochijson2.erl
    line 75

  7. Jonathan Reyes Says:

    Thanks for the google code link of the mochijson2.erl in mochiweb for the mochijson2:decode.

    Happy Coding,
    Jonathan

Leave a Reply