-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat: add deduplication for WeChat kefu text messages within 15 seconds #7788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||
| import asyncio | ||||||
| import os | ||||||
| import sys | ||||||
| import time | ||||||
| import uuid | ||||||
| from collections.abc import Awaitable, Callable | ||||||
| from typing import Any, cast | ||||||
|
|
@@ -140,6 +141,8 @@ async def shutdown_trigger(self) -> None: | |||||
|
|
||||||
| @register_platform_adapter("wecom", "wecom 适配器", support_streaming_message=False) | ||||||
| class WecomPlatformAdapter(Platform): | ||||||
| WECHAT_KF_TEXT_CONTENT_DEDUP_TTL_SECONDS = 15 | ||||||
|
|
||||||
| def __init__( | ||||||
| self, | ||||||
| platform_config: dict, | ||||||
|
|
@@ -166,6 +169,7 @@ def __init__( | |||||
|
|
||||||
| self.server = WecomServer(self._event_queue, self.config) | ||||||
| self.agent_id: str | None = None | ||||||
| self._wechat_kf_seen_text_messages: dict[str, float] = {} | ||||||
|
|
||||||
| self.client = WeChatClient( | ||||||
| self.config["corpid"].strip(), | ||||||
|
|
@@ -210,6 +214,28 @@ def get_latest_msg_item() -> dict | None: | |||||
|
|
||||||
| self.server.callback = callback | ||||||
|
|
||||||
| def _is_duplicate_wechat_kf_text_message(self, session_id: str, text: str) -> bool: | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| normalized_text = text.strip() | ||||||
| if not normalized_text: | ||||||
| return False | ||||||
|
|
||||||
| now = time.monotonic() | ||||||
| expired_keys = [ | ||||||
| key | ||||||
| for key, expires_at in self._wechat_kf_seen_text_messages.items() | ||||||
| if expires_at <= now | ||||||
| ] | ||||||
| for key in expired_keys: | ||||||
| self._wechat_kf_seen_text_messages.pop(key, None) | ||||||
|
Comment on lines
+223
to
+229
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current cleanup logic iterates through the entire |
||||||
|
|
||||||
| dedup_key = f"{session_id}:{normalized_text}" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using string concatenation with a colon as a key can lead to collisions if the
Suggested change
|
||||||
| if dedup_key in self._wechat_kf_seen_text_messages: | ||||||
| return True | ||||||
| self._wechat_kf_seen_text_messages[dedup_key] = ( | ||||||
| now + self.WECHAT_KF_TEXT_CONTENT_DEDUP_TTL_SECONDS | ||||||
| ) | ||||||
| return False | ||||||
|
|
||||||
| @override | ||||||
| async def send_by_session( | ||||||
| self, | ||||||
|
|
@@ -390,6 +416,13 @@ async def convert_wechat_kf_message(self, msg: dict) -> AstrBotMessage | None: | |||||
| abm.message_str = "" | ||||||
| if msgtype == "text": | ||||||
| text = msg.get("text", {}).get("content", "").strip() | ||||||
| if self._is_duplicate_wechat_kf_text_message(abm.session_id, text): | ||||||
| logger.debug( | ||||||
| "忽略 15 秒内重复微信客服文本消息 session_id=%s text=%s", | ||||||
|
Comment on lines
+420
to
+421
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Avoid hard-coding the TTL value in the log message. The TTL is defined as Please format the message using the constant (e.g., Suggested implementation: if self._is_duplicate_wechat_kf_text_message(abm.session_id, text):
logger.debug(
"忽略 %d 秒内重复微信客服文本消息 session_id=%s text=%s",
WECHAT_KF_TEXT_CONTENT_DEDUP_TTL_SECONDS,
abm.session_id,
text,
)If
|
||||||
| abm.session_id, | ||||||
| text, | ||||||
| ) | ||||||
| return None | ||||||
| abm.message = [Plain(text=text)] | ||||||
| abm.message_str = text | ||||||
| elif msgtype == "image": | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the type hint to reflect the use of a tuple key for deduplication, as suggested in the logic below.