instagram widgetを作ってみる

## ゴール

インスタグラムのアカウントにログイン出来る場合に、API経由で画像を取得することにチャレンジ

## Instagram 基本表示APi

* InstagramのAPIを開発するにはFacebook 開発者ログインが必要です
* 自分のアカウントの画像を取得するだけならば、 InstagramグラフAPIでは無く、Instagram基本表示APIが利用できれば十分
* 当然、そのインスタグラムアカウントへのログインが必要
* 最大6ヶ月有効期限のトークンしかとれない
* facebookのアカウントとInstagramのアカウントの紐付け方法
    * facebook 開発者設定から instagramテスターを追加→インスタグラムアカウントを登録
    * Instagramログイン → プロフィール編集 → アプリとウェブサイト → facebookアプリを承認する


## Instagram Graph API
* Instagramをプロアカウントにして、自分が管理しているfacebook ページと紐付ける必要がある
* ただし、そのプロアカウントから見える範囲のinstagram投稿を持ってくることが可能。すなわち公開されている範囲の投稿を投稿者(@Someone-else)とかハッシュタグ(#something-else)で取得する事が可能
* 更新不要なトークンが取得出来るとの噂。。
* こちらのサイトを参考に取得させていただきました：https://arrown-blog.com/instagram-graph-api/#Instagram_Graph_APIWeb

## Let's start

### 1. [スタートガイド](https://developers.facebook.com/docs/instagram-basic-display-api/getting-started)を読んでみる：

1. アプリを作成
2. コネクテッドエクスペリエンスを構築
3. 設定 > ベーシック にて「プラットフォームを追加」により ウェブサイトを追加
4. プロダクト (+) をクリックし、「アプリに製品を追加」により、Instagram Basic Displayを選択
5. ページ下部にスクロールして「Create New App」をクリック

## Basic Displayの設定

* クライアントOAuth設定
    * InstagramAPiサーバーからのリダイレクト先になるけど、画像を撮ってくるだけだと問題無い。。？
* コールバックURLの許可の取消
    * 許可が取り消されたときに呼び出されるURL

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/d7158999-26a7-5d69-0e5d-ab71c44ff5a6.png)


## Instagramテストユーザーを追加

1. facebook側からInstagram アカウントを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/96db5d77-8110-0fa4-3a38-348399b22e59.png)

2．instagram 側から facebook アプリを承認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/b45f32c4-9a68-85b9-bf58-d068a603fad2.png)

## FacebookアプリのInstagramアプリIDとInstagramAppSecretから、AccessTokenを取得する

この方法で取得したAccessTokenの寿命が1時間なので要注意

* 認証コード取得 エンドポイント：https://api.instagram.com/oauth/authorize
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/acab9c49-de54-d401-d699-434a10abfe36.png)

* アクセストークン取得 エンドポイント：https://api.instagram.com/oauth/access_token
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/3591bc45-4aee-78dd-4ee4-bbab40fa3b14.png)

## 長期アクセストークンを取得する

* エンドポイント https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret={{client_secrete}}&access_token={{上で取得したアクセストークン}}

この方法で60日間有効のトークンが取得できるとのこと

Instagram 基本表示APIだと60日有効のトークンまでしか取得できないっぽく、定期的に自動でアップデートする必要があるみたい。

これが、Instagram グラフAPIを使うと無期限有効のトークンが取得できるとのこと。ただし、インスタアカウントをプロアカウントにする必要があるみたい

## facebookアカウントとインスタプロアカウントの紐づけ

1. インスタアカウントを"スマホアプリから"プロアカウントに昇格させる
2. facebookにページを作成し、その管理者になる
3. facebook上に作成したページにインスタアカウントを紐づけ。

## サーバー上で整形

長期間有効なトークンはサーバー上で扱うのが原則です。
http request/responseに収めてしまうとそのトークンを使って乗っ取られる可能性があるからね。

phpだとこんな感じで取得できるみたい

```php
class InstaFeed
{
  public $token = '';
  const ENDPOINT_URL='https://graph.instagram.com/';
  const USER_ID='xxxxxxxxxxxxxxxxx';

  function __construct(){
    $this->token=FB_TOKEN;
  }

  public function get_ids(){
    $url = self::ENDPOINT_URL.self::USER_ID."/media?fields=permalink,media_url&limit=5&access_token=".$this->token;
    $curl = curl_init();
    curl_setopt($curl,CURLOPT_URL,$url);
    curl_setopt($curl,CURLOPT_CUSTOMREQUEST,'GET');
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
    $res = curl_exec($curl);
    curl_close($curl);
    $html="";
    if ($res){
      $obj = json_decode($res);
      if (property_exists($obj,"data")){
        foreach ($obj->data as $article){
          $html .=<<<EOT
    <div class="grid-wrapper">
      <div class="grid-inner">
        <a href="$article->permalink">
          <div class="grid-inner-image" style="background-image: url('$article->media_url')">
          </div>
        </a>
      </div>
    </div>

EOT;
        }
      }
    }
    echo $html;
  }
}
```