Instagram基本表示APIをkurocoから呼び出してInstagramのフィードを表示する

概要

Kurocoは自由にAPIを作成でき、さらに外部のAPIにリクエストを送るプラグインを持っているため、外部システム連携に表示されていないサービスについても、カスタム処理やバッチ処理に動作を記述することで利用が可能です。
本チュートリアルはその例として、Instagram基本表示APIを利用してみます。

kurocoの外部システム連携にInstagramの項目はありませんが、{api}のプラグインでInstagram基本表示APIにリクエストを送ることで、Instagramのフィードを表示します。

学べること

以下の手順でInstagramのフィードを表示します。

前提条件

以下のアカウントが必要になりますので、持っていない場合はアカウントを作成してください。

  • Facebook開発者アカウント。
  • Instagramアカウント。

また、このページはKurocoとNuxt.jsでのプロジェクトが構築済みであることを前提としています。 まだ構築していない場合は、下記のチュートリアルを参照してください。

Instagram基本表示APIは公式ドキュメントを参考に実装しています。
差分があった場合は公式ドキュメントの記載を優先させて下さい。

Instagramの設定

Facebookアプリを作成する

developers.facebook.com/appsにアクセスし、[アプリを作成]をクリックします。
Image from Gyazo

[その他]を選択して[次へ]をクリックします。
Image from Gyazo

アプリタイプは[なし]を選択します。
Image from Gyazo

アプリ名を入力して[アプリを作成]をクリックします。
Image from Gyazo

アプリが作成されてアプリダッシュボードが表示されたら、[設定] -> [バーシック]に移動し、ページの下までスクロールして[プラットフォームを追加]をクリックします。
Image from Gyazo

Websiteを選択して[次へ]をクリックします。
Image from Gyazo

サイトURLの入力欄が表示されるので、KurocoのフロントエンドURLを入力して[変更を保存]をクリックします。
Image from Gyazo

Instagramアプリを作成する

ダッシュボードに戻り、製品を追加の項目からInstagram Basic Displayを探して[設定]をクリックします。
Image from Gyazo

ページの下部にスクロールして[Create New App]をクリックします。

Image from Gyazo

Facebookアプリのアプリ名が表示されているので、そのまま[アプリを作成]をクリックします。
Image from Gyazo

Instagramアプリが作成されたら、「有効なOAuthリダイレクトURI」「コールバックURLの許可の取り消し」「データの削除リクエストURL」にhttps://フロントエンドURL/auth/のURLを入力し、[変更を保存]をクリックします。
「コールバックURLの許可の取り消し」「データの削除リクエストURL」は、最終的にはその処理をできるURLに変更しますが、ここではOAuthリダイレクトURIと同じにして構いません。
Image from Gyazo

Instagramテストユーザーを追加する

[アプリの役割]->[役割]に遷移し、下にある[Instagramテスター]セクションまでスクロールして、[Instagramテスターを追加]をクリックします。
Image from Gyazo

Instagramアカウントのユーザーネームを入力し、送信をクリックします。
Image from Gyazo

www.instagram.comにアクセスして、先ほど招待したInstagramアカウントにサインインします。(プロフィールアイコン) -> [プロフィールを編集] -> [アプリとウェブサイト] -> [テスターの招待]に移動し、招待を受け入れます。
Image from Gyazo

これで、Instagramアカウントは、開発モードになっていても、Facebookアプリからアクセスできるようになりました。

処理の流れの確認

ユーザーの認証から、長期Instagramユーザーアクセストークンの取得までの流れを確認します。

ユーザーの認証は、以下のURLから始まります。

https://api.instagram.com/oauth/authorize?client_id={app-id}&redirect_uri={redirect-uri}&scope=user_profile,user_media&response_type=code

{app-id}と、{redirect-uri}は[INstagram Basic Display]->[Basic Display]の「InstagramアプリID」と「有効なOAuthリダイレクトURI」に置き換えます。
InstagramアプリIDはフェイスブックアプリIDと異なることに注意してください。

Image from Gyazo

例えば以下のようなURLになります。
https://api.instagram.com/oauth/authorize?client_id=684477648739411&redirect_uri=https://socialsizzle.herokuapp.com/auth/&scope=user_profile,user_media&response_type=code

ご自身のInstagramアプリに対応したURLへアクセスすると以下の画面が表示されます。
Image from Gyazo

[許可する]をクリックすると、 指定したリダイレクトURIにリダイレクトされ、URLに認証コードが付加されます。
Image from Gyazo

こちらの認証コードをInstagramアプリIDやInstagram App Secretと共にInstagramのAPIにリクエストすることで、アクセストークンと交換してます。
さらに取得したアクセストークンとユーザーIDをInstagramのAPIにリクエストすることで、Instagramのフィードを取得します。

Kurocoの設定(事前準備)

ここからはKurocoで設定をしていきます。

コンテンツ定義の作成

まずはInstagram長期アクセストークンと、Instagramフィードを保存するコンテンツ定義を作成します。

コンテンツ定義一覧の画面から[追加]をクリックします。
Image from Gyazo

以下の内容で設定をします。

項目設定
名前Instagram
ID=1項目設定:テキスト
項目名:アクセストークン
識別子:token
繰り返し回数:1
ID=2項目設定:テキスト
項目名:メディアURL
識別子:media_url
繰り返し回数:6

Image from Gyazo Image from Gyazo Image from Gyazo

設定ができたら[追加する]をクリックしてコンテンツ定義を追加します。

コンテンツの作成

後で作成するカスタム処理でコンテンツを更新していくように実装するため、空のコンテンツを作成しておきます。

コンテンツ一覧の画面から[追加]をクリックします。
Image from Gyazo

以下を入力し、[追加する]をクリックします。

項目
Slug:instagram
タイトル任意のタイトル

Image from Gyazo Image from Gyazo

定数とシークレットの作成

InstagramアプリIDと、Instagram App SecretはKurocoのカスタム処理で何度か利用する為、定数とシークレットに登録しておきます。
特に機密性の高いものはシークレットに登録することをお勧めします。

InstagramアプリのBasic DisplayからInstagramアプリIDと、Instagram App Secretを確認します。
Image from Gyazo

Kurocoの管理画面に戻り、[環境設定]->[定数]から[追加]をクリックします。
Image from Gyazo

以下を入力して、[追加する]をクリックします。

項目設定
名前INSTAGRAM_APP_ID
InstagramアプリID

Image from Gyazo

追加が完了すると、Smartyで呼び出すための変数が表示されます。
Image from Gyazo

次に、[環境設定]->[シークレット]から[追加]をクリックします。
Image from Gyazo

以下を入力して、[追加する]をクリックします。

項目設定
名前INSTAGRAM_APP_ID
Instagram App Secret

Image from Gyazo

追加が完了すると、Smartyで呼び出すための変数が表示されます。
Image from Gyazo

APIの作成

内部処理用のAPI作成

Kuroco内部でのみ利用するエンドポイントはAPIを分けておくことをお勧めします。
そこで、まずは内部利用のためのAPIを新規で作成します。
既に追加済みの場合は次のステップに進んで構いません。

APIの作成

Kuroco管理画面のAPIより「追加」をクリックします。

Image from Gyazo

API作成画面が表示されるので、下記入力し「追加する」をクリックします。

Image from Gyazo

項目設定内容
タイトルInternal
1.0
ディスクリプション内部処理用のAPI

APIが作成されました。

Image from Gyazo

セキュリティの設定

次にセキュリティの設定をします。[セキュリティ] をクリックします。

Image from Gyazo

セキュリティを[動的アクセストークン]に設定して、[保存する]をクリックします。

Image from Gyazo

セキュリティを[動的アクセストークン]に設定後、Login::tokenのエンドポイントが無い場合、利用をお勧めされますが、内部利用のみの場合は無視して構いません。

Image from Gyazo

CORSの設定

次にCORSの設定をします。[CORSを設定する] をクリックします。

Image from Gyazo

CORS_ALLOW_ORIGINSの [Add Origin] をクリックし、下記を追加します。

  • 管理画面URL

CORS_ALLOW_METHODSの [Add Method] をクリックし、下記を追加します。

  • GET
  • POST
  • OPTIONS

CORS_ALLOW_REDENTIALSの[Allow Credentials]にチェックが入っていることを確認します。

Image from Gyazo

問題なければ [保存する] をクリックします。

KurocoとNuxt.jsで認証の動作を実装する

エンドポイントの作成

エンドポイントはフロントエンドから認証コードを受け取るためのinstagram_authエンドポイントと、取得した長期アクセストークンをKurocoに保存するためのinstagram/updateエンドポイントの2つを作成します。

instagram_authエンドポイント

instagram_authエンドポイントはフロントエンドからリクエストを送るため、DefaultのAPIから[新しいエンドポイントの追加]をクリックします。

Image from Gyazo

以下のエンドポイントを作成します。

項目設定内容
パスinstagram_auth
カテゴリーAPI
モデルApi
オペレーションrequest_api_post
nameinstagram_auth
(後で設定するカスタム処理の識別子と一致させます。)

Image from Gyazo Image from Gyazo

設定ができたら[追加する]をクリックしてエンドポイントを追加します。

instagram/updateエンドポイント

instagram/updateエンドポイントはカスタム処理から呼び出す内部向けのエンドポイントになるため、InternalのAPIから[新しいエンドポイントの追加]をクリックします。

Image from Gyazo

以下のエンドポイントを作成します。

項目設定内容
パスinstagram/update
カテゴリーコンテンツ
モデルTopics
オペレーションupdate
topics_group_id先ほど作成したコンテンツ定義のID(8)

Image from Gyazo Image from Gyazo

設定ができたら[追加する]をクリックしてエンドポイントを追加します。

カスタム処理の作成

[オペレーション] -> [カスタム処理]をクリックします。

Image from Gyazo

[追加]をクリックします。

Image from Gyazo

以下のように入力します。

項目設定
タイトルinstagram_auth
識別子instagram_auth
(Api::request_apiエンドポイントのnameと一致させてください。)
処理以下のコード
{* 短期トークンの取得 *}
{append var=headers value="Content-Type': 'application/x-www-form-urlencoded"}
{assign_array var='body'            values=''}
{assign       var='body.client_id'    value=$smarty.const.INSTAGRAM_APP_ID}
{secret       var='body.client_secret' key='INSTAGRAM_APP_SECRET'}
{assign       var='body.grant_type' value='authorization_code'}
{assign       var='body.redirect_uri' value="`$smarty.const.ROOT_URL`/auth/"}
{assign       var='body.code' value=$smarty.request.code}

{api
    endpoint='https://api.instagram.com/oauth/access_token'
    method='POST'
    headers=$headers
    body=$body
    var=response1
    status_var=status1
}

{* apiプラグインのレスポンスをjson形式に変換*}
{assign var=response1 value=$response1|@json_decode}
{logger msg1="短期アクセストークンの取得" msg2=$body msg3=$response1 msg4=$status1}

{* 長期トークンの取得 *}
{assign_array var='body2'            values=''}
{secret       var='body2.client_secret' key='INSTAGRAM_APP_SECRET'}
{assign       var='body2.grant_type' value='ig_exchange_token'}
{assign       var='body2.access_token' value=$response1.access_token}

{api
    endpoint='https://graph.instagram.com/access_token'
    method='GET'
    queries=$body2
    var=response2
    status_var=status2
}

{* apiプラグインのレスポンスをjson形式に変換*}
{assign var=response2 value=$response2|@json_decode}
{logger msg1="長期アクセストークンの取得" msg2=$body2 msg3=$response2 msg4=$status2}

{* 長期トークンをコンテンツに追加 *}
{assign_array var='body3'            values=''}
{assign       var='body3.token'    value=$response2.access_token}

{if $response2.access_token != null}
    {api_internal
        var='response'
        status_var='status'
        endpoint='/rcms-api/4/instagram/update/instagram'
        method='POST'
        queries=$body3
        member_id='1'}
{/if}

Image from Gyazo

入力ができたら[追加する]をクリックしてカスタム処理を追加します。

フロントエンドの実装

次にリダイレクトURIにアクセスがあった場合に、Kurocoのエンドポイントに認証コードを送信し、カスタム処理を動作させる処理をフロントエンドで実装します。

/pages/auth/のディレクトリに以下のindex.vueファイルを作成します。

/auth/index.vue
<template>
  <div>
    <p>認証が完了しました</p>
  </div>
</template>

<script>
export default {
  validate({ query }) {
        return query.code != null
    },
  methods: {
    async makeAccessToen() {
      const payload = {
        code: this.$route.query.code
      }
      await this.$axios.post('/rcms-api/1/instagram_auth', payload);
    }
  },
  mounted($route) {
    this.makeAccessToen();
  }
}
</script>

動作確認

以下のURLにアクセスして、[許可する]をクリックします。

https://api.instagram.com/oauth/authorize?client_id={app-id}&redirect_uri={redirect-uri}&scope=user_profile,user_media&response_type=code

{app-id}と、{redirect-uri}は[INstagram Basic Display]->[Basic Display]の「InstagramアプリID」と「有効なOAuthリダイレクトURI」に置き換えます。

リダイレクトURIに遷移し、コンテンツにアクセストークンが保存されていることを確認します。
Image from Gyazo

Image from Gyazo

Kurocoで定期的にInstagramのフィードを取得する

Instagramの情報はKurocoのバッチ処理で定期的に取得しに行き、コンテンツを更新するように実装します。

バッチ処理の作成

[オペレーション] -> [バッチ処理]をクリックします。

Image from Gyazo

[追加]をクリックします。

Image from Gyazo

以下のように設定します。

項目設定内容
タイトルinstagram_get_media
識別子instagram_get_media
バッチ毎日 00:00
処理以下のコード
{*現在の長期アクセストークンの取得*}
{assign_array var='method_params'           values=''}
{assign       var='method_params.topics_id' value="instagram"}
{api_method
    var='response'
    model='Topics'
    method='details'
    version='1'
    method_params=$method_params}

{*最新のメディアデータ取得*}
{assign_array var='body'            values=''}
{assign       var='body.fields'    value='media_url'}
{assign       var='body.access_token' value=$response.details.token}
{assign       var='body.limit' value=6}

{api
    endpoint='https://graph.instagram.com/me/media'
    method='GET'
    queries=$body
    var='media'
    status_var=status
}

{* apiプラグインのレスポンスをjson形式に変換 *}
{assign var=media value=$media|@json_decode}

{* apiプラグインのレスポンスをアップデート用の配列に変換 *}
{assign_array var='data.media_url' values=''}
{foreach from=$media.data item=foo}
    {append var='data.media_url' value=$foo.media_url}
{/foreach}

{* コンテンツを更新 *}
{api_internal
        var='response2'
        status_var='status'
        endpoint='/rcms-api/4/instagram/update/instagram'
        method='POST'
        queries=$data
        member_id='1'}

{logger msg1="Instagramメディアの取得" msg2=$response2}

Image from Gyazo

入力ができたら[追加する]をクリックしてバッチ処理を追加します。

動作確認

最後に、[すぐに実行する]をクリックして動作の確認をします。

Image from Gyazo

正しく設定ができていれば以下のようにInstagramメディアURLがコンテンツに保存されます。

Image from Gyazo

Kurocoで定期的に長期アクセストークンを更新する

Instagram基本表示APIの長期アクセストークンは有効期限が60日となっています。
Instagram側で長期アクセストークンを更新するエンドポイントが準備されているので、定期的にリクエストを送るバッチ処理を作成します。

バッチ処理の作成

[オペレーション] -> [バッチ処理]をクリックします。

Image from Gyazo

[追加]をクリックします。

Image from Gyazo

以下のように設定します。

項目設定内容
タイトルupdate_token
識別子update_token
バッチ毎日 01:00
処理以下のコード
{*現在の長期アクセストークンの取得*}
{assign_array var='method_params'           values=''}
{assign       var='method_params.topics_id' value="instagram"}
{api_method
    var='topics'
    model='Topics'
    method='details'
    version='1'
    method_params=$method_params}

{* 長期トークンの更新 *}
{assign_array var='body'            values=''}
{assign       var='body.grant_type' value='ig_refresh_token'}
{assign       var='body.access_token' value=$topics.details.token}

{api
    endpoint='https://graph.instagram.com/refresh_access_token'
    method='GET'
    queries=$body
    var=response
    status_var=status
}

{* apiプラグインのレスポンスをjson形式に変換*}
{assign var=response value=$response|@json_decode}
{logger msg1="長期アクセストークンの更新" msg2=$body msg3=$response msg4=$status}

{* 長期トークンをコンテンツに追加 *}
{assign_array var='body2'            values=''}
{assign       var='body2.token'    value=$response.access_token}

{if $response.access_token != null}
    {api_internal
        var='response'
        status_var='status'
        endpoint='/rcms-api/4/instagram/update/instagram'
        method='POST'
        queries=$body2
        member_id='1'}
{/if}

Image from Gyazo

入力ができたら[追加する]をクリックしてバッチ処理を追加します。

動作確認

最後に、[すぐに実行する]をクリックして動作の確認をします。

Image from Gyazo

正しく設定ができていればコンテンツのアクセストークンが更新されます。

Image from Gyazo

KurocoとNuxt.jsでInstagramのフィードを表示する

ここまで準備ができたら後はKurocoのコンテンツに追加したInstagramのメディアURLをフロントに表示するだけです。

エンドポイントの作成

DefaultのAPIから[新しいエンドポイントの追加]をクリックします。

Image from Gyazo

以下のエンドポイントを作成します。

項目設定内容
パスinstagram
カテゴリーコンテンツ
モデルTopics
オペレーションdetails
topics_group_idコンテンツ定義のID(8)

Image from Gyazo Image from Gyazo

設定ができたら[追加する]をクリックしてエンドポイントを追加します。

フロントエンドの実装

フロントエンドは/pages/instagram/のディレクトリに以下のindex.vueファイルを作成しました。

/pages/instagram/index.vue
<template>
  <div>
    <h2>Instagram</h2>
    <div class="square_contents">
      <a v-for="(n,i) in response.details.media_url" :key=i href="https://www.instagram.com/" target="_blank">
        <img :src=n>
      </a>
    </div>
  </div>
</template>

<script>
export default {
  async asyncData({ $axios }) {
    return {
      response: await $axios.$get('/rcms-api/1/instagram/instagram'),
    };
  },
};
</script>

<style>
.square_contents {
  display: flex;
  flex-wrap: wrap;
  width:720px;
}
.square_contents a {
  display: block;
  position: relative;
  width: 31%;
  margin: 1%;
}
.square_contents a::before {
  content: "";
  display: block;
  padding-top: 100%;
}
.square_contents img {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  object-fit: cover;
}
</style>

表示の確認

フロントエンドの表示を確認すると、Instagramのフィードが表示できていることが確認できます。

Image from Gyazo

以上で、Instagramのフィードが表示され、更新があった場合も自動でKucoroのコンテンツが更新されるようになりました。

今回はInstagramのフィードを表示させるのみのため、Instagram基本表示APIを利用しましたが、@メンションやハッシュタグが付いたメディアの特定、他のInstagramユーザーに関するデータの取得、ストーリーズの利用等をする場合は同様の手順でInstagramグラフAPIを利用ください。

関連ドキュメント

お探しのページは見つかりましたか?解決しない場合は、問い合わせフォームからお問い合わせいただくか、Slackコミュニティにご参加ください。