先日仕事でInstagram Graph APIを叩く機会がありました。Graph APIで他人のフォロワー数を取得するというものです。
個人的にFacebookのドキュメントって意味不明で苦手意識があり(そもそもFacebookもInstagramもほぼ使っておらず、用語の意味が分からんのです。。)、ちょっとAPI叩きたい時はRapidAPIの非公式APIで済ませていたので、Graph APIを触るのは今回が初めてでした。
そこで「instagram graph api access token」のキーワードでググってみたのですが、出てくる記事には「第一アクセストークン、第二アクセストークン、第三アクセストークン」などといった謎の言葉が飛び交っていて頭がカオスに。おまけに、みなさん丁寧に画面のスクショを貼ってくれてるのですが、FacebookのUIやAPI仕様変更が頻繁なので、現在のスクリーンと違っていて余計に混乱してしまいました。
これはもう急がば回れだろうということでしぶしぶ本家ドキュメントに立ち戻り、ようやく「第〇アクセストークン」の意味が分かってきたので、これからGraph APIを試したい人が、これらのアクセストークンを正しく理解して、欲しい情報をGraph APIから取得できるように解説記事を書いていきたいと思います。
API version: v14
この記事で触れること
- 無期限のアクセストークンを使ってGraph APIで他人アカウントの基本情報を取得する方法(バックグランドジョブで使うことを想定)
- ユーザーアクセストークン、ページアクセストークンの種類について
この記事で触れないこと
Instagram Graph APIを使用するための事前準備は完了していることを前提に書いてるので、以下の項目については説明しません。
- Facebookページ作成
- Instagramアカウント作成
- InstagramアカウントをFacebookページにリンクさせる
- Meta for DevelopersでFacebookビジネスアプリを作成
リファレンス
Facebookのドキュメントは情報が散乱してて探すのに苦労するので、リファレンスを先にまとめておきます。
例えばGraph APIについてさっき見ていたページどこだっけ?あれ、ない。。と思ったら、よくよくURLを見るとルートが違っていた、なんてことが頻繁にあるので気を付けてください。
Graph API
Instagram Graph API
Access Token
- https://developers.facebook.com/docs/facebook-login/guides/access-tokens
- https://developers.facebook.com/docs/pages/access-tokens
Tools
前提知識
Instagram Graph APIはFacebookアカウントの認証によってアクセストークンを取得するため、Facebookログインのページに書いてあるアクセストークンについて理解する必要があります。
ひとえにアクセストークンと書かれていても、「User Access Token」、「App Access Token」、「Page Access Token」、「Client Token」の4種類があります。どのアクセストークンを使うかによって、叩けるAPIエンドポイントや取得できる情報が異なるようです。本記事では、このうち謎の「第〇アクセストークン」に関連する「User Access Token」、「Page Access Token」の2つを説明します。
User Access Token
まずはドキュメントからの引用です。
この種類のアクセストークンは、アプリがAPIを呼び出して、特定の利用者のFacebookデータをその利用者の代わりに読み取り、変更、書き込みを行う際に必ず必要になります。ユーザーアクセストークンは、一般的にログインダイアログを通して取得され、アプリがトークンを取得することを利用者が許可する必要があります。
アプリがユーザー(Facebookアカウント)に代わって、APIを通じてユーザーの情報の読み書きを行うために使用するトークンです。OAuthといえば一般にこのイメージですね。
ユーザーアクセストークンには、Short-Term Tokens(以下、「短期ユーザーアクセストークン」)とLong-Term Tokens(以下、「長期ユーザーアクセストークン」)の2種類があり、短期ユーザーアクセストークンは通常1時間、長期ユーザーアクセストークンは通常60日間の有効期限となっています。
短期ユーザーアクセストークンは、Facebookログインの実装を通して、または、 Graph API Explorerで取得できます。
長期ユーザーアクセストークンを取得するには、/oauth/access_token
エンドポイントを使う必要があります。(後述)
Page Access Token
こちらもまずはドキュメントからの引用です。
この種類のアクセストークンはユーザーアクセストークンに似ていますが、Facebookページに属するデータの読み取り、書き込み、変更を行うAPIに対してアクセス許可を提供する点が異なります。ページアクセストークンを取得するには、まずユーザーアクセストークンを取得してから、ページへのアクセス許可または必要なアクセス許可をリクエストする必要があります。ユーザーアクセストークンを取得したら、グラフAPIを介してページアクセストークンを取得します。
どうやら、アプリがFacebookページの操作を代わりに行うために払い出されるトークンのようです。このトークンを取得するためには、まずは対象のFacebookページに対して必要な権限を有しているFaceboookアカウントでUser Access Tokenを取得し、その後別途Page Access Tokenを取得する流れになるようです。
そして重要な点として、Page Access Tokenにも短期と長期の概念があり、短期ユーザーアクセストークンを使用して払い出されたページアクセストークンは短期ページアクセストークン(有効期限1時間)、長期ユーザーアクセストークンを使用して払い出されたページアクセストークンは長期ページアクセストークン(有効期限なし) になります。これは今まで見てきたドキュメントとは別のページに書かれているので非常に分かりにくいです。
そして、今回の目標はバックグランドジョブで使用する有効期限なしのアクセストークンを取得することであったため、長期ページアクセストークンを取得すればいいということになります。
それでは順を追って長期ページアクセストークンを取得していきましょう。
1. 短期ユーザーアクセストークンを取得する
これは先述したとおり、Facebookログインの実装を通すか、Graph API Explorerで取得することが出来ます。今回はアプリを第三者ユーザーに公開することは意図していないため、Graph API Explorerで取得するのが簡単そうです。
注意点としては、アクセストークンの生成にあたって適切なアクセス許可を設定することです。今回はInstagramのユーザーの基本情報を取得したいので、以下のアクセス許可を最低限与えてやる必要があります。(どのアクセス許可が必要かは目的によって変わります。叩きたいエンドポイントのドキュメントに必要な許可が書かれているので適宜探してください。)
pages_show_list
instagram_basic
instagram_manage_insights
「Generate Access Token」というボタンを押すと、短期ユーザーアクセストークンが払い出されます。(なお、2022年6月9日時点では、生成するトークンの種類の切り替え候補に「ページアクセストークンを取得」とありますが、これを選択して払い出したアクセストークンも実は短期ユーザーアクセストークンのようです。)
生成されたアクセストークンをデバッグするにはAccess Token Debuggerが便利です。今回払い出されたトークンを入れてみると、Type: User
で有効期限が1時間のアクセストークンだということが分かります。(画像は一部表示データをマスクしています)
2. 長期ユーザーアクセストークンを使用する
目的である長期ページアクセストークンを取得するためには、長期ユーザーアクセストークンを先に取得しなければならないためこの手順を踏む必要があります。
pagesのドキュメントに長期ユーザーアクセストークンの取得方法が書かれているのが解せないですが、GET /oauth/access_token
エンドポイントを使えばいいそうです。以下の変数名は長ったらしいですが、トークンの種類が分かりやすいようにしてます。
const getLongTermUserAccessToken = async (appID, secret, ShortTermUserAccessToken) => {
// SEE: https://developers.facebook.com/docs/pages/access-tokens?locale=en_US
const url = `https://graph.facebook.com/v14.0/oauth/access_token?grant_type=fb_exchange_token&client_id=${appID}&client_secret=${secret}&fb_exchange_token=${ShortTermUserAccessToken}`;
const res = await fetch(url);
// 有効期限60日の長期ユーザーアクセストークン
const { access_token } = await res.json();
return access_token;
};
3. 長期ユーザーアクセストークンを使って長期ページアクセストークンを取得する
GET /me/accounts
エンドポイントを使うと、ユーザーがタスクを実行できるPages(Facebookページ)リストを取得でき、各Pageにはaccess_token
フィールドがあります。これがページアクセストークンです。ドキュメントはこちらとこちら。
jsで書くと以下のような感じです。先述したように、ここで引数に渡すuserAccessToken
が短期なら短期ページアクセストークン、長期なら長期ページアクセストークン(有効期限なし)が返されます。
const getPageBelongsToMe = async (userAccessToken) => {
// https://developers.facebook.com/docs/graph-api/reference/user/accounts/
const url = `https://graph.facebook.com/v14.0/me/accounts?fields=access_token,instagram_business_account&access_token=${userAccessToken}`;
const res = await fetch(url);
const { data } = await res.json();
// dataはpagesの配列なので、この中からInstagramアカウントとリンクさせたページを探す
const page = data[0]
return page;
};
取得したpage.access_token
の値をAccess Token Debuggerで確認してみると、Type: Page
で有効期限: 受け取らない
と期待した結果になっています。
Instagram Graph APIを試してみる
長期ページアクセストークンを取得できたので、ビジネスディスカバリーのAPIを叩いてみましょう。
GET /{ig-user-id}/business_discovery
APIを叩くにはInstagramのUserIDが必要です。このUserIDはどこで取得できるかというと、Page.instagram_business_account
フィールドにあります。
上述のgetPageBelongsToMe
関数ではこのフィールドを取得するようにパラメータを与えているので、返り値のpage.instagram_business_account.id
にInstagramのUserIDが入っているはずです。
これを使用して、ドキュメントと同じくBlue Bottle Coffeeの基本データを取得してみます。
// Meta for Developersのアプリ設定から取得
const APP_ID = "****************"
const APP_SECRET = "*****************"
// Graph API Explorerから生成
const SHORT_TERM_USER_ACCESS_TOKEN = "*********************************************";
const testGraphAPI = async () => {
const longTermAccessToken = await getLongTermUserAccessToken(
APP_ID,
APP_SECRET,
SHORT_TERM_USER_ACCESS_TOKEN
);
const page = await getPageBelongsToMe(longTermAccessToken);
const {
instagram_business_account: { id: igUserID },
access_token: accessToken,
} = page;
const url = `https://graph.facebook.com/v14.0/${igUserID}?fields=business_discovery.username(bluebottle){followers_count,media_count}&access_token=${accessToken}`;
const res = await fetch(url);
const j = await res.json();
console.log({ bluebottle: j });
};
// 実行
testGraphAPI();
出来ました。
最後に
やっぱりFacebookのドキュメントは探しにくいし読みにくかった。
ちなみに、謎だった「第〇アクセストークン」もこれで対応関係が明らかになりました。
- 第一アクセストークン -> 短期ユーザーアクセストークン
- 第二アクセストークン -> 長期ユーザーアクセストークン
- 第三アクセストークン -> 長期ページアクセストークン
なお、Instagram Graph APIはユーザーアクセストークンでも叩けたので、必ずしも長期ページアクセストークンを取得する必要はありません。