Discord Webhook/Bot連携実装

WebhookとBotの選択

Discord への連携には2つの方式があり、先に選び間違えると作り直しになります。

WebhookBot
できること指定チャンネルへ投稿するだけ投稿・受信・返信・コマンド・権限操作
準備チャンネル設定でURLを発行アプリ登録、招待、権限設定
常時接続不要(HTTPを1回叩く)必要(WebSocketで待ち受ける)
運用サーバー不要。CIやcronから叩ける常駐プロセスが要る

通知を送るだけなら Webhook で十分です。 CI の結果、監視のアラート、定期レポート — これらはすべて一方向です。Bot を用意すると常駐プロセスの運用が発生し、得るものがありません。

逆に「利用者がコマンドを打って応答する」なら Bot が必要です。Webhook では受信できません。

Webhookで送る

[[Webhook]] の一般的な仕組みどおり、発行されたURLへ POST するだけです。

curl -X POST "$DISCORD_WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -d '{
    "username": "デプロイ通知",
    "embeds": [{
      "title": "本番デプロイ完了",
      "description": "v1.4.2 を公開しました",
      "color": 3066993,
      "fields": [{ "name": "所要", "value": "3分12秒", "inline": true }]
    }]
  }'

embeds は構造化された表示枠です。本文にすべてを詰め込むより、タイトル・説明・項目に分けたほうが読まれます。[[監視とアラート]] の通知では、何が起きたかをタイトル、次に何をするかを説明に置くと、受け取った人がすぐ動けます。

通知が無視されるようになる原因

運用で最も起きる失敗は、技術的な不具合ではなく通知の飽和です。

  • 正常時にも送る — 成功通知が大半を占めると、失敗が埋もれます
  • 同じ内容を繰り返す — 監視の再送で同一メッセージが並び、誰も読まなくなります
  • 重大度が混ざる — 情報と障害が同じチャンネルに来ると、優先度が判断できません

対処は、チャンネルを重大度で分ける、同一の事象はまとめる、正常は送らない(または日次でまとめる) の3つです。これは Discord 固有ではなく通知設計の一般論ですが、送るのが簡単な分だけ飽和しやすくなります。

実装で気をつけること

  • URLは秘密情報 — 発行されたURLを知っていれば誰でも投稿できます。リポジトリに直接書かず、環境変数やシークレットに置きます。漏れたら再発行するのが唯一の対処です
  • [[レートリミット]] がある — 短時間に多数投稿すると 429 が返ります。応答の retry_after に従って待ちます。まとめて送る設計にすると当たりません
  • 文字数の上限 — メッセージ本体は2,000文字、embed には項目ごとの上限があります。ログをそのまま流すと静かに切れるため、要点を抜き出すか外部へのリンクにします
  • 失敗を握り潰さない — 通知の送信自体が失敗しても、本体の処理は成功しています。送信失敗をログに残さないと、「通知が来ない=何も起きていない」と誤解されます

Botにする場合

常駐して待ち受けるため、プロセスの死活監視が必要になります。落ちていても誰も気づかない状態は、通知系で最も危険です。

権限は必要最小限を選びます。招待時に与えた権限は後から効いてくるため、「とりあえず管理者」で入れると、そのサーバー全体を操作できるアカウントが増えることになります。

関連技術とのつながり

  • [[Webhook]] — 送信側の仕組み。Discord連携はその具体例
  • [[REST API]] — Botから投稿する場合も結局はHTTPのAPIを呼ぶ
  • [[レートリミット]] — まとめて送る設計にして当たらないようにする
  • [[監視とアラート]] — 通知の飽和を避ける設計はここと共通
  • [[GitHub REST API活用パターン]] — 収集した状態を通知へ流す組み合わせ
Q: CIの結果を通知するだけの用途で適切なのはどれ?
- [x] Webhook(URLへPOSTするだけで常駐プロセスが不要)
- [ ] Bot(常時接続して待ち受ける)
- [ ] どちらでも同じ
解説: 一方向の通知にBotを使うと、常駐プロセスの運用が発生するだけで得るものがありません。

Q: Discord Webhook の URL が漏れたときの対処はどれ?
- [ ] 権限設定でアクセスを制限する
- [x] URLを再発行する
- [ ] IPアドレスで制限する
解説: URLを知っていれば誰でも投稿できます。URL自体が資格情報です。

Q: 通知が誰にも読まれなくなる典型的な原因はどれ?
- [ ] embedを使っていること
- [x] 正常時にも送り続け、失敗が大量の成功通知に埋もれること
- [ ] 通知先が1チャンネルしかないこと
解説: 重大度でチャンネルを分け、同一事象をまとめ、正常は送らないか日次にまとめます。