Facebookの投稿Feedを取得してAMP HTMLのamp-facebookで表示させる手順のまとめ

APIがコロコロ変わって何かと面倒で有名なFacebookですが、投稿フィードを取得してAMP HTMLのamp-facebookを使ってページに埋めこむWordPressのプラグインを作成したので、その際に必要となった手順をまとめました。APIのバージョンは2016年10月現在最新のv2.8です。

まずはFacebookのアクセストークンの種類を知る

Facebookのフィードを取得するにはFacebookが提供しているGraph APIを使用する必要がありますが、ここで必要となるのがアクセストークンです。ただし一口にアクセストークンといっても、Facebookでは開発者用ページにあるように4種類のアクセストークンがあります。

  • ユーザーアクセストークン

    ユーザートークンは、最も一般的に使用される種類のトークンです。この種類のアクセストークンは、アプリがAPIを呼び出して、特定の利用者のFacebookデータをその利用者の代わりに読み取り、変更、書き込みを行う際には常に必要になります。ユーザーアクセストークンは、一般的にログインダイアログを通して取得され、アプリが取得するのを利用者が許可する必要があります。

  • アプリアクセストークン

    この種類のアクセストークンは、アプリ設定を変更したり読み取ったりする際に必要になります。また、Open Graph actionを公開するためにも使用できます。アプリアクセストークンは、アプリとFacebookとの間で事前に合意されたapp secretを使用して生成され、アプリ全体の設定を変更する呼び出しで使用されます。アプリアクセストークンは、サーバー間呼び出しを通して取得します。

  • ページアクセストークン

    これらのアクセストークンはユーザーアクセストークンに似ていますが、Facebookページに属するデータの読み取り、書き込み、変更を行うAPIに対してアクセス許可を提供する点が異なります。ページアクセストークンを取得するには、まずユーザーアクセストークンを取得してから、manage_pagesアクセス許可をリクエストする必要があります。ユーザーアクセストークンを取得したら、Graph APIを介してページアクセストークンを取得します。

  • クライアントアクセストークン

    クライアントトークンは、アプリを識別するために、ネイティブモバイルバイナリやデスクトップアプリに埋め込むことができる識別子です。クライアントトークンは、アプリに埋め込まれるため、シークレット識別子になることはできません。クライアントトークンは、アプリレベルの非常に限られたサブセットのAPIにアクセスするために使用されます。クライアントトークンは、アプリのダッシュボードに表示されます。クライアントトークンはほとんど使用されることがないため、このドキュメントでは説明を省略しますが、これについてはすべて、クライアントトークンを使用するAPIドキュメントに説明があります。

こららのアクセストークンの中で、比較的簡単に発行することができるのがアプリアクセストークンです。その分アクセスすることのできるAPIは限られますが、これで投稿フィードを取得することが可能です。またアプリアクセストークンとしてApp IDとapp secretを”|”(パイプ)で繋げたものを使用することも可能なので、一旦アプリを登録すればapp secretをリセットしない限りこのトークンはずっと有効になります。当たり前ですが、これをクライアントサイドに晒してしまうなんていう愚かなことをしてはいけません。

アプリアクセストークンの発行

まずは開発者向けFacebookページでFacebook開発者としてログインして、右上メニューの「新しいアプリを追加」からアプリを登録します。今回のようなウェブページでFacebookの投稿を表示させたい場合は、プラットフォームとして「ウェブサイト」を選択します。

その後「Quick Start for ウェブサイト」の画面で適当なアプリの名前を入力すれば(例えばWordPressのプラグインならそのプラグイン名)、アプリIDとapp secretが発行されます。

アプリIDとapp secretが発行されたら、公式のアプリアクセストークンの説明ページにしたがって

GET /oauth/access_token
    ?client_id={app-id}
    &client_secret={app-secret}
    &grant_type=client_credentials

でアプリアクセストークンを取得します。curl等で叩くのもいいですし、Facebook SDK v5 for PHPを使って

$fb = new Facebook\Facebook([
    'app_id' => '{app-id}',
    'app_secret' => '{app-secret}',
    'default_graph_version' => 'v2.8'
]);
$accessToken = $fb->getApp()->getAccessToken();

でアプリアクセストークンを取得することもできます。また、アプリIDとapp secretを”|”(パイプ)で繋げたものもアプリアクセストークンとして使用することができます(こちらは期限無制限のアクセストークンです)。

アプリアクセストークンでGraph APIを叩く

叩くエンドポイントは/{page-id}/feedです。取得できる上限は100投稿ですが、ホームページ等で表示させるだけならこれで問題ありません。PHPのFacebook SDKを使う場合は

$fb = new Facebook\Facebook([
    'app_id' => '{app-id}',
    'app_secret' => '{app-secret}',
    'default_graph_version' => 'v2.8'
]);
$accessToken = $fb->getApp()->getAccessToken();
 
try {
    $response = $fb->get('/{page-id}/posts?fields=id,link,message,full_picture,created_time', $accessToken);
    $items = $response->getDecodedBody();
} catch(\Facebook\Exceptions\FacebookResponseException $e) {
    // When Graph returns an error
    echo 'Graph returned an error: ' . $e->getMessage();
    exit;
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
    // When validation fails or other local issues
    echo 'Facebook SDK returned an error: ' . $e->getMessage();
    exit;
}

で取得できます。jsonファイルに保存したい場合はさらに

file_put_contents(dirname(__FILE__).'/json/facebook.json', json_encode(["items" => $response->getDecodedBody()['data']], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));

のように$responseからgetDecodedBodyメソッドを呼ぶことで、投稿情報をjsonに保存することができます。

おまけ:ページIDの取得

ページIDはFind my Facebook IDから調べることができます。

amp-facebookで投稿を表示するショートコード

amp-facebookで使用するのは各投稿のlinkプロパティです。ということでamp-facebookで表示させる場合は

<amp-facebook class="amp-facebook" data-href="<?= $item['link'] ?>" width="300" height="300" layout="responsive"></amp-facebook>

のような感じになります。ここで$itemは各投稿情報の入っている変数として定義されているものとしています。

取得したfeedのidプロパティは{user-id}\_{post-id}のようになっているので、AMPオフィシャルのamp-facebookに関する説明ページでの例

data-href="https://www.facebook.com/zuck/posts/10102593740125791"

と同じフォーマットにしたい場合は

<amp-facebook class="amp-facebook" data-href="https://www.facebook.com/<?= explode('_', $item['id'])[0] ?>/posts/<?= explode('_', $item['id'])[1] ?> width="300" height="300" layout="responsive"></amp-facebook>

のようになります。

参考ページ

Facebook API: 有効期限の長い Access Token を取得する