Qiitaのストックに溜まりに溜まった記事を定期的にSlackに通知して振り返ろう！

# 導入
こんにちは😀
私は、いつもこうなんです。。
いつか読もうと思った、Qiitaのストック、Zennのいいね、Chromeのブックマーク、RSSも、読もうと思って買った本も... etc. etc.

山のようにストックを溜めて溜めて、結局読まずにまたストックする。
言うならば**積ん読のプロ**です！！*

<font color="red">本当はそんな人生から解放されたい！！</font>

ならば、自動的にリマインドさせて、ちゃんと読む機会を与えてあげましょう！(自分に)

ということで、今回は**Qiita APIを使って、Qiitaで自分がストックした記事を定期的にSlackに通知してくれる機能**を作りました。
※定期実行するのは、自分のローカルPCです。サーバー代なんてかかりません。エコですね。

さて、今回作った機能を紹介していきます。
作ったソースはこちらで公開しています。
※今後、他のツールを作ったり、リポジトリを変更する可能性はあります。

https://github.com/fm-phibia/useful-tools

# Qiita APIについて
まず、Qiita APIについてです。

https://qiita.com/api/v2/docs

`Qiita API`とは、「Qiita」の機能をプログラムから利用できるようにするためのAPIです。
まんまですが、笑

`Qiita API`を使うことで、Qiita上の記事の投稿や編集、取得、コメントの操作などをプログラムで自動化することができるそうです。ユーザー情報やタグ情報の取得も可能です。

具体的な利用シーンとしては、以下のようなものがあります。
(ChatGPTが言っていました。)

- 自動で定期的に自分のQiita記事をバックアップする
- 自分のブログやウェブサイトにQiitaの記事を自動で投稿する
- 人気のタグや記事をリストアップするアプリケーションを作成する

あまり1点目のようなバックアップに利用することはない気がしますが、2点目とかは良さそうですね。
いつか使ってみたいものです。

## Qiita APIを使うために必要なもの

- Qiitaのアクセストークン
- APIを実行する環境(ソースコード)

だけ！！なので、アクセストークンさえ発行すればゴールとも言えます。

### アクセストークンの発行方法

1. 右上のアイコンから「設定」を選択
![スクリーンショット 2024-08-17 9.04.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/6f6586c7-4eb8-7421-f38a-71399cb3ea34.png)
2. 「アプリケーション」を選択し、「新しいトークンを発行する」を選択
![スクリーンショット 2024-08-17 9.05.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/6a0bd83c-a3b6-3b6d-5f1e-cd88b84b4a5c.png)
3. 説明を自由に入れて、`read_qiita`にチェックを入れた状態で、「発行する」を選択
![スクリーンショット 2024-08-17 9.05.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/3da5c30c-1a4e-dcaf-c9ae-d76c5697ebba.png)
4. アクセストークンをコピーしておきましょう
![スクリーンショット 2024-08-17 17.19.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/dcb06f50-54b3-c70c-790e-849277d641a3.png)

## Qiita APIの呼び出し方

:::note info
実際に実装したコードからクエリパラメータを除いたり、処理を省いたりしています。
ソースコード全体は、私のリポジトリをご覧ください。
https://github.com/fm-phibia/useful-tools/blob/master/lib/getQiitaStock.ts
:::

```ts
const USER_ID = (自分のQiitaのユーザーID);
const ACCESS_TOKEN = (先ほど取得したアクセストークン);

interface Stock {
  title: string;
  url: string;
}

// ストックの項目を取得する関数
const getStocks = async () => {
  try {
      
    // Qiita APIのエンドポイント
    const API_URL = `https://qiita.com/api/v2/users/${USER_ID}/stocks`;
    
    const response = await axios.get(API_URL, {
      headers: {
        Authorization: `Bearer ${ACCESS_TOKEN}`,
      },
    });
    
    const stocksData = response.data as Stock[];
    stocksData.forEach((stock: Stock, index: number) => {
      console.log(`${index + 1}: ${stock.title} (${stock.url})`);
    });
    
  } catch (error) {
    console.error('Error fetching likes:', error);
  }
}

getStocks();
```

たったこれだけです。簡単ですね。
私の実際の実装はクエリパラメータをいい感じに調整して、全件取得できるようにしました。

# Slackへのメッセージ送信
メッセージ送信には、Slack APIを利用します。
これを利用するにはSlackのアプリの作成が必要になります。
アプリを作成し、設定したあと、ソースコードからメッセージを通知する処理を実装し、実行します。

## Slack用アプリの作成と設定

まず、アプリの作成です。
こちらのページからアプリを作成していきます。

https://api.slack.com/apps

1. [Create an App]をクリック
![スクリーンショット 2024-08-17 11.37.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/c38b9f4c-e3ee-5891-cf85-c67b3f850d37.png)
2. [From scrach]をクリック
![スクリーンショット 2024-08-17 11.38.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/78491b7b-f7dc-2f96-2506-eefd8da900f1.png)
3. アプリ名を入力し、通知したいワークスペースを選択し、[Create App]をクリック
![スクリーンショット 2024-08-17 11.38.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/6c6ce032-57e6-bb4e-8c27-14ce44d97d35.png)
4. アプリの設定画面で、[OAuth & Premissions]を選択し、下の方の`Scopes`の`Bot Token Scopes`の[Add an OAuth Scopes]をクリックし、[chat: write]を設定します
![スクリーンショット 2024-08-17 11.39.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/2d83614b-651a-8941-fd56-c4a12cbe5d10.png)
![スクリーンショット 2024-08-18 22.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/023a142b-37e6-1079-a8f4-f5d1c461747b.png)
5. [App Home]を選択し、[App Display Name]を設定します。[Default Name]は`qiita`としました。
![スクリーンショット 2024-08-18 22.32.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/d75f64e5-41d0-cc86-ccfb-97080df7b232.png)
6. もう一度、[OAuth & Premissions]に戻り、次は[OAuth Tokens]の[Install to (ワークスペース名)]を選択
![スクリーンショット 2024-08-17 11.42.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/94562350-c9a3-19ec-b1af-707c8d2e9bc7.png)
7. [許可する]をクリックし、画面に表示される[OAuth Token]をコピーしておきます。次のソースコード上で利用します。
![スクリーンショット 2024-08-18 22.46.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/7d8c0629-3469-4215-4a56-61e1f9c47d10.png)
8. Slackの画面にいき、メッセージ送信したいチャンネルの設定から、`チャンネルID`を取得します。これも次のソース上で利用します。
![スクリーンショット 2024-08-18 22.40.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/5e388e32-c77a-dcb5-86b7-a1c307098427.png)
9. 最後にそのチャンネルに、作成したアプリを追加しましょう。`/invite @(アプリ名)`で追加が可能です。
![スクリーンショット 2024-08-17 12.13.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/4a2843ed-a3cc-04e4-ce41-c511ee3c8d57.png)

## Slackへの通知処理

:::note info
こちらも実際に実装したコードからクエリパラメータを除いたり、処理を省いたりしています。
ソースコード全体は、私のリポジトリをご覧ください。
https://github.com/fm-phibia/useful-tools/blob/master/lib/sendToSlack.ts
:::

```ts
const SLACK_BOT_TOKEN = (取得したOAuth Token);
const SLACK_CHANNEL_ID = (送信先のスラックのチャンネルID);

export const sendToSlack = async (message: string) => {
  try {
    const response = await axios.post('https://slack.com/api/chat.postMessage', {
      channel: SLACK_CHANNEL_ID,
      text: message,
    }, {
      headers: {
        'Authorization': `Bearer ${SLACK_BOT_TOKEN}`,
        'Content-Type': 'application/json',
      }
    });

    if (response.data.ok) {
      console.log('Message sent to Slack successfully!');
    } else {
      console.error('Error sending message to Slack:', response.data);
    }
  } catch (error) {
    console.error('Error sending message to Slack:', error);
  }
};
```

こちらも大して複雑な処理ではないので、解説しませんが、APIは便利ですね。

## 動作確認

それでは上の2つのソースをいい感じにつなぎ合わせて実行してみましょう！

他の方の記事が表示されるので、ほとんどが隠されていますが...
こんな感じに通知されました！
![スクリーンショット 2024-08-18 23.01.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/bbef482c-4de1-bf41-f47e-b620bb97e80a.png)

# 定期実行設定

最後に定期実行させていきます。
単にMacのcronを設定するだけです。
私のリポジトリには、`shell/run.sh`というスクリプトがあるので、こちらを定期実行させています。

```bash
crontab -e
```
毎時0分に通知されるように設定しました。
```
0 * * * * /User/hoge/hoge/shell/run.sh
```

# 終わりに

最後まで読んでいただき、ありがとうございます。

今回は、日々溜め込んでしまう情報に対するアプローチの一つとして、自分自身のリマインダーを作成したものです。
皆さんも、Qiitaに限らず、様々な情報源で重なりに重なった**「積ん読」を少しでも減らす**ために、今回の方法を活用してみてはいかがでしょうか？

また、今回紹介した技術は他の場面でも応用可能です！
例えば、Slack APIを使って定期的に他のリマインダーを設定したり、Qiita APIを使って独自の分析ツールを作成したりすることもできます。
自分の生活に合わせたツールを作ることで、より効率的な情報管理ができるようになるはずです。

それでは、引き続き楽しいエンジニアライフを！