微信 iLink Bot API 是微信 ClawBot 功能背后的 HTTP/JSON 协议。基座地址:https://ilinkai.weixin.qq.com。CDN:https://novac2c.cdn.weixin.qq.com/c2c。
概述
协议分三个阶段:登录(二维码扫码)、消息(长轮询 + 发送)、媒体(CDN 上传/下载 + AES 加密)。最关键的概念是 context_token —— 每个回复必须回传入站消息中的 token。
扫码登录流程
登录采用二维码扫码确认模式,类似微信网页版登录。
状态机: wait → scaned → confirmed(或 expired → 重新获取二维码)
bot_token 是 Bearer token,后续所有 API 调用都要携带。baseurl 可能与默认值不同 —— 始终使用返回值。
消息收发循环
消息通过长轮询(getupdates)接收,不是 WebSocket。服务器挂起连接约 35 秒。
关键规则:
- 首次请求:
get_updates_buf: ""(空字符串) - 每次响应返回新的
get_updates_buf—— 作为不透明游标 ret: 0= 成功;ret: -14= 会话过期- 消息包含
context_token—— 回复时必须原样回传
输入状态指示器
显示"对方正在输入中"需要两次 API 调用:先获取 typing_ticket,再发送。
提示: 按用户缓存 typing_ticket(有效期约 24 小时)。status: 1 = 开始,status: 2 = 停止。
媒体上传/下载
媒体文件(图片、视频、文件、语音)在上传到微信 CDN 之前使用 AES-128-ECB 加密。
会话过期与恢复
会话在一段时间后过期。服务器在任何 API 调用时返回 errcode: -14。
所有 SDK 自动处理此流程 —— 用户只需扫描新的二维码。
通用请求头
每个业务 POST 请求需要以下请求头:
Content-Type: application/json
AuthorizationType: ilink_bot_token
Authorization: Bearer <bot_token>
X-WECHAT-UIN: <base64(String(random_uint32))>
所有请求体包含:
{ "base_info": { "channel_version": "2.0.0" } }
X-WECHAT-UIN 每次请求重新生成:随机 4 字节 → uint32 → 十进制字符串 → base64。
接口列表
| 接口 | 方法 | 用途 |
|---|---|---|
| GET /get_bot_qrcode?bot_type=3 | GET | 获取登录二维码 |
| GET /get_qrcode_status?qrcode=... | GET | 轮询扫码状态 |
| POST /getupdates | POST | 长轮询消息(35秒挂起) |
| POST /sendmessage | POST | 发送文本或媒体消息 |
| POST /getconfig | POST | 获取用户的 typing_ticket |
| POST /sendtyping | POST | 显示/隐藏输入状态 |
| POST /getuploadurl | POST | 获取 CDN 上传参数 |
| POST CDN /upload | POST | 上传 AES 加密媒体 |
| GET CDN /download | GET | 下载 AES 加密媒体 |
context_token — 核心概念
context_token 是 iLink 协议最重要的概念。它不是可选的 —— 没有它,回复无法路由到正确的微信会话。
规则:
- 每条入站消息包含
context_token - 每条出站
sendmessage必须包含它 - 按
(userId)缓存 —— 每个用户保留最新的 token - 跨重启持久化(Node.js SDK 通过 storage 实现)
- 会话过期(
-14)或重新登录时清除
SDK 如何处理:
所有 SDK 通过 reply() 方法自动管理 —— 开发者无需关心。
AES-128-ECB 加密
微信 CDN 上所有媒体使用 AES-128-ECB + PKCS7 填充加密。
三种密钥编码格式(所有 SDK 均支持解码):
| 格式 | 示例 | 来源 |
|---|---|---|
| base64(原始 16 字节) | ABEiM0RVZneImaq7zN3u/w== | CDNMedia.aes_key (格式A) |
| base64(十六进制字符串) | MDAxMTIyMzM0NDU1NjY3Nzg4OTlhYWJiY2NkZGVlZmY= | CDNMedia.aes_key (格式B) |
| 直接十六进制 (32字符) | 00112233445566778899aabbccddeeff | image_item.aeskey |
加密后大小: ceil((rawSize + 1) / 16) * 16
错误码
| 错误码 | 含义 | SDK 处理 |
|---|---|---|
| ret: 0 | 成功 | — |
| errcode: -14 | 会话过期 | 清除状态 → 重新登录 |
| ret: -2 | 参数错误 | 检查请求体 |
| HTTP 4xx | 请求错误 / 认证失败 | 检查 token |
| HTTP 5xx | 服务端错误 | 指数退避重试 |
SDK 如何映射协议
| 协议操作 | Node.js / Python | Go / Rust |
|---|---|---|
| 二维码登录 | bot.login() | bot.Login() / bot.login() |
| 长轮询收消息 | bot.start() | bot.Run() / bot.run() |
| 发送回复 | bot.reply(msg, text) | bot.Reply() / bot.reply() |
| 输入状态 | bot.sendTyping() | bot.SendTyping() / send_typing() |
| errcode -14 | 自动(事件 + 重新登录) | 自动 |
| context_token | ContextStore(持久化) | Dict / sync.Map / HashMap |
所有 SDK 遵循 Telegraf(中间件)、Discord.js(EventEmitter)和 python-telegram-bot(装饰器处理器)的设计模式。