Qiitaを読む習慣をつけるためにLINEにQiita最新記事を定期送信してみた

# はじめに
技術への感度を上げるためにQiitaの記事を読む癖をつけたいと思っていました。
ですが、中々習慣になっていなかった時にふと**LINEニュースっていつも見るな**と思ったので、自分のLINEに定期的にQiitaの最新記事を飛ばすようにしてみました。

https://github.com/shoei555/qiita-to-line-bot

# 実装ステップ
色々調べた結果以下のステップで完全無料で実装できそうだぞ〜
1. Qiita APIから最新記事を取得する
2. LINE Messaging APIを設定
3. スクリプトを作成
4. Github Actionsで定期実行を実装

:::note info
Github Actionsはこれまでデプロイにしか使っていなかったので、
スクリプトの定期実行にも使えるというのは自分の中で目から鱗でした。
:::

# 実装方法

## 1. Qiita APIから最新記事を取得する

### まずはQiita APIのアクセストークンを取得

以下の記事を見たらアクセストークンは簡単に取得できます！！（サボりです）
[Qiita APIを触ってみる](https://qiita.com/miyuki_samitani/items/bfe89abb039a07e652e6)

### 取得したアクセストークンでcurlコマンドを実行してみる
```bash
curl -H "Authorization: Bearer {ACCESS_TOKEN}" "https://qiita.com/api/v2/items?page=1&per_page=5"
```

:::note info
クエリパラメータに`page=1&per_page=5`を設定することで最新の5つの記事を取得できるようになってます。
:::

以下のような返答がありますよ(一部抜粋)
```
[{"rendered_body":"\u003ch1 data-sourcepos=\"1:1-1:14\"\u003e\n\u003cspan id=\"は
じめに\" class=\"fragment\"\u003e\u003c/span\u003e\u003ca 
href=\"#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB\"\u003e\u003ci class=\"fa fa-
link\"\u003e\u003c/i\u003e\u003c/a\u003eはじめに\u003c/h1\u003e\n\u003cp data-
sourcepos=\"2:1-4:120\"\u003e記念すべき初投稿記事！！やったね！\u003cbr\u003e\nということで今回
はタイトル通り、パラメトリック型を使った監視可能なクラスを作ってみました！\u003cbr\u003e\nまた、サンプルと
```

## 2. LINE Messaging APIを設定
LINE Messaging APIを使ってメッセージを送信するには、以下のステップが必要です。

* LINE Developersの登録: LINE Developersにアクセスし、アカウントを作成
* チャネルの作成: LINEの「Messaging API」を使用するためのチャネルを作成
* チャネルアクセストークンの取得: メッセージを送信するために必要なアクセストークンを取得

参考：[LINE Messaging API概要](https://developers.line.biz/ja/docs/messaging-api/overview/)

### LINE Developersの登録

[LINE Developers](https://developers.line.biz/ja/)にアクセスしてアカウントを作成しましょう。

### チャネルの作成

[チャンネル作成方法](https://developers.line.biz/ja/docs/messaging-api/getting-started/#using-console)

友達1で寂しいですが以下のようなチャンネルができます。
(ちなみにこのチャンネルフォローしても皆さん宛に自動投稿はされないのでご勘弁です。)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3369754/8bc680fa-148b-73a2-696c-60562c3b5e3f.jpeg" width=50%>

:::note warn
チャンネル作成しなくても[Line notify](https://notify-bot.line.me/ja/)という機能を使えば、もっと簡単に自分たちのグループチャットなどに自動通知可能です。（自分はその事実を実装時に知らなかった。。。）
:::

### チャネルアクセストークンの取得

[チャネルアクセストークンの取得方法](https://poster.ooo/howto/check-access-token/)

これでできる！！と思いきや、チャンネルで行う場合はチャンネル内の自分のユーザーIDがないとメッセージを送信できないです。

:::note warn
これでできる！！と思いきや、チャンネルで行う場合はチャンネル内の自分のユーザーIDがないとメッセージを送信できないです。これがちょっと大変でした。
:::

[ユーザーIDの取得方法](https://tgg.jugani-japan.com/tsujike/2023/01/line5/)

## 3. スクリプトを作成

※こちらはTypeScriptで実装しています。
```typescript
import axios from 'axios';
import dotenv from 'dotenv';
dotenv.config();

// Qiitaのアクセストークン（環境変数から取得）
const qiitaToken: string = process.env.QIITA_ACCESS_TOKEN!;
// LINEのチャネルアクセストークン（環境変数から取得）
const lineToken: string = process.env.LINE_CHANNEL_ACCESS_TOKEN!;
// LINEチャンネルのユーザーID（環境変数から取得）
const userId: string = process.env.LINE_CHANNEL_USER_ID!;

// Qiitaの記事の型定義
interface QiitaArticle {
    title: string;
    url: string;
}

// Qiitaの最新記事を取得する関数
async function fetchQiitaArticles(): Promise<QiitaArticle[]> {
    try {
        const response = await axios.get<QiitaArticle[]>('https://qiita.com/api/v2/items?page=1&per_page=5', {
            headers: {
                'Authorization': `Bearer ${qiitaToken}`
            }
        });
        return response.data;
    } catch (error) {
        console.error('Error fetching Qiita articles:', error);
        return [];
    }
}

// LINEにメッセージを送信する関数
async function sendLineMessage(message: string): Promise<void> {
    try {
        await axios.post('https://api.line.me/v2/bot/message/push', {
            to: userId,  // 送信先のユーザーID
            messages: [
                {
                    type: 'text',
                    text: message
                }
            ]
        }, {
            headers: {
                'Authorization': `Bearer ${lineToken}`,
                'Content-Type': 'application/json'
            }
        });
    } catch (error) {
        console.error('Error sending LINE message:', error);
    }
}

// メイン処理
(async () => {
    const articles = await fetchQiitaArticles();
    if (articles.length > 0) {
        const message = articles.map(article => `タイトル: ${article.title}\nURL: ${article.url}`).join('\n\n');
        await sendLineMessage(message);
    } else {
        console.log('No new articles found.');
    }
})();
```

# 4. Github Actionsで定期実行を実装

`.github/workflows`ディレクトリを作成し、以下のコードを追加
```yml
name: Send Qiita Articles to LINE

on:
  schedule:
    - cron: '0 22,3,8,11 * * *'  # 毎日7,12,17,20時に実行

jobs:
  sendQiitaArticles:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14'

      - name: Install dependencies
        run: npm install

      - name: Run script
        env:
          QIITA_ACCESS_TOKEN: ${{ secrets.QIITA_ACCESS_TOKEN }}
          LINE_CHANNEL_ACCESS_TOKEN: ${{ secrets.LINE_CHANNEL_ACCESS_TOKEN }}
          LINE_CHANNEL_USER_ID: ${{ secrets.LINE_CHANNEL_USER_ID }}
        run: npx ts-node src/index.ts
```
:::note info
毎日7,12,17,20時に実行するように設定しました。
:::

# 完成！！！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3369754/006b1fd7-c1de-4dc7-f474-084f58e8957f.jpeg" width=50%>


# 最後に
定期的に記事が来ると結構見ますね。
同じようにQiitaを見る習慣をつけたいという方にはおすすめです。

個人開発って面白いですね。

https://github.com/shoei555/qiita-to-line-bot