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

FBMLに触ってみる

Facebook Django

FMBLについては、以下のページを参照。

詳しくは上のページや、前述した「FBMLとiframeの違い」のページに書いてあるが、とりあえずは、「Facebookのルックアンド&フィール、ユーザーエクスペリエンスに統合されたUIを実現するための専用マークアップ言語」と理解した。

単純なFBMLのテストには、専用のテストツールがあるので、自分のサーバーでアプリケーションを書いてみるまでもない。

例えば、このFBML Test Consoleで、

<fb:name uid="1" useyou="false" />

のように入力すると、Previewには、

Facebook User

と表示される。FBMLでは、このfb:nameのようによく使われるコンポーネントを定義している。

単に情報を表示するだけのコンポーネントはテストコンソールで試すことができるのだが、ユーザ入力を受け付けて何かをイベントを発生させるタイプのコンポーネントはテストコンソールでは挙動がつかみきれないので、自分でコードを書くことにする。

fb:request-form, fb:multi-friend-selectorを使う

高度に訓練されたFacebookアプリケーション開発者は、自分自身のコンポーネントJavascriptライブラリとかASライブラリとして持っているらしくFBMLを使わないのかもしれないが、「複数の友達を選択して、その友達に対して何らかのアクションを行う。しかも友達一覧はグループごとにフィルターできたりする」みたいなUIを実現するのは、かなりの労力がいる。

具体的には、次のようなUI, コンポーネント

Flashをバリバリ使ってアプリケーションを作っているPlayfishですら、このコンポーネントを使っているので、まずこのコンポーネントを使ってみる。

使ってみるといっても、このページにあるpyfacebook+Djangoの例に手を加えて挙動を確認するだけだが。

まず、fb:multi-frined-selectorを呼び出すビュー関数。

@facebook.require_login()
def invite_friends(req):
    # HTML escape function for invitation counter
    from django.utils.html import escape

    if req.method == 'POST':
        print req.POST

    facebook_uid = req.facebook.uid
    fql = "SELECT uid FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1='%s') AND is_app_user = 1" % facebook_uid
    result = req.facebook.fql.query(fql)

    # extract the user ID's returned in the FQL request into a new array
    if result and isinstance(result, list):
        friends_list = map(lambda x: str(x["uid"]), result)
    else:
        friends_list = []

    # Convert the array of friends into a comma-delimeted strings.
    exclude_ids = ','.join(friends_list)

    # Prepare the inviatation text that all invited users will receive.
    content = u"""<fb:name uid="%s" firstnameonly="true" shownetwork="false" />ここに送信メッセージの説明が入ります <fb:req-cho\
ice url="%s" label="リクエストを送信" />""" % (facebook_uid, req.facebook.get_add_url())

    invitation_content = escape(content)

    ctxt = RequestContext(req,
                          { 'content': invitation_content,
                            'exclude_ids': exclude_ids,
                            })
    return render_to_response('facebook/invite_friends.fbml', ctxt)

そして、テンプレート"facebook/invite_friend.fbml"を用意する。

<fb:request-form
  action="http://apps.facebook.com/yourapp/invite_friends/"
  method="POST"
  invite="true" type="Online Games" content="{{ content }}">
  <fb:multi-friend-selector max="20"
      actiontext="ここにモーダルウィンドウの説明が入ります"
      showborder="true"
      rows="5"
      exclude_ids="{{ exclude_ids }}">
</fb:request-form>

その上で、"http://apps.facebook.com/yourapp/invite_friends/"が上記のinvite_friends関数にルーティングされるようにurls.pyを変更する。

試してみたところ、上記のコンポーネントで選択したユーザにNotificationを送った後、サードパーティ側にPOSTで結果が通知されるようだ。アプリケーション側では招待したユーザと、招待が送られたユーザのIDを取得できるので、この値を利用して、以降の新規ユーザ登録に特別な処理(招待したユーザを自分のコミュニティ/グループ/チーム等に加える)を加えればよい。

OpenSocialでも、opensocial.requestSocialAppのコールバック関数を利用すれば同じことができるはずであるが、このopensocial.requestSocialAppのコールバック関数のスペックを調査しきれていないので、これ以上のことは書けない。


このコンポーネントを使えば、友達に招待メールが送ることができるはずだと思って試していたら、「一日の招待可能数を超えました」的なエラーでメッセージを送ることができなくなってしまった。こういうところも、Facebookはちゃんとしてるよねぇ。