【GitHub Actions】GitHubの草を生やしてない日はLINEに通知を送ろう

# はじめに
こんにちは、kenです。
みなさんGitHubの草生やしてますか？草がたくさん生えている人のプロフィールってなんだか圧倒されるものがありますよね！

かくいう私はというと....全然生えてないです！！！！（ズコー）

![スクリーンショット 2024-04-14 20.29.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/f1e1c263-7369-1dd5-2db2-6a49a18a0a2b.png)


「俺も草がびっしり生えた人になりたい...！！」

「でもいつも忘れて草が途切れてしまう...。」

「それなら一日の終わりに草が生えてなかったら通知を送るようにすればいいんじゃね？」

こう考えたのが今回の記事のきっかけです。
LINEのAPIとGitHub Actionsを使って毎晩22時に草が生えてなかったらLINEの通知を送るようにしてみます。


# 手順
以下の3ステップからなります。
1.  [LINE Notify](https://notify-bot.line.me/ja/)でトークンの取得
1.  GitHubのリポジトリに取得したトークンを追加
1.  GitHub Actionsのワークフローを作成

## 1. LINE Notifyでトークンの取得
[LINE Notify](https://notify-bot.line.me/ja/)にログインし、マイページの「トークンを発行する」を押下します。

![スクリーンショット_2024-04-13_9_28_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/e88d7873-b3de-a5d9-52ec-3a059a4f67d4.png)

適当にトークン名を入力し、「1:1でLINE Notifyから通知を受け取る」を選択してトークンを発行します。

![スクリーンショット_2024-04-13_9_31_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/75a434c7-bd64-b0ab-0f59-a15e5fb6784c.png)

発行されたトークンをコピーしてこの画面は閉じます。
![スクリーンショット_2024-04-13_9_33_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/cf634f0c-4b99-8893-b7d7-10a9cd3dcf89.png)

## 2.GitHubのリポジトリに取得したトークンを追加
リポジトリを新規作成します。
「Settings」→「Secrets and variables」→「Actions」の「New repository secret」から先程取得したトークンを設定します。
トークンの名前は何でもいいですが、ステップ3で紹介するコード内では`LINE_TOKEN`という名前でこのトークンを参照する実装になっているので、特にこだわりがない方は`LINE_TOKEN`で設定するといいと思います。
![スクリーンショット_2024-04-13_9_42_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/8ddcb829-00e4-6fb9-70f6-440aa1a876a2.png)

## 3.GitHub Actionsのワークフロー作成
ローカルで適当なディレクトリを作成し、`git init`して先ほど作ったリモートリポジトリとローカルのリポジトリを連携します。
そして以下のyamlを`.github/workflows`配下に保存します。

草が生えていない場合に送るメッセージの文章は各自好きなものに変えてください。
```yaml
name: Check GitHub Contributions and Notify

on:
  schedule:
    - cron: "0 13 * * *" # UTC時間で毎日13時（日本時間で22時）に実行

jobs:
  check-and-notify:
    runs-on: ubuntu-latest
    steps:
      - name: Check for Contributions on Main and Master Branches
        id: check_contributions
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          DATE=$(date -u +"%Y-%m-%dT00:00:00Z")
          USERNAME="${{ github.repository_owner }}"
          QUERY="{\"query\": \"query { user(login: \\\"$USERNAME\\\") { contributionsCollection(from: \\\"$DATE\\\", to: \\\"$DATE\\\") { commitContributionsByRepository { repository { name, defaultBranchRef { name } } contributions(first: 100) { totalCount } } } } }\"}"

          RESPONSE=$(curl -H "Authorization: bearer $GITHUB_TOKEN" -H "Content-Type: application/json" -d "$QUERY" https://api.github.com/graphql)
          echo "Response: $RESPONSE"
          MAIN_COUNT=$(echo $RESPONSE | jq '[.data.user.contributionsCollection.commitContributionsByRepository[] | select(.repository.defaultBranchRef.name == "main") | .contributions.totalCount] | add // 0')
          MASTER_COUNT=$(echo $RESPONSE | jq '[.data.user.contributionsCollection.commitContributionsByRepository[] | select(.repository.defaultBranchRef.name == "master") | .contributions.totalCount] | add // 0')
          TOTAL_COUNT=$(($MAIN_COUNT + $MASTER_COUNT))

          echo "Total contributions to main and master: $TOTAL_COUNT"
          echo "CONTRIBUTIONS_COUNT=$TOTAL_COUNT" >> $GITHUB_ENV

      - name: Send LINE Notification if No Contributions
        if: env.CONTRIBUTIONS_COUNT == '0'
        env:
          LINE_TOKEN: ${{ secrets.LINE_TOKEN }}
          MESSAGE: "まもなく今日が終わりますがまだGitHubの草が生えてません！今すぐ草を生やしましょう！"
        run: |
          curl -X POST -H "Authorization: Bearer $LINE_TOKEN" -F "message=$MESSAGE" https://notify-api.line.me/api/notify
```
ここではGitHubのAPIを叩いて本日中のコミットの中にmainまたはmasterブランチへのコミットがあるかを確認し[^1]、なかったらLINE NotifyのAPIを叩いています。

GitHubの草が生える条件は[GitHub Docs](https://docs.github.com/ja/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-settings-on-your-profile/viewing-contributions-on-your-profile#what-counts-as-a-contribution)によると
> プロフィールページでは、特定のアクションがコントリビューションとしてカウントされます:
>- リポジトリの既定のブランチまたは gh-pages ブランチへのコミット
> - ブランチの作成
> - イシューのオープン
> - ディスカッションをオープンすること
> - ディスカッションに回答すること
> - プルリクエストを提案すること
> - pull request レビューの送信

とのことですが、ワークフロー内でこれらすべてを確認するのは大変なので、ここでは最も代表的と思われる「リポジトリの既定のブランチへのコミットが本日中に行われたか」をチェックしています。[^1][^2]
[^1]: 既定ブランチがmainやmaster以外の名前の可能性もありますが、あまりそういうケースはないだろうということで無視しています。
[^2]: GitHubのデフォルトの設定では、プライベートリポジトリへのコミットはコントリビューションとしてカウントされません。しかし、上記のyamlの設定ではプライベートリポジトリのコミットもコントリビューションとして含めています。プライベートリポジトリのコミットをコントリビューションとして含めるようにするには、GitHubの設定を変更する必要があります。具体的には、「Settings」→「Include private contributions on my profile」のオプションにチェックを入れることで設定できます。

あとはこのyamlを`git push`したら準備完了。毎日22時にこのワークフローが動くのでもし草を生やしてなかったら通知が来るはずです。[^3]とても簡単に設定できました。

[^3]:ただし22時ピッタリに来ることは少なく、少し後ろにずれるみたいです。

![スクリーンショット 2024-06-11 22.49.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/2f00e262-0a9e-df46-010a-a773079d5025.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/8f857636-370e-daec-c385-ff4e20e95a6d.png)


# さいごに
こういった記事すでにあるかなと思ったんですが、意外になかったので書いてみました。GitHub Actionsはたまにしか触らないんですが、特に難しいこともなく設定できました。ちょっとしたことでも日常をハックできると嬉しいですね。
間違いなどあればコメントにてご指摘ください、最後まで読んでいただきありがとうございました。

今回作ったリポジトリへのリンクも置いておきます。

https://github.com/ken-hashimoto/contribute-reminder/blob/main/.github/workflows/reminder.yaml
# P.S.

この記事の執筆とbotの作成は2ヶ月前に行ったことなんですが、あれから草を生やす習慣がついてきました。通知が来たら無理にでもなにか1つコミットするようにしています...w

![スクリーンショット 2024-06-06 22.01.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/fbaf4eb9-1782-8b18-886b-9b0391c88991.png)