https://developers.facebook.com/docs/opengraph/actionlinks/

オープングラフアクションは、ユーザがアプリ内で取る高レベルなインタラクションです。これらのアクションが投稿されると、アクティビティはユーザのタイムラインと、友だちのニュースフィードやリアルタイムフィードに表示されます。

アクションリンクはいいね!とコメントの横に表示され、友だちは流れてきた投稿から離れること無く、レスポンスとしてアクションを取ることができます。これにより、より少ないクリックでより多くのディストリビューションを持つことができます。


アクションクリックが設定されているアクション投稿


attachment


クリック後


attachment2


アクションリンクは、ビルトインアクションカスタムアクションに対して設定できます。ユーザがアクションを取り、そのアクションに対する投稿をすると、アクションリンク付きの投稿がユーザのタイムライン,友だちのニュースフィード,リアルタイムフィードに流れます。

ただし、アクションリンクはモバイル端末には表示されないことに気をつけてください。

このドキュメントでは、以下の内容をカバーします。

  • 動作: アクションリンクを表示するためのフロー
  • 設定: アクションリンクの設定
  • 実装をテストする: アクションリンクの実装をデバッグする最良の方法
  • FAQ: よくある質問と、デバッグのコツ
  • サンプルコード: アクションリンク投稿のサンプル

How It Works

ここでは例を示しつつ、アクションリンクの挙動と実装のポイントを紹介します。

Example Flow

ここで紹介する例は、「ユーザがレシピを料理する」アクションを用いる料理アプリです。これを用いて、アクションリンクの投稿とそのフローを紹介します。

  1. ユーザ1がアプリ場でアクションを実行し、「レシピを料理」します。アプリはアクションリンクを通じてユーザがレシピを「保存」できるようにします。これは、ユーザはレシピを料理したり保存できると言う事実に基づいています。
  2. ユーザ2はユーザ1が「レシピを料理した」投稿を見ます。その投稿中には、いいね!やコメントと並んで、「レシピを保存する」という文言が表示されています。
  3. ユーザ2が「レシピを保存する」をクリックすると、Facebookはユーザ2がアプリをインストール済みかチェックします。

    • インストール済みの場合: FacebookはApp Dashboardのアクションリンク設定で指定したエンドポイントを呼びます。この呼び出しではsigned_requestパラメータが渡され、それには以下のデータが含まれています。

      • ユーザ2のアクセストークン
      • ユーザ2のuser_id.
      • 以下の形式のアクションの型<APP_NAMESPACE>:<ACTION>.
      • アクションID(オプション)
      • オブジェクトのURL
      • 以下は、signed_requestの例です。

          {
             "objects": [
                {
                   "url": "http:\/\/www.sugarmedia.com\/nyccookbook\/pizza.html"
                }
             ],
             "action_link": {
                "type": "nyccookbook:save"
             },
             "actions": [
                {
                   "id": "3936222850404"
                }
             ],
             "algorithm": "HMAC-SHA256",
             "expires": 1335830400,
             "issued_at": 1335823862,
             "oauth_token": "12345678901234567890",
             "user": {
                "country": "us",
                "locale": "en_US"
             },
             "user_id": "621273"
          }
        
    • インストールされていない場合:Authenticated Referralsの設定に基づいてユーザ2はリダイレクトされます。

      • Enableになっている場合、ダイアログが表示されてアプリをインストールするよう促します。インストール完了後、ユーザ2はオブジェクトURLへとリダイレクトされます。.
      • Disableになっている場合、ユーザ2はオブジェクトURLへとリダイレクトされます。
      • オブジェクトURLへ遷移したとき、以下のデータが渡されます。
        • fb_action_idsパラメータでアクションIDが渡ります。
        • fb_action_link_typeパラメータで、<APP_NAMESPACE>:<ACTION>形式でアクションの型が渡ります。
  4. アクションリンクを扱うエンドポイントは、"success=>true"もしくは"redirect=>"のいずれかのメッセージを返すことができます。  
    • "success=>true"の場合
      1. ユーザ1が投稿したのと同じオブジェクト(レシピ)に対して、このエンドポイントはユーザ2の代理としてsaveアクションを投稿します。
      2. その後、JSONエンコードされた"success"メッセージを返します。
      3. ユーザ2には、"レシピを保存する"だったアクションリンクが「保存されました(saveアクションの過去形として定義されたもの)」に変更して表示されます。
      4. 注意:ユーザが投稿をリロードしたり再度閲覧した場合、すでに「保存」アクションが投稿されているため、「レシピを保存する」のアクションリンクは表示されません。
    • "redirect=>http://www.myserver.com/somepage"の場合
      1. エンドポイントは、ユーザ2がアプリをインストールするように、もしくはアクションに関する他の情報を表示するために、ユーザ2をFacebookから他のページに対してリダイレクトすることができます。これを行うには、エンドポイントは、JSONエンコードされたredirectメッセージとrecirect_urlを返します。
      2. ユーザ2にはダイアログが表示され、アプリに遷移してプロセスを続行することができると示されます。ユーザはFacebookに留まることが期待されているため、このフローはエラーとして扱われます。


attachment3


Suppressing Action Links

App Dashboardでアクションリンクを設定している場合、任意のアクション投稿時にno_action_link=trueパラメータを指定することで、アクションリンクが表示されないように設定することができます。

Integration Points

これらは、アクションリンクを適切に扱う上で必要となるステップです。

  • App Dashboardでアクションリンクを設定する
  • アクションリンクのクリック時に呼び出されるエンドポイントの実装
  • オプションとして、Authenticated Referralsの設定(アプリ未インストール状態でアクションリンクをクリックしたユーザに、まずインストールしてから続行させたい場合)。

アプリ設定のステップとサンプルコードを以下で紹介します。


Configuration

App Dashboardを使って、任意のアクションに他のアクションが伴うようにアクションリンクの設定をします。

  1. まだアクションが用意されていない場合、アクションリンクに使うアクションを用意します。先ほどの例であれば、save(保存する)アクションです。
  2. メインとなるcook(料理する)アクションをsaveと繋がるようにします。Advancedセクションを選択し、Linked Actionフィールドにsaveを入力してください。
  3. アクションリンクを扱うエンドポイントの情報を入力します。このエンドポイントが、アクションリンクのクリック時に呼ばれることになります。このURLはアプリのドメインと一致し、なおかつhttps://で始まるものでなくてはなりません。cookアクションのAdvancedセクションにあるAction Link URLに、そのURLを入力します。

attachment4


Imperative Tenseの項目を変更したい場合があるかもしれません。デフォルトでは現在形の動詞と同じ設定になっています。先ほどの例であればsaveですので、ここは変更しません。


attachment5


注意:すでにアクションがサブミットされ、Facebook Platformによって許可されている場合、Imperative Tenseの設定は現在形の動詞と同じものになっていて、変更できません。


Testing Your Implementation

  1. アクション,imperative tense,エンドポイントが設定されていれば、テストを開始することができます。
  2. まず、設定済みのアクションを投稿してください。
  3. 投稿したのと同じ開発者アカウントで自分のプロフィールを開き、Activity Logを見ます。
  4. 投稿した内容が表示されますので、タイムスタンプをクリックし、ニュースフィード上での表示の体裁を確かめます。
  5. いいね!,コメント,フォローをやめるの横にアクションリンクが表示されていることを確かめます。
  6. アクションリンクをクリックし、設定したエンドポイントが呼ばれるのを確かめます。
    1. サーバ側でJSONエンコードされたsuccessメッセージを返します。
    2. 先ほどの投稿を見ると、アクションリンクの文言が過去形に置き換わっています。
    3. 開発者アカウントであれば、エンドポイントか返り値で問題があった場合、エラーメッセージが表示されます。

Re-Testing

  • 任意のオブジェクトのアクションリンクをクリックした後は、該当ユーザにはアクションリンクが表示されなくなります。テスト中、アクションリンクを再度使えるようにするには、アクションリンク投稿のaction_idを見つけ出し、https://graph.facebook.com/<action_id>に対してHTTP DELETEリクエストを投げます。それ以降ページをリロードすると、アクションリンクは再度表示されているはずです。
  • 先ほどのサンプルであれば、"cooked a recipe"に対する"saved a recipe"投稿にDELETEリクエストを投げることになります。

Frequently Asked Questions

Q: アクションリンクをクリックしたときにアクション投稿をしなかったらどうなりますか?
A: ユーザがアクション投稿を見るとき、毎回アクションリンクが表示されます。ちゃんとアクション投稿をしてこれを止めない限り、ユーザにとって悪いアプリ体験となってしまいます。

Q: アクションリンクはモバイルのニュースフィードにも表示されますか?
A: まだ実装されていませんが、すぐにできるようになります。

Q: アクションリンクからの投稿で要約表示はできますか?
A: はい、アクションリンクからの投稿も通常のアクション投稿と全く同じものですので、同様のプロパティや要約を用いることができます。

Q: httpsで始まるエンドポイントが必要ですか?
A: sandboxモードではない場合に必要です。まだ開発中でsandboxモードがオンになっている場合なら、http://でも大丈夫です。


Sample Code

以下にアクションリンクのエンドポイントに用いるサンプルコードを示します。データを受け取り、recipeオブジェクトを保存するアクションを行います。最後にはsuccess=>trueをJSONエンコードして返しています。

<?php

  $app_id = 'APP_ID'; // Your app Id
  $app_secret = "APP_SECRET"; // Your app secret

  // Function to parse an incoming signed request and get the
  // data
  function parse_signed_request($signed_request, $secret) {
    list($encoded_sig, $payload) = explode('.', $signed_request, 2);

    $sig = base64_url_decode($encoded_sig);
    $data = json_decode(base64_url_decode($payload), true);

    if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
      error_log('Unknown algorithm. Expected HMAC-SHA256');
      return null;
    }

    // Check the signature
    $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
    if ($sig !== $expected_sig) {
      error_log('Bad Signed JSON signature!');
      return null;
    }
    return $data;
  }

  // Helper function for parsing signed request
  function base64_url_decode($input) {
    return base64_decode(strtr($input, '-_', '+/'));
  }

  // Variable to hold success result
  $success_result = 'false';

  // Parse the signed request
  $parsed_data = parse_signed_request($_REQUEST['signed_request'],$app_secret);
  if ($parsed_data != null) {
    // Get the access token
    $access_token = $parsed_data['oauth_token'];
    // Get the object URL
    $recipe = $parsed_data['objects'][0]['url'];

    // The Graph API endpoint for publishing a save action
    $graph_url_publish = 
      "https://graph.facebook.com/me/nyccookbook:save?access_token=" . $access_token;
    $postdata = http_build_query(
      array(
        'recipe' => $recipe
      )
    );
    $opts = array('http' =>
      array(
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => $postdata
      )
    );
    $context  = stream_context_create($opts);
    // Publish the save action
    $result = json_decode(file_get_contents($graph_url_publish, false, $context));
    if (($result != null) && isset($result->id)) {
      // Set the result flag to true
      $success_result = 'true';
    }
  }

  // Print the output
  $success = array(
    'success' => $success_result
  );
  $output = json_encode($success);
  echo $output;
?>