前言
做企业微信相关业务时,很多人第一反应是接官方开放平台。官方接口在应用授权、通讯录、客户联系等场景很完善,但一旦你要做 聚合会话、多账号托管、更贴近终端行为的自动化链路,往往会遇到「只能发指令收不到完整事件」或「收得到通知却不好驱动业务动作」的断层。
协议型能力通常会同时提供两条通道:
- 主动调用:业务系统主动请求,完成发消息、建群、加好友等动作
- 回调下发:协议侧把消息、登录态、联系人/群变动推到你的服务
只有两边配合,客服、SCRM、社群运营这类链路才能闭环。本文先把双通道模型讲清楚,再给一条最小可验证路径。
一、为什么需要双通道
可以把系统拆成两个方向:
你的业务系统 --POST 调用--> 协议服务 --> 企业微信终端行为
你的回调服务 <--HTTP 推送-- 协议服务 <-- 消息/事件
- 只有调用:能发消息、能建群,但收不到实时会话与状态变化,客服坐席会「盲发」
- 只有下发:能监控事件,但无法主动触达客户、无法完成加好友/改标签等动作
因此生产系统通常是:
- 写操作走 调用
- 读事件、驱动状态机走 下发
二、主动调用侧在做什么
协议调用侧常见约定(不同实现细节可能略有差异,以你实际对接文档为准):
| 项 | 常见做法 |
|---|---|
| 请求方式 | POST + JSON(媒体上传多为 multipart) |
| 路径形态 | /wxwork/{接口名} |
| 实例标识 | uuid(指定当前操作哪个在线实例) |
| 账号标识 | vid(登录成功后持久化,用于自动恢复) |
伪代码示例:
POST /wxwork/SendTextMsg
Content-Type: application/json
javascript
{
"uuid": "实例uuid",
"to": "会话对象标识",
"content": "你好,这是一条测试消息"
}
要点:
- 所有业务动作都挂在 uuid 上,不要串实例
- 先登录成功再调业务接口
- 返回值要打日志,失败时区分「未登录 / 参数错误 / 风控限制」

三、回调下发侧在做什么
回调通常是一个公网可访问的 HTTP 接口。协议侧推送时,常见信封结构类似:
javascript
{
"uuid": "实例uuid",
"type": "事件类型",
"json": { }
}
消息类事件还要继续看 json 内的 msgtype(文本、图片、文件等)。
建议入口代码结构:
javascript
app.post('/callback', async (req, res) => {
const { uuid, type, json } = req.body
// 1. 先快速 200,避免超时重推(按你方 SLA 调整)
res.status(200).send('ok')
// 2. 异步分发
await dispatch(uuid, type, json)
})


四、一条最小闭环(建议先跑通)
- 初始化实例,拿到
uuid - 配置回调地址
- 扫码登录企微账号
- 调用一条最简单的文本发送
- 在回调里看到对应消息/状态事件
验证清单:
- 回调地址公网可访问
- 回调日志能打印
type - 同一
uuid调用与下发能对上 - 发消息后,对端能收到,且本端回调有记录
五、能力按业务模块理解更高效
对接时不建议按「几百个接口名」死记,更建议按业务模块:
- 连接与账号
- 消息收发
- 客户与联系人
- 群聊运营
- 朋友圈
- 客服工作台
- 营销与收款
- 开放平台 ID 互转
门户侧对模块做了摘要说明,完整接口清单与示例可在体验环境中按菜单查阅:
- 项目门户:wecomkit.com
- 接口体验环境:接口体验

六、小结
双通道不是概念包装,而是业务闭环的必要结构:
- 调用:你控制系统行为
- 下发:系统把变化告诉你