fix(telegram): 按鈕回覆靜默兩大根因修復
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 17m40s

問題一:ai_advisory_* 按鈕(容量預測/合規等)
  - 按下後只發 toast(2-3 秒消失),群組永無回覆
  - 修法:_handle_ai_advisory_action 加 message_id 參數,
    answer_callback 後額外 sendMessage reply 到原卡片

問題二:已解決告警再次點「批准」
  - sign_approval early-return(status != pending)但
    _notify_approval_result 仍發「 執行中...」→ 永無後續
  - 修法:僅 approval.status == APPROVED 時才發「執行中...」
    其他終態改發「ℹ️ 此告警已處理(狀態:...)」並 return

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-04-22 01:57:47 +08:00
parent ca8361e0bc
commit 1625e7bd19

View File

@@ -2229,6 +2229,7 @@ class TelegramGateway:
user_id: int,
username: str,
user: dict,
message_id: int | None = None,
) -> dict:
"""
2026-04-19 P0 修 (ADR-092): 處理 4 LLM scanner 的互動按鈕.
@@ -2269,6 +2270,18 @@ class TelegramGateway:
feedback_text = result.get("feedback_text", "已收到")
await self._answer_callback(callback_query_id, action, text=feedback_text)
# 2026-04-22 Claude Sonnet 4.6: 發群組 replytoast 2-3 秒消失,群組才是永久可見)
if message_id and feedback_text:
try:
await self._send_request("sendMessage", {
"chat_id": settings.OPENCLAW_TG_CHAT_ID,
"text": feedback_text,
"reply_to_message_id": message_id,
})
logger.info("ai_advisory_group_reply_sent", action=pure_action, message_id=message_id)
except Exception as _ge:
logger.warning("ai_advisory_group_reply_failed", action=pure_action, error=str(_ge))
return {
"action": action, "advisory_type": advisory_type, "advisory_id": advisory_id,
"user": user, "success": result.get("success", False),
@@ -3141,6 +3154,7 @@ class TelegramGateway:
user_id=user_id,
username=username,
user=user,
message_id=message_id,
)
# ===================================================================
@@ -5544,26 +5558,43 @@ class TelegramGateway:
)
if approval:
from src.models.approval import ApprovalStatus
status_val = approval.status.value if hasattr(approval.status, "value") else str(approval.status)
logger.info(
"telegram_approval_signed_via_polling",
approval_id=approval_id,
user_id=user_id,
status=approval.status.value,
execution_triggered=execution_triggered,
)
# 2026-04-09 Claude Sonnet 4.6: 回應 Telegram — 更新訊息狀態 + answer callback
await self._notify_approval_result(
message_id=message_id,
incident_id=approval_id,
action="approve",
username=username,
status=status_val,
execution_triggered=execution_triggered,
)
# 2026-04-22 Claude Sonnet 4.6: 只有真正轉為 APPROVED 才發「執行中...」
# 非 PENDING 狀態下 sign_approval early-return → approval 是舊 record
# 此時不應發「執行中...」,應告知用戶告警已處理過
if approval.status == ApprovalStatus.APPROVED:
# 2026-04-09 Claude Sonnet 4.6: 回應 Telegram — 更新訊息狀態 + answer callback
await self._notify_approval_result(
message_id=message_id,
incident_id=approval_id,
action="approve",
username=username,
execution_triggered=execution_triggered,
)
else:
# 告警已是 execution_failed / execution_success / rejected 等終態
try:
await self._send_request("sendMessage", {
"chat_id": settings.OPENCLAW_TG_CHAT_ID,
"text": f" 此告警已處理(狀態:{status_val}),無法重複批准 by @{username}",
"reply_to_message_id": message_id,
})
except Exception as _ne:
logger.warning("telegram_approval_already_resolved_notify_failed", error=str(_ne))
return
# ADR-073 修補 + 2026-04-14 Claude Sonnet 4.6 修復:
# 原本 gate 用 execution_triggeredrace condition 時失效(樂觀鎖失敗)
# 改用 approval.status == APPROVED與 REST API 路徑 approvals.py:360 對齊)
# 用 Redis lock exec:{approval_id} 防重入REST + Telegram 同時簽核)
from src.models.approval import ApprovalStatus
if approval.status == ApprovalStatus.APPROVED:
import asyncio