From e34b0f2e9a7567fc05db28c12954c03b5bc16b1c Mon Sep 17 00:00:00 2001 From: OG T Date: Fri, 27 Mar 2026 09:27:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20Telegram=20=E5=8E=BB=E9=87=8D=20+?= =?UTF-8?q?=20=E4=BF=AE=E5=BE=A9=20INC-INC-INC-=20=E9=87=8D=E8=A4=87?= =?UTF-8?q?=E5=89=8D=E7=B6=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 加入 Redis 去重機制 (10 分鐘 TTL) - 修復 approval_id 重複添加 INC- 前綴 Co-Authored-By: Claude Opus 4.5 --- apps/api/src/services/decision_manager.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/api/src/services/decision_manager.py b/apps/api/src/services/decision_manager.py index b313ad3b8..2d54dcd9f 100644 --- a/apps/api/src/services/decision_manager.py +++ b/apps/api/src/services/decision_manager.py @@ -53,13 +53,26 @@ async def _push_decision_to_telegram( 決策就緒時推送到 Telegram Phase 6.5: 整合 Signal Worker 流程與 Telegram 通知 + 2026-03-27 ogt: 加入 Redis 去重機制 (10 分鐘 TTL) """ try: # 延遲導入避免循環依賴 + from src.core.redis_client import get_redis from src.services.telegram_gateway import ( get_telegram_gateway, ) + # 🔴 去重檢查:同一個 incident 10 分鐘內只發一次 + redis = get_redis() + dedup_key = f"telegram_sent:{incident.incident_id}" + if await redis.exists(dedup_key): + logger.debug( + "telegram_push_skipped", + reason="Already sent within 10 minutes", + incident_id=incident.incident_id, + ) + return + # 檢查是否有設定 Bot Token if not settings.OPENCLAW_TG_BOT_TOKEN: logger.debug( @@ -81,7 +94,8 @@ async def _push_decision_to_telegram( source = proposal_data.get("source", "unknown") # 建立 approval_id (使用 incident_id 作為追蹤) - approval_id = f"INC-{incident.incident_id}" + # 2026-03-27 ogt: 修復 INC-INC-INC- 重複前綴 bug + approval_id = incident.incident_id # 已經是 INC-xxx 格式 await gateway.send_approval_card( approval_id=approval_id, @@ -95,6 +109,9 @@ async def _push_decision_to_telegram( namespace=incident.signals[0].labels.get("namespace", "default") if incident.signals else "default", ) + # 🔴 發送成功後設置去重 key (TTL 10 分鐘) + await redis.setex(dedup_key, 600, "1") + logger.info( "telegram_decision_pushed", incident_id=incident.incident_id,