インスタグラムのタイムライン的なのをつくる

#更新（2020.1.29）
Instagram API Platform が廃止になったようで、アクセストークンの取得やAPIアクセス部分が変わった様です。
Facebookとの連携が必要になり、トークンも有効期限が設けられた様です。
https://developers.facebook.com/docs/instagram-basic-display-api/

こちらの記事にて、無期限のトークンの取得方法が記載されておりました。
[Instagram（インスタグラム）のアクセストークンの取得方法](https://ferret-plus.com/13130)（2019.11.02）

#更新（2018.10.15）
今更ながら、APIを取得する部分の処理を変更しました！
file_get_contentsからcURLを使用するようにしました。
理由としては、file_get_contentsでタイムアウトしたときに、サイトが表示できなくなってしまったためです…。

#インスタの投稿をWEBページに埋め込みたい
SNSの投稿をWEBページに埋め込んでるサイトは結構多いと思います。
Twitterのタイムラインや、Facebookの投稿などは、簡単に埋め込むことができます。

しかし、Instagramは、投稿の一覧ではなく、投稿ごとでしか埋め込むことができません。
Twitterのタイムラインみたいにしたい！というとき、APIを使って色々やらなければならないのですが、これが意外と調べても載っていない…。
ということで、調べたことをまとめてみました。

**参考にしたサイトは結構古いサイトです。もし、新しい方法とかあれば教えてください！**

出来上がるタイムライン部分はこんな感じ

<img width="300px" alt="インスタタイムライン.png" src="https://qiita-image-store.s3.amazonaws.com/0/195419/67c0d176-9478-4dc4-dcf5-795e3326723c.png">


#外部サービスを利用する
[Snapwidget](https://snapwidget.com/)
調べると一番多く出てくるのがこれでした。

手っ取り早く使いたい〜という時はこれで十分かなと思います。

#自分でAPIを取得して投稿をとってくる
なかなか情報が見つからなかったのがこっち。
どうやら、Instagramは他人の投稿一覧を表示させるものに関しては審査などがあり、厳しいようです。
なので、業者に頼んだ方がいいとか、ぜひ依頼してくださいとかで、結局どうすればいいのかがあまり見つからず…。

でも、自分の投稿情報を持ってくるだけなら、特に審査とか必要なくとってくることができます。

##APIの取得
[Instagram Developer](https://www.instagram.com/developer/)に登録してから取得します。

詳しい取得の仕方とかは、いろんなサイトで説明しているので、そちらを見た方がわかりやすいです。
ちなみに登録するときに、**「Security」**タブに切り替えて**「Disable implicit OAuth」**のチェックを外さないと、トークンを取ってくるときにエラーになります。
（私はチェック外し忘れて30分くらいつんでました）
####ここで参考にしたサイト
[Instagram APIを使ってWEBサイトに写真を表示させてみよう](https://capotast.co.jp/article/detail/21/)
[Instagram APIを取得してWebサイトと連携し、投稿写真を自動に掲載する方法](https://liginc.co.jp/web/service/other-service/146750)

#さっそく取ってきてみる！
上で参考にしたサイトでも、取ってきてくれる方法は載せてくださってました。
でも色々やりかたがありすぎて。
とりあえず取ってきたいんだ！って人はコピペして使うといいと思います。
（保証はいっさいしません！）

##表示側

```php:instagram.php
        <div class="inst">
            <div class="inst_wrap">
                <div class="inst_container">
                <?php 
                    get_instagram();
                 ?>
                </div>
            </div>
        </div><!-- インスタ -->
```
##取ってきてる部分
```php:function.php

<?php
function get_instagram(){
    $option = [
        CURLOPT_RETURNTRANSFER => true, //文字列として返すかどうか
        CURLOPT_TIMEOUT        => 3, // タイムアウト時間
    ];

    $myAccessToken = '[取ってきたアクセストークン]';
    $count = 9; //表示件数
    $url = 'https://api.instagram.com/v1/users/self/media/recent/?access_token='.$myAccessToken."&count=".$count;

    
    $ch = curl_init($url);
    curl_setopt_array($ch, $option);
    
    $json    = curl_exec($ch);
    $info    = curl_getinfo($ch);
    $errorNo = curl_errno($ch);

    if ($errorNo !== CURLE_OK) {
        // 詳しくエラーハンドリングしたい場合はerrorNoで確認
        // タイムアウトの場合はCURLE_OPERATION_TIMEDOUT
        return [];
    }
    
    // 200以外のステータスコードは失敗とみなし空配列を返す
    if ($info['http_code'] !== 200) {
        return [];
    }
    
    //取ってきた内容を読み込んで、取得した件数分まわす
    $obj = json_decode($json);
    foreach($obj->data as $data){
        print('<div class="inst_list_item">');
        print('<div class="inst_thumb_wrap">');
        print('<div class="inst_thumb">');
        printf('<a href="%s" target="_blank">',$data->link);
        printf('<img src="%s" alt="">',$data->images->low_resolution->url);
        print('</a>');
        print('</div>');
        print('</div>');
        print('<div class="inst_comment">');
        printf('<p><i class="fa fa-heart" aria-hidden="true"></i>いいね　%d</p>',$data->likes->count);
        print('</div>');
        print('</div>');
    };
}//インスタ取得終了

```

##レイアウト

```css:instagram.css
.inst_wrap{
    background: #fff;
    width: 300px;
    border-radius: 4px;
    overflow: hidden;
    border: 1px solid #d5d5d5;
}
.inst_container{
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    padding: 5% 0;
}
.inst_list_item{
    width: 30%;
    margin: 1px;
    border: 1px solid #f1f1f1;
}
.inst_thumb img{
    width: 100%;
    height: 90px;
    object-fit: cover;
    object-position: 0% 0%;
    opacity: 1;
    -webkit-transition: .3s ease-in-out;
    transition: .3s ease-in-out;
}
.inst_thumb:hover img{
    opacity: .5;
}
.inst_comment{
    font-size: 12px;
    padding: 5%;
}
```
#中身の解説
じゃあ、どこがどこの機能を担当してるの？という部分を解説します。

##取ってきてる部分
表示されてる中身、投稿された画像や日付、いいね数などをとってきてる部分について部分ごとに解説します。

###自分の投稿データをとってくる
```php
$myAccessToken = '[アクセストークン]';
$count = 9;
$json = file_get_contents('https://api.instagram.com/v1/users/self/media/recent/?access_token='.$myAccessToken."&count=".$count);
```
アクセストークンから、自分の投稿に関して取得してきます。
$countは投稿の取得件数です。
**一番新しい投稿から**取得されるので、最新の投稿を9件取得しています。
これを調整すればベージング処理とかもできると思いますが、面倒なので私はこれで…。

この取ってきたデータは、json形式なようです。
var_dumpで中身を確認すると、ゔああああああっとすごい文字が表示されました。

###取ってきた投稿データの中身をみる
```php
$obj = json_decode($json);
```
json形式のデータなので、phpで使えるようにします。
といってもそれ以上の詳しいことは、私にはわかりませんでした。勉強します。

とりあえず、json形式のデータが変換されて配列で取得できるようになるみたいです。

###投稿内容を表示させる
```php
foreach($obj->data as $data){
    //処理する内容
}
```
よくあるforeach文です。
変換したデータは、配列になっているので、これで回して中身を呼び出すことができます。

#####**投稿記事へのリンクの取得**

```php
<a href="<?php echo $data->link; ?>" target="_blank"></a>
```
`$data->link`の部分が、投稿記事へのリンクを配列からとってきています。

#####**投稿された画像を取得**

```php
<img src="<?php echo $data->images->low_resolution->url; ?>" alt="">
```
`$data->images->low_resolution->url`の部分が投稿された画像のリンクを取得しています。

#####**投稿記事のいいね数を取得**
```php
<p><i class="fa fa-heart" aria-hidden="true"></i>いいね　<?php echo $data->likes->count; ?></p>
```

`$data->likes->count`の部分が、いいね数を取得してます。


####取得できる投稿情報一覧
じゃあコメントとかキャプションとかはどう書けばとってこれるの？？

ここが調べても調べてもわからなかった…んですが、載せてくれているところがありました。
[Instagram API から投稿画像を取得しスライダー/カルーセル表示](http://www.lesson5.info/?p=262)

この中から多分よく使うだろうというものを抜粋してご紹介します。
最初の$dataの部分は、foreachで使用している変数名です。

| パラメーター | 内容 |
|:--:|:--|
| $data->pagination | ページネーション(次ページ情報) |
| $data->next_url | 次ページのURL |
| $data->data->id | 投稿のメディアID |
| $data->data->tags[] | 投稿に付けられたハッシュタグ(配列形式) |
| $data->data->type | 投稿のメディアタイプ<br>画像か動画かとか |
| $data->data->location->name | 場所名 |
| $data->comments->count | コメント数 |
| $data->comments->data[] | それぞれのコメントデータ<br>(配列形式で最新8件まで) |
| $data->comments->data[]->text | コメントのテキスト |
| $data->created_time | 投稿日時 |
| $data->link | 投稿へのURL |
| $data->likes->count | ライク数 |
| $data->images->low_resolution{} | 306×306の画像情報 |
| $data->images->thumbnail{} | 150×150の画像情報 |
| $data->images->standard_resolution{} | 640×640の画像情報 |
| [上の部分の{}の手前まで]->url | 画像へのURL |
| $data->caption{} | キャプションの情報<br>作品の説明部分 |
| $data->caption->text | キャプションのテキスト |
| $data->user{} | 投稿者のユーザー情報 |

他は上記URLのサイトをみると、もっと載っています。

###投稿を一覧っぽく表示させる
ここはもう、個人の好きな感じでいいと思います。
foreachの中は、投稿１件なので、ループしたいHTMLはそこに記述する感じです。

#おまけ
ヘッダー部分がないので、ヘッダーっぽいのをつくって、自分のインスタURLに飛ぶようにするとそれっぽくなると思います。
ついでに、フォローボタンをつけたい人は、こちらのサイトを参考にするといいと思います。

[美しいInstagramフォローボタンのCSSデザイン例と設置方法](https://saruwakakun.com/html-css/reference/instagram)
[新しいInstagramの公式フォローボタンがない！公式風の改造CSSをブログに設置する方法](http://blog.shinoegg.com/entry/2017/10/24/203217)

私が簡単につくったものも紹介します。
<img width="300px" alt="インスタタイムライン_ヘッダー.png" src="https://qiita-image-store.s3.amazonaws.com/0/195419/054a4fa3-ec07-d29f-34df-f43a8d4ddb26.png">


##表示の部分

```html
<div class="inst_prof">
    <div class="inst_prof_wrap">
        <a class="inst_prof_link" href="https://www.instagram.com/[ユーザー名]/" target="_blank">
            <span class="inst_prof_title">おなまえ</span>
            <i class="fa fa-instagram" aria-hidden="true"></i>
        </a>
    </div>
    <div class="inst_follow_wrap">
        <a href="https://www.instagram.com/[ユーザー名]/?ref=badge" class="inst_follow">
            <i class="fa fa-instagram"></i> <span>Follow Me</span>
        </a>
    </div>
</div>
```
##CSSの部分
```css
.inst_prof{
    height: 30px;
    padding: 5%;
    text-align: center;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    border-bottom: 1px solid #d5d5d5;
}
.inst_prof_wrap{
    width: 70%;
}

.inst_prof_link{
    font-size:32px;
    color: #000;
    font-family: YuGothic,'Yu Gothic';
    text-decoration: none;
    opacity: 1;
    -webkit-transition: .3s ease-in-out;
    transition: .3s ease-in-out;
}
.inst_prof_link:hover{
    opacity: 0.5;
}
.inst_prof_title{
    /* グラデーション */
    background: -webkit-linear-gradient(135deg, #427eff 0%, #f13f79 70%) no-repeat;
    background: linear-gradient(135deg, #427eff 0%, #f13f79 70%) no-repeat;
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text; /* 文字部分をグラデーションにする */
    padding: 4px;
}
/*--------------
    follow button
----------------*/
.inst_follow_wrap{
    width: 30%;
}
.inst_follow{
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    text-decoration:none;
    color: #FFF;
    border-radius: 5px;
    position: relative;
    font-size: 14px;
    padding: 2px;

    /* グラデーション部分 */
    background: -webkit-linear-gradient(135deg, #427eff 0%, #f13f79 70%) no-repeat;
    background: linear-gradient(135deg, #427eff 0%, #f13f79 70%) no-repeat;
    overflow: hidden;
    /* hover時のアニメーション */
    opacity: 1;
    -webkit-transition: .3s ease-in-out;
    transition: .3s ease-in-out;
}

.inst_follow:before{
  /* グラデーション */
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: -webkit-linear-gradient(15deg, #ffdb2c, rgb(249, 118, 76) 25%, rgba(255, 77, 64, 0) 50%) no-repeat;
  background: linear-gradient(15deg, #ffdb2c, rgb(249, 118, 76) 25%, rgba(255, 77, 64, 0) 50%) no-repeat;
}
.inst_follow:hover{
      opacity: 0.5;
}
.inst_follow .fa-instagram{
  /* アイコン */
  font-size: 18px;
  position: relative;
}

.inst_follow span {
  /* 文字部分 */
  position: relative;
  transition: .5s
}

.inst_follow:hover span{
  /*ホバーで一周回転*/
  -webkit-transform: rotateX(360deg);
  -ms-transform: rotateX(360deg);
  transform: rotateX(360deg);
}
```

最後、ヘッダー部分とタイムライン部分を囲ってしまえば、Twitterのような埋め込みタイムラインの完成です。

#参考サイト
##API・中身部分
[Instagram APIを使ってWEBサイトに写真を表示させてみよう](https://capotast.co.jp/article/detail/21/) （2016.10.10）
[Instagram APIを取得してWebサイトと連携し、投稿写真を自動に掲載する方法](https://liginc.co.jp/web/service/other-service/146750) （2015.02.18）
##データの取得内容部分
[instagramをホームページに埋め込む方法](https://vegl.biz/2017/03/04/instagram%E3%82%92%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AB%E5%9F%8B%E3%82%81%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95/)（2017.03.04）
[Instagram API から投稿画像を取得しスライダー/カルーセル表示](http://www.lesson5.info/?p=262)（2015.4.10）
[APIなどにfile_get_contents()を使うのはオススメしない理由と代替案](https://qiita.com/shinkuFencer/items/d7546c8cbf3bbe86dab8)（2017.01.24）


##ヘッダーのCSS部分
[美しいInstagramフォローボタンのCSSデザイン例と設置方法](https://saruwakakun.com/html-css/reference/instagram)
[新しいInstagramの公式フォローボタンがない！公式風の改造CSSをブログに設置する方法](http://blog.shinoegg.com/entry/2017/10/24/203217)