Discord Webhook/Bot連携実装
WebhookとBotの選択
Discord への連携には2つの方式があり、先に選び間違えると作り直しになります。
| Webhook | Bot | |
|---|---|---|
| できること | 指定チャンネルへ投稿するだけ | 投稿・受信・返信・コマンド・権限操作 |
| 準備 | チャンネル設定で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チャンネルしかないこと
解説: 重大度でチャンネルを分け、同一事象をまとめ、正常は送らないか日次にまとめます。