読者です 読者をやめる 読者になる 読者になる

ゆーすけべー日記

はてなBlogってどーなの!?

自分のWallにポストするFacebookアプリを簡単に作る

Facebookやっていると飯どきの時間に空腹な人をターゲットとしてotsuneさんとかが、 焼肉の画像とかを貼付けて攻撃をしてきます。 これを画像爆撃と呼びます。 そこで、Facebook上でGoogleの画像検索を行いすぐに自分のWallにその画像をポストできれば、 こうした画像爆撃が簡単になると思い、 「画像検索爆撃」というFacebook上で動くアプリケーションを作ってみました。

Facebook | 画像検索爆撃

参考資料 - Facebook開発者」。 ここの資料にある「Applications on Facebook.com」ってやつですね。 Facebookの公式ドキュメント、APIの仕様は読みやすいのですが、 例の記述が少ない部分があって試し試しでやらんといかんとです。

「Facebook上のアプリケーション」にはFBML/FBJSで組むタイプとページをiframeでFacebook.com上で読み込ませるタイプ2種類あります。 今回はjQueryを使ったJSオンリーで済ませようと思ったのでiframeで読み込ませるようにしました。 JSのAPIだけで認証及びWallへのポストができちゃうんで、 基本的にjs含むHTMLさえあればアプリケーションは完結します。

Facebook上でのアプリケーションの登録とかの仕方はめんどくさいんで省きます。 自分で調べてください。というかFacebook上でいじってればなんとなくわかります。

肝心なのはJSでFacebookのWallへ投稿するところです。 もっと詳しく言えば、指定した画像の添付付きで投稿するプロンプトを出すことです。 これは、ログインさえ済んでいれば、以下のコードでいけます。

var publish = {
    method: 'stream.publish',
    message: 'デフォルトのメッセージ',
    attachment: {
        name: //添付ファイルの名前,
        href: //添付ファイルのとび先URL,
        media: [
            {
                type: 'image',
                href: //画像のとび先URL,
                src: //画像のソースURL
            }
        ]
    },
    user_prompt_message: 'プロンプトのメッセージ'
};
FB.ui(publish);

FB.uiメソッドに{ method: 'stream.publish' }をはじめとしたハッシュを渡しているという感じです。 これを例えば画像をクリックした際に画像のプロパティを引き継いで発火させればいいのです。 ちなみにこのattachmentには mp3、swf も指定できます。

画像の検索部分は特にFacebook向けに工夫することなく、 GoogleのAPIを通常のJSON処理と同じように叩いています。

ということで全ソースコード71行を貼付けておきます。

var currentPage = 1;
var currentQuery = '';

$().ready(function(){
    FB.init({
        appId  : 'xxxxx',
        status : true,
        cookie : true,
        xfbml  : true
    });
    FB.getLoginStatus(function(response) {
        if (response.session) {
        } else {
            FB.login(function(response) {}, {perms:'publish_stream'});
        }
    });
    $('#form').submit(function(){
        var query = $("#query").val();
        searchImage( query );
        return false;
    });

});

function searchImage(query){
    if( query == currentQuery ){
        currentPage++;
    }else{
        currentPage = 1;
        currentQuery = query;
    }
    var start = ( currentPage - 1 ) * 8 ;
    var jsonURL = 'http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=large&q=' + query + '&start=' + start + '&callback=?';
    $.getJSON(jsonURL,function(json){
        if(json.responseData){
            showImage(json.responseData.results);
        }
    });
}

function showImage(items){
    jQuery.each(items,function(){
        var img = $('<img/>').attr('src',this.tbUrl);
        var a = $('<a/>').attr('href','#');
        a = setAnchor(a, this);
        $('#result').prepend(a.append(img));
    });
}

function setAnchor(a,item) {
    a.click(function(){
        var publish = {
            method: 'stream.publish',
            message: '',
            attachment: {
                name: item.contentNoFormatting,
                href: item.unescapedUrl,
                media: [
                    {
                        type: 'image',
                        href: item.unescapedUrl,
                        src: item.tbUrl
                    }
                ]
            },
            user_prompt_message: '自分のWallへポストする'
        };
        FB.ui(publish);
    });
    return a;
}