アジアで一番Facebookアプリを作った男の教えるFacebookアプリの作り方

こんにちは。
最近、坊主が伸びてきて某SFマンガのネギ星人に似ていると言われたWebエンジニア山下です。
坊主の時は、進撃する巨人に似ていたことから、「SF男子」などと囁かれていたようです。

元坊主の私は、主に、診断ペアーズと測驗派愛族(台湾版診断ペアーズ)の開発をしています。

最近では、pairsの高速化や安定化まで担当し、「pairsの成長において、山下は不可欠」なはずなのですが、なぜかエウレカの人々は私の扱いが雑なのが最近の悩みです。

参考:今日から始めるfluentd × Elasticsearch × kibana – カジュアルな解析・高速化

さて、今回は、あの有名な「アジアで一番Facebookアプリを作った男」について、話をしたいと思います。

Facebookアプリとは?

まず、「Facebookアプリ」と聞くと、皆さんどのようなものを思い浮かべるでしょうか?

Facebookアプリと言ってもコンテンツ内容は多種多様で、共通しているのは「Facebookの情報を利用した、Facebookユーザーの為に作られたアプリケーション」ということです。
今回「アジアで一番Facebookアプリを作った男」の話で登場するのは、『診断ペアーズ』のような、Facebookのタイムライン上で楽しめる「診断系アプリ」です。

皆さんも一度は以下のような投稿を、友達のタイムラインで見たことはありませんか?

 

wall

 

このように、アプリで遊んだ結果や内容を自分のタイムラインに投稿することで、Facebook上でどんどん拡散するところが、この診断系アプリの特徴です。

Facebookアプリの開発

ところで、皆さん、そろそろ気になっている頃だと思います。

「アジアで一番Facebookアプリを作った男」って一体誰なんだ?と。

実は、何を隠そう私、山下のことなのです(もちろん自称です)。

ブログを書くに当たって数えてみたのですが、この一年間で194個ものFacebookアプリを開発していました。
194という数字がどれほどすごいかというと、ブラジル出身力士・魁聖の身長が194cmです。

 

ということで、ここからは「アジアで一番Facebookアプリを作った男(自称)」のテクニックを少しだけご紹介させていただきます。

アジアで一番Facebookアプリを作った男(自称)の開発手法

診断系アプリを作るには、Facebookが用意しているSDKを使います。
私が作ったFacebookアプリはすべてWeb版のみです。
使うSDKはJavaScriptとPHPの両刀使いです。

用途は、それぞれ以下に説明します。

JavaScript SDKではログイン認証を行います。

[ Facebook JavaScript SDK によるFacebookログイン認証サンプル ]
// javascript

var perms = ‘user_likes,user_birthday’;
FB.getLoginStatus(function(response) {
  if (response.status === 'connected') {
    // ログイン成功 (response.authResponse.accessToken)
  } else {
    FB.login(function(response) {
      if (response.status === 'connected') {
        // ログイン成功 (response.authResponse.accessToken)
      } else {
        top.location.href='https://www.facebook.com/';
      }
    }, {scope: perms});
  }
});

 Facebookアプリ開発者にはおなじみのFBオブジェクトですね。

 

初めての方向けに簡単に説明すると、Facebook JavaScript SDKをロードすると、
グローバルスコープで”FB”というオブジェクトが使用可能になります。
Facebookのユーザーデータの取得やFacebook内でのiframe位置取得といった、
Facebookに関連する様々な処理は、このオブジェクトを使って行っていきます。

上記のコードにはないですが、FBオブジェクトはJavaScript用のFacebook SDKを読み込んだ後に実行しなければいけないので、「window.fbAsyncInit = function() { [ココ] }」の[ココ]に入れるようにしましょう。

 

〜Facebook認証の流れ〜

  1. FB.initでFBオブジェクトをセットアップします。
  2. FB.getLoginStatusでログイン済みかどうか確認
  3. 未ログインの場合はFB.loginでポップアップ表示

※2と3でログイン済みやログイン成功の場合はレスポンスの “authResponse.accessToken” でアクセストークンを取得できます。

ここまででJavaScript SDKの出番は終わりです。

PHPのSDKでFacebookのユーザー情報を取得する

[ Facebook PHP SDK ]
// PHP

$config = array(
  'appId' => アプリID,
  'secret' => アプリSECRET_ID
);  
$this->facebook = new Facebook($config);

//JavaScript SDKで取得したアクセストークンを受け取る
$access_token = $_POST[‘access_token’];
//受け取ったアクセストークンをセット
$this->facebook->setAccessToken($access_token);
$me = $this->facebook->api('/me', array('fields' => 'id,name,gender,birthday,first_name,last_name'));

ここがPOINT 「ログイン認証はJavaScriptのSDK!」


 

PHPのログイン認証はセッションで整合性が保てない場合があるので、 JavaScriptでアクセストークンを取得し、そのアクセストークンをサーバに渡してPHPのSDKでsetAccessToken()をする。

こうすることで安定したアプリのワークフローを保つことができます。
また、JavaScriptのログイン認証はポップアップを選択できるので、無駄に画面遷移をさせずにユーザービリティも良くなりますね。

Facebook APIを使ったフィード情報の取得

今回は具体的に「いいね!グランプリ」という非常に面白いアプリで説明していきたいと思います。

いいね!グランプリ」とは、

ユーザーの一年間のFacebookでの投稿を解析し、投稿に「いいね!」をしてくれた人を多い順にランキング表示するアプリです。

このアプリの開発POINTは3つ。

POINT1 ユーザーが過去一年間に投稿した全ての情報をFacebook APIから取得する。

[ batchリクエストで一気に情報を取得する ]
// PHP

$now = date('Y-m-d')[
$since = date('Y-m-d', strtotime('-1 year'));
$until = $since;
$timeflag = false;
while($timeflag == false) {
    $until = date('Y-m-d', strtotime($until.' +8 days'));
    if ($until > $now) {
        $until = $now;
        $timeflag = true;
    }   
    $requestArray[] = array(
        'method'=>'GET',
        'relative_url' => urlencode('/'.$fbid.
            '?fields=feed.fields(likes.limit(300),privacy).limit(500).
            since('.$since.').until('.$until.')&locale=ja_JP'
        )
    );
    $since = date('Y-m-d', strtotime($until.' +1 days'));
}

$response = $this->facebook->api('/?batch='.json_encode($requestArray), 'POST');
$feeds = array();
foreach($response as $value) {
    $body = json_decode($value["body"], true);
    $feeds[] = $body;
}

大量のデータをとってくる場合はbatchリクエストというものを使えば一回のリクエストで高速に取得ができます。

また、「.limit()」を適切につけてあげることで、データ量が制限されずに正しく取得できるのです。

POINT2 結果を集計する。

※投稿範囲を「自分のみ」に設定しているものや、グループへの投稿は除外(アプリによってユーザーの秘匿な情報が漏れてしまうのを防ぐため)

→今回の「いいね!グランプリ」では「いいね!」しているかどうかだけなので必要ないですが、ユーザーのフィード情報をアプリで使うときはこの部分は十分に注意しましょう。

[ Facebook からのレスポンスを解析する ]
// PHP

$likes_count = 0;
$best_friends = array();
foreach($feeds as $feed) {
    // feedが配列じゃない場合はスキップ
    if (!is_array($feed)) continue;

    // feed内容が存在しない場合はスキップ
    if (!array_key_exists('feed', $feed)) continue;

    foreach($feed['feed']['data'] as $article) {
        // 公開範囲が適切で無い場合はスキップ
        if (!permissionCheck($article)) continue;
        // いいね!がない場合はスキップ
        if (!array_key_exists('likes', $article)) continue;

        foreach($article['likes']['data'] as $person) {
            if (array_key_exists($person['id'], $best_friends)) {
                $best_friends[$person['id']]['like']++;
                $likes_count++;
            } elseif ($person['id'] != $me['id'] && array_key_exists('name', $person)) {
                    $best_friends[$person['id']]['like'] = 1;
                    $best_friends[$person['id']]['name'] = $person['name'];
                    $likes_count++;
            }
        }
    }
}

// いいねしてくれたのが多い順に並び替え
foreach ($best_friends as $key => $value) {
  $key_id[$key] = $value['like'];
  $best_friends[$key]['id'] = $key;
}   
if (isset($key_id)) {
  array_multisort($key_id, SORT_DESC, $best_friends);
} 

// 公開範囲をチェックする関数
function permissionCheck($article) {
  if (array_key_exists('privacy',$article)) {
    if (array_key_exists('description',$article['privacy'])) {
      if ($article['privacy']['description'] == '公開' || $article['privacy']['description'] == '友達') {
        return true;
      }
    }
  }
  return false;
}

ネストが激しくてなんとも見苦しいコードになっていますが、Facebookの情報は人によって様々なので、 長年の時を経て上記のようなものになりました。 キーが存在するかちゃんとチェックする、ということがポイントです。

POINT3 結果出力

wall

 

出ました。上位はエウレカメンバーが独占しています。

私のことを好きな順ランキングですね。

備考:API 1.0をつかっているので全員でますが、API 2.0に切り替えるとアプリを認証している人達のみでるようになります。

分速で開発できるスキームを用意する

194個も作っていると、リリース10分前にデザインがあがってきたり、 一日に6つリリースが重なったり、と色々なことがありました。

それを解決した唯一の方法とは”コードのモジュール化”です。

 

◇占い系のアプリならA

◇相関図系のアプリならB

◇検定系のアプリならC

◇ゲーム系のアプリならD

 

これら全てのスキームを一つのプロジェクトでまとめて管理することによって、 「引き出しからモノを取り出すイメージ」で、ぽんぽんアプリを作っていくことができます。

エウレカではこの引き出しプロジェクトを「FacebookAppKit」と呼んでいます。

これを使えば誰でも簡単に分速でアプリが作ることが出来るので、 定期的に社内のディレクター、デザイナー、エンジニアをチーム分けして「 Facebookアプリハッカソン大会」なんてこともやったりします。

ココがPOINT: 開発はスピード勝負!


 

Facebookアプリはどれだけ早くリリースできるかがヒットすることにおいて結構キモだったりします。

最短で無駄なく開発できる環境さえ整っていれば、あなたも、この山下を飛び越えて、「世界で一番Facebookアプリを作った人」を目指せるかもしれません。

 

Facebookアプリの運用

先日発表されたFacebook API 2.0では、開発者泣かせな項目がいくつか追加されました。

しかし、きちんとルールを守り、Facebookユーザーの為に、という意識を持つことで、 一日に100万人以上のユーザーが使うアプリが簡単に作れるのです。

Facebookというソーシャルメディアの中だからこそ、プロモーションを一切せずとも、ユーザーからユーザーに拡散していき、リアルタイムはうなぎ上り、GAを見ながらニヤニヤできます。

あるアプリの2ヶ月間のユーザー数遷移

GA_graph

 

このアプリはすごかったです。
最初の波でユーザー数が170万人を超えています。
ユーザーは一瞬でドバっとやってきて、パタっとはいなくなります。
ピーク時には、てんやわんやしながらも、サーバー台数は20倍、15秒でサーバーを起動する術が身に付けることができました。

こんな経験からオススメのサーバー構成は以下です。

 

FacebookAppServer

すみません、オススメとか言っておきながら、至ってシンプルです。
アプリケーションはデータベースレスで構築するのはマストですね。
また、安定稼働時はオートスケーリング設定をしておくと便利です。

【AWSのオートスケーリングをコンソールから設定する】

① EC2のコンソール画面左下のAUTO SCALINGタブのLaunch Configurations作成

EC2を立てるときと同様にAMIを選択したあと、ストレージやセキュリティグループを指定して完了です。

② Auto Scaling Groupsを作成します。

①で作ったconfigrationを指定して、ネットワークやサブネットを指定します。

③ Scaling Policiesを設定します。

aws

ココがPOINT: やばい時は一気に増やし、減らすときは緩やかに

“Scaling Policies”とは、簡単に言えば「増やす時と減らすときのルールを決めておくこと」です。
画像はサンプルですが、増やすときはインスタンスのCPUが60%以上になったら/次の判定は120秒後減らす時はインスタンスのCPUが10%以下になったら/次の判定は300秒後、といった感じです。Facebookアプリのアクセスは一気に来ます。
びっくりするくらい急にCPUが100%にはりついてしまいます。

なので、増やすときは躊躇せず一気にいき、減らす時は余裕をもってスケーリングするようにすると良いです。

今後のFacebookアプリ

今回の記事ではアプリ開発の初歩的な話ばかりでしたが、 エウレカには、先日プレスリリースを出したように、「Facebookページのいいね!数800万を獲得できるマーケティングの実績」があります。

そのあたりの話は、いつかエウレカディレクターズブログで語られることを期待していますが、 バイラルメディアがSNSのタイムラインを席巻している世の中で、「どうすれば多くのユーザーに使ってもらえるFacebookアプリを企画できるか」も重要になっています。

(私も、仕事中にタイムラインを眺めていると、面白い動画や記事が流れてきてついつい見てしまい、一日が終わってしまっていることがほとんどです。内緒ですよ)

ただ、診断系アプリは人によって結果が異なり、単なるメディアよりもユーザーが主体になるので、ユーザーシェアからの拡散力には無限大の可能性を秘めていると思います。

ユーザーが主体的であるからこそ、そこからアプリの結果によって新たなコミュニケーションが生まれるので、今までにないFacebookアプリの形を常に模索しながら、僕はこれからもFacebookアプリを作り続けます。

リアルタイムアクセス2万を越えるサービスを開発、またはサーバ運用してみたい方、ぜひコチラからご連絡ください。