diff --git a/apps/api/src/services/security_interceptor.py b/apps/api/src/services/security_interceptor.py index 6946807d..2b7e1414 100644 --- a/apps/api/src/services/security_interceptor.py +++ b/apps/api/src/services/security_interceptor.py @@ -411,10 +411,17 @@ class TelegramSecurityInterceptor: nonce = f"{action}:{approval_id}:{timestamp}:{random_part}" + # Telegram callback_data limit is 64 bytes. + # Long action names (e.g. docker_restart=14 chars) with UUID approval_id push nonce to 71+ bytes. + # Drop the random suffix when over limit — timestamp still guarantees temporal uniqueness. + if len(nonce.encode()) > 63: + nonce = f"{action}:{approval_id}:{timestamp}" + logger.debug( "callback_nonce_generated", approval_id=approval_id, action=action, + nonce_len=len(nonce.encode()), ) return nonce @@ -447,7 +454,8 @@ class TelegramSecurityInterceptor: "is_info_action": True, } - if len(parts) != 4: + # 接受 3-part(長 action 名截斷 random)和 4-part(標準)兩種格式 + if len(parts) not in (3, 4): raise ValueError(f"Invalid callback_data format: {callback_data}") return { diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py index 0fb4db77..ad3910b6 100644 --- a/apps/api/src/services/telegram_gateway.py +++ b/apps/api/src/services/telegram_gateway.py @@ -1378,14 +1378,6 @@ class TelegramGateway: ) as span: try: response = await self._http_client.post(url, json=payload) - if response.status_code >= 400: - import json as _json - _payload_str = _json.dumps(payload, ensure_ascii=False) - logger.error("telegram_api_rejected", method=method, - status=response.status_code, - response_body=response.text[:300], - payload_len=len(_payload_str), - payload_preview=_payload_str[:1000]) response.raise_for_status() result = response.json()