EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

インスタグラムの@メンション投稿を収集する

弊社のサービス「クスパ 」では、「クスパ公認インスタアンバサダー」の方々によるインスタグラム投稿を、特設ページに集約して掲載をしています。

cookingschool.jp

インスタ投稿の収集と表示はサードベンダーのASPサービスを利用していたのですが、インスタグラムのAPIや権限の変更が多いため、できることが色々と変わったり動作が不安定になったりしていたので、自社で実装する事にしました。

インスタグラムで自分のアカウントに対する@メンション投稿は、webhookを実装することで可能になります。 今回は、仕組みをさくっと作りたかったので、サーバーサイドをnode.jsで実装しました。

インスタグラムの@メンションの収集構築

収集する仕組みを構築するために、ざっと以下のステップを踏みました。

  1. Facebookアプリとして、自分のインスタグラムアカウントを使えるようにする
  2. FacebookアプリでWebhooksを使えるようにする
  3. webhookのエンドポイントを実装する
  4. サブスクリプションを有効にする

1. Facebookアプリとして、自分のインスタグラムアカウントを使えるようにする

これだけで記事が書ける内容なのですが、実際に記事はたくさんあるので、それを参考にするのが良いと思います。

instagram グラフAPI - Google 検索

公式のドキュメント(InstagramグラフAPI - Instagramプラットフォーム - ドキュメンテーション - Facebook for Developers )も重要な情報源ですが、大概の公式ドキュメントって拙い日本語(未訳も多い)で理解し難いですよね。 雑にまとめると

  1. FacebookアカウントとFacebookページを用意
  2. Instagramアカウントをビジネスアカウントにする
  3. FacebookページとInstagramアカウントを紐づける
  4. Facebookアプリを作成する

さらに、グラフAPIを使って投稿を取得したりするなら、

アクセストークン取得&永続化

も、やっておくと良いでしょう。 でも、これってやり方はよく語られているけど、セキュリティ的には良くない話ですよね…。

2. FacebookアプリでWebhooksを使えるようにする

Facebook for Developersのアプリコンソールにアクセスし、左側メニューの「プロダクト(+)」から、Webhooksを追加できます。

f:id:eatsmart:20210305200504p:plain
Webhooks

これでWebhooksを追加し、設定で「Instagram」を選ぶ事で、インスタ投稿のwebhook設定を追加することができます。

f:id:eatsmart:20210305200730p:plain
Webhook設定

この設定で、webhook用の通知のエンドポイントとトークン(URL認証用のトークン文字列)を設定することができます。

3. webhookのエンドポイントを実装する

webhookのエンドポイントとしては、FacebookからのURL認証リクエスト(GET)と、実際の投稿イベント(POST)の2つを受信できるように実装する必要があります。詳しくは Webhooks - グラフAPI - ドキュメンテーション - Facebook for Developers を見ていたけば分かると思います。

今回は、URL認証リクエスト用として

router.get('/hook', function (req, res) {
  let mode = req.query['hub.mode'];
  if(mode!='subscribe') {
    res.status(500).send({error: 'mode is '+mode});
    return;
  }
  let verify_token = req.query['hub.verify_token'];
  if(verify_token!=VERIFY_TOKEN) {
    res.status(500).send({error: 'verify_token is '+verify_token});
    return;
  }
  let challenge = req.query['hub.challenge'];
  res.send(challenge);
});

投稿イベント受信用として

router.post('/hook', function (req, res) {
  console.log(JSON.stringify(req.body));
  // JSONを操作したりグラフAPIで投稿内容を詳しく取得したりDBに格納したり
  res.send('');
});

という実装をしています。ここでJSONを格納するためにPostgreSQLJSON型を使ったりしました。

eatsmart.hatenablog.com

4. サブスクリプションを有効にする

Webhooksの設定を済ませ、URL認証を済ませ、投稿イベント受信エンドポイントを実装したら、DevelopersコンソールのWebhooks設定からテストリクエストを送信して、受信のテストをすることができます。 テストが済んだら、以下のPOSTを送信してサブスクリプションを有効にすることで受信が開始されます。

curl -i -X POST \
'https://graph.facebook.com/v8.0/{page-id}/subscribed_apps?subscribed_fields=mention&access_token=EAA・・・'

ここでpage-idは、 グラフAPIエクスプローラ - Facebook for Developers で、me/accounts から管理ページのIDを調べることで取得できます。

{
  "data": [
    {
      "access_token": "EAA・・・",
      "category": "キッチン・クッキング",
      "category_list": [
         ・・・
      ],
      "name": "料理教室ポータルサイト「クスパ」",
      "id": "page-id",
      "tasks": [
        ・・・
・・・
  }
}

ちなみに、グラフAPIエクスプローラで同様に{page-id}/subscribed_appsを調べることで、現在サブスクリプトしている対象を取得することができます(アクセストークンをページアクセストークンにする必要があります)。

{
  "data": [
    {
      "category": "ライフスタイル",
      "link": "https://cookingschool.jp/",
      "name": "料理教室検索クスパ",
      "namespace": "cookingschooljp",
     ・・・
      "subscribed_fields": [
        "mention"
      ]
    }
  ]
}

アクセス許可権限について

Instagram(Facebook)グラフAPIを使うには、適切なアクセス許可を必要とします。アクセス許可はDevelopersコンソールでアプリレビューの申請を通す必要があります。 今回のWebhooksも(現時点で)instagram_manage_commentsが必要で、またサブスクリプションを有効にするPOSTにもpages_manage_metadataが必要となります。

Facebookのアクセス許可は変更が多く年々厳しくなっており、また、自分たちでAPIを使った処理を実装するためにはアプリレビューが大きなハードルに感じられると思います。

ただ、以前恐れられていたように、英語で申請を出す必要があり返事も時間がかかるというようなことはなく、日本語で動画と合わせて申請して1日以内で返事をもらっていました。権限によってはリジェクトされることもありましたが、詳しく説明を付けて再申請することで最終的に許可してもらいました。

インスタグラムユーザーに有益で自分たちのサービスでも使いたい正当な理由があれば、試してみても良いのかなと思います。もちろん、APIの変更やバージョンアップが多いので、追従するための工数を考えると安定したASPを使うことも大いに意味はあると思います。