Ruby on Rails上でInstagram Graph APIを使う情報が少なかったので、はまりポイントも併せて備忘録を残していく。
環境
Service | Version |
---|---|
Ruby | 3.2.2 |
Ruby on Rails | 7.0.4 |
devise | 4.9.2 |
omniauth-oatuh2 | 1.3.1 |
omniauth-rails_csrf_protection | 0.1.2 |
omniauth-facebook | 9.0.0 |
koala | 3.4.0 |
構築
下準備
まずはどんな環境でも必須となる、下記準備を行ってください。
実装
やることは以下です。
- omniauth-facebookでAccessToken取得
- 取得したAccessTokenからFacebookページ用のAccessToken取得
- Facebookページ用のAccessTokenを使ってInstagram Business Account IDを取得
事前準備
まずはMeta Developerでアプリを作成し、アプリIDとapp secretを取得してください。
そしてFacebookログイン/Instagram Graph API設定を行ってください。
config
まずはomniauthの設定。
一応v16を使おうと思ったのでclient_options
を指定していますが、ここは不要だと思います。
scopeに関してもとりあえず詰め込んでいますが、ご自身で精査してください。私も後で精査予定。
config/initializes/devise.rb
config.omniauth :facebook, Rails.application.credentials.dig(:facebool, :app_id), Rails.application.credentials.dig(:facebool, :app_secret), { client_options: { site: 'https://graph.facebook.com/v16.0', authorize_url: "https://www.facebook.com/v16.0/dialog/oauth" }, scope: 'instagram_basic,instagram_content_publish,instagram_manage_comments,instagram_manage_insights,instagram_shopping_tag_products,pages_show_list,pages_read_engagement,instagram_manage_messages' }
callback
ここまでは普通のomniauthなので難しくはないと思うので、viewだとかは省略。
ここからは取得したTokenを使ってInstagram Graph APIを使用できるTokenを取得します。
omniauth_callbacks_controller.rb
def facebook token = request.env['omniauth.auth']['credentials']['token'] # 実際はページングとかもありますが、この解説では無視します。 accounts = Koala::Facebook::API.new(token).get_connections(:me, :accounts) accounts.each do |account| graph = Koala::Facebook::API.new(account["access_token"]) me = graph.get_object(:me, { fields: :instagram_business_account }) ib_id = me["instagram_business_account"]["id"] access_token = account["access_token"] # something process end # something process end
fetch media
上記で取得したib_id
とaccess_token
を使うことで、Instagram Graph APIを利用できます。
media_field = [:id, :media_url, :caption, :media_type, :thumbnail_url ] graph = Koala::Facebook::API.new(access_token) live_media = graph.get_connections(ib_id, "live_media", { fields: media_field })
やったぜ!!
はまりポイント
その1
Q: Facebook/Instagramって別物なの?
ドキュメントを読むと同じエンドポイントっぽいけど、omniauth-instagram-graphやinstagram_graph_apiのようなInstagram特化gemがあるよ?
A: 同じです。
それらのGemは使う必要はないです。
omniauth-instagram-graphは名前にgraphって入ってるのに、発行されるtokenはInstagram Basic Display APIようのものでした。
それっぽい名前使うんじゃねぇ!と言いたいところ。
何か意図があるのかしら。。。
instagram_graph_apiは使ってもよいかも。
omniauthで取得したAccessTokenを食わせれば、callbackの部分に書いた内容を丸っと肩代わりしてくれるかもしれない。
ただ更新が3年前で止まっているので今回は見送りました。
koalaで普通にいけるしね。
その2
Q: Tried accessing nonexisting field (media) on node type (User)
下準備はしっかり行ったのに、エラーが出るよ?
A: Access Tokenは3種類ある!
最初はomniauthで取得できるAccessTokenを使用し、かつ{ig-user-id}
部分をme
で対応していた。
しかしこれは両方ともダメ。
まずAccessTokenは以下の三種類存在するが、最後のページのTokenを利用する必要がある。
- OAuthで取得できるToken
- 長期化したToken
- 各ページごとのToken
omniauth-facebook
は第2トークンまでは勝手に取ってくれる。
第3トークンは実装編に書いている通り。
第2トークンを使っていると、Tried accessing nonexisting field (media) on node type (User)
というエラーが出る。
これに長らくはまってしまった。
そしてこれまたはまりポイントが、{id-user-id}
はちゃんと指定しなければならない。
この取得方法が最初は分からず、ここも詰まってしまった。
そんな中に見つけた下記サイトにヒントを得て、実践編の形に落ち着いた。
https://tsushiru.com/sns/instagram-graph-api-get-access-token-and-business-account-15-0-2.html
所感
APIはFacebook Graph APi/Instagram Graph API/Instagram Basic Display APIと三種類もあるし、
AccessTokenもInstagram Basic Display API用やら短期/長期/ページ用等複数あるし、
app id/app secretもFacebookのものとInstagram Basic Display API用のがあるし、
まずそもそもInstagram Graph APIを使うにはビジネスアカウントにしたりFacebook Pageと連携が必要だったり、
むっずかしいな!!