Files
awoooi/docs/adr/ADR-050-telegram-interactive-incident-v2.md
OG T c9c60c3a61
Some checks failed
E2E Health Check / e2e-health (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
Type Sync Check / check-type-sync (push) Failing after 22s
feat(mcp-integrations): Phase S 架構修復 + MCP 整合基礎建設
Phase S 技術債修復 (首席架構師審查 82→完整):
- S-01: generate_alert_fingerprint 移至 AlertAnalyzer.generate_fingerprint() staticmethod
- S-04: 移除 Pydantic v2 deprecated json_encoders (直接用原生 datetime 序列化)

Sentry MCP 整合 (Phase 23):
- ADR-048: Sentry→OpenClaw AI Triage 架構決策
- sentry_webhook_service.py: parse/analyze/create_incident/build_message Service 層
- config.py: SENTRY_WEBHOOK_SECRET (Fail-Closed HMAC-SHA256)

Playwright MCP 整合 (短期):
- smoke.spec.ts: 5 頁面 E2E smoke test (home/dashboard/incidents/approvals/terminal)
- cd.yaml: E2E Smoke Test 步驟 + Telegram 🎭 Smoke 狀態通知

長期規劃 ADR:
- ADR-049: Figma Code Connect 設計系統同步
- ADR-050: Telegram 互動式 Incident 2.0 (6鍵 Inline Keyboard)
- ADR-051: Context7 依賴升級顧問 (Next.js 14→15, FastAPI 0.115→0.128)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 16:20:57 +08:00

6.4 KiB
Raw Blame History

ADR-050: Telegram 互動式 Incident 管理 2.0

項目 內容
狀態 📋 已批准,待實作
日期 2026-04-01
決策者 首席架構師 + 統帥
觸發 MCP 整合長期計畫

背景

目前 AWOOOI Telegram 告警訊息提供三個 Inline Keyboard 按鈕:

[✅ 批准 (Y)]  [❌ 拒絕 (n)]  [🔕 靜默]

統帥在 Telegram 收到告警時,除了批准/拒絕外,還需要切換到 Web UI 或 CLI 才能:

  • 查看 Incident 的完整詳情metrics、stack trace、診斷結果
  • 重新觸發 OpenClaw 分析(當第一次分析結果可疑時)
  • 查詢歷史相似 Incident 的處置結果

這增加了認知負擔,也拖慢了 MTTRMean Time To Respond

問題

操作 現況 痛點
查看詳情 須切換至 Web UI 手機操作不便,流程中斷
重新診斷 須 CLI 觸發 無法在 Telegram 中完成閉環
歷史對比 須查詢資料庫 完全手動,耗時

決策

擴充 Telegram Inline Keyboard加入第二行按鈕

[✅ 批准]  [❌ 拒絕]  [🔕 靜默]
[📋 詳情]  [🔄 重診]  [📊 歷史]

在後端新增 TelegramCallbackService,處理新按鈕的回調邏輯,並使用 edit_message 在原訊息中就地更新(不發送新訊息)。

架構

回調處理流程

Telegram Inline Button Click
  → Bot API callback_query
  → AWOOOI API POST /telegram/callback
  → TelegramCallbackRouter (apps/api/src/routers/telegram_callback.py)
  → TelegramCallbackService (apps/api/src/services/telegram_callback_service.py)
  → 根據 action 分派:
      "detail"     → IncidentRepository.get_by_id()
                   → 格式化 Markdown 回傳
      "reanalyze"  → IncidentService.trigger_reanalysis()
                   → OpenClaw 重分析排程
      "history"    → IncidentRepository.find_similar()
                   → 格式化歷史對比表格
  → Telegram Bot API edit_message_text()
  → 原訊息就地更新(保留按鈕,附加展開內容)

Callback Data 格式

{action}:{incident_id}

範例:
  detail:INC-2026-0401-001
  reanalyze:INC-2026-0401-001
  history:INC-2026-0401-001

新 Inline Keyboard 結構

# src/services/telegram_notification_service.py
InlineKeyboardMarkup(inline_keyboard=[
    [
        InlineKeyboardButton(text="✅ 批准",   callback_data=f"approve:{incident_id}"),
        InlineKeyboardButton(text="❌ 拒絕",   callback_data=f"reject:{incident_id}"),
        InlineKeyboardButton(text="🔕 靜默",   callback_data=f"silence:{incident_id}"),
    ],
    [
        InlineKeyboardButton(text="📋 詳情",   callback_data=f"detail:{incident_id}"),
        InlineKeyboardButton(text="🔄 重診",   callback_data=f"reanalyze:{incident_id}"),
        InlineKeyboardButton(text="📊 歷史",   callback_data=f"history:{incident_id}"),
    ],
])

詳情回覆格式

📋 Incident 詳情INC-2026-0401-001
━━━━━━━━━━━━━━━━━━
🏷 類型CPU_SPIKE
🖥 主機k3s-node-1 (192.168.0.125)
⏱ 時間2026-04-01 14:32 +08
📊 觸發值CPU 94.3% (閾值 90%)
🤖 OpenClaw 信心0.87

診斷摘要:
過去 30 分鐘 CPU 呈上升趨勢,
與 incident INC-2026-0318-007 模式相符。
建議:重啟 signal_worker pod。

歷史對比格式

📊 相似 Incident 歷史(近 30 天)
━━━━━━━━━━━━━━━━━━
| 日期  | 類型      | 處置  | 結果 |
|-------|-----------|-------|------|
| 03-18 | CPU_SPIKE | 批准  | ✅   |
| 03-10 | CPU_SPIKE | 批准  | ✅   |
| 02-28 | CPU_SPIKE | 靜默  | ⚠️   |

相似度最高INC-2026-0318-007 (0.94)

實作計畫

P1骨架建立Sprint 1

  • 新增 /telegram/callback endpointsrc/routers/telegram_callback.py
  • 建立 TelegramCallbackService 骨架(含 action dispatch
  • 更新 telegram_notification_service.py 的 Inline Keyboard 結構
  • Webhook 設定確認Bot API setWebhook 指向新 endpoint

交付條件:點擊新按鈕不報錯,回傳「功能開發中」佔位訊息

P2詳情查詢 + 重診觸發Sprint 2

  • detail action呼叫 IncidentRepository.get_by_id(),格式化後 edit_message
  • reanalyze action呼叫 IncidentService.trigger_reanalysis(),回傳「重診已排程」
  • 防止重複觸發:重診進行中時,按鈕顯示「 診斷中」並 disable

P3歷史對比分析Sprint 3

  • history actionIncidentRepository.find_similar(incident_id, top_k=5)
  • 相似度演算法:基於 type + host + time_window 的向量搜尋(若已啟用 pgvector
  • 格式化歷史表格,含處置結果與信心分數

技術約束

  1. leWOOOgo 積木化TelegramCallbackService 必須透過 IncidentRepository interface 存取資料,禁止 Router 層直接查 DB 或 Redis
  2. edit_message 限制Telegram Bot API 限制 edit_message 只能在 48 小時內有效,超時需降級為發送新訊息
  3. Callback Query 答覆:所有 callback_query 必須在 5 秒內呼叫 answerCallbackQuery(),否則 Telegram 顯示 loading 轉圈
  4. 去重保護:同一 Incident 的 reanalyze 在 10 分鐘 TTL 內只觸發一次(參考 feedback_telegram_dedup.md

安全考量

  • Callback data 中的 incident_id 需驗證存在且屬於合法狀態
  • Callback query 的 from.id 需與 allowlist 核對(使用現有 Telegram access 控制)
  • 禁止在 callback 中執行不可逆操作(如刪除 Incident

影響

面向 影響
MTTR 預計減少 40%(統帥不需切換視窗)
API 新增 1 個 endpoint無現有 endpoint 變更
DB 新增 find_similar query需確認索引
Telegram Bot 需重新設定 Webhook一次性操作

相關文件