Qiitaの閲覧数をMQTTで記録する

Qiitaに投稿した記事が、どれくらいのView数か気になりませんか？
いいね数でもある程度人気はわかりますが、View数の上昇率がわかると、もう少し詳しくみなさんが求めていることがわかるのではないかと思いました。

前回に引き続きMQTTでAWS IoTにPublishするのですが、今回は、Qiita APIを利用して自分の投稿の閲覧数を定期的に取得し、蓄積したいと思います。
（可視化はそのあとで。。。と言いながらよくわからん。。。）

# Qiita API仕様を知る

以下に記載されています。
　https://qiita.com/api/v2/docs

① まずは、自分が投稿した記事の一覧を取得します。
　GET /api/v2/authenticated_user/items

② 記事の閲覧数を含んだ記事情報を取得します。
　GET /api/v2/items/:item_id

上記を実行するために、自分は誰かを示す個人用アクセストークンを払い出します。
以下のアカウントページから取得できます。

https://qiita.com/settings/applications

40文字程度の長さのトークンが払い出されますので、それを覚えておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/725715c1-7fa1-dded-eafd-b8600696def2.png)

# 実装する

早速、実装していきましょう。

以下のnpmモジュールを使います。

> npm init -y
> npm install --save node-fetch
> npm install --save mqtt
> npm install --save dotenv


```:index.js
const fetch = require('node-fetch');
var mqtt = require('mqtt');
require('dotenv').config();
const { URLSearchParams } = require('url');

const MQTT_HOST = process.env.MQTT_HOST || 【Mosquittoサーバのホスト名】;
const MQTT_TOPIC = process.env.MQTT_TOPIC || 【Publishするトピック名】;

const QIITA_PRIVATE_TOKEN = 【個人用アクセストークン】;

console.log('MQTT_HOST=' + MQTT_HOST);
console.log('MQTT_TOPIC=' + MQTT_TOPIC);

var client = mqtt.connect(MQTT_HOST);

var base_url = 'https://qiita.com/api/v2';

function do_get_token(url, qs, token){
    var params = new URLSearchParams();
    for( var key in qs )
        params.set(key, qs[key] );

    console.log(url + '?' + params.toString());
    return fetch(url + '?' + params.toString(), {
        method : 'GET',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization' : 'Bearer ' + token }
    })
    .then((response) => {
        return response.json();
    });
}


async function aggregate_views(){
    try{
        var json = await do_get_token(base_url + '/authenticated_user/items', {}, QIITA_PRIVATE_TOKEN )
    //    console.log(json);
        for( var i = 0; i < json.length ; i++ ){
            console.log(json[i].id);

            var id = json[i].id;
            var item = await do_get_token(base_url + '/items/' + id, {}, QIITA_PRIVATE_TOKEN )
    //        console.log(item);

            var date = new Date();

            var message = {
                id: id,
                title: item.title,
                views: item.page_views_count,
                likes: item.likes_count,
                created_at : item.created_at,
                updated_at: item.updated_at,
                createdat: date.getTime(),
                createdatstr: date.toLocaleString()
            };

            client.publish(MQTT_TOPIC, JSON.stringify(message));
        }
        
        setTimeout( ()=>{
            process.exit();
        }, 5000 );

    }catch(err){
        console.log(err);
        process.exit();
    }
}

aggregate_views();
```

Publishするデータフォーマットは以下の通りです。これが記事の数分だけPublishされます。

```
var message = {
    id: id,
    title: item.title,
    views: item.page_views_count,
    likes: item.likes_count,
    created_at : item.created_at,
    updated_at: item.updated_att,
    createdat: date.getTime(),
    createdatstr: date.toLocaleString()
};
```

以下の部分を環境に合わせて変更します。

【Mosquittoサーバのホスト名】
【Publishするトピック名】：Publishするトピック名です。例えば、「awsiot/qiita」とします。
【個人用アクセストークン】：先ほど払い出したQiitaの個人用アクセストークンです。

以下の流れです。

① Qiita APIで閲覧回数を取得
② mqttで、イントラネットにあるMosquittoサーバにPubish
③ Mosquittoサーバは、AWS IoTにPublishデータを転送
④ AWS IoTは、受け取ったPublishデータをDynamoDBに格納

※②③の部分は、すでにセットアップが完了している前提です。以下を参考にしてください。
[AWS IoTにMosquittoをブリッジとしてつなぐ](https://qiita.com/poruruba/items/084317e01b9fababc02e)

# DynamoDBのテーブルを作成する。

以下の投稿で作成したテーブルをそのまま使います。

[Xiaomi Mijia 温湿度計 をIoTデバイスとして使う](https://qiita.com/poruruba/items/d16b58dfb45e513111d6)

# AWS IoT側でDynamoDBに登録されるようにする

AWS IoTで受け取ったPublishデータをDynamoDBに登録するために、AWS IoTのルールを定義します。
左側のナビゲータから、ACTを選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/7476d938-0cfe-bc1e-9886-bdd7299b4658.png)

右上の作成を押下します。
適当な名前を付けます。例えば、「IoTAnalytics_qiita」

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/63dd42ad-c8b9-85c4-3da4-7fa6ef4c3838.png)

ルールクエリステートメントには、以下のように指定します。FROMの部分はトピック名です。

　SELECT * FROM 'awsiot/qiita'

「アクションの追加」ボタンを押下します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/df48058e-1fe0-8f94-89ba-1965e2146bb8.png)

DynamoDBテーブルにメッセージを挿入する を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/c684bb15-611b-9d2e-0f52-144919b679bd.png)

テーブル名には、さきほど作成したDynamoDBのテーブル名を指定します。
そうすると、ハッシュキーやレンジキーおよびそのタイプが自動的に入力されます。
ハッシュキー値には、今後追加されるであろう他のデータと区別するために、「qiita」としました。
レンジキーの値には、「${countedat}」としました。
このcountedatは、さきほどの実装の中で説明しましたが、Publishデータの中の１項目で、View数を取得した日時です。

# 実行

以下の投稿と同じやりかたです。
トピック名は、今回は、「awsiot/qiita」です。

[Xiaomi Mijia 温湿度計 をIoTデバイスとして使う](https://qiita.com/poruruba/items/d16b58dfb45e513111d6)

DynamoDBにも登録されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/bdfd9246-a760-8d21-e4ea-eb81f14bdd1d.png)

今後ももっともっと取得するデータを増やしていこうと思います。

# (補足) 10分毎に閲覧数を取得する

これも、以下の投稿と同じです。

[Xiaomi Mijia 温湿度計 をIoTデバイスとして使う](https://qiita.com/poruruba/items/d16b58dfb45e513111d6)

以上です。