From 0545653494ae101ff6402960491d70ebe2b565ec Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 16 May 2025 16:54:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=BD=AE=E8=AF=A2?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/config/default.py | 12 ++++++++ .../wechatpadpro/wechatpadpro_adapter.py | 28 +++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/astrbot/core/config/default.py b/astrbot/core/config/default.py index 9a8ba66eb..f74532aa7 100644 --- a/astrbot/core/config/default.py +++ b/astrbot/core/config/default.py @@ -162,6 +162,8 @@ CONFIG_METADATA_2 = { "admin_key": "stay33", "host": "这里填写你的局域网IP或者公网服务器IP", "port": 8059, + "wpp_active_message_poll": False, + "wpp_active_message_poll_interval": 3, }, "weixin_official_account(微信公众平台)": { "id": "weixin_official_account", @@ -218,6 +220,16 @@ CONFIG_METADATA_2 = { }, }, "items": { + "wpp_active_message_poll": { + "description": "是否启用主动消息轮询", + "type": "bool", + "hint": "只有当你发现微信消息没有按时同步到 AstrBot 时,才需要启用这个功能,默认不启用。" + }, + "wpp_active_message_poll_interval": { + "description": "主动消息轮询间隔", + "type": "int", + "hint": "主动消息轮询间隔,单位为秒,默认 3 秒,最大不要超过 60 秒,否则可能被认为是旧消息。" + }, "kf_name": { "description": "微信客服账号名", "type": "string", diff --git a/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py b/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py index b5094a025..1b9dde9c1 100644 --- a/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py +++ b/astrbot/core/platform/sources/wechatpadpro/wechatpadpro_adapter.py @@ -45,6 +45,10 @@ class WeChatPadProAdapter(Platform): self.admin_key = self.config.get("admin_key") self.host = self.config.get("host") self.port = self.config.get("port") + self.active_mesasge_poll = self.config.get("wpp_active_message_poll", False) + self.active_message_poll_interval = self.config.get( + "wpp_active_message_poll_interval", 5 + ) self.base_url = f"http://{self.host}:{self.port}" self.auth_key = None # 用于保存生成的授权码 self.wxid = None # 用于保存登录成功后的 wxid @@ -67,7 +71,9 @@ class WeChatPadProAdapter(Platform): if self.auth_key and await self.check_online_status(): logger.info("WeChatPadPro 设备已在线,跳过扫码登录。") # 如果在线,连接 WebSocket 接收消息 - asyncio.create_task(self.connect_websocket()) + self.ws_handle_task = asyncio.create_task(self.connect_websocket()) + if self.active_mesasge_poll: + asyncio.create_task(self._active_message_poll()) else: logger.info("WeChatPadPro 设备不在线或无可用凭据,开始扫码登录流程。") # 1. 生成授权码 @@ -91,7 +97,9 @@ class WeChatPadProAdapter(Platform): if login_successful: # 登录成功后,连接 WebSocket 接收消息 - asyncio.create_task(self.connect_websocket()) + self.ws_handle_task = asyncio.create_task(self.connect_websocket()) + if self.active_mesasge_poll: + asyncio.create_task(self._active_message_poll()) else: logger.warning("登录失败或超时,WeChatPadPro 适配器将关闭。") await self.terminate() @@ -307,6 +315,20 @@ class WeChatPadProAdapter(Platform): logger.warning("登录检测超过最大尝试次数,退出检测。") return False + async def _active_message_poll(self): + """ + 部分 case 下,必须要重建 WebSocket 连接才能同步消息。 + """ + while True: + await asyncio.sleep(self.active_message_poll_interval) + logger.debug("主动拉取消息中...") + try: + if self.ws_handle_task.cancel(): + await asyncio.sleep(0.5) + self.ws_handle_task = asyncio.create_task(self.connect_websocket()) + except Exception as e: + logger.error(f"主动拉取消息时发生错误: {e}") + async def connect_websocket(self): """ 建立 WebSocket 连接并处理接收到的消息。 @@ -583,4 +605,4 @@ class WeChatPadProAdapter(Platform): adapter=self, ) # 调用实例方法 send - await sending_event.send(message_chain) \ No newline at end of file + await sending_event.send(message_chain)