技術記事を定期的にLINEに投げたい

# これは何？
自主的に勉強をしたり記事を探したりするのがとても苦手なので、勝手に情報入ってくるようにしたいと思い、qiitaの記事が勝手にLINEに流れてくるようにしてみます

# まずはqiitaのapiを調べる
ありました
https://qiita.com/api/v2/docs
`
利用制限
認証している状態ではユーザごとに1時間に1000回まで、認証していない状態ではIPアドレスごとに1時間に60回までリクエストを受け付けます。
`
認証してなくても叩けるようですが、開発過程とかもっと叩くだろうということで認証認可の部分参考にして、個人用のtokenを発行します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/392d2537-94c9-47a9-8171-90e95cce7743.png)
投稿の取得はこの辺でできそうです
https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF
試してみます
```
curl -H 'Authorization: Bearer xxxxxxxxxxxxxxxxxxxx' 'https://qiita.com/api/v2/items?page=1&per_page=1' | jq
```
結果は載せませんが、結論上記で取れました
さらに、取得する記事はそれなりに絞り込みたいので、どんな条件で絞れるか調べてみます
https://help.qiita.com/ja/articles/qiita-search-options
特定の日付以降でストック10件以上とかで絞り込みます
```
https://qiita.com/api/v2/items?page=1&per_page=20&query=created:>2022-01-01+stocks:>10
```

複数条件使う時はちょっと癖があるみたいなので以下を参考にしました
https://qiita.com/kijibato/items/1f8b86fc5e7cd3b0db17

# 取得した記事を記録していく
Google spread sheetに書いていきます
自動でLINEに送る仕組みの構築にはGASを使います
最初、cloud functions上で実行してapiでspread sheetに記載しようかと思ったのですが、
Google sheet apiが結構苦労する感じだったので、
spread sheetの値の読み取り、書き込みなどやりやすいGASでやることにしました

とりあえずQiitaのapi叩いてspread sheetに書き込むところまではこんな感じで動きました
```
function getQiitaItems(tag) {
  var searchTag = tag ? tag : 'javascript';
  const page = 1;
  const perPage = 2;
  const createdLimit = Utilities.formatDate(new Date('2022/01/01'), "Asia/Tokyo", "YYYY-MM-DD");
  const stocks = 100;
  var url = `https://qiita.com/api/v2/items?page=${page}&per_page=${perPage}&query=created%3A%3E${createdLimit}+stocks%3A%3E${stocks}+tag%3A${searchTag}`;

  const token = "xxxxx"
  const options = {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${token}`
    }
  };
  var response = UrlFetchApp.fetch(url, options);
  var data = JSON.parse(response.getContentText()).map((d) => ({
    id: d['id'],
    title: d['title'],
    url: d['url'],
    likes_count: d['likes_count']
  }));
  return {data, dataLength: data.length};
}

function writeQiitaItemsToSheet() {
  var {data, dataLength} = getQiitaItems("typescript");
  var spreadSheet = SpreadsheetApp.getActiveSheet();
  var currentMaxRow = spreadSheet.getLastRow();
  var currentItemIds = spreadSheet.getRange(2, 1, currentMaxRow).getValues();
  var dataNum = 0;
  for (var i = currentMaxRow; i < currentMaxRow + dataLength; i++) {
    var id = data[dataNum].id;
    if (currentItemIds.some(itemId => itemId == id)) {
      console.log('skip write', data[dataNum].id);
      dataNum++;
      continue;
    }
    var maxRow = spreadSheet.getLastRow();
    spreadSheet.getRange(maxRow + 1, 1, 1, 4).setValues(
      [[data[dataNum].id, data[dataNum].title, data[dataNum].url, data[dataNum].likes_count]]
    );
    dataNum++;
  }
}
```

結果はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/3e0538b8-5bb2-fe7d-8df7-cfa2a22f0ae7.png)

# LINEに投稿する
LINEの公式ドキュメントを参考にします
https://developers.line.biz/ja/docs/messaging-api/

LINEのDeveloper consoleからアカウント登録し、チャンネルなどを設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/22d6b8a6-ab4d-b298-7600-d7ecc3dade93.png)
各項目を埋めて規約に同意し、チャンネルを作成します
作成が完了すると管理画面が開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/878b8cc8-111c-6600-b065-c85a21da1f79.png)
Messaging API設定を開きます。
このQRコードを読み込めば友達として追加できるみたいです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/73a4d7f9-facb-619e-469e-63d9cb37fd17.png)
Messaging apiをGASから実行するにはこのチャネルアクセストークンを利用すればできそうです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/2e5c324b-dd9f-ec66-2a10-2c286ab7d0a5.png)
あと送信先ってどう指定すればいいのかなと思ったんですが、今回は送り先が自分だけなので、
その場合はチャネル基本設定の中に「あなたのユーザーID」を参照して指定すれば良いようです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/a3f41819-dab4-3d63-70a7-9021f59c9480.png)
LINEへの投稿はこんな感じでできました
```
function postMessageToLINE(message) {
  var msg = message ? message : "Hello, world!";
  const myUserId = "userId";
  const token = "ACCESS_TOKEN";
  const url = "https://api.line.me/v2/bot/message/push";
  const data = {
    "to": myUserId,
    "messages":[
        {
            "type":"text",
            "text":msg
        },
    ]
  };
    var headers = {
      'Content-Type': 'application/json',
      'Authorization': "Bearer " + token, 
    }
    var options = {
  'method' : 'post',
  'headers': headers,
  'payload' : JSON.stringify(data)
  };
  var res = UrlFetchApp.fetch(url, options);
}
```

さらに、すでに送信されたものは投稿したくないので、スプレッドシートに送信日を記録しておいて、送信日が埋まっているものは送信スキップするようにしました
```
function postQiitaToLINE() {
  var spreadSheet = SpreadsheetApp.getActiveSheet();
  var currentMaxRow = spreadSheet.getLastRow();
  var data = spreadSheet.getRange(2, 1, currentMaxRow, 5).getValues();
  for (var i = 0; i < currentMaxRow - 1; i++) {
    if (data[i][4]) { // 送信日の列が埋まっている場合はスキップ
      continue;
    }
    const today = Utilities.formatDate(new Date(), "JST","yyyy-MM-dd");
    const title = data[i][1];
    const url = data[i][2];
    postMessageToLINE(title + '\n' + url); // LINEに送信
    spreadSheet.getRange(i + 2, 5).setValue(today); // 送信日を記録
    break;
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/a32b505f-04fb-1cb5-3eb2-c3d6bc03895c.png)
こんな感じで投稿できました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/5fcfa6ea-f69b-cc80-7f13-c2c7501fc90a.png)
あとはこの投稿関数が定期的に実行されるようにします
GASのconsoleでトリガーのタブを開き、新しいトリガーを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/08dfe38f-11d7-59e8-a717-db65aaa65b81.png)
時間主導型で日付ベースのタイマー、午前6時 ~ 7時にすることで、毎朝見れるようにします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/2353bc6a-0a12-49e7-1b64-0ac6ecd9a6ad.png)
翌朝見たらちゃんと時間通りに通知されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484082/fa59c781-e3d1-c6b4-2bc7-524cd7d89522.png)
これを使って継続的にインプットしていきます..!