kintoneのTOPページにInstagramハッシュタグ結果を表示してみよう

プログラム等の"挑む"


この記事はkintone 2 Advent Calendar 2020の記事です。
https://qiita.com/advent-calendar/2020/kintone
https://qiita.com/advent-calendar/2020/kintone2

この記事でお伝えしたいこと:

この記事では、Intagramのハッシュタグ検索結果を、kintoneのトップ画面(ポータル画面)に表示する仕方をご紹介します。

実施背景:そもそもアドベントカレンダーって・・?

僕は雑貨を取り扱う企業で長い間働いてたこともあり、
アドベントカレンダーは、クリスマスまでのカウントダウンを楽しむもの。
そんな、イメージがとても強いです。

僕がおもうアドベントカレンダー
https://blog.jp.flyingtiger.com/item/zebrajapan-flyingtigercopenhagen-1571890892496-apparelcloud.productclass-4613da6b-5715-4205-97bf-dca94f84316f

テック系のアドベントカレンダーにどうにかクリスマス感をだせないか
というテーマで記事を書いていきますね。

そして、テック系アドベントカレンダー初チャレンジです!!!

手取り早く、クリスマス感を出すには・・写真だ!

といってもクリスマス感って、なかなか出せないし、装飾とか苦手だしなぁ・・
そう思ったので、Instagramで素敵な写真を、ボーッと眺めていて思いました。

Photo by Yannis Cotsonis on Unsplash

こういうInstagramの写真、kintoneに表示させちゃえばいいじゃないか!
ということで、Instagramとkintone連携始めます。

大まかな連携構成

Instagram のGraphAPIを活用し、データ取得。
その結果をkintoneに出力します。

Instagram側(facebook側)の設定が少しハードル高めですが、一つ一つ潰していきましょう。
※Instgaram側の仕様・画面変更は頻繁にあるので、画面が異なる可能性があります。

そして、FacebookやInstagramの仕様が曖昧なことや、テック系アドベントカレンダー初体験なので、間違っていても生暖かい目で見守っていただけると嬉しいです。

Instagramアクセストークンを取得しよう

Instagaramからデータを所得するにはアクセストークンが必要です。
このアクセストークンは期限が設けられており、設定により無期限にすることが可能です。

ただ、今回の場合、クリスマスまで画像を表示ができればいいので、2ヶ月以内のアクセストークンを使用しています。

一時的なアクセストークン取得(数時間の期限)

Facebook

へアクセスします。ここでアプリ作成を行います。

アプリというと・・
がっつりしたスマートフォンアプリのようなプログラムを想像しますが、APIを実行するための箱のようなものを想像するといいと思います。

アプリを作成 > ビジネス統合の管理 を選択します。

アプリ表示名:任意
アプリの連絡先メールアドレス:ご自身のアドレス
アプリの目的:自分自身または自分のビジネス

画面が遷移するので、Instagram グラフAPIを選択(設定)を押下。

その後メニューに戻り、詳細画面から、設定 > ベーシックに遷移します。

アプリIDapp secretメモします。
これは後のAPIの引数として使用するので、必ずメモしてください。

https://developers.facebook.com/tools/explorer/
へアクセス

この画面でAPIを実行できるようです。
Facebookアプリ:作成したアプリを選択
Generate Access Tokenを押下。

アプリのアクセストークンをFacebookのログインユーザーで作成していいか聞いてくるので、
ログインしてください。

アクセストークン枠に値が入り、アクセス許可にもpublic_profileが表示されました。
今回はInstagramにアクセスする必要があるので、アクセス許可を増やします。

以下の8つを選択した後にもう一度、Gererate Access Tokenを選択しましょう。
read_insights
publish_video
pages_show_list
business_management
instagram_basic
instagram_manage_comments
instagram_manage_insights
public_profile

先ほどとは違った内容が出てきますが、OKを押して進めていきます。
最終的に許可が終了すると、再度アクセストークンの値が変更して表示されます!

中期的なアクセストークンの取得

アクセストークンはゲットできたのですが、これは数時間で切れるらしいので、少しその期限を伸ばしてみます。

画面で中規定なアクセストークンにする方法と、APIを実行する方法両方あります。
両方紹介しますね。

その1:画面からトークンを延長する方法


アクセストークンの i部分をクリックします。


iを押したら、アクセストークンツールで開くをクリック。
ページ遷移後の最下部、アクセストークンを延長するをクリックします。

そうすると、アクセスの有効期限が3ヶ月に伸びます。
いやぁ、簡単!

その2:APIからトークンを延長する方法

ちなみにAPIで呼び出す場合は以下のようなコマンドを入れます。
FacebookのAPIページにはこう書かれていますが・・
https://developers.facebook.com/docs/facebook-login/access-tokens/refreshing?locale=ja_JP

curl -i -X GET "https://graph.facebook.com/{graph-api-version}/oauth/access_token?  
    grant_type=fb_exchange_token&
    client_id={app-id}&
    client_secret={app-secret}&
    fb_exchange_token={your-access-token}" 

画面上のここにoauthから値をいれてください。


なのでこんな感じ。

oauth/access_token?grant_type=fb_exchange_token&client_id=メモしたアプリID&client_secret=メモしたapp-secret&fb_exchange_token=先ほど取得したトークン 

この結果が、3ヶ月に延長されたトークンです。

{
  "access_token": "EAAEcFD......0v1WAB",
  "token_type": "bearer",
  "expires_in": 51...00
}

Instagraのuser_idを取得する。

続いて、ハッシュタグ検索を実際に行うInstagramのユーザーのuser_idを取得します。

実行するAPI(先に取得したアクセストークンを使用。)

me/accounts/?access_token=EAAEcFD......0v1WAB


実行結果(かなり省略してます。)

"id": "1784....3642",

ハッシュタグのIDを取得する。

今度はハッシュタグのIDを取得します。
APIを実行する時に、実際のハッシュタグ名を直接いれないんですね。

実行するAPI(先に取得した、ユーザーIDと、アクセストークンを使用)

ig_hashtag_search?user_id=17841....3642&q=クリスマス&access_token=EAAE.....m0v1WAB

結果(かなり省略してます。)

"id": "1784....10118"

一応引数として、user_idを使うのですが、どのuser_idにしても、ハッシュタグIDは同値になります。

今までの値をすべて含めて、いよいよハッシュタグデータを取得

実行するAPI(ハッシュタグID、ユーザーID、アクセストークンを使用)

1784....10118/top_media?user_id=1784....3642&fields=media_url,media_type,id,children{media_url,permalink},permalink&access_token=EAAEcF.....WAB

実行結果:一部抜粋

{
  "data": [
    {
      "media_url": "<a rel="noreferrer noopener" target="_blank" href="https://scontent-nrt1-1.cdninstagram.com/v/t51.29350-15/129242752_3542755535807926_8630538524617958287_n.jpg?_nc_cat=109&amp;ccb=2&amp;_nc_sid=8ae9d6&amp;_nc_ohc=_cUsLhH7S1UAX-Pfb3v&amp;_nc_ht=scontent-nrt1-1.cdninstagram.com&amp;oh=8630c0606ed679d37d0f58f197c90cc9&amp;oe=5FEB700A">https://scontent-nrt1-1.cdninstagram.com/v/t51.29350-15/129242752_3542755535807926_8630538524617958287_n.jpg?_nc_cat=109&amp;ccb=2&amp;_nc_sid=8ae9d6&amp;_nc_ohc=_cUsLhH7S1UAX-Pfb3v&amp;_nc_ht=scontent-nrt1-1.cdninstagram.com&amp;oh=8630c0606ed679d37d0f58f197c90cc9&amp;oe=5FEB700A</a>",

      "media_type": "IMAGE",

      "id": "<a href="https://developers.facebook.com/tools/explorer/312348116531268/?method=GET&amp;path=17844009163028327%2Ftop_media%3Fuser_id%3D17841401027013642%26fields%3Dmedia_url%2Cmedia_type%2Cid%2Cchildren%7Bmedia_url%2Cpermalink%7D%2Cpermalink%26access_token%3DEAAEcFDaIOEQBAHZBk16dZC5hZCk03WySrga5lsbvnnRYJm274XiXK1kimG1uUp4aRHZAUOZBJzukGB1DlqwipjwZCAqLQJhOfwTAMsoNNZCNdXht0lryCSvxjwMMaMcrB1l1OLvI7iZCsjvilKkvXVT4GCVT2LIS4qyhwK4LCFq2PxNGnm0v1WAB&amp;version=v9.0#">17888635738756586</a>",

      "permalink": "<a rel="noreferrer noopener" target="_blank" href="https://www.instagram.com/p/CIPzcBQJUkQ/">https://www.instagram.com/p/CIPzcBQJUkQ/</a>"
    },

  ],

  "paging": {
    "cursors": {
      "after": "OGExYmMwYjU0ZADdiNGQyNmIwNmY0OWI1N2M4ZATE0ZATUZD"
    },

    "next": "<a href="https://developers.facebook.com/tools/explorer/312348116531268/?method=GET&amp;path=17844009163028327%2Ftop_media%3Fuser_id%3D17841401027013642%26fields%3Dmedia_url%2Cmedia_type%2Cid%2Cchildren%7Bmedia_url%2Cpermalink%7D%2Cpermalink%26access_token%3DEAAEcFDaIOEQBAHZBk16dZC5hZCk03WySrga5lsbvnnRYJm274XiXK1kimG1uUp4aRHZAUOZBJzukGB1DlqwipjwZCAqLQJhOfwTAMsoNNZCNdXht0lryCSvxjwMMaMcrB1l1OLvI7iZCsjvilKkvXVT4GCVT2LIS4qyhwK4LCFq2PxNGnm0v1WAB&amp;version=v9.0#">https://graph.facebook.com/v9.0/17844009163028327/top_media?access_token=EAAEcFDaIOEQBAHZBk16dZC5hZCk03WySrga5lsbvnnRYJm274XiXK1kimG1uUp4aRHZAUOZBJzukGB1DlqwipjwZCAqLQJhOfwTAMsoNNZCNdXht0lryCSvxjwMMaMcrB1l1OLvI7iZCsjvilKkvXVT4GCVT2LIS4qyhwK4LCFq2PxNGnm0v1WAB&amp;pretty=0&amp;fields=media_url%2Cmedia_type%2Cid%2Cchildren%7Bmedia_url%2Cpermalink%7D%2Cpermalink&amp;user_id=17841401027013642&amp;limit=25&amp;after=OGExYmMwYjU0ZADdiNGQyNmIwNmY0OWI1N2M4ZATE0ZATUZD</a>"
  }

}

Javascriptで、完成したAPIを実行する。


結果がとれたので、これを上手く使って今度はkintoneに表示してみます!

はい。こんな感じでJavascript書いてみました。

JSON形式をHTMLに配置する方法がスマートにかけてないので、
もっといい方法あると思います。。。


注意点:
var URLに、最後に実行したAPIをいれてください。
いままでの実行で省略した、https://graph.facebook.com/v9.0/を頭につけるのを忘れずに!

(function () {

    'use strict';
    
    // ポータル表示時のイベント
    kintone.events.on('portal.show', function() {
   
        // ポータルの上側の空白部分の要素を取得する
        var el = kintone.portal.getContentSpaceElement();

        // XMLHttpRequestオブジェクトの作成
        var request = new XMLHttpRequest();
        var URL = 'https://graph.facebook.com/v9.0/1784...0118/top_media?user_id=1784....3642&fields=media_url,media_type,id,children{media_url,permalink},permalink&access_token=EAAEc...v1WAB';
        var roopcnt =0;
        var html_imgobj ;
        var html_divobj

        // URLを開く
        request.open('GET', URL, true);
        request.responseType = 'json';

        // レスポンスが返ってきた時の処理を記述 
        request.onload = function () {
        var jsondata = this.response.data;
        console.log(jsondata);

        //divを作る。
        html_divobj = document.createElement('div');
        html_divobj.style.margin='0 auto';
        html_divobj.style.width='80%';
        //空白部分に挿入
        el.appendChild(html_divobj);

           for (var item in jsondata) {

                //mdeia_type=CAROUSEL_ALBUMはカルーセル
                if (jsondata[item]['media_type'] ==='CAROUSEL_ALBUM'){
            
                    //カルーセルは複数写真持っているのでループ。
                    for (var chll_item in jsondata[item]['children']['data']) {
                        console.log(item + '-' + roopcnt + ':' + jsondata[item]['children']['data'][roopcnt]['media_url']);
                        
                        //imgを挿入
                        html_imgobj = document.createElement('img');
                        html_imgobj.src = jsondata[item]['children']['data'][roopcnt]['media_url'];
                        html_imgobj.style.width ='200px';
                        html_imgobj.style.height ='200px';
                        html_imgobj.style.objectfit='cover';
                        html_imgobj.style.margin='10px';
                        //divに挿入
                        html_divobj.appendChild(html_imgobj);
                        roopcnt = roopcnt + 1 ;

                    }
                
                    roopcnt = 0;
        
                //media_type=IMAGEは通常投稿
                }else if(jsondata[item]['media_type'] ==='IMAGE'){
                    
                    //imgを挿入
                    html_imgobj = document.createElement('img');
                    html_imgobj.src = jsondata[item]['media_url'];
                    html_imgobj.style.width ='200px';
                    html_imgobj.style.height ='200px';
                    html_imgobj.style.objectfit='cover';
                    html_imgobj.style.margin='10px';
                    //divに挿入
                    html_divobj.appendChild(html_imgobj);
                    console.log(item + ': ' + jsondata[item]['media_url']);
                }
       
            }
        }
        

// リクエストをURLに送信
request.send();

    });
})();

最後はこれをkintoneで表示しよう!

先に紹介したJavascriptをJSファイルに保存して、kintoneに投入します。
今回はkintoneのトップ画面での表示なので、アプリの設定ではなく、kintoneシステム管理に完成したJSファイルを配置します。

はい、これでkintoneトップ画面にいくと、クリスマスツリーの画像が表示されるはず!
お疲れ様でしたー。


めちゃくちゃクリスマスっぽいkintone!
自分で飾りつけなくても、しっかりクリスマス感じれるの嬉しいし、ほぼリアルタイムで更新されていくのも嬉しい!

ちなみに・・
facebook Graph APIには1時間あたりの回数制限があるそうです。
以下の記事を参考にしてください。
https://developers.facebook.com/docs/graph-api/overview/rate-limiting

はぁ・・初アドベントカレンダーチャレンジ緊張した。。。笑
無事やり切れてよかった・・笑

参考にしたページ:(Special Thanks!!)

グラフAPIを使って任意のハッシュタグを持つ投稿をインスタグラムから取得する
https://qiita.com/yayoshM/items/684a5702e160d0382d23

忘れやすい、複雑なJSONの要素をfor…in文で取り出す方法https://www.weed.nagoya/entry/2016/05/11/105145

kintoneポータルのカスタマイズをしてみよう
https://developer.cybozu.io/hc/ja/articles/360029930952

コメント

タイトルとURLをコピーしました