# 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 的處置結果 這增加了認知負擔,也拖慢了 MTTR(Mean 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 結構 ```python # 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` endpoint(`src/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` action:`IncidentRepository.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(一次性操作) | ## 相關文件 - [ADR-035-telegram-alert-chain-enforcement.md](ADR-035-telegram-alert-chain-enforcement.md) - [ADR-045-telegram-gateway-consolidation.md](ADR-045-telegram-gateway-consolidation.md) - [feedback_telegram_dedup.md](~/.claude/projects/-Users-ogt-awoooi/memory/feedback_telegram_dedup.md) - [feedback_telegram_alert_format.md](~/.claude/projects/-Users-ogt-awoooi/memory/feedback_telegram_alert_format.md) - [feedback_lewooogo_modular_enforcement.md](~/.claude/projects/-Users-ogt-awoooi/memory/feedback_lewooogo_modular_enforcement.md)