Instagram APIを使ってみた

Instagramの投稿一覧を表示してみたくなったのでInstagram Graph APIを使って表示させてみた。

# 準備

Instagramのアカウントをビジネスアカウントに切り替える。（アプリでしか出来ない？）
[設定]-[アカウント]-[プロアカウントに切り替える]

facebookでページの作成をする。
[設定とプライバシー]-[設定]-[ページを作成]（フッターにある）

## Instagramアカウントをfacebookにリンク

facebookのページの設定でInstagramアカウントをリンクする。
[ページ設定]-[Instagram]-[アカウントをリンク]
![スクリーンショット 2020-05-17 0.04.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76063/90019eaa-fc27-eb9f-ce10-74b6ffbd0bd5.png)


## facebook for developersでアプリを作成

アカウントを作成してアプリを作成する。
[facebook for developers](https://developers.facebook.com/)

## アプリのプロダクトにInstagramを追加

[プロダクト]-[Instagram]
<img width="573" alt="スクリーンショット 2020-05-15 21.05.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76063/42613bd0-271e-4016-fbe7-fb39d791b413.png">

## アクセストークンの作成

グラフAPIエクスプローラを表示する。
<img width="330" alt="スクリーンショット 2020-05-15 21.03.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76063/34f27437-9230-8cf9-f928-0a44cd7d6709.png">

Facebookアプリ、ユーザまたはページ、アクセス許可を設定する。
![スクリーンショット 2020-05-15 21.08.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76063/9929074c-609b-8ef2-8e02-7a2af03dce92.png)

Facebookアプリには**作成したアプリ**を設定
ユーザまたはページには**ユーザートークン**を設定
アクセス許可には
**pages_show_list**
**instagram_basic**
を設定

（画像にはあるけど）以下は無くても大丈夫。
business_management
instagram_manage_comments
instagram_manage_insights

[Generate Access Token]ボタンをクリックするとアクセストークンが作成される。

## Instagram User IDを調べる

グラフAPIエクスプローラで`me/accounts?fields=id`を入力して送信ボタンをクリックする。
![スクリーンショット 2020-05-17 11.28.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76063/8d894e08-e75f-c04f-6389-e3579eb95fca.png)

続けて取得したidを使って`000000000000000?fields=instagram_business_account`を入力して送信ボタンをクリックする。
![スクリーンショット 2020-05-17 11.28.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76063/2388fd26-d82c-3459-7388-f87327d5f8a2.png)

Instagram User IDが表示される。

# 実装

ページ表示時に自分の投稿一覧をタイル状に表示させてみる。
<img width="847" alt="スクリーンショット 2020-05-18 21.44.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76063/49b5d32a-1dba-e915-3f3f-0bacef257da1.png">


```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Instagram</title>
</head>

<body>

  <div class="container"></div>

  <script src="./app.js"></script>
</body>

</html>
```

```javascript:app.js
import style from './style.scss';

const apiUrl = 'https://graph.facebook.com/v7.0/';
const igUserId = '10000000000000000';
const accessToken = 'トークンを入力';

document.addEventListener('DOMContentLoaded', () => {
  _getMyMeida();
});

function _getMyMeida(url = '') {
  // Get the Instagram Business Account's Media Objects
  const api = url || `${apiUrl}${igUserId}/media?fields=caption,children,comments_count,id,like_count,media_type,media_url,thumbnail_url&access_token=${accessToken}`;

  fetch(api)
    .then(response => {
      return response.json();
    })
    .then(data => {
      if (data.data !== undefined) {
        _createTile(data.data, (url === '') ? true : false);

        if (data.paging !== undefined && data.paging.next !== undefined) {
          _getMyMeida(data.paging.next);
        }
      }
    })
    .catch(error => {
      console.log(error);
    });
}

function _createTile(media, insert) {
  const container = document.querySelector('.container');
  const fragment = document.createDocumentFragment();

  media.forEach((item, i) => {
    const tile = document.createElement('div')
    tile.classList.add('tile');

    const figure = document.createElement('figure');
    const img = document.createElement('img');
    img.src = item.thumbnail_url || item.media_url;
    figure.appendChild(img);

    const caption = document.createElement('figcaption');
    caption.textContent = item.caption;
    figure.appendChild(caption);
    tile.appendChild(figure);

    fragment.appendChild(tile);
  });

  if (insert) {
    container.insertBefore(fragment, null);
  } else {
    container.appendChild(fragment);
  }
}
```

```scss:style.scss
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  height: 100vh;
  background-image: linear-gradient(to left bottom, #fa709a 0%, #fee140 100%);
}

.container {
  display: flex;
  flex-wrap: wrap;

  .tile {
    flex: 0 0 calc(100% / 5);
    position: relative;
    transition: transform 0.2s linear;
    &:hover {
      transform: scale(1.5);
      z-index: 1;
    }

    &::before {
      display: block;
      content: "";
      padding-top: 100%;
    }

    figure {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    figcaption {
      position: absolute;
      left: 2%;
      bottom: 2%;
      width: 96%;
      height: 3em;
      padding: 0 5px;
      background: rgba(80, 80, 80, 0.7);
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      overflow: hidden;
      text-overflow: ellipsis;
      color: #f0f0f0;
      font-size: 12px;
      line-height: 1.5;
    }
  }
}
```

github
[h23k/instagram-embed](https://github.com/h23k/instagram-embed)