Files
Wechat-Bot/wechat-bot/bot/wecom_bot.py
2026-04-08 11:00:31 +08:00

105 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
企业微信桥接模块
使用 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())