Qiitaから興味のある記事を自動収集したい！

# 背景・目的
新聞など一般的な最新情報ではなく、自分が気になるテーマにフォーカスした情報収集手段があったらいいな。

例）会社に導入されたツールの活用方法を知りたい。
　　最近配信が開始されたスマホアプリは便利か知りたい。

# 使用環境
今回は
・Node-RED
・Qiita API
を使って、あったらいいなを形にします。


# 実装①：Tableau（気になるキーワード）に関する記事を検索させる
Node-REDを用いてQiitaの記事を検索させて、記事のタイトルを取得する。


フロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775986/9ac96888-4f1f-6d7d-e528-a909c1dfe050.png)


コード
```json
[{"id":"c7b82841e090b746","type":"inject","z":"54b90769be817b10","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":290,"y":180,"wires":[["53ba6d09da1bfedd"]]},{"id":"53ba6d09da1bfedd","type":"function","z":"54b90769be817b10","name":"function","func":"msg.query = encodeURI(\"Tableau\");\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":180,"wires":[["9d0f78d828b4c633"]]},{"id":"9d0f78d828b4c633","type":"http request","z":"54b90769be817b10","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?query='{{{query}}}","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":690,"y":180,"wires":[["848e4ea34c073e08"]]},{"id":"848e4ea34c073e08","type":"debug","z":"54b90769be817b10","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":890,"y":180,"wires":[]}]
```

実行結果
```json
[
    "Tableau×リーダブルコード②",
    "【Tableau prep】prepを用いた差分更新の方法",
    "【Tableau】カスタムSQLでの同一項目名のエラーについて",
    "オフラインでの Tableau Server のライセンス認証",
    "【Trailhead】Salesforceの学習の道程（2024/04/01〜2024/06/30）",
    "Tableau×リーダブルコード①",
    "Informaticaのデータ統合サービスCloud Data IntegrationでDatabricksにELTしてみた",
    "[初級編]7.Tableau Prep Builderの利用方法(インストールとライセンス認証)",
    "[初級編]6.Tableau Desktopの利用方法(シート/ダッシュボード/ワークブックの作成)\t",
    "[初級編]5.Tableau Desktopの利用方法(インストールとライセンス認証)",
    "[初級編]4.プロダクトキー(ライセンスキー)",
    "[初級編]3.Tableauを利用するための費用（ライセンスの種類）",
    "[初級編]2.Tableau製品の種類を超簡単に説明",
    "[初級編]1.Tableauとは何かを超簡単に説明"
]
```

ひとまず、キーワードにヒットした記事のタイトルをJSON形式で取得することができた。


# 実装②：定期的に記事を検索させる
次にInject ノードの「繰り返し」機能を用いて、特定時間帯や日付に自動で記事を検索させてみる。実行結果確認のため、今回は1分毎に繰り返し実行するように設定する。

フロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775986/6703a097-fd5a-193c-530a-49af21ae09d3.png)


コード
```json
[{"id":"c32d281a459ff77e","type":"inject","z":"54b90769be817b10","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"60","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":290,"y":460,"wires":[["8105d8c532744ec2"]]},{"id":"8105d8c532744ec2","type":"function","z":"54b90769be817b10","name":"function_key","func":"msg.query = encodeURI(\"Tableau\");\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":460,"wires":[["91055949f21a0bb3"]]},{"id":"91055949f21a0bb3","type":"http request","z":"54b90769be817b10","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://qiita.com/api/v2/items?query={{query}}","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":670,"y":460,"wires":[["20bc75438cd9ced5"]]},{"id":"6d80cc8c6ca4f613","type":"debug","z":"54b90769be817b10","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1050,"y":460,"wires":[]},{"id":"20bc75438cd9ced5","type":"function","z":"54b90769be817b10","name":"function_title","func":"let array_data =  msg.payload;\nlet title = [];\n\n//記事のタイトルを取得\nfor(let i=0;i<14;i++){\n    title[i] = array_data[i].title;\n}\nmsg.title = title;\n\nmsg.payload = msg.title;\n\nreturn msg;\n\n//タイトルに加えて、更新日とurlも取りたい。\n//3次元配列にできないか？\n//取得した情報は累積して次回検索時にも参照したい。\n//更新日をキーに最新記事（未読記事）を通知させる。","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":870,"y":460,"wires":[["6d80cc8c6ca4f613"]]}]
```

実行結果
2024/5/16 0:35:58 に取得した記事タイトル
```json
[
    "Tableau×リーダブルコード②",
    "【Tableau prep】prepを用いた差分更新の方法",
    "【Tableau】カスタムSQLでの同一項目名のエラーについて",
    "オフラインでの Tableau Server のライセンス認証",
    "【Trailhead】Salesforceの学習の道程（2024/04/01〜2024/06/30）",
    "Tableau×リーダブルコード①",
    "Informaticaのデータ統合サービスCloud Data IntegrationでDatabricksにELTしてみた",
    "[初級編]7.Tableau Prep Builderの利用方法(インストールとライセンス認証)",
    "[初級編]6.Tableau Desktopの利用方法(シート/ダッシュボード/ワークブックの作成)\t",
    "[初級編]5.Tableau Desktopの利用方法(インストールとライセンス認証)",
    "[初級編]4.プロダクトキー(ライセンスキー)",
    "[初級編]3.Tableauを利用するための費用（ライセンスの種類）",
    "[初級編]2.Tableau製品の種類を超簡単に説明",
    "[初級編]1.Tableauとは何かを超簡単に説明"
]
```

2024/5/16 0:36:53 に取得した記事タイトル
```ruby:qiita.json
[
    "Tableau×リーダブルコード②",
    "【Tableau prep】prepを用いた差分更新の方法",
    "【Tableau】カスタムSQLでの同一項目名のエラーについて",
    "オフラインでの Tableau Server のライセンス認証",
    "【Trailhead】Salesforceの学習の道程（2024/04/01〜2024/06/30）",
    "Tableau×リーダブルコード①",
    "Informaticaのデータ統合サービスCloud Data IntegrationでDatabricksにELTしてみた",
    "[初級編]7.Tableau Prep Builderの利用方法(インストールとライセンス認証)",
    "[初級編]6.Tableau Desktopの利用方法(シート/ダッシュボード/ワークブックの作成)\t",
    "[初級編]5.Tableau Desktopの利用方法(インストールとライセンス認証)",
    "[初級編]4.プロダクトキー(ライセンスキー)",
    "[初級編]3.Tableauを利用するための費用（ライセンスの種類）",
    "[初級編]2.Tableau製品の種類を超簡単に説明",
    "[初級編]1.Tableauとは何かを超簡単に説明"
]
```

2024/5/16 0:37:54 に取得した記事タイトル
```json
[
    "Tableau×リーダブルコード②",
    "【Tableau prep】prepを用いた差分更新の方法",
    "【Tableau】カスタムSQLでの同一項目名のエラーについて",
    "オフラインでの Tableau Server のライセンス認証",
    "【Trailhead】Salesforceの学習の道程（2024/04/01〜2024/06/30）",
    "Tableau×リーダブルコード①",
    "Informaticaのデータ統合サービスCloud Data IntegrationでDatabricksにELTしてみた",
    "[初級編]7.Tableau Prep Builderの利用方法(インストールとライセンス認証)",
    "[初級編]6.Tableau Desktopの利用方法(シート/ダッシュボード/ワークブックの作成)\t",
    "[初級編]5.Tableau Desktopの利用方法(インストールとライセンス認証)",
    "[初級編]4.プロダクトキー(ライセンスキー)",
    "[初級編]3.Tableauを利用するための費用（ライセンスの種類）",
    "[初級編]2.Tableau製品の種類を超簡単に説明",
    "[初級編]1.Tableauとは何かを超簡単に説明"
]
```

繰り返しを平日の昼休みなど自分が好きなのタイミングに設定すれば、「好きな時に気になるテーマの記事を勝手に知らせてくれる。」なんてことも実現できる。


# 改良案
:::note warn
・記事のurlを表示する。
・記事の更新日が前回検索日時よりも新しければ、新着記事として通知する。
・Qiita以外の記事も検索し、通知する。
:::


# おわりに
今回は自分が思うあったらいいなを最近知ったツール（Node-RED）を用いて形にする方法を調べ、作ってみました。実際に自分で手を動かしていく中で、こんな改良もできそうだなという発見があったので、今後も勉強を続けていきたいと思います。


# 参考文献
https://qiita.com/api/v2/docs
https://qiita.com/ooooooooookawa/items/d27564623f85abdb67cc

JSON形式のデータを成形する際に使用したツール
https://one-ap-engineer.com/tools/json-formatter/