""" 企业微信桥接模块 使用 wecom-aibot-python-sdk 与企业微信建立 WebSocket 长连接, 接收用户消息后通过 ADK API 调用远程 Agent,再将 Agent 回复发送给用户。 本模块仅负责: - 创建 WSClient 实例 - 注册事件和消息处理器 """ import json import logging import traceback from aibot import WSClient, WSClientOptions from config import Config from bot.agent_client import close_http_client from bot.handlers import handle_message from bot.message_parser import extract_metadata logger = logging.getLogger(__name__) def create_bot_client() -> WSClient: """ 创建企业微信机器人 WebSocket 客户端,并注册所有事件和消息处理器。 """ ws_client = WSClient( WSClientOptions( bot_id=Config.WECHAT_BOT_ID, secret=Config.WECHAT_BOT_SECRET, ) ) # ---- 事件处理器 ---- @ws_client.on("authenticated") def on_authenticated(): logger.info("企业微信机器人认证成功") @ws_client.on("event.enter_chat") async def on_enter_chat(frame): """用户进入会话,发送欢迎语""" meta = extract_metadata(frame) user_id = meta.get("user_id", "") logger.info("用户进入会话: %s", user_id) try: await ws_client.reply_welcome( frame, { "msgtype": "text", "text": { "content": "您好!我是智能助手,有什么可以帮您的吗?" }, }, ) except Exception as e: logger.error("发送欢迎语失败: %s", e) @ws_client.on("event.feedback_event") async def on_feedback(frame): """用户反馈事件""" body = frame.get("body", {}) logger.info("收到用户反馈: %s", json.dumps(body, ensure_ascii=False)) @ws_client.on("disconnected") def on_disconnected(reason): logger.warning("连接被断开(可能被新连接踢掉): %s", reason) # ---- 消息处理器 ---- @ws_client.on("message.text") async def on_text(frame): await _safe_handle(ws_client, frame, "text") @ws_client.on("message.image") async def on_image(frame): await _safe_handle(ws_client, frame, "image") @ws_client.on("message.voice") async def on_voice(frame): await _safe_handle(ws_client, frame, "voice") @ws_client.on("message.file") async def on_file(frame): # file 类型可能包含视频 body = frame.get("body", {}) msg_type = "video" if body.get("video") else "file" await _safe_handle(ws_client, frame, msg_type) @ws_client.on("message.mixed") async def on_mixed(frame): await _safe_handle(ws_client, frame, "mixed") return ws_client async def _safe_handle(ws_client, frame: dict, msg_type: str): """安全地处理消息,捕获异常防止崩溃""" try: await handle_message(ws_client, frame, msg_type) except Exception as e: logger.error("处理%s消息异常: %s\n%s", msg_type, e, traceback.format_exc())