Github Actionsを使って、Qiitaの投稿記事（のどれか）でLGTMされたらSlackで通知する。

# 1. はじめに
- Qiitaで書いた記事でLGTMをもらえると励みになります。
  - ただ、残念なことに、LGTMの通知がwebしかありません。常時自分のマイページを開いているわけではないので、気がつかないこともしばしば。

![InformFromQiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624259/fe5fcad3-6fe3-e584-3a44-9b27d53e14c4.png)


- Slackで通知できないかな、と思ったので作成することにしました。

# 2. 構想

![overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624259/058ca402-9658-19f7-d7ff-c26c406ef773.png)

※図はDraw.ioで描きました。

- 構想の流れは以下の通りです。
  - Qiitaはwebから情報を取得するAPIを提供しているから、記事のLGTM数はこれで取得できる。
    - LGTM数を取得して、前回より増えていたらslackに通知することにしよう。
      - 前回値を保持しておく必要があるな。
      - 自分のローカルで動かしていると、常にサーバを稼働させないと行けないから嫌だな。→ web上に配置したい。
      - webに合って、データが保持できるものは…、Githubでよくね？Actionsもあるからこれで定期処理が組める。
  - Slackってapiあるの？→たくさん合って選びたい放題。
    - Actionsから呼べる簡単なスクリプトで実現できないかな…、できる！
- 上記のような思考を経て、図のような構成としました。

# 3. 参考ページ
- [Qiita Developer Doc](https://qiita.com/api/v2/docs)
  - Qiita APIの使い方はこちらを確認しました。
- [QiitaのAPIv2を使用して自身の記事取得](https://qiita.com/tatsuo-iriyama/items/c1e56c1a197e39087b6e)
  - Qiita APIの使い方、認証について参考にさせていただきました。
- [Webhookを使ってシェルスクリプトで手軽にslack通知する](https://chariosan.com/2020/02/01/slack_webhook_shellscript/)
  - Slack apiの作り方、webhook方法、通知の仕方サンプルを参考にさせていただきました。
- [Github Actions で secret を使う](https://qiita.com/inouet/items/c7d39ac4641c05eec4a0)
  - ActionではQiitaの認証情報を使うので、シークレット変数と使い方を参考にさせていただきました。
- [GitHub Actions でワークフロー中に発生した差分を Push する](https://zenn.dev/lollipop_onl/articles/eoz-gha-push-diffs)
  - Actionのjob処理中にgithubプロジェクトへpushする方法を参考にさせていただきました。

# 4. 構築

## 4.1. QiitaのAccess Tokenの構築

- 「[QiitaのAPIv2を使用して自身の記事取得](https://qiita.com/tatsuo-iriyama/items/c1e56c1a197e39087b6e)」の記事で紹介されているToken生成の方法で作成しました。

## 4.2. Githubの構築
- 今回のGithubプロジェクトですが、LGTM数を記載したファイルをpush更新するためにprivateプロジェクトで作成しました。
- プロジェクト以下のディレクトリ・ファイル構成は以下の通りです。
  - ブランチは2本で、masterブランチ、lgtmブランチとしています。
  - lgtm.jsonはLGTM数を保持するjsonファイルで、lgtmブランチのみに存在するファイルとなります。
  - ActionsでのLGTM総数更新は、lgtmブランチに対して実施します。
- secret変数の登録は、「[Github Actions で secret を使う](https://qiita.com/inouet/items/c7d39ac4641c05eec4a0)」を参照願います。
  - 本プロジェクトでは、QIITA_ACCESS_TOKEN、SLACK_WEB_HOOKを登録しました。
    - QIITA_ACCESS_TOKEN : Qiitaの認証情報、SLACK_WEB_HOOK : webhook url (後述)

```bash
checker-qiita-lgtm/
├── .github/workflows/check-qiita.yml     # Github Actionsのjobファイル
├── check-qiita.sh                        # 処理を記載したスクリプト
├── lgtm.json                             # LGTM総数を保持するファイル
├── LICENSE
└── README.md
```

- 処理を記述したcheck-qiita.sh、lgtm.jsonの構造、Github Actionsのcheck-qiita.ymlは以下の通りです。
  - 本処理では、curlとjqを利用します。
  - slack通知処理については、「[Webhookを使ってシェルスクリプトで手軽にslack通知する](https://chariosan.com/2020/02/01/slack_webhook_shellscript/)」を参考にさせていただきました。
  - pushジョブについては、「[GitHub Actions でワークフロー中に発生した差分を Push する](https://zenn.dev/lollipop_onl/articles/eoz-gha-push-diffs)」を参考にさせていただきました。

```bash
#-----------------------------------------------------------
# @file check-qiita.sh
# @brief qiitaのLGTM数を確認して、slackに通知する
# @auther tomoten-umino
# @date 2021-09-30
#-----------------------------------------------------------

# 検索するユーザ名
USER=tomoten
# 認証付きcurl
CURL="curl -H \'Authorization: Bearer ${QIITA_ACCESS_TOKEN}\'"

#-----------------------------------------------------------
# @fn main
# @brief メイン処理
# @param なし
# @return void （0）
#-----------------------------------------------------------
function main {
  # ユーザの記事一覧(id)の取得
  local LIST=
  LIST=`$CURL --silent https://qiita.com/api/v2/users/$USER/items |  jq .[].id`

  # 各記事のLGTM数を取得
  local LGTM_NUM=0
  for list in $LIST
  do
    local tmplist=`echo $list | tr -d "\""`
    local lgtm_list=`$CURL --silent https://qiita.com/api/v2/items/$tmplist/likes | jq .[].created_at`
    # LGTM総数を加算していく
    tmp_lgtm_num=`echo $lgtm_list | wc -w`
    LGTM_NUM=$(( $LGTM_NUM + $tmp_lgtm_num ))
  done

  # 前回値と比較 -> 増えていたらslack通知
  local PREV_LGTM_NUM=0
  PREV_LGTM_NUM=`cat lgtm.json | jq .LGTM_NUM`
  if [ $LGTM_NUM -gt $PREV_LGTM_NUM ]; then
    # slack更新
    send_slack_msg
  fi

  # data更新
  cat lgtm.json | jq .LGTM_NUM=$LGTM_NUM  >tmp_lgtm.json
  rm lgtm.json && mv tmp_lgtm.json lgtm.json

  return 0
}

#-----------------------------------------------------------
# @fn send_slack_msg
# @brief slackに更新された旨を通知する
# @param なし
# @return void （0）
#-----------------------------------------------------------
function send_slack_msg {
  local MSG="\"QiitaでLGTMされました！マイページを確認しよう！\n https://qiita.com/tomoten\""
  curl -X POST -H 'Content-type: application/json' --data "{"text":$MSG}" ${SLACK_WEB_HOOK}
  return 0
}

# main処理
main
```

```json
{
  "LGTM_NUM": ここにLGTM総数を設定する。
}
```

```yaml
# check-qiita.yml 
name: Check Qiita LGTM

# UTC時刻に注意
# 7 ~ 23時の間で30分になったときにjob実行
on: 
  schedule:
    - cron: '30 0-14,22-23 * * *'

jobs:
  check_qiita_lgtm:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2
        with:
          ref: lgtm

      - name: check and send msg
        env:
          QIITA_ACCESS_TOKEN: ${{ secrets.QIITA_ACCESS_TOKEN }}
          SLACK_WEB_HOOK: ${{ secrets.SLACK_WEB_HOOK }}
        run: ./check-qiita.sh

      - name: push
        run: |
          git remote set-url origin https://github-actions:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}
          git config --global user.name "${GITHUB_ACTOR}"
          git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
          if (git diff --shortstat | grep '[0-9]'); then \
            git add .; \
            git commit -m "Update LGTM data by github-actions"; \
            git push origin lgtm; \
          fi
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

## 4.3. Slackの構築
- 「[Webhookを使ってシェルスクリプトで手軽にslack通知する](https://chariosan.com/2020/02/01/slack_webhook_shellscript/)」にしたがってAPIを作成しましょう。
  - Slackについては、「[slack個人利用：google連携、RSS連携](https://qiita.com/tomoten/items/196a840bf4078e628234)」で構築した個人利用Slackをつかっています。
  - 今回、私はアプリ名：ScriptBot、通知チャンネル：sw-prototypingで作成しました。
  - 作成したときに表示されるwebhook urlをGithubシークレット変数に必ず登録してください。

![scriptbot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624259/bad11faf-fb43-e14e-a165-ad60e5a9f52d.png)


## 4.4. 動作確認
- ~~動作確認として、現状のLGTM総数を取得し、それより1少ない値をlgtm.jsonに設定した状態でGithub Actionsを実行します。実行すると、以下のような表示がslackアプリ側に通知が来ます。~~
  - ~~時刻がスケジュール通りでないのは、テストのためにGithub Actionsをマニュアル実行しているからです。~~
- (2021-10-02追記)LGTMしていただいた皆様、ありがとうございます。実際にGithub Actionsのスケジュール実行が動作し、Slack通知を受信できることを確認できました。

![SlackMessage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624259/3f1c8927-281e-ccbe-5401-e8522c0f0457.png)

# 5. おわりに
- どの記事でLGTMがもらえたのか、誰がLGTMしてくれたのか、などの情報も取得できるので、データ構造をしっかり考えればより詳細な情報をSlack通知できるようになります。
- その場合、jsonファイルでのデータ管理はとても煩雑になるので、素直にデータベースの力を借りるのがいいと思っています。
- 簡単なスクリプト処理、データ保持等を考慮すると、AWSでlambdaを軸に構築するのがよいと思います。