本番エラーを毎朝 Discord に届ける!Claude Code ルーティンで作ろう

要約
毎朝、クラウドの Claude が Vercel のエラーを取得し、Discord の Webhook に送る。Vercel はコネクタでつないで書き込み系はブロック、Webhook URL は環境変数に置く
意見はこのエリアに表示されます
アイキャッチ画像

本番エラーを毎朝 Discord に届ける仕組みを、Claude Code のルーティンで作った。流れはこれだ

  1. 毎朝9:05、クラウドで Claude が起動する
  2. Vercel から過去7日分のエラーを取ってくる
  3. 新しく出たものと、前から続いているものに分ける
  4. どこで・何が・利用者への影響を日本語でまとめる
  5. Discord の Webhook に1通だけ送る
  6. 気になるエラーは、bot 経由で Claude に読ませて調べる

要は、パソコン閉じてても定期的に何か実行させて、Discord に通知しちゃうぜって方法だね

ワイは普段、Slack の代わりに Discord を使って様々なものを管理している。課金はしてない

Claude Code + bot で Discord に読み書きさせてる

エラーログ、障害報告、MTGのtldv(文字起こし)を報告後 todo を投稿させたり、まぁ色々集約していて一元管理してる。本当に便利

画像の説明を入れてください
Discord チャンネル

Claude Code のルーティン

Claude Code のルーティンは、決めた時刻にクラウドで Claude が起動して、指示どおりに作業してくれる仕組み

PCを閉じた状態でもクラウド上でClaude Codeを自動実行する。GitHub トリガーや、定期実行、アラートなどが可能。

スケジュールで実行するルーティンを定義したり、API 呼び出しでトリガーしたり、Anthropic が管理するクラウドインフラストラクチャから GitHub イベントに反応させたり

Vercel のコネクタをつなげば、エラーの一覧を返すツール(get_runtime_errors)がそのまま使える。アプリには触らなくていい

流れはこんな感じ

  • 毎朝9:05に、クラウドで Claude が起動する
  • Vercel から過去7日分のエラーのまとまりを取る
  • 24時間以内に初めて出たものと、前から続いているものに分ける
  • 日本語でまとめて、curl で Discord の Webhook に送る
画像の説明を入れてください
Discord チャンネルに自動通知。毎朝9時過ぎに告知される

今どきでよい

以下から、Desktop アプリ、または CLI から、ルーチンを作成する

Vercel Cronは見送り。Next.js に API ルートを1本足して、毎朝 Vercel のエラーを取りに行かせるというやり方

アプリの中からエラーを取りに行くには、Vercel の API トークンを環境変数に置くことになる。プロジェクトを操作できる強い鍵。通知のためだけに置くのはなんだか嫌だった

送り先は自分専用の Discord サーバー

候補は Discord、Slack、Google スプレッドシートなど色々あるが、結局、普段いちばん見ている Discord にした

既存のサーバーにはほかのメンバーもいるので、本番のエラーを流すのはやめておきたい。自分ひとりのサーバーを新しく作った。案件ごとにチャンネルを分けていけば、ほかのサービスの通知もここに集められる

Discord のサーバーは作った時点で非公開。「コミュニティ」と「サーバー発見」を有効にしない限り、検索にも出ない

通知は Webhook で送る。チャンネル設定の「連携サービス」から URL を1つ発行するだけでOK

画像の説明を入れてください
Discord bot

準備でつまずいたところ

手元の Vercel プラグインは、クラウドからは使えない

Claude Code には Vercel のプラグインを入れていて、手元ではエラーログを普通に読めていた。ところが、クラウドで動くルーティンからはこれが使えない

ルーティンが使えるのは、claude.ai の「コネクタ」としてつないだサービスだけ。claude.ai の設定から Vercel をつなぎ直した

画像の説明を入れてください
claude 設定画面のマイコネクタ

認可の画面では、対象を izanami のプロジェクトだけに絞った。「今後作るプロジェクトもすべて許可する」のチェックは外して、仕事で使っているほかのチームも許可していない

書き込み系のツールは全部ブロック

Vercel のコネクタには、デプロイや設定変更までできるツールも入っている。ルーティンは誰も見ていないところで動くので、指示文で「使うな」と書くだけだと不安

コネクタのツール権限で、読み取り専用のツールは「常に許可」、書き込みと削除のツール92個は「ブロック」にした

Webhook の URL をどこに置くか

指示文に URL を直接書くと、設定画面にそのまま表示されてしまう

クラウド環境には「ネットワークシークレット」という、鍵を見せずに API を呼べる機能がある。ただ、これは通信の途中でヘッダーに鍵を差し込む仕組み。Discord の Webhook は URL の途中に鍵が入っているので、このやり方だと渡せない

結局、普通の環境変数に入れた。この環境変数の欄、環境を新しく作る画面には出てこない。作ったあとの「クラウド環境を編集」の、いちばん下にある。歯車のアイコンから開ける。ここはけっこう探した

画像の説明を入れてください
エラー通知

ネットワークは「制限付き」にして、外に出られるのは discord.com だけにした。Vercel のコネクタは Anthropic 経由でつながる

試しに動かしてみる

「今すぐ実行」を押したら、30秒くらいで Discord に通知が届いた

ここで気づいたことがいくつか

画面の「デフォルト」と実際のモデルが違った

作成画面では、モデルが「デフォルト・Opus 5.5」と表示されていた。なのに、実行ログを見たら Sonnet で動いている。設定が空のままだと、表示とは別のモデルが使われるらしい。モデルは明示的に選んでおく

最初の通知は、自分でも読みにくかった

最初の通知は、指示文を書き換えて、エラーごとに「どこで」「何が」「利用者への影響」を日本語で書かせるようにした。原因が確かでないところには「(推測)」を付けさせている

毎朝見ていれば、もっと早く気づけたエラー

最初の通知でいちばん上に出たのが「記事ページの読み込みに失敗」。7日間で2万4千回以上

調べてみると、ほとんどは削除済みの記事への古いリンクだった。検索エンジンのクローラーなんかが開きに来て、データベースに記事が無いので失敗している。利用者には「非公開記事です」のページが出るだけで、サイトが壊れているわけではない

ただ、本当は問題じゃないものがエラーとして記録され続けていたせいで、ほかのエラーが埋もれていた。毎朝の通知を見ても「またこれか」で終わってしまう

削除済みの記事はエラーではなく普通の記録として残すようにして、記事 ID の形をしていない URL はデータベースに問い合わせる前に弾くようにした。見え方は変えていない。データベースが本当に落ちたときは、これまでどおりエラーとして残る

通知の代表例には別のエラーコードが出ていて、最初はそっちが原因だと思い込んでいた。ログを何件か開いてみて、中身が2種類混ざっていると気づけたのはよかった

Claude から通知を読めるようにした

Webhook は送るだけの仕組みなので、Claude は届いた通知を読めない。「今朝の通知を見て、気になるエラーを調べて」と頼めるように、読み書きできる bot を作って Discord サーバーに入れた

ここでもいくつか引っかかった

  • 公開 Bot をオフにすると、「インストール」タブのデフォルトの認証リンクを「なし」にしないと保存できない
  • Webhook が投稿した本文を読むには、Message Content Intent をオンにしないといけない
  • 非公開チャンネルは、bot をサーバーに招待しただけでは読めない。チャンネルの権限にも bot を足す

bot のトークンを Claude Code に渡すところでも失敗した。Claude Code の入力欄で ! を付けると、その場でシェルのコマンドを実行できる。そこで read -s でトークンを打ち込もうとしたら、入力欄が出ずに空のまま終わった。次にクリップボードから読む方法にしたら、今度はコマンドをコピーした時点でトークンが上書きされる

最後は、クリップボードのトークンをファイルに保存してクリップボードを空にする短いスクリプトを作ってもらった。手で打てる長さなので、トークンをコピーしたまま実行できる

やってみて

いちばんの収穫は、4か月続いていたエラーに、仕組みを作ったその日のうちに気づけたこと

設定自体は画面をたどっていくだけ。でも、「手元で使えるものがクラウドでは使えない」「鍵の置き場所がわかりにくい」みたいな、小さな引っかかりがいくつもあった

ブラウザの中で起きたエラーは、いまもこの仕組みでは拾えない。次は、エラー画面が出たときにサーバー側のログへ送る仕組みを足すつもり

Explore More
関連記事はありません。