今更ながらGithub Actionsを用いてRSSフィードを自動取得・メール送信を実現する

# 何をするか
- Javascript(Node.js)でRSSフィードを取得する。
    - その後SendgridのAPIを使用して、取得したRSSフィードの一覧をメールで送信する。
- 上記のコードをGithub Actionsで1日1回実行し、自動取得・自動メール送信を実現する。

メモ程度に書き殴るので情報量は少なめ..御了承を

:::note Nodemailerを使う方法を考えたが断念
ちなみにメール送信はGmailで[Nodemailer](https://nodemailer.com/about/)をはじめは使用していたが、Gmail側の[セキュリティ設定](https://nodemailer.com/usage/using-gmail/)ではローカルではうまく動くもののGithub Actions上ではうまくいかない([OAuth2](https://nodemailer.com/smtp/oauth2/)を設定すればうまくいく？かもしれないが今回は手軽にしたかった)ため断念
:::


# 開発環境
- macOS :Monterey12.4 (M1)
- Node.js : 16.15
- npm : 8.5.5
    - sendgrid-nodejs : 7.7.0
    - nodemailer : 6.7.5
    - rss-parser : 3.12.0

# RSSフィードを取得
RSSの取得には[rss-parser](https://www.npmjs.com/package/rss-parser)を使う。[公式](https://github.com/rbren/rss-parser#nodejs)によると、以下のように使うらしい。  
そういうわけで、`parser.parseURL('https://www.reddit.com/.rss')`のURLを自身の好きなRSSフィードのURLにすればデータが取得できる。
```js
let Parser = require('rss-parser');
let parser = new Parser();

(async () => {

  let feed = await parser.parseURL('https://www.reddit.com/.rss');
  console.log(feed.title);

  feed.items.forEach(item => {
    console.log(item.title + ':' + item.link)
  });

})();
```
また、実行結果はこのように出力される。
```js
feedUrl: 'https://www.reddit.com/.rss'
title: 'reddit: the front page of the internet'
description: ""
link: 'https://www.reddit.com/'
items:
    - title: 'The water is too deep, so he improvises'
      link: 'https://www.reddit.com/r/funny/comments/3skxqc/the_water_is_too_deep_so_he_improvises/'
      pubDate: 'Thu, 12 Nov 2015 21:16:39 +0000'
      creator: "John Doe"
      content: '<a href="http://example.com">this is a link</a> &amp; <b>this is bold text</b>'
      contentSnippet: 'this is a link & this is bold text'
      guid: 'https://www.reddit.com/r/funny/comments/3skxqc/the_water_is_too_deep_so_he_improvises/'
      categories:
          - funny
      isoDate: '2015-11-12T21:16:39.000Z'
```
今回は、とりあえず`title` `link` `pubDate`の一覧をメールで送信することとする。

# 取得したデータをメールで送信(Sendgrid API 使用)
[Sendgrid](https://sendgrid.kke.co.jp/about/email-api/)のAPIを使用する。使用には登録が必要なので注意!  
[ここを参考](https://sendgrid.kke.co.jp/docs/Tutorials/A_Transaction_Mail/manage_api_key.html)に登録後APIキーを発行するのだが、**APIキーはメール送信時に使用するため覚えておく**。

[公式のブログ](https://sendgrid.kke.co.jp/blog/?p=1026)を参考にコードを書く。
以下の部分の`text` `html`部分に先ほど取得したRSSフィードの一覧を入れれば、メッセージにRSSフィードの一覧が表示される。  
```js
    subject: '[sendgrid-nodejs-example] フクロウの名前は%fullname%さん', // 件名
    text: '%familyname%さんは何をしていますか？\n彼は%place%にいます', // textパート
    html: '<strong>%familyname%さんは何をしていますか？</strong><br>彼は%place%にいます。', // htmlパート
    substitutionWrappers: ['%', '%'], // 置換タグの指定
```
そのため、たとえば以下のように`html`でRSSの一覧をリスト整形して入れれば、リストで整然としたメッセージを送信できる。
```html
<ul>
    <li> <a href='${items.link1}'> ${items.title1} </a>: ${items.pubDate1} </li>
    <li> <a href='${items.link2}'> ${items.title2} </a>: ${items.pubDate2} </li>
    .
    .
    .
    <li> <a href='${items.linkN}'> ${items.titleN} </a>: ${items.pubDateN} </li>
</ul>

```

ちなみに`.env`に記入した以下の内容はGithub Actionsを使用するときに必要になるため頭の隅で覚えておく。
```.env
API_KEY=api_key
TOS=送信先のメールアドレス複数の場合カンマ区切り
FROM=送信元のメールアドレス
```

# Github Actionsで自動化する
以下を参考に`.github/workflow`に実行したい任意のyamlファイルを書いていく。

https://github.com/actions/setup-node#usage 

ここで注意することとしてGithub Actionsを無料で使うには、リポジトリをPublicにする必要がある。そのため、APIキーやメールアドレスなどの公開すべきでない情報がソースコードに書いていないかを確認してからpushすることをお勧めします。

yamlファイルの例を以下に示す。
```yml
name: rss
on:
  schedule:
    - cron: '0 0 * * *' #cronで定期実行、例では毎日0時0分に実行される。

jobs:
  build:
    # Ubuntuの最新版環境内で処理を実行することを指定
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '16'
      - run: npm ci #package-lock.jsonから依存関係のインストール
      - run: |
            cat <<EOL >> ./.env 　　　
            API_KEY="${{secrets.API_KEY}}"
            FROM="${{secrets.FROM}}"
            TOS="${{secrets.TOS}}"
            EOL
      - run: node main.js #RSS取得とメール送信の処理を書いたファイルを指定
```
以下の部分では上でやったSendgrid用の`.env`ファイル生成を行う。
```yml
      - run: |
            cat <<EOL >> ./.env 　　　
            API_KEY="${{secrets.API_KEY}}"
            FROM="${{secrets.FROM}}"
            TOS="${{secrets.TOS}}"
            EOL
```
`${{secrets.API_KEY}}` `${{secrets.FROM}}` `{{secrets.TOS}}`はGithub ActionsのsecretsでAPIキーなどを呼び出している。  
[secrets](https://docs.github.com/ja/actions/security-guides/encrypted-secrets)を参考に`.env`の内容を登録することで、安全にAPIキーなどを使用することが可能となる。

# あとは待つだけ
以上でRSSを自動取得し1日1回メール配信を行えるようになりました！

# 終わりに
土台は作れたので徐々に良くしていければと思う次第です。
一応、稚拙ですがソースは以下にあります。参考になれば幸いです。
https://github.com/cacaoMath/windows_news_collector
まだ学び始めもあり、間違いなどありましたらご指摘・コメントなどいただけると嬉しいです！
ありがとう御座いました！

## 参考文献
- RSS取得関連
    - https://www.npmjs.com/package/rss-parser
    - https://github.com/rbren/rss-parser#nodejs

- Sendgridでのメール送信
    - https://sendgrid.kke.co.jp/about/email-api/
    - https://sendgrid.kke.co.jp/docs/Tutorials/A_Transaction_Mail/manage_api_key.html
- Github Actions関連
    - https://zenn.dev/hashito/articles/7c292f966c0b59
    - https://docs.github.com/ja/actions/security-guides/encrypted-secrets
    - https://qiita.com/inouet/items/c7d39ac4641c05eec4a0
    - https://github.com/actions/setup-node#usage 
- その他
    - 定期実効する際のcronの設定
        - https://www.kagoya.jp/howto/it-glossary/server/cron/