perlでFacebook Legacy REST API を使ってみる

Facebook::Graph を利用すればperlから簡単にFacebookAPIが扱えますね!
http://helloperl.com/example_facebook.permalink
http://d.hatena.ne.jp/sugyan/20101008/1286471717


しかし、Legacy REST API でないと扱えない情報もあったりするので
もしかしたら使いたいというニーズもあるのでは…*1
http://developers.facebook.com/docs/reference/rest/


Codezineにサンプルがありました、
http://codezine.jp/article/detail/1790
が、使い方が悪いのかそもそも現在のAPI認証に対応していないのか
WWW::Facebook::API が動かなかったんですよねー。


というわけで動くまで頑張ってみたメモ。
今回は Facebook上で動くアプリ を対象にしています。



FacebookAPI認証

http://developers.facebook.com/docs/guides/canvas/#auth
このドキュメントとWWW::Facebook::APIのexampleとWWW::Facebook::API::Canvasのソースをにらめっこしてみると、
そもそもWWW::Facebook::APIの認証方式は現在対応してないっぽいのでは?という結論に。

Facebook.pm

cpanにはそのものズバリFacebookというモジュールも存在しており、
podを見てみると認証部分とWWW::Facebook::API/Facebook::Graphのラッパーになっているようです。
ただし、ドキュメントがまだ整備されていないようだし
まだリリースされて間もないのでα版っぽい気もします。


で、このFacebookアプリのソースを追っかけてて気付いたのですが、
Facebook::Signed というモジュールが
http://developers.facebook.com/docs/guides/canvas/#auth
の認証に対応しているっぽい。


上記ドキュメントのPHPのソースをperlに置き換えるとこんな感じになりますでしょうか。

#!/usr/local/perlbrew/bin/perl
use strict;
use CGI;
use Facebook::Signed;
use URI::Escape qw(uri_escape);
my $q = new CGI;

my $app_id      = "app_id";
my $canvas_page = "canvas_page";
my $secret      = "secret";

my $auth_url = "http://www.facebook.com/dialog/oauth?client_id=" . $app_id . "&redirect_uri=" . uri_escape($canvas_page);

my $signed;
my $signed_request = $q->param('signed_request');
if($signed_request){
    $signed = Facebook::Signed->new(
        canvas_param => $signed_request,
        secret => $secret,
    );
}

print $q->header;
if ($signed) {
    print "Welcome User: " . $signed->get('user_id')."\n";
}else{
    print "<script> top.location.href='" . $auth_url . "'</script>";
}


$signedが取れると $signed->get('oauth_token') でアクセストークンを取得できるので
これを使ってREST APIをほげほげできます!

my $access_token = $signed->get('oauth_token');
my $furl = Furl->new;
my $notifications = $furl->get("https://api.facebook.com/method/notifications.get?access_token=$access_token&format=json");

access_tokenを使ってWWW::Facebook::APIを使いたい

WWW::Facebook::APIに以下のようなパッチを当てて
毎回access_tokenを送るようにすれば使えます。

@@ -212,9 +213,13 @@
         params => $params,
         secret => delete $params->{'secret'},
     );
+    my @params = ();
+    push @params, $_ . '=' . $args{$_} for keys %args;
+    push @params, 'format=json';
+    my $uri = "https://api.facebook.com/method/".$method."?". join("&", @params);
 
-    $response = $self->_post_request( $params, $sig, $raw_data, $filename );
-
+    $response = $self->ua->get($uri)->content;
+    # $response = $self->_post_request( $params, $sig, $raw_data, $filename );
     carp $self->log_string( $params, $response ) if $self->debug;
     if ( $self->_has_error_response($response) ) {
         if ( $self->throw_errors ) {

ただし無理に使うことはないでしょう。

結論

いろいろ面倒なので Facebook::Graph を使いましょう。

*1:自分なわけですが