プラットフォームとして台頭して来た Facebook
2010.12.27
週末はクリスマス休暇でロスに住む長男が遊びに来ていたのだが、金曜日の朝になって面白そうなFacebookユーザー向けのサービス案を提案して来たので、さっそく作ってみた。24日にはクリスマスパーティもあったし、テニスも毎朝していたので、正味プログラミングをしていた時間は30時間ぐらいしかなかったのだが、発案からわずか3日でサービスがローンチできてしまうとは(Google App EngineとFacebook APIのおかげ)、ずいぶんと便利な時代になったものだ。
日本ではまだまだだが、米国では人口の7割以上がアカウントを持つと言われるFacebook。Twitterでの不特定多数向けの「つぶやき」よりも、友達・知り合い間での「プライベートなコミュニケーション」向けのFacebookは、どちらかと言えばmixiに似ている。mixiとの根本的な違いは「大人も使っている」点。
特に最近は、「プラットフォーム」としてのAPIを充実させて来ており、簡単なソシアル・ネットワーク・アプリを作るのであれば、Facebook APIを使った方が、アカウントの管理も楽だし、「フレンド・ネットワーク」にもアクセスできるし、Wall(自分専用の掲示板のようなもの)にメッセージをポストすることによりバイラル・ネットワーク効果も狙える、という一石三鳥のすぐれものだ。
今回作ったもの(Facebookアカウントを通じたネットワーク効果の測定中なので、まだここにはURLを公開しない)は、まさにそんなアプリの典型。Facebookアカウントでログインしてもらうと、Facebook APIを利用して友達のリストを取得し、その友達との間の「遊びの場」を提供する。この仕組みを使うと、Facebookの中と同じように「友達間に限定したコミュニケーション」をFacebookの外に簡単に築くことができるのがすばらしい。
ちなみに、このサービスは最近だいぶ慣れて来たGoogle App Engine上に作った。特にフレームワークのようなものは使わず、今まで作って来たアプリのコードをあれこれと再利用しながら構築したのだが、とにかくユーザー認証の部分を100% Facebook API に頼れるというのが何とも楽。クローズなアプリなのでSEOの必要もないので、データはすべて json over HTTP で取得して、JavaScript側でHTMLを生成するという方法で構築。
このアーキテクチャ(ユーザー認証はFacebookにまかせ、Google App Engine上にPythonで json over HTTP なAPIを構築し、JavaScript側でUIの生成)だと、ものすごく開発効率が高い(一度ちゃんとした解説本でも書きたいのだが、時間が...)。
Facebook APIがプラットフォームとしてどのくらい使い勝手が良いかを示すために、このアプリのソースコードを一部公開する。
まずは、「フレンド・リスト」を取得したのち、このサービス内にアカウントを持っている人のIDだけを抜き出す部分。
gdispatch.route(lambda: ('/api/friend/list', FriendListHandler))
class FriendListHandler(webapp.RequestHandler):
@login_required
def get(self):
graph = facebook.GraphAPI(self.current_user.access_token)
connections = graph.get_connections("me", "friends")
if not connections:
return self.response.out.write('{"success":false, "errors":["failed"]}')
friends = connections["data"]
ids = ['fb:%s' % friend['id'] for friend in friends]
users = User.get_multi(ids)
result = ','.join('"%s"' % user.id for user in users)
self.response.out.write('{"success":true, "result":[%s]}' % result)
login_requiredは私が作ったFacebookアカウント専用のデコレータで、ここでユーザー認証をしている(認証済みのユーザーオブジェクトは self.current_user に格納される)。そしてfacebook.GraphAPIで認証したユーザーのアクセストークンを使ってアカウントに紐づいたAPIオブジェクト(graph)を取得し、次の行で「自分("me")のフレンドリスト("friends")」を取得している。
ユーザーに代わって Wall にメッセージを書き込むのもとても簡単。
gdispatch.route(lambda: ('/api/comment/submit', CommentSubmitHandler))
class CommentSubmitHandler(webapp.RequestHandler):
@login_required
@gdispatch.kwargs
def post(self, message):
graph = facebook.GraphAPI(self.current_user.access_token)
graph.put_wall_post(message)
self.response.out.write('{"success":true}')
今になって考えてみると、Microsoftがいっとき力を入れて広めようとしていた Microsoft Passport(今は Windows Live IDと呼ばれている)は、まさにこんな風に他のウェブサービス向けの「ユーザー認証プラットフォーム」になることを狙っていたもの。大風呂敷を広げた割には市場に全く受け入れられず、いつのまにかベンチャー企業のFacebookにこんな大切な部分を持って行かれてしまったとはなんとも皮肉なものだ。
しかし、少なくともMicrosoftはFacebookの株主である点が救い(Microsoftとしては買収をしたかったが、Facebook側が拒否したので、しかたがなく投資をしたというのが一般的な解釈)。Facebookのプラットフォームとしての台頭が許せないのはGoogleだろう。GoogleもGoogleアカウントという仕組みを持ってはいるが、プラットフォームとしては全く不十分だし、Google WaveにしろGoogle Buzzにしろ、FacebookやTwitterに対抗しようというGoogleの試みはことごとく失敗している。Googleとしては、例によって「(facebookみたいなクローズドなものではなくて)オープンなOpenIDを使おう」という作戦に出て来ているが、今後どうなるかは何とも言えない。
私のように利害関係を持たない第三者は、とにかく開発効率を重視するので、対立関係にあるGoogleとFacebookそれぞれのプラットフォームを組み合わせてアプリを作ったりできるので、それはそれで痛快だったりする。
できるだけ早く立ち上げてみたいサービスがあるので、この辺りの技術に大変興味があります。是非ご教授願えますでしょうか。
Posted by: Kazuki Sekiya | 2011.01.02 at 04:57