fix(telegram): 按鈕回覆靜默兩大根因修復
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 17m40s
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:
@@ -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: 發群組 reply(toast 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_triggered,race 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user