Noël Café : Blog
Noëlの公開備忘録とひとりごと。コメント・トラックバックご自由に

Instagram基本表示APIのGoogle Apps Scriptを使用した登録方法

IFTTT無料範囲減対応に関する備忘録とhow to。
まだまだいきます。

今回はInstagram編。
Instagramに投稿した文章+画像をGoogle Apps Script(GAS)経由でtwitterに投稿したいと思います。
まずはその手はじめ。
Instagramの情報を呼び出す前の段階です。


InstagramのAPI

自分の投稿を取得するだけなら基本情報APIを使えば充分です。
InstagramnのAPIには2020現在2種類あります。

  • Instagram Graph API
  • Instagram Basic Display API (基本表示API)

Instagram APIでGoogleで色々調べると出てくるのは前者の方で、
Instagramをビジネスアカウントにする必要がありちょっとハードルが高いです。
今回やりたいことはGASで自分の投稿の読み込みだけなので
基本表示APIの方で十分でした。
アプリレビューもいらないのでかなりハードル下がります。
ただ、情報が少ないのが困りました。

前提条件

今回の作業を実施するために必要な環境は以下の通りです。

  1. Facebookのアカウントと開発者アカウント
  2. Instagramアカウント(プロアカウントの必要なし)

1のFacebook開発者アカウントは以下のURLから登録。
https://developers.facebook.com/apps
2020年10月現在、開発者アカウント取得には
Facebookアカウントの個人認証(携帯電話番号登録かクレジットカード登録)が必要になります。
リンク先によるような気がしますが、COVID-19で個人認証が止まっているようです。

2のInstagramアカウントは言わずもがなですね。
今回は自分の投稿を取得するだけなのでプロアカウントにする必要はありません。

[手順1] Facebookアプリの作成

まず初めにFacebookアプリを作成します。
アプリ名にInstagram, Insta, gramはInstagramの商標に引っかかるため使えません。

Facebookアプリはずっと「開発中」のままで使えます。
今回は自分のInstagramを自分のGASで動かすだけですし。

[手順2] FacebookアプリにInstagramを設定

FacebookアプリにInstagram Basic Display APIを設定/登録します。

まず作成したFacebookアプリの「プロダクト」から「Instagram Basic Display」を設定します。
それから各種設定を入力していきます。
「クライアントOAuth設定」はTwitterとGASを連携する時にも出てきた
コールバックURLを入れるのが妥当かと思います。
https://script.google.com/macros/d/スクリプトID/usercallback
参考:Twitter APIとGoogle Apps Script 連携でツイート (備忘録)

[手順4]で「InstagramアプリID」, 「Instagram App Secret」, 「有効なOAuthリダイレクトURI」の3つが必要になります。

[手順3] Instagramテストユーザーの追加

Facebookアプリの「役割」から「Instagramテスター」を追加します。
(「テストユーザー」という場所もありますがそこは違います。)
ここに自分のInstagramアカウントを追加、送信します。

今度はInstagramを開いて、
自分のアカウント → 設定 → アプリとウェブサイト → テスターへの招待
を開いて先ほど作ったアプリからのリクエストを承認します。

[手順4] テストユーザーの認証 (認証コードの取得)

ここから先はGASを活用していきましょう!

先にGASのスクリプトを。

// 設定(トークン取得完了後中身削除OK)
var insta_appid = "XXXXXXXX";         // InstagramアプリID
var insta_appsecret = "XXXXXXXX";      // Instagram App Secret
var insta_redirecturl = "XXXXXXXX";    // 有効なOAuthリダイレクトURI

function insta_get_code() {
  var insta_url = "https://api.instagram.com/oauth/authorize?client_id=" + insta_appid + "&redirect_uri=" + insta_redirecturl + "&scope=user_profile,user_media&response_type=code";
  Logger.log(insta_url);
}

 

流れは以下の通りです。

  • GASに上のスクリプトを書く。
  • XXXXXXXXの部分を自分の環境に合わせて書き換える。
    Facebookアプリの[プロダクト] → [Instagram Basic Display] → [Basic Display]で確認
  • insta_get_codeを実行
  • [表示]→[ログ]で出てきたURLにアクセス(ブラウザで開く)
  • Instagram承認画面が出るので承認
  • 「ページが見つかりません」的なページへ移行するので
    そのURLをメモし”code=”と”#_”の間を取得
    次の手順で使用します。1時間有効です。

見ればわかると思いますが、ただ認証コード取得用URLをログに書き出しているだけです。
GASでやる必要はあんまりありません。(が自分でつなげるより楽ね。)

[手順5] ユーザーID, 長期トークンの取得

ココ、GASで一気に行きます!

先にGASのスクリプトです。

// 設定(トークン取得完了後中身削除OK)
var insta_appid = "XXXXXXXX";         // InstagramアプリID
var insta_appsecret = "XXXXXXXX";      // Instagram App Secret
var insta_redirecturl = "XXXXXXXX";    // 有効なOAuthリダイレクトURI

// insta_get_code後に入力(トークン取得完了後中身削除OK)
var insta_code = "YYYYYYYY";           // [手順4]で取得したコード (*1)

function insta_get_token(){
  // insta_get_codeで作成したコードをinsta_codeに入力してから実施すること。
  // 長期トークン(insta_token)がPropertiesServiceへ格納される

  // 短期トークンを取得
  var insta_endpoint = "https://api.instagram.com/oauth/access_token";
  var response = UrlFetchApp.fetch(insta_endpoint, {
    method: "post", 
    payload: {
      'client_id' : insta_appid,
      'client_secret' : insta_appsecret,
      'grant_type' : "authorization_code",
      'redirect_uri' : insta_redirecturl,
      'code' : insta_code
    }
  });

  // 短期トークンとユーザーIDを格納
  var insta_token = JSON.parse(response).access_token;
  var insta_userid = response.toString().match(/\"user_id\": [0-9]+/).toString().match(/[0-9]+/).toString(); // (*2)
  PropertiesService.getScriptProperties().setProperty("insta_userid", insta_userid);

  // 長期トークンを取得
  json_url = "https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret=" + insta_appsecret + "&access_token=" + insta_token;
  json = UrlFetchApp.fetch(json_url).getContentText();

  // 長期トークンを格納
  var insta_token = JSON.parse(json).access_token;
  PropertiesService.getScriptProperties().setProperty("insta_token", insta_token);

}

 

流れは以下の通りです。

  • GASに上のスクリプトを書く。
    最初の4行は前のスクリプトと同じです。
    XXXXXXXXXは自分の環境を入れてください。
  • YYYYYYYYの部分を[手順4]で取得したコード(code=と_#の間の長い文字列)にする(*1)
  • insta_get_tokenを実行する
  • 必要に応じてここまでのGASスクリプトを削除する

このコードを実行すると、
短期トークン, ユーザーIDの取得 → 長期トークンの取得(期限2ヶ月)
まで一気にやってしまいます。

今後必要となるユーザーIDと長期トークンはスクリプトのPropertiesServiceに格納されます。
同じプロジェクトからならば以下のコードで取り出しできます。

  var insta_token = PropertiesService.getScriptProperties().getProperty("insta_token");
  var insta_userid = PropertiesService.getScriptProperties().getProperty("insta_userid");

 

ただ、今回取得したトークンは期限2ヶ月なので注意が必要です。
その対応は次項にて。

ちなみにスクリプトの肝は*2の部分です。
すでにInstagramのユーザーIDは17桁を超えているので
普通にJSON.parseすると下の方の桁がゼロになってしまいます。
JavaScriptなら他の方法(json-bigint)を使えば良いのですがGASはできず…。
parseする前の情報から引き抜きました。
それと当然ですが文字列のまま扱う必要があります。

[手順6] 長期トークン更新

前項で取得したトークンは期限2ヶ月ですので、トークン更新の仕組みも作りましょう。
(Graph APIでは無期限トークン作れるようですが基本表示APIではダメみたいです。)

まず、GASスクリプトから。

function insta_reflesh_token(){
  // 現在のトークンを取得
  var insta_token = PropertiesService.getScriptProperties().getProperty("insta_token");
  
  // 長期トークンを更新
  json_url = "https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=" + insta_token;
  json = UrlFetchApp.fetch(json_url).getContentText();

  // 新トークンを格納
  var insta_token = JSON.parse(json).access_token;
  PropertiesService.getScriptProperties().setProperty("insta_token", insta_token);

}

 

流れは以下の通りです。

  • GASに上のスクリプトを書く。
  • insta_reflesh_tokenをGASのトリガーで月1回実行するようセット

お疲れさまでした。
Instagramのデータにアクセスする前段階完了しました。

このプログラムを動かすのは2ヶ月で1回で良いと言えば良いのですが、
一応念のために1ヶ月1回の方がトリガーがちょっと遅れたときはいいかなと思います。

今回のGASスクリプト

// 設定(トークン取得完了後中身削除OK)
var insta_appid = "XXXXXXXX";         // InstagramアプリID
var insta_appsecret = "XXXXXXXX";      // Instagram App Secret
var insta_redirecturl = "XXXXXXXX";    // 有効なOAuthリダイレクトURI

// insta_get_code後に入力(トークン取得完了後中身削除OK)
var insta_code = "YYYYYYYY";           // [手順4]で取得したコード (*1)


function insta_get_code() {
  // これを実行した後に[表示]→[ログ]で出てきたURLにアクセス
  // Instagram承認画面が出るので承認
  // その後GAS「ページが見つかりません」的なページへ移行するので
  // そのURLをメモし"code="と"#_"の間を取得する
  // 上の設定のinsta_codeに入れる
  // insta_codeは取得後1時間有効
  // 設定(トークン取得完了後中身削除OK)

  var insta_url = "https://api.instagram.com/oauth/authorize?client_id=" + insta_appid + "&redirect_uri=" + insta_redirecturl + "&scope=user_profile,user_media&response_type=code";
  Logger.log(insta_url);

}


function insta_get_token(){
  // insta_get_codeで作成したコードをinsta_codeに入力してから実施すること。
  // 長期トークン(insta_token)がPropertiesServiceへ格納される
  // 設定(トークン取得完了後中身削除OK)

  // 短期トークンを取得
  var insta_endpoint = "https://api.instagram.com/oauth/access_token";
  var response = UrlFetchApp.fetch(insta_endpoint, {
    method: "post", 
    payload: {
      'client_id' : insta_appid,
      'client_secret' : insta_appsecret,
      'grant_type' : "authorization_code",
      'redirect_uri' : insta_redirecturl,
      'code' : insta_code
    }
  });

  // 短期トークンとユーザーIDを格納
  var insta_token = JSON.parse(response).access_token;
  // insta_useridは17桁以上あるのでJSON.parseするとおかしくなる。
  // responseを文字列に変更して抜き出す
  var insta_userid = response.toString().match(/\"user_id\": [0-9]+/).toString().match(/[0-9]+/).toString();
  PropertiesService.getScriptProperties().setProperty("insta_userid", insta_userid);

  // 長期トークンを取得
  json_url = "https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret=" + insta_appsecret + "&access_token=" + insta_token;
  json = UrlFetchApp.fetch(json_url).getContentText();

  // 長期トークンを格納
  var insta_token = JSON.parse(json).access_token;
  PropertiesService.getScriptProperties().setProperty("insta_token", insta_token);

}


function insta_reflesh_token(){
  // 長期トークンを更新する
  // 長期トークンの期限が2ヶ月なので月1回のトリガーで実行すればOK

  // 現在のトークンを取得
  var insta_token = PropertiesService.getScriptProperties().getProperty("insta_token");
  
  // 長期トークンを更新
  json_url = "https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=" + insta_token;
  json = UrlFetchApp.fetch(json_url).getContentText();

  // 新トークンを格納
  var insta_token = JSON.parse(json).access_token;
  PropertiesService.getScriptProperties().setProperty("insta_token", insta_token);

}

 

Reference

認証までは公式サイトのスタートガイドが思ったより親切に買いてあります。
認証から後は最初は全部イー・ポッケさん通りにやりました。
今回の記事を書くにあたり、認証より後は全部自分でスクリプトを書きましたが、
イー・ポッケさんには本当に助かりました♪


余談

私が5年以上前にFacebook開発者アカウントに登録したときは
電話番号による認証は不要だった気がします。
Facebookに電話番号を登録した途端、
「知り合いかも」に知り合いがどどっと出てきて気持ち悪くなりました。
私は携帯電話10年以上前のガラケーを使っているので
普段使用しているiPadには全く電話帳中身ないので良いのですが、
気づかぬうちに電話帳の内容を抜かれているってことですね。
(実際には選択するところがあるだろうけど、そこにたどりつく人が全員でないでしょう。)

Leave a Reply

*


CAPTCHA



Trackback URL