From 2e988bdb8124bede347cae8b25280cede679294a Mon Sep 17 00:00:00 2001 From: OG T Date: Sun, 19 Apr 2026 01:07:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(telegram):=20drift=20=E5=9F=B7=E8=A1=8C?= =?UTF-8?q?=E7=B5=90=E6=9E=9C=E8=B2=BC=E5=9B=9E=E5=8D=A1=E7=89=87=20+=20au?= =?UTF-8?q?dit=20log=20user=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IDE 抓到 _stamp 未使用(結果沒送)+ user_id 未使用(audit 缺漏)。 修: 1. _edit_drift_card_outcome 不只移除按鈕,還 send 簽核戳訊息 (reply_to 原卡片,若 msg_id 存在),格式: ✅ 已採納 by @username (成功) Drift 2. _handle_drift_action 加 drift_callback_dispatched log(audit) Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/api/src/services/telegram_gateway.py | 50 +++++++++++++++++------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py index 2bddd73a..26bed6fa 100644 --- a/apps/api/src/services/telegram_gateway.py +++ b/apps/api/src/services/telegram_gateway.py @@ -2005,6 +2005,11 @@ class TelegramGateway: approval_id 在 drift card 即 report_id (send_drift_card 設計)。 """ report_id = approval_id + logger.info( + "drift_callback_dispatched", + action=action, report_id=report_id, + user_id=user_id, username=username, + ) try: if action == "drift_view": await self._answer_callback(callback_query_id, action, text="🔍 撈全部 Diff...") @@ -2102,23 +2107,42 @@ class TelegramGateway: self, report_id: str, verb: str, by: str, ok: bool, ) -> None: """ - drift_adopt/drift_revert 執行後 edit 原卡片加簽核戳。 + drift_adopt/drift_revert 執行後: + 1. 原卡片移除按鈕(用 editMessageReplyMarkup) + 2. 在原卡片下 reply 執行結果訊息(包含 verb/by/成功失敗) """ + _icon = "✅" if ok else "❌" + _stamp = ( + f"{_icon} {html.escape(verb)} by @{html.escape(by)} " + f"({'成功' if ok else '失敗'})\n" + f"Drift {html.escape(report_id)}" + ) + _msg_id: int | None = None try: _msg_id_raw = await get_redis().get(f"tg_drift:{report_id}") - if not _msg_id_raw: - return - _msg_id = int(_msg_id_raw) - _icon = "✅" if ok else "❌" - _stamp = f"\n━━━━━━━━━━━━━━━━━━━\n{_icon} {verb} by @{html.escape(by)} ({'成功' if ok else '失敗'})" - # 先移除按鈕 - await self._send_request("editMessageReplyMarkup", { - "chat_id": settings.OPENCLAW_TG_CHAT_ID, - "message_id": _msg_id, - "reply_markup": {"inline_keyboard": []}, - }) + if _msg_id_raw: + _msg_id = int(_msg_id_raw) + # 先移除按鈕 + await self._send_request("editMessageReplyMarkup", { + "chat_id": settings.OPENCLAW_TG_CHAT_ID, + "message_id": _msg_id, + "reply_markup": {"inline_keyboard": []}, + }) except Exception as _e: - logger.warning("drift_card_outcome_edit_failed", report_id=report_id, error=str(_e)) + logger.warning("drift_card_buttons_remove_failed", report_id=report_id, error=str(_e)) + + # 送簽核戳訊息(reply_to 原卡片,若有 msg_id) + try: + _payload: dict = { + "chat_id": settings.OPENCLAW_TG_CHAT_ID, + "text": _stamp, + "parse_mode": "HTML", + } + if _msg_id: + _payload["reply_to_message_id"] = _msg_id + await self._send_request("sendMessage", _payload) + except Exception as _e: + logger.warning("drift_outcome_stamp_send_failed", report_id=report_id, error=str(_e)) # ========================================================================= # ADR-075: TYPE-8M Meta-System 告警(飛輪/告警鏈路健康)