👻

「貴方がこのメッセージを読んでいるということは、私はもうこの世にはいないのでしょう」みたいなの

2024/05/11に公開

我が家では家族間のコミュニケーションツールとしてSlackを使っているのですが、私がSlackにn日アクセスしない場合に、家族に向けて任意のメッセージを投下するような仕組みをGitHub Actionsで作ったので紹介します

掲題の小説みたいなメッセージが投げられるやつです

https://github.com/ryooo/last-will

構成

Slackのteam.accessLogs APIから取得した最終ログイン日時と暗号化されたjsonメッセージを比較して、設定された日数以上ログインされていないことが確認できたらSlackにpostMessageするジョブを作成しています。
これをGitHub Actionsのcronで日次実行するように設定しています。

使い方

last-will.json(メッセージ平文)の設定オプションとして以下の3つのオプションを用意しています。

1. 任意の日数 未ログインだった場合に通知

{
  "messages": [
    {
      "condition": {
        "type": "account",
        "account": {
          "userId": "U0AAASAAA", // ← Slack UserID
          "silentDays": 1 // ← 未ログインの日数
        }
      },
      "message": "メッセージ"
    }
  ]
}

2. 任意の日付に通知

{
  "messages": [
    {
      "condition": {
        "type": "date",
        "date": "2024-04-29"
      },
      "message": "メッセージ"
    }
  ]
}

3. 任意の日付時点で未ログイン日数がn日以上だった場合に通知

{
  "messages": [
    {
      "condition": {
        "type": "dateAndAccount",
        "date": "2025-12-01",
        "account": {
          "userId": "U0AAASAAA",
          "minSilentDays": 365
        }
      },
      "message": "メッセージ"
    }
  ]
}

これらの設定を使って未ログイン日数15日くらいに起動するように設定しておけば、死後以下のようなメッセージをSlackに投下できるようになります。

工夫

パブリックリポジトリ化

以下のメリットがあるため、メッセージを暗号化したうえでパブリックリポジトリで公開しました。

  • Actions含め死後も無料で使える。
  • forkしてもらえれば他の方にも使ってもらえる可能性がある。

artifactを活用

Slackのteam.accessLogs APIはデフォルトで100件まで取得できます。ページングも可能ですが、本当にお亡くなりになってしまってずっとログインしなければ故人のaccessLogsは取得できなくなります。

そのため、accessLogsから取得した最終ログイン日時をjson化してartifactとして保存し、次回のAction実行時にダウンロード&マージすることで故人の最終ログイン日時をずっと取得できるようにしています。

actions/download-artifactが初回エラーになる件

actions/download-artifactは、通常artifactが存在しない場合にが以下のエラーで失敗します。

Error: Unable to find any artifacts for the associated workflow

そして、前回のartifactのダウンロードに失敗した場合は(誤ったartifactが保存されてほしくないため)後続の処理をスキップする必要があります。

結果的にいつまで経ってもartifactがアップロードできないので、通常は初回だけfailure()でもupload-artifact実行するような一手間が必要になります。

このひと手間を回避するために、download-artifactの前の工程で以下のようなステップを入れて回避しています。

      - id: check-artifact-exist
        name: Check the last artifact
        run: |
          url="https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${{ run-id }}/artifacts"
          echo "artifact-name=$(curl -fsSL "$url" | jq -r '.artifacts[0].name')" >> $GITHUB_OUTPUT
      - uses: actions/download-artifact@v4
        if:
          ${{ steps.check-artifact-exist.outputs.artifact-name ==
          'last-login-result' }}

最後に

どこまで動いてくれるかわからないので大事なメッセージは託せませんが、GitHub WorkspaceのAIによる不具合修正機能が進化したら、死後動かなくなっても自動で修正してくれたりできるようになるのかな🤔

Discussion