Skip to content

回调字典

内容消息和联系人通知推送的请求体就是这条消息本身:按 contentType类型速查表里找到读法,messageType 用来分清单聊、群聊还是系统通知。事件名在 X-Eyun-Event 请求头中,见回调说明。样本来自生产环境真实推送(2026-09-10 至 09-12),已脱敏。

脱敏规则

fromUserId / toUserId / uin / roomId / corpId 等 int64 换成同格式占位(1688850000000001 本账号、7881300000000002 外部客户、10000000000002 群、1970320000000001 企业;系统号 10030 / 10014 / 10120 是协议常量,保留);md5 / aesKey 写作 <md5> / <aesKey>,下载 URL 里的临时凭证省略,长 id / hex 截断标注;姓名与企业名换成「示例客户」「示例网络科技」。字段名与结构保持真实。

一条推送长这样

json
{
  "id": 1013420,
  "messageType": 0,
  "contentType": 0,
  "roomId": 0,
  "fromUserId": 7881300000000002,
  "toUserId": 1688850000000001,
  "senderName": "",
  "summary": "您好",
  "sendTime": 1789093735,
  "syncKey": 12014383,
  "flag": 16777216,
  "appInfo": "<appInfo>",
  "extraData": "",
  "devInfo": 0,
  "content": [{ "type": 0, "text": "您好" }]
}

常用字段

字段含义
id消息 id,同一账号内唯一,可用来去重;撤回消息时作为 serverMsgId
messageType会话类型:0 好友(单聊)、1 群聊、3 系统通知
contentType内容类型,决定 content 怎么读,见类型速查表
roomId群 id;单聊与系统私发为 0,系统通知里可能是群 id 或系统号
fromUserId发送方 id(uin);群消息里是真实成员,系统通知里常是系统号(如 10030
toUserId接收方 id,通常是本账号;群消息与部分系统通知为 0
summary可直接展示的摘要,如 您好[图片]、文章标题
sendTime发送时间,秒级时间戳
content消息内容,读法见下一节

idsyncKeyfromUserIdtoUserIdroomId 是 int64 大整数,解析时不要转成 JS Number 或浮点数(前端用 json-bigint,或后端转字符串)。

其余字段(原样透传即可)
字段含义
senderName发送方昵称,大多为空;要昵称请调通讯录接口
syncKey同步位置,递增,可作同步消息的位置标记
flag企微内部标志位
appInfo企微内部推送信息
extraData企微内部数据(base64 编码的 protobuf,含 @ 与引用),一般无需解析
devInfo设备信息标记

content 怎么读

看到的 content常见类型怎么读
数组 [{ "type": 0, "text": "…" }]文本各段 text 是明文,拼起来就是正文;type=0 纯文本、type=3 表情;type=5userId 是 @某人,不带则是 @所有人
对象,带 idaesKey图片、语音、视频、文件媒体文件:用 idaesKeyCDN 下载;单聊图片、视频还带可直接下载的 url
对象 { "hex": "…", "msgType": … }多数系统通知、表情、图文hex 是十六进制编码的数据(不是 base64),msgType 与外层 contentType 相同;系统通知里常为空,只当作「有变化」的信号,去调对应接口刷新
对象,带明文字段好友申请 2357、链接卡片 13字段直接可用

和同步消息不一样

推送的文本是明文数组,媒体是带下载凭证的明文对象,系统类常为 {hex, msgType}同步消息拉历史时的 content 基本是企微 protobuf,文本拿不到明文。推送和同步消息必须分开解析,不能共用同一套读法。发送接口的响应则回显你发送的内容或上传字段。

类型速查表

内容消息(多为 messageType 01,图文 31 的样本是 3

类型contentType样本收到后怎么做
文本0,单聊变体 2看样本拼接 content[].text
图片14 群 / 101 单聊看样本CDN 下载101 可直接用 url
语音16看样本调 CDN 下载,silk 格式
视频23,单聊 103看样本调 CDN 下载;103 可直接用 url
文件15,群与转发 20看样本调 CDN 下载
动画表情104看样本原样保存
图文、公众号文章卡片31,系统图文 105看样本展示 summary(即标题)
链接、视频号卡片13看样本titleurl 等明文字段
位置6读经纬度与地址
名片41读明文字段
小程序78读明文字段(两层结构)
红包26原样保存

系统通知(多为 messageType 3,也有群事件;已读回执 2001 的样本是 0

类型contentType样本收到后怎么做
已读回执2001看样本发消息后必收一条,可忽略
外部联系人信息变动或删除2131看样本同步外部数据(非企业)
好友申请(带明文)2357看样本展示申请,调同意新客户
好友申请2132看样本同意新客户
群信息变动2118看样本获取群资料刷新
群成员变动、建群1006看样本刷新群成员
联系人免打扰、置顶2104看样本原样保存
个人标签变更2186同步标签syncType=2
企业标签变更2185同步标签syncType=1
内部联系人变动2188调通讯录同步
撤回消息2063按撤回处理
其它系统信号2130 / 2180 / 2201看样本含义未确认,原样保存

— 表示还没抓到真实推送(经接口发送不会触发回调,只能等客户端真实操作),含义按协议整理,结构可能有出入;查不到的 contentType 原样保存,由业务判断。

内容消息

对应事件为 message.received,用于文本、图片、视频等内容类消息。

文本(0 / 2 单聊变体)

正文在 content[].text。单聊文本(2)结构相同,messageTyperoomId 都是 0

查看样本
json
{
  "id": 1000554,
  "messageType": 1,
  "contentType": 0,
  "roomId": 10000000000002,
  "fromUserId": 1688850000000011,
  "toUserId": 0,
  "summary": "",
  "sendTime": 1789106713,
  "syncKey": 15993462,
  "flag": 83886080,
  "content": [{"type": 0, "text": "就仅仅"}]
}

图片(14 群 / 101 单聊)

  • 14(群):用 idaesKeyCDN 下载
  • 101(单聊):content 还带 url、中图 wechatMidImagewechatAuthKeyurl 带临时凭证,可直接下载;summary[图片]
查看样本
json
{
  "id": 1013724,
  "messageType": 1,
  "contentType": 14,
  "roomId": 10000000000002,
  "fromUserId": 1688850000000001,
  "sendTime": 1789183828,
  "content": {
    "id": "<下载凭证>",
    "md5": "<md5>",
    "aesKey": "<aesKey>",
    "size": 1209017,
    "width": 1080,
    "height": 1920,
    "thumbMd5": "<md5>",
    "thumbWidth": 326,
    "thumbHeight": 580,
    "thumbFileSize": 25455,
    "midImageFileSize": 25455
  }
}

语音(16)

voiceTime 是秒数;silk 格式,调 CDN 下载

查看样本
json
{
  "id": 1013637,
  "messageType": 0,
  "contentType": 16,
  "summary": "[语音]",
  "fromUserId": 7881300000000002,
  "toUserId": 1688850000000001,
  "sendTime": 1789112161,
  "content": {
    "id": "<下载凭证>",
    "md5": "<md5>",
    "aesKey": "<aesKey>",
    "size": 2608,
    "voiceTime": 2
  }
}

视频(23 / 单聊 103)

  • 23:用 idaesKeyCDN 下载pathsourcePath 是发送端本地路径,忽略即可。
  • 103(单聊):带 url 与封面 previewImgUrl,都带临时凭证,可直接下载;另有 videoWidth / videoHeight / videoDurationsummary[视频]
查看样本
json
{
  "id": 1013739,
  "messageType": 0,
  "contentType": 23,
  "summary": "",
  "fromUserId": 1688850000000001,
  "toUserId": 7881300000000002,
  "sendTime": 1789184127,
  "content": {
    "id": "<下载凭证>",
    "md5": "<md5>",
    "aesKey": "<aesKey>",
    "size": 2533630,
    "width": 1920,
    "height": 1080,
    "duration": 2,
    "thumbUrl": "https://wework.qpic.cn/wwpic3az/…(封面直链)",
    "path": "<发送端本地路径>",
    "sourcePath": "<发送端本地路径>"
  }
}

文件(15 / 群与转发 20)

idaesKeyCDN 下载,文件名在 name20 结构相同,summary 形如 发送人昵称 : [文件名]

查看样本
json
{
  "id": 1013745,
  "messageType": 0,
  "contentType": 15,
  "summary": "",
  "fromUserId": 1688850000000001,
  "toUserId": 7881300000000002,
  "sendTime": 1789184468,
  "content": {
    "id": "<下载凭证>",
    "md5": "<md5>",
    "aesKey": "<aesKey>",
    "url": "",
    "name": "示例文件.jpg",
    "size": 1863186
  }
}

动画表情(104)

hex 是十六进制数据,内含表情的 CDN 地址与表情信息。

查看样本
json
{
  "id": 1013605,
  "messageType": 0,
  "contentType": 104,
  "summary": "[动画表情]",
  "fromUserId": 7881300000000002,
  "toUserId": 1688850000000001,
  "sendTime": 1789111816,
  "content": {
    "hex":
      "0a4768747470733a2f2f…(十六进制,内含 CDN url 与表情信息)",
    "msgType": 104
  }
}

图文、公众号文章卡片(31 / 105)

summary 就是文章标题,可直接展示;标题、摘要、落地页与配图等明细在 hex 里。系统图文(105,如「一周小结」)结构相同。

查看样本
json
{
  "id": 1013415,
  "messageType": 3,
  "contentType": 31,
  "roomId": 10120,
  "fromUserId": 10120,
  "summary": "同事们在看《示例文章标题》",
  "sendTime": 1789085330,
  "content": {
    "hex":
      "0aeb020a…(十六进制,内含标题 / 摘要 / 落地页 / 配图 url)",
    "msgType": 31
  }
}

普通链接读 titledescriptionimageUrlurl 四个字段;视频号卡片在 sph_feed_h5_message 里,字段是 base64。

查看样本
json
{
  "id": 1001089,
  "messageType": 1,
  "contentType": 13,
  "roomId": 10000000000002,
  "fromUserId": 1688850000000001,
  "summary": "发送人昵称 : [视频号]的视频",
  "sendTime": 1789191553,
  "content": {
    "title": "卡片标题",
    "description": "卡片描述",
    "imageUrl": "https://example.com/cover.jpg",
    "sph_feed_h5_message": {"url": "<base64>"}
  }
}

系统通知

已读回执(2001)

发出任意消息后都会收到一条,hex 很短,一般可忽略。

查看样本
json
{
  "id": 1013420,
  "messageType": 0,
  "contentType": 2001,
  "roomId": 0,
  "fromUserId": 1688850000000001,
  "toUserId": 7881300000000002,
  "sendTime": 1789089094,
  "content": {"hex": "080210aba6dd052800", "msgType": 2001}
}

外部联系人信息变动或删除(2131)

对应事件为 contact.modified;删除外部联系人还会产生 friend.deleted。不能只凭 2131 判断删除,需同步外部联系人后判断是增是删。

fromUserId 是系统号 10030hex 为空,只当信号。收到后调同步外部数据(非企业)拉增量。

查看样本
json
{
  "id": 1013407,
  "messageType": 3,
  "contentType": 2131,
  "roomId": 10030,
  "fromUserId": 10030,
  "toUserId": 0,
  "summary": "",
  "sendTime": 1789047615,
  "content": {"hex": "", "msgType": 2131}
}

好友申请 · 带明文(2357)

对应事件为 friend.added

少数直接给明文的系统通知:uin 是申请人,corpIdcorpName 是其企业,customerName 是昵称,source 是来源。可直接展示,用同意新客户同意。

查看样本
json
{
  "id": 1013589,
  "messageType": 3,
  "contentType": 2357,
  "roomId": 10030,
  "fromUserId": 10030,
  "summary": "示例客户@微信申请添加你为联系人",
  "sendTime": 1789111073,
  "content": {
    "uin": 7881300000000002,
    "corpId": 1970320000000001,
    "source": "微信",
    "corpName": "示例网络科技",
    "customerName": "示例客户"
  }
}

好友申请(2132)

对应事件为 friend.added

同为好友申请,但 hex 为空,只当信号;同意同样用同意新客户

查看样本
json
{
  "id": 1013587,
  "messageType": 3,
  "contentType": 2132,
  "roomId": 10030,
  "fromUserId": 10030,
  "summary": "",
  "sendTime": 1789111073,
  "content": {"hex": "", "msgType": 2132}
}

群信息变动(2118)

对应事件为 contact.modified

群设置一有变更就会推送若干条 2118 以及具体事件,是最频繁的群推送(hex 为空);按 roomId获取群资料刷新即可。

查看样本
json
{
  "id": 1001024,
  "messageType": 1,
  "contentType": 2118,
  "roomId": 10000000000002,
  "fromUserId": 1688850000000012,
  "summary": "",
  "sendTime": 1789182975,
  "content": {"hex": "", "msgType": 2118}
}

群成员变动、建群(1006)

对应事件为 contact.modified

hex 解出来是分号连接的成员 id 列表,收到后刷新群成员。

查看样本
json
{
  "id": 1001020,
  "messageType": 1,
  "contentType": 1006,
  "roomId": 10000000000002,
  "fromUserId": 1688850000000012,
  "summary": "",
  "sendTime": 1789182974,
  "content": {
    "hex": "31363838…(十六进制,解出为分号连接的成员 uin 列表)",
    "msgType": 1006
  }
}

其它系统信号(2104 / 2130 / 2180 / 2201 等)

结构都一样:messageType3,发送方是系统号,content.hex 为空。除 2104(联系人免打扰、置顶)外,含义都未确认,原样保存。

查看样本
json
{
  "id": 1013412,
  "messageType": 3,
  "contentType": 2180,
  "roomId": 10014,
  "fromUserId": 10014,
  "summary": "",
  "sendTime": 1789047766,
  "content": {"hex": "", "msgType": 2180}
}

连接事件

实例的企微连接建立时推送 instance.online,请求体为 {};断开时推送 instance.offline,请求体形如:

json
{ "code": 0, "message": "手动关闭长链", "time": "2026-09-11 16:50:12" }

instance.offlinecode 按下表处理:

code含义
0用户主动关闭
-1008移动端主动退出
-11001需要断线重连
-11002已在其他设备登录
-2007已下线
-1连接异常,详情看 message

-11001-11002 都会推送 instance.offline。同时保留定期业务探测,见实例与代理 · 掉线检测与恢复

只有 -11001 可以自动重连

-11002 不要自动重连,否则会和另一台设备互相顶号、反复掉线。应置为离线,提示「已在其他设备登录」,由用户决定是否重新登录。

断线重连返回 code=0 只代表已经开始恢复;之后的业务调用不再报 -11002 / -2007,才可继续判断在线状态。重连失败要间隔几十秒以上再试,连续失败就重新扫码。

大文件上传完成

上传大文件到 CDN是异步的:接口先返回 requestId,上传完成后系统推送一条大文件事件。事件名以可订阅事件列表接口返回为准。请求体如下(暂无真实样本,按协议整理):

json
{
  "content": {
    "id": "*1*<大文件 id,含下载凭证>",
    "name": "文件名",
    "url": "",
    "size": 6342632,
    "aesKey": "",
    "md5": "<md5>"
  },
  "requestId": "<与同步响应一致>"
}

requestId 与接口同步返回的一致;content.id*1* 开头)可直接用来发送大文件。上传失败时推送的结构相同;源地址 404 时接口直接返回 code -1,不推送,只有「下载成功、上传失败」才推送失败通知。

下一步