LoginSignup
27
24

More than 3 years have passed since last update.

Instagram から Graph API で画像を取得する

Last updated at Posted at 2019-12-04

メチャクチャにめんどくさいです…… :frowning2:

他の手段

2019/10 に Instagram Basic Display API というのが出たようですが、トークンの有効期限が1時間だそうなので、サイトに画像を埋め込むような用途には使えません。

参考にした記事

こちらの記事が詳しく、非常に助かりました。 :pray:

以下は、上の記事を読む前提での補足です。

構成

次のような構成にします。

image.png

ダミーの Instagram アカウント、Facebook ページを使う

Instagram へのアクセス権限を得るには、ダミーの Facebook ページと Instagram アカウントを作るのが無難そうでした。その方が、運用・引き継ぎもしやすいのではないかと思います。

最初は顧客の Facebook ページに編集者で入れてもらって試しましたが、権限の制約なのかバグなのか、 instagram_business_account の ID 取得がうまくいきませんでした。

instagram_business_account が出力されないバグについて

専用の Instagram, FB ページを作ると、失敗しても何度でも試せるので安心です。

ダミーの Instagram ビジネス ID とアクセストークンを使って、全く関係ない第三者の Instagram 画像を取得できます。

開発モードで FB アプリを使う

Facebook アプリは開発モードのままで使います。

公開しようとすると、スクリーンキャプチャ動画を含むレビュー申請が発生してしまいます。。。

当初は、顧客のアカウントでアプリに OAuth ログインしてもらう選択肢もあるのでは、、と思っていましたが、レビューの手間に見合う気がしないので諦めました。

自分もしくはアプリ上で役割を持つ誰かが開発モードでのみアプリを使用する場合、アプリを申請する必要ありません。アプリダッシュボードの[役割]タブにリストされているアカウント(管理者、開発者、テスターなど)であれば、すべてのアクセス許可を使用できます。

とのことなので、開発モードのアプリを本番で使っても、おそらくは大丈夫なのではと思います。

運用・引き継ぎ

  • Instagram のアカウント情報は、複数のメンバーに教えておきます
  • FB アプリ、FB ページは、複数の管理者を設定しておきます
  • 担当者が外れる際は、別のメンバーにトークンを生成しなおしてもらいます

トークン生成を半自動化する

有効期限なしのトークンを生成する PHP のスクリプトを作成しました。トークンを取得する手順の詳細は、最初にご紹介した記事を参照してください。

第一段階目のトークンを手動で取得

https://developers.facebook.com/tools/explorer/ を使って、

  • manage_pages
  • pages_show_list
  • business_management
  • instagram_basic
  • instagram_manage_comments
  • instagram_manage_insights
  • public_profile

が許可されたアクセストークンを作成します。

アクセストークンとその他の設定を JSON で保存

次に以下のような JSON を get_token.json という名前で保存します。

{
  "appID": "1234567890", // FB アプリの ID
  "appSecret": "xxxxxxxxxxxxxx", // FB アプリのシークレットキー
  "pageName": "小関百貨店",  // ダミーの FB ページの名前 (複数ある場合の選択に使います)
  "userAccessToken": "xxxxxxxxxxxxxxx....xxxxxxxxxxxx" // 上で取得したトークン
}

スクリプトを実行

上の JSON と同じ階層に、以下を get_token.php で保存。$ php get_token.php で実行します。同階層get_images.json に無期限のトークンが出力されます。

<?php

$conf = json_decode(file_get_contents('get_token.json'));

$ver = 'v5.0';
$appID = $conf->appID;
$appSecret = $conf->appSecret;
$pageName = $conf->pageName;
$userAccessToken = $conf->userAccessToken;

$url = "https://graph.facebook.com/$ver/oauth/access_token?grant_type=fb_exchange_token&client_id=$appID&client_secret=$appSecret&fb_exchange_token=$userAccessToken";

echo "----------------------------------------------------------------\n";
echo "Bearer トークンを取得します。\n";
echo "URL: $url\n";
echo "----------------------------------------------------------------\n";

$json = file_get_contents($url);
$data = json_decode($json);

$accessToken = $data->access_token;
echo "Bearer トークン: $accessToken\n";

$url = "https://graph.facebook.com/$ver/me?fields=id,name,accounts&access_token=$accessToken";

echo "----------------------------------------------------------------\n";
echo "アカウント情報を取得します。\n";
echo "URL: $url\n";
echo "----------------------------------------------------------------\n";

$json = file_get_contents($url);
$data = json_decode($json);
// var_dump($data);

$userName = $data->name;
$userID = $data->id;

echo "トークンと紐付くユーザ名: $userName\n";
echo "ユーザID: $userID\n";

foreach ($data->accounts->data as $a) {
    echo "  FB Page: " . $a->name . "\n";
    if ($a->name == $pageName) {
        $pageID = $a->id;
        $pageAccessToken = $a->access_token;
    }
}
echo "FB Page ($pageName) のID: $pageID\n";
echo "FB Page のアクセストークン: $pageAccessToken\n";


$url = "https://graph.facebook.com/$ver/me?fields=instagram_business_account{id,name}&access_token=$pageAccessToken";

echo "----------------------------------------------------------------\n";
echo "Instagram の情報を取得します。\n";
echo "URL: $url\n";
echo "----------------------------------------------------------------\n";

$json = file_get_contents($url);
$data = json_decode($json);

$instagramAccountName = $data->instagram_business_account->name;
$instagramBusinessAccount = $data->instagram_business_account->id;
echo "Instagram ビジネスアカウント ($instagramAccountName) のID: $instagramBusinessAccount\n";

$json = "{\n  \"instagramBID\":\"$instagramBusinessAccount\",\n".
      "  \"accessToken\":\"$pageAccessToken\"\n}\n";

$out = fopen('get_images.json', 'w');
fputs($out, $json);
fclose($out);

echo "\n\nget_images.json にトークンを書き出しました。\n\n";

実際に画像を取得する

get_images.json と同じ階層に、以下を保存します。

<?php

$conf = json_decode(file_get_contents('get_images.json'));

$instagramBID = $conf->instagramBID;
$accessToken = $conf->accessToken;

$targetUser = $argv[1];

$query = 'business_discovery.username(' . $targetUser . '){id,followers_count,media_count,ig_id,media{caption,media_url,media_type,like_count,comments_count,timestamp,id}}';

$url = "https://graph.facebook.com/v5.0/$instagramBID";
$url .=  "?fields=" . $query . "&access_token=" . $accessToken;

$data = json_decode(file_get_contents($url));
var_dump($data);

次のようにして実行し、指定したアカウントの画像データを取得できるのを確認します。

$ php get_images.php Instagramアカウント名
27
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
24