跳到主要内容

微信(Weixin)设置

将 Hermes 连接到 微信(微信),腾讯的个人消息平台。适配器使用腾讯的 iLink Bot API 用于个人微信账户 — 这与企业微信(WeCom)不同。消息通过长轮询投递,因此无需公共端点或 webhook。

信息

此适配器用于个人微信账户。如果你需要企业/公司微信,请参阅 WeCom 适配器

前置要求

  • 个人微信账户
  • Python 包:aiohttpcryptography
  • qrcode 包是可选的(用于设置期间终端二维码渲染)

安装所需依赖:

pip install aiohttp cryptography
# 可选:用于终端二维码显示
pip install qrcode

设置

1. 运行设置向导

连接微信账户最简单的方式是通过交互式设置:

hermes gateway setup

出现提示时选择 Weixin。向导将:

  1. 从 iLink Bot API 请求二维码
  2. 在你的终端显示二维码(或提供 URL)
  3. 等待你用微信手机应用扫描二维码
  4. 提示你在手机上确认登录
  5. 自动将账户凭证保存到 ~/.hermes/weixin/accounts/

确认后,你会看到类似消息:

微信连接成功,account_id=your-account-id

向导存储 account_idtokenbase_url,因此你无需手动配置。

2. 配置环境变量

初始 QR 登录后,至少在 ~/.hermes/.env 中设置账户 ID:

WEIXIN_ACCOUNT_ID=your-account-id

# 可选:覆盖 token(通常从 QR 登录自动保存)
# WEIXIN_TOKEN=your-bot-token

# 可选:限制访问
WEIXIN_DM_POLICY=open
WEIXIN_ALLOWED_USERS=user_id_1,user_id_2

# 可选:用于 cron/通知的主频道
WEIXIN_HOME_CHANNEL=chat_id
WEIXIN_HOME_CHANNEL_NAME=Home

3. 启动网关

hermes gateway

适配器将恢复保存的凭证,连接到 iLink API,并开始长轮询消息。

功能

  • 长轮询传输 — 无需公共端点、webhook 或 WebSocket
  • 二维码登录 — 通过 hermes gateway setup 扫码连接设置
  • DM 和群组消息 — 可配置的访问策略
  • 媒体支持 — 图片、视频、文件和语音消息
  • AES-128-ECB 加密 CDN — 所有媒体传输自动加密/解密
  • 上下文 token 持久化 — 跨重启的磁盘备份回复连续性
  • Markdown 格式化 — 标题、表格和代码块为微信可读性重新格式化
  • 智能消息分块 — 消息在限制内保持为单个气泡;仅超大型载荷在逻辑边界拆分
  • 打字指示器 — 当 agent 处理时在微信客户端显示"typing…"状态
  • SSRF 保护 — 出站媒体 URL 在下载前被验证
  • 消息去重 — 5 分钟滑动窗口防止重复处理
  • 带退避的自动重试 — 从瞬态 API 错误恢复

访问策略

DM 策略

控制谁可以向机器人发送直接消息:

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

群组策略

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

行为
open机器人在所有群组中响应
allowlist机器人仅在 group_allow_from 中列出的群组 ID 中响应
disabled所有群组消息都被忽略(默认)
备注

微信的默认群组策略是 disabled(与企业微信不同,后者默认为 open)。这是故意的,因为个人微信账户可能在很多群组中。

媒体支持

入站(接收)

适配器接收用户的媒体附件,从微信 CDN 下载,解密并本地缓存以供 agent 处理:

类型处理方式
图片下载、AES 解密并缓存为 JPEG
视频下载、AES 解密并缓存为 MP4
文件下载、AES 解密并缓存。保留原始文件名。
语音如果有文本转录可用,作为文本提取。否则下载并缓存音频( SILK 格式)。

引用消息: 引用(回复)消息中的媒体也会被提取,因此 agent 拥有用户回复内容的上下文。

AES-128-ECB 加密 CDN

微信媒体文件通过加密 CDN 传输。适配器透明处理:

  • 入站: 使用 encrypted_query_param URL 从 CDN 下载加密媒体,然后使用消息负载中提供的每文件密钥通过 AES-128-ECB 解密
  • 出站: 文件使用随机 AES-128 密钥在本地加密,上传到 CDN,加密引用包含在出站消息中
  • AES 密钥是 16 字节(128 位)。密钥可能以原始 base64 或十六进制编码到达 — 适配器处理两种格式
  • 这需要 cryptography Python 包

无需配置 — 加密和解密自动进行。

出站(发送)

方法发送内容
send带 Markdown 格式化的文本消息
send_image / send_image_file原生图片消息(通过 CDN 上传)
send_document文件附件(通过 CDN 上传)
send_video视频消息(通过 CDN 上传)

所有出站媒体通过加密 CDN 上传流程:

  1. 生成随机 AES-128 密钥
  2. 使用 AES-128-ECB + PKCS#7 填充加密文件
  3. 从 iLink API(getuploadurl)请求上传 URL
  4. 将密文上传到 CDN
  5. 发送包含加密媒体引用的消息

上下文 Token 持久化

iLink Bot API 需要 context_token 与每个出站消息一起回显给给定对等方。适配器维护磁盘备份的上下文 token 存储:

  • Token 按账户+对等方保存到 ~/.hermes/weixin/accounts/<account_id>.context-tokens.json
  • 启动时恢复之前保存的 token
  • 每个入站消息更新该发送者的存储 token
  • 出站消息自动包含最新的上下文 token

这确保了即使网关重启后回复连续性。

Markdown 格式化

微信个人聊天不原生渲染完整 Markdown。适配器重新格式化内容以提高可读性:

  • 标题# Title)→ 转换为 【Title】(1 级)或 **Title**(2 级+)
  • 表格 → 重新格式化为带标签的键值列表(例如 - Column: Value
  • 代码块 → 按原样保留(微信渲染效果还不错)
  • 过多空行 → 折叠为双换行符

消息分块

消息作为单个聊天消息投递,只要它们在平台限制内。只有超大型载荷被拆分投递:

  • 最大消息长度:4000 字符
  • 低于限制的消息即使包含多个段落或换行也保持完整
  • 超大消息在逻辑边界(段落、空行、代码块)拆分
  • 代码块尽可能保持完整(除非代码块本身超过限制)
  • 超大单个块回退到基础适配器的截断逻辑
  • 发送多个块时 0.3 秒的块间延迟防止微信限速

打字指示器

适配器在微信客户端显示打字状态:

  1. 当消息到达时,适配器通过 getconfig API 获取 typing_ticket
  2. Typing ticket 按用户缓存 10 分钟
  3. send_typing 发送打字开始信号;stop_typing 发送打字停止信号
  4. 网关在 agent 处理消息时自动触发打字指示器

长轮询连接

适配器使用 HTTP 长轮询(而非 WebSocket)接收消息:

重试行为

API 错误时,适配器使用简单重试策略:

条件行为
瞬态错误(第 1-2 次)2 秒后重试
重复错误(3+)退避 30 秒,然后重置计数器
会话过期(errcode=-14暂停 10 分钟(可能需要重新登录)
超时立即重新轮询(正常长轮询行为)

所有环境变量

变量必填默认值描述
WEIXIN_ACCOUNT_IDiLink Bot 账户 ID(来自 QR 登录)
WEIXIN_TOKENiLink Bot token(从 QR 登录自动保存)
WEIXIN_BASE_URLhttps://ilinkai.weixin.qq.comiLink API base URL
WEIXIN_CDN_BASE_URLhttps://novac2c.cdn.weixin.qq.com/c2c媒体传输的 CDN base URL
WEIXIN_DM_POLICYopenDM 访问策略:openallowlistdisabledpairing
WEIXIN_GROUP_POLICYdisabled群组访问策略:openallowlistdisabled
WEIXIN_ALLOWED_USERS(空)DM 白名单的逗号分隔用户 ID
WEIXIN_HOME_CHANNEL用于 cron/通知输出的聊天 ID
WEIXIN_HOME_CHANNEL_NAMEHome主频道显示名称

故障排除

问题修复
Weixin 启动失败:需要 aiohttp 和 cryptography安装两者:pip install aiohttp cryptography
Weixin 启动失败:需要 WEIXIN_TOKEN运行 hermes gateway setup 完成 QR 登录,或手动设置 WEIXIN_TOKEN
Weixin 启动失败:需要 WEIXIN_ACCOUNT_ID在你的 .env 中设置 WEIXIN_ACCOUNT_ID 或运行 hermes gateway setup
另一个本地 Hermes 网关正在使用此 Weixin token先停止另一个网关实例 — 每个 token 只允许一个 poller
会话过期(errcode=-14你的登录会话已过期。重新运行 hermes gateway setup 扫描新二维码
设置期间二维码过期二维码自动刷新最多 3 次。如果持续过期,检查你的网络连接
机器人在 DM 中不响应检查 WEIXIN_DM_POLICY — 如果设置为 allowlist,发送者必须在 WEIXIN_ALLOWED_USERS
机器人忽略群组消息群组策略默认为 disabled。设置 WEIXIN_GROUP_POLICY=openallowlist
媒体下载/上传失败确保 cryptography 已安装。检查到 novac2c.cdn.weixin.qq.com 的网络访问
阻止不安全 URL(SSRF 保护)出站媒体 URL 指向私有/内部地址。只允许公共 URL
语音消息显示为文本如果微信提供转录,适配器使用该文本。这是预期行为
消息重复出现适配器按消息 ID 去重。如果你看到重复,检查是否运行了多个网关实例
iLink POST ... HTTP 4xx/5xxiLink 服务的 API 错误。检查你的 token 有效性和网络连接
终端二维码不渲染安装 qrcodepip install qrcode。或者,打开二维码上打印的 URL