跳到主要内容

WeCom(企业微信)

将 Hermes 连接到 WeCom(企业微信),腾讯的企业消息平台。该适配器使用 WeCom 的 AI Bot WebSocket 网关实现实时双向通信——无需公网端点或 webhook。

前提条件

  • 一个 WeCom 企业账号
  • 在 WeCom 管理后台创建的一个 AI Bot
  • 从 Bot 凭证页面获取的 Bot ID 和 Secret
  • Python 包:aiohttphttpx

设置

步骤 1:创建 AI Bot

hermes gateway setup

选择 WeCom 并使用 WeCom 手机端扫描二维码。Hermes 将自动创建一个具有正确权限的 Bot 应用程序并保存凭证。

设置向导将:

  1. 在终端显示二维码
  2. 等待您用 WeCom 手机端扫描
  3. 自动获取 Bot ID 和 Secret
  4. 引导您完成访问控制配置

备选:手动设置

如果扫码创建不可用,向导将回退到手动输入:

  1. 登录 WeCom 管理后台
  2. 导航到 应用管理创建应用AI Bot
  3. 配置 Bot 名称和描述
  4. 从凭证页面复制 Bot IDSecret
  5. 运行 hermes gateway setup,选择 WeCom,并根据提示输入凭证
注意

请妥善保管 Bot Secret。任何拥有它的人都可以冒充您的 Bot。

步骤 2:配置 Hermes

hermes gateway setup

选择 WeCom 并按照提示操作。向导将引导您完成:

  • Bot 凭证(通过二维码扫描或手动输入)
  • 访问控制设置(白名单、配对模式或开放访问)
  • 用于通知的主频道

选项 B:手动配置

将以下内容添加到 ~/.hermes/.env

WECOM_BOT_ID=your-bot-id
WECOM_SECRET=your-secret

# 可选:限制访问
WECOM_ALLOWED_USERS=user_id_1,user_id_2

# 可选:用于定时任务/通知的主频道
WECOM_HOME_CHANNEL=chat_id

步骤 3:启动网关

hermes gateway

功能特性

  • WebSocket 传输 — 持久连接,无需公网端点
  • 私聊与群聊消息 — 可配置的访问策略
  • 按群组设置发送者白名单 — 精细控制每个群组中谁可以与 Bot 交互
  • 媒体支持 — 图片、文件、语音、视频的上传与下载
  • AES 加密媒体 — 自动解密接收的附件
  • 引用上下文 — 保留回复线程
  • Markdown 渲染 — 富文本响应
  • 回复模式流式输出 — 将响应与输入消息上下文关联
  • 自动重连 — 连接断开时指数退避重试

配置选项

config.yamlplatforms.wecom.extra 下设置以下项:

默认值描述
bot_idWeCom AI Bot ID(必填)
secretWeCom AI Bot Secret(必填)
websocket_urlwss://openws.work.weixin.qq.comWebSocket 网关地址
dm_policyopen私聊访问策略:open(开放)、allowlist(白名单)、disabled(禁用)、pairing(配对)
group_policyopen群聊访问策略:open(开放)、allowlist(白名单)、disabled(禁用)
allow_from[]允许私聊的用户 ID(当 dm_policy=allowlist 时)
group_allow_from[]允许群聊的群组 ID(当 group_policy=allowlist 时)
groups{}按群组配置(见下文)

访问策略

私信策略

控制谁可以向机器人发送私信:

行为
open任何人都可以给机器人发私信(默认)
allowlist只有 allow_from 中的用户 ID 可以发私信
disabled忽略所有私信
pairing配对模式(用于初始设置)
WECOM_DM_POLICY=allowlist

群聊策略

控制机器人在哪些群聊中响应:

行为
open机器人在所有群聊中响应(默认)
allowlist机器人仅在 group_allow_from 中列出的群 ID 中响应
disabled忽略所有群消息
WECOM_GROUP_POLICY=allowlist

按群聊的发件人白名单

为了实现精细控制,你可以限制特定群聊中哪些用户可以与机器人交互。这在 config.yaml 中配置:

platforms:
wecom:
enabled: true
extra:
bot_id: "your-bot-id"
secret: "your-secret"
group_policy: "allowlist"
group_allow_from:
- "group_id_1"
- "group_id_2"
groups:
group_id_1:
allow_from:
- "user_alice"
- "user_bob"
group_id_2:
allow_from:
- "user_charlie"
"*":
allow_from:
- "user_admin"

工作原理:

  1. group_policygroup_allow_from 控制决定群聊是否被允许。
  2. 如果群聊通过了顶层检查,groups.<group_id>.allow_from 列表(如果存在)会进一步限制该群聊内哪些发件人可以与机器人交互。
  3. 通配符 "*" 群聊条目作为未明确列出的群聊的默认设置。
  4. 白名单条目支持 * 通配符以允许所有用户,且条目不区分大小写。
  5. 条目可以选择使用 wecom:user:wecom:group: 前缀格式——前缀会被自动去除。

如果某个群聊没有配置 allow_from,则该群聊中的所有用户都被允许(假设该群聊本身通过了顶层策略检查)。

媒体支持

接收(入站)

适配器接收来自用户的媒体附件,并将其缓存到本地以供 Agent 处理:

类型处理方式
图片下载并缓存到本地。支持基于 URL 和 base64 编码的图片。
文件下载并缓存。文件名保留原始消息中的名称。
语音如果可用,提取语音消息的文本转录。
混合消息解析企业微信混合类型消息(文本+图片),提取所有组件。

引用消息: 也会提取被引用(回复)消息中的媒体,以便 Agent 了解用户回复的上下文。

AES 加密媒体解密

企业微信使用 AES-256-CBC 加密某些入站媒体附件。适配器会自动处理:

  • 当入站媒体项包含 aeskey 字段时,适配器会下载加密的字节,并使用 AES-256-CBC 和 PKCS#7 填充进行解密。
  • AES 密钥是 aeskey 字段的 base64 解码值(必须恰好为 32 字节)。
  • IV 由密钥的前 16 个字节派生。
  • 这需要 cryptography Python 包(pip install cryptography)。 无需配置——当收到加密媒体时,解密会自动透明进行。

出站(发送)

方法发送内容大小限制
sendMarkdown 文本消息4000 字符
send_image / send_image_file原生图片消息10 MB
send_document文件附件20 MB
send_voice语音消息(原生语音仅支持 AMR 格式)2 MB
send_video视频消息10 MB

分块上传: 文件通过三步协议(初始化 → 分块 → 完成)以 512 KB 分块上传。适配器会自动处理。

自动降级: 当媒体超过原生类型的尺寸限制但未超过绝对 20 MB 文件限制时,会自动作为通用文件附件发送:

  • 图片 > 10 MB → 作为文件发送
  • 视频 > 10 MB → 作为文件发送
  • 语音 > 2 MB → 作为文件发送
  • 非 AMR 音频 → 作为文件发送(企业微信原生语音仅支持 AMR)

超过绝对 20 MB 限制的文件会被拒绝,并向聊天发送一条提示消息。

回复模式流式响应

当机器人通过企业微信回调收到消息时,适配器会记住入站请求 ID。如果在请求上下文仍处于活动状态时发送响应,适配器会使用企业微信的回复模式(aibot_respond_msg)并配合流式传输,将响应直接关联到入站消息。这能在企业微信客户端中提供更自然的对话体验。

如果入站请求上下文已过期或不可用,适配器会回退到通过 aibot_send_msg 主动发送消息。

回复模式也适用于媒体:上传的媒体可以作为对原始消息的回复发送。

连接与重连

适配器会维持一个到企业微信网关 wss://openws.work.weixin.qq.com 的持久 WebSocket 连接。

连接生命周期

  1. 连接: 打开 WebSocket 连接,并发送一个包含 bot_idsecretaibot_subscribe 认证帧。
  2. 心跳: 每 30 秒发送应用层 ping 帧以保持连接活跃。
  3. 监听: 持续读取入站帧并分发消息回调。

重连行为

连接断开时,适配器使用指数退避进行重连:

尝试次数延迟
第 1 次重试2 秒
第 2 次重试5 秒
第 3 次重试10 秒
第 4 次重试30 秒
第 5 次及以上重试60 秒

每次成功重连后,退避计数器会重置为零。断开连接时,所有待处理的请求 future 都会失败,以免调用方无限挂起。

去重

入站消息使用消息 ID 进行去重,窗口为 5 分钟,最大缓存 1000 条。这可以防止在重连或网络抖动期间重复处理消息。

所有环境变量

变量必填默认值描述
WECOM_BOT_ID企业微信 AI Bot ID
WECOM_SECRET企业微信 AI Bot Secret
WECOM_ALLOWED_USERS(空)网关级别白名单的用户 ID,逗号分隔
WECOM_HOME_CHANNEL用于定时任务/通知输出的聊天 ID
WECOM_WEBSOCKET_URLwss://openws.work.weixin.qq.comWebSocket 网关 URL
WECOM_DM_POLICYopen私聊访问策略
WECOM_GROUP_POLICYopen群聊访问策略

故障排除

问题解决方法
WECOM_BOT_ID and WECOM_SECRET are required设置这两个环境变量,或在设置向导中配置
WeCom startup failed: aiohttp not installed安装 aiohttp:pip install aiohttp
WeCom startup failed: httpx not installed安装 httpx:pip install httpx
invalid secret (errcode=40013)确认 secret 与你的机器人凭据匹配
Timed out waiting for subscribe acknowledgement检查到 openws.work.weixin.qq.com 的网络连接
机器人在群聊中无响应检查 group_policy 设置,确保群 ID 在 group_allow_from
机器人忽略群聊中的某些用户检查 groups 配置部分中每个群的 allow_from 列表
媒体解密失败安装 cryptographypip install cryptography
cryptography is required for WeCom media decryption入站媒体是 AES 加密的。安装:pip install cryptography
语音消息以文件形式发送企业微信仅支持 AMR 格式的原生语音。其他格式会自动降级为文件。
File too large 错误企业微信对所有文件上传有 20 MB 的绝对限制。请压缩或拆分文件。
图片以文件形式发送图片 > 10 MB 超出原生图片限制,会自动降级为文件附件。
Timeout sending message to WeComWebSocket 可能已断开。检查日志中的重连消息。
WeCom websocket closed during authentication网络问题或凭据错误。请验证 bot_id 和 secret。