随着 iLink Bot API 的正式开放,以及配套 npm 包 @tencent-weixin/openclaw-weixin 的发布,开发者首次拥有了官方认可的微信自动化开发通道。
本文不谈宏观生态,只聚焦微观实战:拆解协议细节、梳理调用逻辑、预警潜在陷阱。
内容硬核,建议加入收藏夹随时查阅。
一、架构全景:三层模型解析
先睹为快,整体架构一目了然:

核心逻辑可概括为:上层处理业务逻辑,中层管理媒体文件,底层维持通信通道。
两个关键域名务必牢记:
| 域名 | 用途 |
|---|---|
https://ilinkai.weixin.qq.com |
所有 API 请求的统一入口 |
https://novac2c.cdn.weixin.qq.com/c2c |
图片、语音、视频等媒体文件的传输通道 |
二、身份鉴权:如何证明“我是我”?
每次发起 API 调用,都必须向微信服务器证明身份的合法性。鉴权信息需嵌入 HTTP 请求头中。
2.1 标准请求头格式
Content-Type: application/json
AuthorizationType: ilink_bot_token
X-WECHAT-UIN:
Authorization: Bearer
2.2 X-WECHAT-UIN:防重放攻击的精妙设计
function randomWechatUin() {
// 生成随机 uint32
const uint32 = crypto.randomBytes(4).readUInt32BE(0);
// 转为十进制字符串并进行 Base64 编码
return Buffer.from(String(uint32), "utf-8").toString("base64");
}
关键点:该字段需在每次请求时动态生成。这是一种经典的防重放攻击机制——即便请求被截获,也无法原样 replay。
2.3 bot_token 获取方式
通过扫码登录流程获取,具体步骤将在下一节详述。
三、API 端点速查表
开发过程中高频使用的接口汇总,建议截图留存:
| 端点 | 方法 | 功能描述 | 关键参数 | | | ---- | | - | | /ilink/bot/get_bot_qrcode | GET | 获取登录二维码 | ?bot_type=3 | | /ilink/bot/get_qrcode_status | GET | 轮询扫码状态 | ?qrcode=xxx | | /ilink/bot/getupdates | POST | 长轮询接收消息 | { get_updates_buf } | | /ilink/bot/sendmessage | POST | 发送消息 | { msg } | | /ilink/bot/getuploadurl | POST | 获取 CDN 上传地址 | { filekey, md5, len } | | /ilink/bot/getconfig | POST | 获取配置信息 | { base_info } | | /ilink/bot/sendtyping | POST | 发送“正在输入”状态 | { to_user_id, typing_ticket } |
共计 7 个核心端点,结构清晰,易于掌握。
四、核心业务流程详解
4.1 二维码登录:从扫描到获取 Token
这是所有操作的起点。流程虽不复杂,但需注意几个关键细节:

注意事项:
-
bot_type=3为固定值,对应特定账号类型,不可随意更改。 -
二维码过期后会自动刷新,最多支持 3 次。
-
整个登录过程超时时间为 480 秒(8 分钟),时间充裕。
4.2 长轮询收消息:系统的核心引擎
登录成功后,核心任务便是接收消息。iLink 采用经典的长轮询(Long Polling)机制。
let getUpdatesBuf = "";
async function pollMessages() {
const resp = await fetch(`${BASE}/ilink/bot/getupdates`, {
method: "POST",
headers: buildHeaders(),
body: JSON.stringify({
get_updates_buf: getUpdatesBuf,
base_info: { channel_version: "1.0.3" }
})
});
const { msgs, get_updates_buf: newBuf } = await resp.json();
getUpdatesBuf = newBuf ?? getUpdatesBuf; // ⚠️ 必须更新!
return msgs ?? [];
}
⚠️ 高危预警:
get_updates_buf相当于消息游标。每次请求后必须用返回的新值覆盖旧值,否则将陷入重复接收消息的死循环。
其他要点:
-
默认超时时间为 35 秒,无消息时返回空数组。
-
连续失败 3 次后,系统会自动退避 30 秒再重试,防止对服务器造成压力。
4.3 发送消息:关键字段不可遗漏
async function sendMessage(toUserId, text, contextToken) {
await fetch(`${BASE}/ilink/bot/sendmessage`, {
method: "POST",
headers: buildHeaders(),
body: JSON.stringify({
msg: {
to_user_id: toUserId,
message_type: 2, // 1=用户消息,2=BOT 消息
message_state: 2, // 2=FINISH(发送完毕)
context_token: contextToken, // ⚠️ 必须携带!
item_list: [
{ type: 1, text_item: { text } }
]
}
})
});
}
重点强调:
context_token是消息的唯一标识符。回复消息时必须原样携带该字段,否则微信无法识别对话上下文,导致逻辑混乱。建议将该 token 进行内存缓存并持久化存储,确保服务重启后仍能延续对话。
五、消息类型全览
5.1 五大消息类型
| 类型 ID | 消息类型 | 数据结构 | 简述 |
|---|---|---|---|
| 1 | 文本 | TextItem { text } |
基础类型,最常用 |
| 2 | 图片 | ImageItem { media, thumb_media, aeskey, ... } |
含缩略图,CDN 加密 |
| 3 | 语音 | VoiceItem { media, encode_type, playtime, text } |
自带 ASR 转写文本 |
| 4 | 文件 | FileItem { media, file_name, md5, len } |
支持任意文件格式 |
| 5 | 视频 | VideoItem { media, thumb_media, video_size, ... } |
含封面图 |
5.2 语音编码格式对照
| encode_type | 格式 | 说明 |
|---|---|---|
| 1 | PCM | 原始音频数据 |
| 5 | AMR | 移动端常用格式 |
| 6 | SILK | 微信默认格式 |
| 7 | MP3 | 通用格式 |
💡 惊喜发现:语音消息自带 text 字段,微信已内置 ASR 能力,直接可用,无需额外接入第三方模型。
5.3 消息 ID 命名规范
-
普通用户:
xxx@im.wechat -
Bot 账号:
xxx@im.bot
通过后缀即可快速区分消息来源。
六、CDN 媒体加密机制:微信的安全锁
图片、语音等文件传输并非明文,而是经过加密处理。
6.1 加密算法:AES-128-ECB + PKCS7 填充
const { createCipheriv, createDecipheriv } = require("crypto");
function encryptAesEcb(plaintext, key) {
const cipher = createCipheriv("aes-128-ecb", key, null);
return Buffer.concat([cipher.update(plaintext), cipher.final()]);
}
function decryptAesEcb(ciphertext, key) {
const decipher = createDecipheriv("aes-128-ecb", key, null);
return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
}
虽然 ECB 模式在密码学中常被认为存在安全隐患,但在本场景中,每个文件均使用一次性随机密钥,且传输基于 HTTPS,实际风险可控。
6.2 文件上传六步法
-
📂 读取文件并计算 MD5
-
🔑 生成随机 16 字节 AES-128 密钥
-
📡 调用
POST /ilink/bot/getuploadurl获取upload_param -
🔒 使用 AES-128-ECB 加密文件内容
-
⬆️ 上传至 CDN:
POST https://novac2c.cdn.weixin.qq.com/c2c/upload -
💬 发送消息时携带
download_param和aes_key
6.3 文件下载两步走
-
GET 请求下载链接,携带加密参数
-
使用消息中的
aes_key解密返回内容
流程简洁高效。
七、多账号管理与状态持久化
实际应用中,往往需要管理多个微信号。iLink 提供了清晰的多账号支持方案。
7.1 账号数据结构
type WeixinAccountData = {
token?: string; // Bearer token
baseUrl?: string; // API 基础 URL
userId?: string; // 微信用户 ID
savedAt?: string; // 保存时间戳
};
7.2 本地存储目录结构
~/.openclaw/
├── openclaw-weixin/
│ ├── accounts.json # 账号索引
│ └── accounts/
│ ├── {accountId}.json # 账号凭证
│ ├── {accountId}.sync.json # 同步游标
│ └── {accountId}.context-tokens.json # 上下文 token 缓存
7.3 自动去重机制
同一微信号重新登录后,系统会自动清理旧记录,避免 userId 重复导致 context_token 冲突。
八、错误码参考
目前公开的错误码较少:
| errcode | 含义 | 处理建议 |
|---|---|---|
| 0 | 成功 | 🎉 继续执行 |
| -14 | 会话过期 | 暂停请求,等待恢复或重新登录 |
随着 API 迭代,错误码体系将更加完善。
九、实战应用场景
技术只是手段,场景才是目的。以下是六大典型应用方向:
场景 1:个人 AI 助手 🤖
-
上下文管理:天然支持
context_token关联 -
多模态交互:图文混合理解,Vision 模型直接介入
-
工具调用:天气查询、搜索、命令执行等
💡 体验优化:利用 sendtyping 发送“正在输入”状态,提升交互真实感。
场景 2:运维控制台 🖥️
-
CI/CD 构建通知
-
服务器异常报警
-
远程指令执行
微信即控制台,无需额外搭建通知系统。
场景 3:知识库问答(RAG)📚
将文档、笔记向量化,微信内直接问答。
场景 4:家庭群管家 👨👩👧👦
-
天气查询
-
定时提醒
-
菜价播报
语音消息自带 ASR,老人零门槛使用。
场景 5:轻量客服系统 💬
多账号并发 + 自动回复 + 人工接管,context_token 实现对话隔离。
场景 6:自动化工作流 ⚡
-
微信指令触发 GitHub Actions
-
RSS 监控推送
-
定时任务提醒
十、从零到一:实测全流程
理论结合实践,以下三步带你跑通完整流程:登录 → 验证 → 收发。
测试代码已开源,项目结构如下:
weixin-clawbot/
├── scripts/
│ ├── login.js # 扫码登录
│ ├── test-connection.js # 验证连接 + 自动回复
│ └── send-message.js # 主动发消息
├── package.json
└── .weixin-credentials.json # 登录后自动生成
10.1 环境准备
git clone <项目地址>
cd weixin-iLink
npm install
package.json 已预设快捷命令:
{
"scripts": {
"login": "node scripts/login.js",
"test": "node scripts/test-connection.js",
"send": "node scripts/send-message.js"
}
}
10.2 Step 1:扫码登录
npm run login
脚本执行流程:
-
请求二维码
-
终端渲染 ASCII 码
-
轮询扫码状态
-
登录成功,保存凭证

扫码后点击“继续连接”,日志输出登录成功信息。

生成的凭证文件示例:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"baseUrl": "https://ilinkai.weixin.qq.com",
"botId": "ilink_bot_xxxx",
"userId": "xxxx@im.bot",
"savedAt": "2026-03-25T01:00:00.000Z"
}
💡 若需重新登录,删除
.weixin-credentials.json后再次运行即可。
10.3 Step 2:验证连接 + 自动回复
npm run test
功能包括:
-
验证 Token 有效性
-
进入自动回复模式

若返回 errcode: -14,表示会话过期,需重新登录。
10.4 Step 3:主动发送消息

# 指定用户发送
npm run send -- "abc123@im.wechat" "你好,这是一条主动消息"
# 列出已知用户
npm run send -- -l
技术亮点:
① context_token 持久化
每次收到消息即保存 context_token,确保重启后仍可续聊。
② “正在输入”状态模拟
调用 sendtyping 接口,提升交互体验。
③ typing_ticket 获取
需先调用 getconfig 获取 ticket,完整流程为:getconfig → sendtyping → sendmessage。
10.5 测试结果汇总
| 测试项 | 结果 | 备注 | | | ---- | -- | | 二维码获取 | ✅ | ASCII 渲染正常 | | 扫码登录 | ✅ | Token 获取成功 | | Token 验证 | ✅ | ret=0 | | 长轮询收消息 | ✅ | 35 秒超时,实时到达 | | 文本回复 | ✅ | context_token 正常 | | 主动发送 | ✅ | 需有效 token | | “正在输入” | ✅ | typing_ticket 正常 | | 会话过期检测 | ✅ | errcode=-14 识别准确 |
十一、限制与风险提示
| 限制项 | 说明 |
|---|---|
| 🚫 无历史消息接口 | 仅支持向前游标,无法回溯 |
| ❓ 速率限制未公开 | 需自行测试阈值 |
| 📱 需扫码登录 | 无法完全无人值守 |
| 🤔 群聊支持不明 | 字段存在但能力未明示 |
官方条款隐含信息:
-
腾讯仅提供通道,不存储内容
-
保留限速、封禁、终止服务的权利
-
今日可用 ≠ 明日仍可用
建议:核心业务务必设计降级方案,避免单点依赖。
十二、资源汇总
| 资源类型 | 地址/名称 |
|---|---|
| npm 包 | @tencent-weixin/openclaw-weixin |
| CLI 工具 | @tencent-weixin/openclaw-weixin-cli |
| npm 页面 | https://www.npmjs.com/package/@tencent-weixin/openclaw-weixin |
| 测试代码 | weixin-iLink/scripts/ |
快速安装命令:
npx -y @tencent-weixin/openclaw-weixin-cli install
openclaw channels login --channel openclaw-weixin
结语
本文系统梳理了 iLink Bot API 的架构设计、鉴权逻辑、消息机制、加密方案、多账号管理,并展示了六大应用场景,最后通过三个脚本实现了从登录到收发的完整闭环。
若你打算动手尝试,三条建议供参考:
-
先跑通示例脚本,确保基础功能正常
-
评估业务风险,核心场景预留 Plan B
-
紧跟官方动态,协议尚处早期,变动频繁
微信此次开放 API,释放了一个明确信号: