| layout | default |
|---|---|
| title | 接口文档 |
| has_children | true |
| nav_order | 3 |
| toc | true |
| toc_levels | 1..4 |
| permalink | /main/dev.html |
{:.no_toc }
{: .no_toc }
- TOC {:toc}
| 修改时间 | 对应的客户端版本 | 协议修改内容 |
|---|---|---|
| 2018.9.28 | v0.2.0 | 简化ack_type类型,"发消息任务"的字段有调整 |
| 2018.10.12 | v0.2.2 | 回调地址改为到wehub后台网页里进行配置,增加secret key进行安全性验证 |
| 2018.10.17 | v0.2.3 | login中增加"local_ip"字段 |
| 2018.10.23 | v0.2.6 | 增加 report_contact_update ; userInfo 结构新增sex,country,province,city等字段 |
| 2018.11.16 | v0.2.15 | login,logout中增加 machine_id 字段(起辅助作用);新增task_type 为14的任务类型 |
| 2018.11.29 | v0.3.0 | 在report_contact 中增加对当前账号关注的公众号信息的上报;开始支持语音消息中的语音数据上传;支持下发扩展的gif表情任务 |
| 2018.12.11 | v0.3.3 | 上报的文本消息中新增atuserlist字段;支持发文件消息中的文件数据上传;report_room_member_info有新增字段 |
| 2018.12.27 | v0.3.6 | 客户端增加缓存清理设置(接口协议无修改) |
| 2019.1.18 | v0.3.8 | 增加report_friend_removed |
| 2019.3.15 | v0.4.0 | 客户端新增升级功能并强制在登陆时做安全验证. 新增检查僵尸粉的任务类型(task_type为15), report_contact_update 的userInfo 结构中新增is_friend字段. |
| 2019.4.4 | v0.4.2 | 上报的个人微信号的信息中(城市,省份,国家等信息已准确),新增100,101两种本地打标签的任务类型. wehub已支持websocket方式的通讯(见文档最下方的描述).在发消息任务中增加at_style字段,可以把@符号放在文本中的任意位置 (见该任务类型的详细描述) |
| 2019.8.14 | v0.4.6 | 新增了"查询个人号详情"的任务(task_type为16)和"创建新的群"的任务(task_type为17);新增report_user_info; report_new_msg上报的消息中新增了msg_id和msg_timestamp字段(分别代表消息的id和消息的时间戳) |
| 2019.8.29 | v0.4.9 | login_ack增加option字段(服务端可自定义report_contact中上报的数据内容),新增task_type为18的任务类型 |
| 2019.10.23 | v0.4.12 | 新增任务类型:接受入群邀请(task_type=19), 支持发送小程序 |
| 2019.12.23 | v0.4.26 | 新增退出群的通知report_room_removed,新增client_session字段 |
appid是一段字符串,WeHub使用它来区分不同的第三方。任何想使用wehub服务的第三方首先向推宝科技申请,申请时需提交自己的回调接口地址,推宝科技会对该地址做审核。
第三方在使用WeHub时首先要在WeHub中配置appid,WeHub验证通过后才会post数据到第三方的回调接口地址上。
就如同每个人都有一个身份证号一样,每个微信帐号/微信群都有唯一的标识字符串用来做区分。
对于微信群,其格式为xxxxxx@chatroom(如8680025352@chatroom)。
对于个人微信账号,其格式为wxid_xxxxxxx(以wxid_ 开头,如wxid_p9597egc5j1c21)或者xxxxxxx(不以wxid_开头,在注册微信时由注册者自定义,如fangqing_hust)
本文档中所有数据结构中的"wxid"/"room_wxid"字段即代表个人微信账号/微信群号的唯一的标识字符串
WeHub和回调接口之间采用http的方式进行通讯,双方都采用utf-8编码json格式的数据(Content-Type为application/json).
当微信中有相关的事件发生时,WeHub会主动post http request到回调接口,该http request中包含了解释具体微信事件的数据。
回调接口需返回适当的http respone,respone中包含下发给WeHub执行的任务(任务的格式见文档中描述)
wehub发送的数据(简称为:request)json格式为:
{
"action": "具体业务名",
"appid": "第三方申请的id",
"wxid": "当前登录的wxid",
"client_session":"xxxxxxxx", //0.4.26版本中新增(详情见:http://wehub.weituibao.com/doc/post/version0426.html)
"data": {具体业务的相关数据}
}
wehub用"action"字段来区分发送的数据/事件的种类. 比如当前微信收到一条新消息时,wehub会发送action为"report_new_msg"的json数据, "data"中的数据为一条具体的消息(包含的消息发送者的wxid和消息的内容) 不同种类的action,对应的data的数据格式也不一样(接下来文档中会有详细描述)
回调接口返回的数据(简称为:respone)json格式为:
{
"error_code": 0, //0代表没有错误,其他的第三方自定义
"error_reason": "", //如果出错,这里写出错原因的描述,否则留空
"ack_type":"xxxx_ack", //ack_type 字段不能缺失
"data":{
xxxxx:xxxxxx //具体的附带的数据,不同的ack_type对应不同的data格式
}
}
对于respone中带双引号的数据域,如果其语义为字符串,则双引号不可缺少
如:"ack_type":"login_ack"
ack_type字段其值代表具体的业务名称(字符串), 因此login_ack前后的""符号不能省略
又如: "error_code": 0,
error_code其值语义为一个具体的错误码(数字),因此0前后不需要""符号
wehub发送的request 以utf-8编码,回调接口返回的respone 中的json格式数据 wehub 也以utf-8编码来解析 ,文档的示例代码中出现的 "$xxx" 符号代表这里应该出现一个名为"xxx"结构的数据对象,如 $task $report_msgunit等
| request中的action类型 | respone中的ack_type |
|---|---|
| login | login_ack |
| logout | logout_ack |
| pull_task | pull_task_ack |
| report_contact | common_ack |
| report_contact_update | common_ack |
| report_new_friend | common_ack |
| report_new_msg | common_ack |
| report_task_result | common_ack |
| report_room_member_info | common_ack |
| report_room_member_change | common_ack |
| report_friend_add_request | common_ack |
| report_new_room | common_ack |
| report_friend_removed | common_ack |
| report_zoom_check_status | common_ack |
| report_user_info | common_ack |
注:上述action中,回调接口必须实现对login的正确处理,否则使用相应appid的wehub 客户端将无法使用,对于其他不感兴趣/不想处理的action,可简单返回一个空的json{}.(总之收到wehub发送request后,回调接口必须有respone返回, 原因见Faq
这是appid验证通过并且微信登陆后向回调接口发送的第一个request 回调接口必须对这个request做出正确的响应,否则wehub 会提示登陆失败/安全验证失败
自0.2.2版本开始,wehub引进了"安全性验证"机制. 第三方的管理员请登录WeHub后台 对回调参数进行配置, 系统会自动为每一个appID生成了"secret key"(该值用于之后的签名计算).
WeHub的计费策略是每月按appid统计登陆wehub的微信号的数量, 因此登陆wehub的微信号数量直接影响第三方的wehub使用费用. 为了使登陆的微信号处于可控状态,第三方必须在服务端建立白名单,只允许白名单之内的微信号登陆. 在处理login请求时对白名单之外的微信号返回登陆失败,这样没有列入 白名单的微信号将无法登陆wehub,也不会计入当月的使用量.
- 如何将我信任的微信号加入到白名单中?
点击该微信PC客户端左上方头像,将弹出的界面中显示的微信号的字符串值加入到的白名单中.
- 回调接口在收到login时如何判断请求登陆微信帐号的合法性?
- 我想添加群里其他人的微信号到我的白名单里,但是为何我看不到他们中某些人的微信号?
这是因为你与这些微信是陌生人关系.微信系统出于安全考虑,会对陌生人屏蔽微信号.加对方为好友后你就可以看到对方微信号了
login request格式为
{
"action" : "login", //登录的业务名为"login"
"appid": "xxxx", //申请的appid
"wxid" : "wxid_fo1039029348sfj", //当前登陆的微信账号的wxid
"data" : {
"nickname": "Bill", //微信昵称
"wx_alias": "mccbill", //自定义的微信别号(有可能为空)
"head_img": "http://xxxxxx", //微信的头像地址
"client_version":"xxxxxx" //wehub的版本号
"nonce":"xxxxxxxxxxxxxxx" //回调接口在计算签名时用到这个nonce值
//有这个字段时服务端必须返回正确的签名
//没有这个字段时回调接口无需做签名处理
"local_ip":"192.168.0.104|211.168.0.104"
//当前wehub所在系统中的网卡ip,如有多个以'|'分隔, 该字段是在0.2.3 版本中新加入的
"machine_id":"xxxxxx" //wehub客户端的标识(由计算机名+进程id生成)0.2.15版本中加入
}
}
回调接口返回(respone):
{
"error_code": 0,
"error_reason": "",
"ack_type":"login_ack",
"data":{
"signature":"xxxxxxxxxxx" //返回给wehub客户端的签名
"option":{
"flag_report_contact": xxx //可选标志位(0.4.9 版本中新增)
}
}
}
签名算法:
将login request中的wxid和nonce两个字段的值取出
然后将wxid,nonce,secretkey用'#'符号拼接成字符串,计算出md5值,该md5值的32位编码字符串即为签名值.
例如:wxid为"fangqing_hust",nonce值为"helloworld",secretkey为"112233",
则signature = md5("fangqing_hust#helloworld#112233") = "4B8D798F8B34A7BD2CD3B4CBFA309D9C"
注意:返回的是md5值的32位字符串,不是16位的.(大写小写都可以)
WeHub收到回调接口的login respone后
1.校验signature(若不通过,则弹框提示签名失败)
2.检查error_code的值.若不为0,则会弹框提示登陆失败及失败原因(从error_reason字段中取值)
通过以上检测后WeHub才算登陆成功(之后才会上报各种事件)
- 关于login_ack中flag_report_contact {:#flag_report_contact} 若在report_contact中完整上报[好友+群+公众号]三者的数据会导致数据量太大/冗余,故新增该flag来设置只上报其中一部分关心的数据
| 值 | 含义 |
|---|---|
| 1 | 发送的report_contact中包含好友的信息(friend_list) |
| 2 | 发送的report_contact中包含群的信息(group_list) |
| 4 | 发送的report_contact中包含关注的公众号的信息(public_list) |
(flag_report_contact的值可以为上述选项其中一个或多个选项的数值相加后的结果)
eg:
上报所有的信息 则值指定为7(1+2+4=7)
- 1 :friend_list
- 2 :group_list
- 4 :public_list
如只上报好友和群的信息,则值指定为3(1+2=3)
- 1 :friend_list
- 2 :group_list
- 4 :public_list
如只上报好友和公众号的信息,则值指定为5(1+4=5)
- 1 :friend_list
- 2 :group_list
- 4 :public_list
如只上报群和公众号的信息,则值指定为6(2+4=6)
- 1 :friend_list
- 2 :group_list
- 4 :public_list
如不上报任何信息,则值指定为0
- 1 :friend_list
- 2 :group_list
- 4 :public_list
从0.4.0版本开始,wehub客户端已强制要求做安全验证(无论后台是否取消了安全验证,request中都会有nonce 字段).对于服务端而言,只需判断受到的request中是否有nonce 字段, 有这个字段时服务端必须返回正确的签名!!! 没有这个字段时回调接口无需做签名处理(signature可以置空)
wehub的登录流程图如下 [点击查看]:
request格式:
{
"action":"logout",
"appid": "xxxxxx", //申请的appid
"wxid": "wxid_xxxxxxx",
"data":{
"client_version":"xxxxxx" //wehub的版本号
"machine_id":"xxxxxx" //wehub客户端的标识(由计算机名+进程id生成)0.2.15版本中加入
}
}
respone格式
{
"error_code": 0,
"error_reason": "",
"ack_type":"logout_ack",
"data":{}
}
WeHub在收到回调接口返回的login_ack之后,会做相关校验以验证登陆是否成功.
若登陆成功,会上报当前好友/群/公众号的信息, 如果微信的好友/群的数量比较多,这个request post的数据将会非常大.
别避免这种情况,在0.4.9中引进了flag_report_contact选项
由于微信客户端对联系人的信息加载是个lazy load 的过程,因此在report_contact 中上报的联系人信息可能不全,
比如有的头像信息没有获取到,wehub会通过 report_contact_update的方式进行增量更新,详情见[上报成员信息变化]
report_contact 这个http请求Post的数据量会比较大(好友/群越多,post的数据就越大),请将服务端能接受的post_max_size 调整成至少10M
request格式
{
"action": "report_contact",
"appid": "xxxxxx",
"wxid": "wxid_xxxxxxx",
"data":{
"friend_list":[$userInfo,$userInfo,$userInfo,...], //好友
"group_list":[$groupinfo,$groupinfo, $groupinfo,......], //群
"public_list":[$publicinfo,$publicinfo,$publicinfo,....] //公众号
}
}
data中相关字段描述
- groupinfo(群信息结构):
{
"wxid": "xxxxxxx", //群的wxid,格式为 xxxxx@chatroom
"name": "xxxxxx", //群名称
"owner_wxid": "xxxxxxxx", //群主的wxid
"member_count": 100, //该群成员总数
"head_img":"http://xxxxxxxx" //群的头像的url地址
"member_wxid_list" :['wxid_xxx1','wxid_xxx2',...] //当前群的成员wxid的列表
}
- userInfo(好友信息结构)
{
"wxid": "wxid", //wxid
"wx_alias": "xxxxx", //微信号(有可能为空)
"nickname":"xxxxx", //微信昵称
"remark_name" :"xxxx", //好友备注
"head_img":"http://xxxxxxxx" //头像的url地址
"sex" : xx , //性别:1男,2女,0(未知)
"country":"xxx", //祖国(可能为空)
"province":"xxxx", //省份(可能为空)
"city":"xxxxx" //城市(可能为空)
}
- publicinfo(公众号信息)
{
"wxid": "gh_xxxxx", //某些公众号也可能以wxid_ 开头
"nickname":"xxxxx", //公众号名称
"head_img":"http://xxxxxxxxxx" //头像
}
respone格式为:common_ack格式
{: #common_ack}
{
"error_code": 0,
"error_reason": "",
"ack_type":"common_ack",
"data":{
"reply_task_list": [$task,$task,...]
//回复的任务列表,如果没有要回复的任务,则列表为空
}
}
注:每个$task都是一个json对象,代表一个要下发给wehub执行的任务,格式见 [任务类型格式]
示例 通过common_ack 向wehub回复两个任务,第一个任务让wehub向一个群发送3条消息(1条文本消息(同时@了两个群成员),1条图片消息,1条链接消息),第二个任务让wehub上报两个微信群的群成员信息
{
"error_code": 0,
"error_reason": "",
"ack_type":"common_ack",
"data":
{
"reply_task_list":
[
{
"task_type": 1,
"task_dict":
{
"wxid_to":"wxid_test@chatroom",
"at_list":["wxid_b1","wxid_b2"],
"msg_list":
[
{
"msg_type":1,
"msg":"自动回复,test"
},
{
"msg_type":3,
"msg":"https://www.baidu.com/img/bd_logo1.png"
},
{
'msg_type':49,
'link_url':"http://httpd.apache.org/",
"link_title":"apache",
"link_desc":"apache官网",
"link_img_url":"http://httpd.apache.org/images/httpd_logo_wide_new.png"
}
]
}
},
{
"task_type":4,
"task_dict":
{
"room_wxid_list":["wxid_test1@chatroom","wxid_test2@chatroom"]
}
}
]
}
}
触发时机: wehub探测到联系人列表中的信息有更新(如昵称,头像等)."联系人"可能是我的好友,也可能是某个群里的成员,也可能是某个陌生人---总之这个联系人不表述好友关系); 亦或是在上报report_contact时尚未获取到的联系人/群信息. 为节省流量,wehub 会每隔10s检查这些变化,然后上传这些变化的信息.
request格式
{
"action":"report_contact_update",
"appid":"xxxxxxxx",
"wxid":"xxxxxxx",
"data":{
"update_list":[
$userInfo,$groupbaseInfo,$userInfo,$groupbaseInfo,.....
// 群基本信息(groupbaseInfo)和联系人信息(userInfo)的无序列表
// 如果其wxid字段以@chatroom结尾,其为groupbaseInfo
// 否则代表联系人信息(userInfo)
]
}
}
$userInfo
- userInfo(好友信息结构)
{
"wxid": "wxid", //wxid
"wx_alias": "xxxxx", //微信号(有可能为空)
"nickname":"xxxxx", //微信昵称
"remark_name" :"xxxx", //好友备注
"head_img":"http://xxxxxxxx" //头像的url地址
"sex" : xx , //性别:1 男, 2 女
"country":"xxx", //祖国(可能为空)
"province":"xxxx", //省份(可能为空)
"city":"xxxxx" //城市(可能为空)
'is_friend': x //0:不是我的好友;1:是我的好友
}
$groupbaseInfo (群基本信息):
{
"wxid": "xxxxxxx", //群的wxid:格式为 xxxxx@chatroom
"name": "xxxxxx", //群名称
"head_img":"http://xxxxxxxx" //群头像的url地址
"owner_wxid":"xxxxxx", //群主的wxid,0.3.8版本中加入
"member_count":xx //群成员总数,0.3.8版本中加入
}
respone格式为[common_ack格式]
触发时机: 由回调接口通过下发"任务"来被触发
request
{
"action":"report_room_member_info",
"appid": "xxxxxxxx", //申请的appid
"wxid" : "wxid_fo1039029348sfj",
"data" : {
room_data_list:[
{
"room_wxid":"xxxxx1@chatroom", //群wxid
"name":"xxxx", //群名(0.3.3版本中新增)
"owner_wxid":"xxxxx", //群主wxid(0.3.3版本中新增)
"head_img":"xxxxxxx", //群头像(0.3.3版本中新增)
"member_count": xxx, //群内有多少个成员(0.3.3版本中新增)
"memberInfo_list":[$memberInfo,$memberInfo.....]
//群内成员信息
},
........
]
}
}
$memberInfo 结构如下:
{
"wxid": "wxid", //wxid
"wx_alias": "xxxxx", //微信号(有可能为空)
"room_nickname": //这个微信号的群昵称
"nickname":"xxxxx", //微信昵称
"head_img":"http://xxxxxxxx" //头像的url地址
"sex":xx, //0未知,1 男, 2 女
"country":"xxx",
"province":"xxx",
"city":"xxx"
}
respone格式为[common_ack格式]
触发时机:群成员增加或减少时上报
request
{
"action":"report_room_member_change",
"appid":"xxxxxxx",
"wxid": "wxid_xxxxxxx",
"data":{
"room_wxid":"xxxxxxx@chatroom",
"owner_wxid":"xxxxx", //群主wxid, 0.3.8版本中加入
"wxid_list";["xxxxxx","xxxxx"], //变化的成员的wxid列表
"flag": flag //0,群成员减少;1,群成员增加
}
}
respone格式为[common_ack格式]
触发时机:当发现新的群时(比如被拉进了新的群或新建了新的群)
request
{
"action":"report_new_room",
"appid":"xxxxxxx",
"wxid": "wxid_xxxxxxx",
"data":{
"wxid":"xxxxx", //新群的wxid
"name:"xxxx", //群名(可能为空)
"owner_wxid":"xxxxx", //群主的wxid
"head_img":"xxxx", //群头像的url地址
"memberInfo_list":[$memberInfo,$memberInfo,.....] //见memberInfo结构
}
}
$memberInfo结构如下
{
"wxid": "wxid", //wxid
"wx_alias": "xxxxx", //微信号(有可能为空)
"room_nickname": //这个微信号的群昵称
"nickname":"xxxxx", //微信昵称
"head_img":"http://xxxxxxxx" //头像的url地址
}
respone格式为[common_ack格式]
触发时机:被踢出群或者主动退出某个群
request
{
"action":"report_room_removed",
"appid":"xxxxxxx",
"wxid": "wxid_xxxxxxx",
"data":{
"wxid_removed":"xxxxx", // 退出的群
}
}
respone格式为[common_ack格式]
触发时机:当收到私聊消息或所在的某个群内有人发言(含自己发送的消息)
对于做了自动回复功能的第三方接口,需要过滤自己发的消息.否则会陷入"回调接口下发自动回复-->wehub发消息--->微信消息事件回调--->wehub上报刚才自己发的消息--->回调接口又下发聊天任务"的死循环
一旦陷入死循环,容易导致wehub高频率地发消息,这极易触发微信系统的安全提醒甚至被封号
如何过滤自己发的消息?
若使用的wehub版本<0.1.4,回调接口在收到report_new_msg时,判断msg中的wxid是否为这个wehub上登陆的wxid. 若是,则不要下发task_type=1的发消息的任务
若使用的wehub版本>=0.1.4,回调接口在收到report_new_msg时,判断msg中的wxid_from是否为这个wehub上登陆的wxid.若是,则不要下发task_type=1的发消息的任务
request
{
"action" : "report_new_msg",
"appid": "xxxxxxxx", //申请的appid
"wxid" : "wxid_fo1039029348sfj",
"data" : {
"msg": $report_msgunit //上报单条消息
//report_msgunit格式见[上报的消息单元的格式]
}
}
respone格式为[common_ack格式]
{: #report_msgunit}
| 聊天消息类型 | 类型值msg_type | 是否支持任务下发 | 是否支持上传消息中的文件 |
|---|---|---|---|
| 文本消息 | 1 | 支持 | ---- |
| 图片消息 | 3 | 支持 | 支持消息中的图片文件上传 |
| 个人名片 | 42 | 支持 | ---- |
| 语音 | 34 | 暂不支持 | 从0.3.0版本开始支持 |
| 视频 | 43 | 支持 | 支持消息中的视频文件上传 |
| 表情消息 | 47 | 从0.3.0版本开始支持 | 不支持 |
| 链接消息 | 49 | 支持 | ---- |
| 小程序 | 4901 | 0.4.12开始支持 | ---- |
| 转账 | 4902 | 暂不支持 | ---- |
| 文件消息 | 4903 | 支持 | 支持 |
| 微信系统通知 | 10000 | 不支持 | ---- |
- 文本消息
{
"msg_id": "xxxxx" //消息id(字符串)
"msg_timestamp": xxxxxx, //消息的时间戳(单位为毫秒)
"msg_type": 1, //1 代表文本消息
"room_wxid": "xxxxxxxx@chatroom", //聊天消息发生在哪个群(如果是私聊则为空)
"wxid_from": "wxid_xxxxxx", //消息发送者的wxid
//如果是自己发的消息这里的wxid就是自己的微信号
"wxid_to": "wxid_xxxxx", //消息的接收者的wxid
//如果发往群的消息,这个值就是群的wxid
//如果是别人私聊给自己的消息,这里就是自己的微信号
"atUserList": ["xxx","xxx"] //这条消息@的对象列表
"msg": "xxxxxxxx" //具体的文本内容
//如果A在群里面at了B(群昵称为BN),C(群昵称为CN),则msg的格式为"@BN @CN XXXXXX" (@BN @CN之间有空格)
}
例如:
A用户在B群里发了一条消息:
"room_wxid": "B群wxid",
"wxid_from":"A的wxid",
"wxid_to": "B群wxid",
A给我私聊了一条消息:
"room_wxid": "",
"wxid_from":"A的wxid",
"wxid_to": "我的wxid",
我在B群里发了一条消息:
"room_wxid": "B群wxid",
"wxid_from":"我的wxid",
"wxid_to": "B群wxid",
我向A发了一条私聊消息:
"room_wxid": "",
"wxid_from":"我的wxid",
"wxid_to": "A的wxid",
- 图片消息
{
"msg_id": "xxxxx", //消息id(字符串)
"msg_timestamp": xxxxxx, //消息时间戳(单位为毫秒)
"msg_type": 3, //3 代表图片消息
"room_wxid": "xxxxxxxx@chatroom", //同文本消息
"wxid_from": "wxid_xxxxxx", //同文本消息
"wxid_to": "wxid_xxxxx", //同文本消息
"file_index":"xxxxxx" //图片文件的唯一索引(由wehub生成)
//该字段在wehub上报消息时有效
//如果是自己发/转发的图片,file_index为本地的文件路径
}
- 链接消息
(可能是一个入群的链接,也可能是一个分享的网页的链接)
{
"msg_id": "xxxxx",
"msg_timestamp": xxxxxx,
"msg_type":49, //49 代表链接消息
"room_wxid": "xxxxxxxx@chatroom",
"wxid_from": "wxid_xxxxxx",
"wxid_to": "wxid_xxxxxx",
"link_title":"标题", //链接标题
"link_desc": "副标题", //链接描述(副标题)
"link_url":"http://xxxxx", //链接的url
"link_img_url": "http://xxxxxxx", //链接的缩略图的的Url,jpg或者png格式
"sub_type": x, //链接消息的子类型(0.4.12版本中新增)
//当值为5时并且link_url的值是以这种格式开头:
//"https://support.weixin.qq.com/cgi-bin/mmsupport-bin/addchatroombyinvite?ticket=xxxxxx时"
//该链接消息是一个入群邀请链接(每个入群链接的ticket参数不一样,见任务类型:接收进群邀请)
//入群邀请链接只在一段时间内有效,过期后将无法进入被邀请的群
"raw_msg": "xxxxxxx" //微信的原始消息,xml格式,0.3.14版本中新增
}
raw_msg 中的关键字段有"title","des","url","thumburl"(分别与link_title,link_desc,link_url,link_img_url值对应),
如果link_url值为空,请自行分析raw_msg中的url.
- 表情消息
{
"msg_id": "xxxxx",
"msg_timestamp": xxxxxx,
"msg_type":47,
"room_wxid": "xxxxxxxx@chatroom",
"wxid_from": "wxid_xxxxxx",
"wxid_to": "wxid_xxxxxx",
"emoji_url": "xxxxxxxxx" //表情的url地址(若有需要,请回调接口自行下载该文件)
"raw_msg": "xxxxxxx"
}
- 小程序
{
"msg_id": "xxxxx",
"msg_timestamp": xxxxxx,
"msg_type":4901,
"room_wxid": "xxxxxxxx@chatroom",
"wxid_from": "wxid_xxxxxx",
"wxid_to": "wxid_xxxxxx",
"raw_msg": "xxxxxxx" //微信中的小程序信息的原始数据,xml格式,请自行解析
"file_index": xxxxxxxxxxx //小程序的封面的文件索引, 0.4.12新增 (如果需要转发这个小程序的话,该封面需先上传到第三方的服务器上)
}
- 转账事件
触发时机:
情况一:我转账给他人
1.发起转账时:wxid_from='我的wxid',wxid_to='他人的wxid',paysubtype=1
2.对方确认收账时:wxid_from ='他人的wxid',wxid_to='我的wxid',paysubtype=3
情况二:他人转账给我:
1.发起转账时:wxid_from ='他人的wxid',wxid_to='我的wxid',paysubtype=1
(只有这种情况下才能自动收账,格式见自动收账任务)
2.我确认收账时:wxid_from='我的wxid',wxid_to='他人的wxid',paysubtype=3
{
"msg_id": "xxxxx",
"msg_timestamp": xxxxxx,
"msg_type":4902,
"wxid_from": "wxid_xxxxxx",
"wxid_to": "wxid_xxxxxx",
"transferid": "xxxxxxx" //转账的ID
"paysubtype":paysubtype, //这笔账单的状态
"raw_msg": "xxxxxxx" //微信中的转账事件的原始数据,xml格式
}
- 文件
(从0.3.3版本开始支持文件上传)
{
"msg_id": "xxxxx"
"msg_timestamp": xxxxxx,
"msg_type":4903,
"room_wxid": "xxxxxxxx@chatroom", //发生在哪个群里
"wxid_from": "wxid_xxxxxx", //文件发送者
"wxid_to":"wxid_xxxxx", //文件接收者
"file_index":"xxxxx",
"file_name": "xxxxxx", //文件名
"file_size": xxxxx, //字节数
"raw_msg": "xxxxxxx" //微信中的文件的原始消息,xml格式,请自行解析
}
- 个人名片
{
"msg_id": "xxxxx",
"msg_timestamp": xxxxxx,
"msg_type":42,
"room_wxid": "xxxxxxxx@chatroom",
"wxid_from": "wxid_xxxxxx",
"wxid_to": "wxid_xxxxxx",
"raw_msg": "xxxxxxx" //微信中的名片信息的原始数据,xml格式,请自行解析
}
- 语音消息
(从0.3.0版本开始支持上传消息中的语音文件,将微信中原始语音数据转化为MP3格式后上报)
{
"msg_id": "xxxxx",
"msg_timestamp": xxxxxx,
"msg_type":34,
"room_wxid": "xxxxxxxx@chatroom",
"wxid_from": "wxid_xxxxxx",
"wxid_to": "wxid_xxxxxx",
"file_index":"xxxxxxx",//0.3.0之前的版本中该值都预留为空
"raw_msg": "xxxxxxx" //微信中的原始消息,xml格式
}
- 视频消息
{
"msg_id": "xxxxx",
"msg_timestamp": xxxxxx,
"msg_type":43,
"room_wxid": "xxxxxxxx@chatroom",
"wxid_from": "wxid_xxxxxx",
"wxid_to": "wxid_xxxxxx",
"file_index":"xxxxxx", //视频文件的索引
"raw_msg":"xxxxxxx", //视频文件详细信息(文件大小length,播放时长playlength),需服务端自行解析;可根据文件大小来判断是否要上传
}
- 微信系统通知
{
"msg_id": "xxxxx",
"msg_timestamp": xxxxxx,
"msg_type":10000,
"room_wxid": "xxxxxxxx@chatroom",
"wxid_from": "wxid_xxxxxx",
"wxid_to": "wxid_xxxxxx",
"raw_msg": "xxxxxxxx" //具体的通知内容,纯文本格式
}
无需对系统通知做自动回复
eg:
1.发消息-被对方拉黑之后,raw_msg 为"消息已发出,但被对方拒收了"
2.有红包出没时:"发出红包,请在手机上查看"
3.修改群名称后:xxxxx修改群名为xxxxxxx
其他:
群主已恢复默认进群方式。
群主已启用“群聊邀请确认”,群成员需群主确认才能邀请朋友进群。
你已成为新群主
xxxxxx已成为新群主
你邀请xxxx加入了群聊
xxxx邀请xxxx加入了群聊
xxxxx通过扫描你分享的二维码加入群聊"
xxxxx通过扫描xxxxxx分享的二维码加入群聊"
在WeHub后台配置文件上传的接口地址,WeHub会将需要上传的文件(比如聊天消息中的图片,语音,视频等)数据post到该地址上(form-data方式).
基本流程:
1.wehub收到图片消息/视频消息,上报基本信息(此时wehub仅仅通过report_new_msg上报该图片的索引file_index值,不上传具体文件的二进制信息)
2.回调接口根据file_index的值查询当前服务端文件存储系统中是否已经存在该索引的文件,若需要wehub上传,在ack中携带上传文件的任务类型:
比如
{
"error_code": 0,
"error_reason": "",
"ack_type":"common_ack",
"data":
{
"reply_task_list":
[
{
"task_type": 9,
"task_dict":
{
"file_index":"xxxxxxx"
}
}
]
}
}
3.wehub收到指令后通过文件上传接口上传文件(post 方式)
4.上传接口返回文件处理的结果
{
'error_code':0,
'error_reason':'',
'ack_type':'upload_file_ack',
'file_index':file_index //接收到的文件的file_index
}
以下为 wehub向上传接口上传图片文件的http request示例(Content-Type: multipart/form-data)
Content-Type: multipart/form-data; boundary="boundary_.oOo._OTg2Ng==MzU3Mg==MjEwNzE="
MIME-Version: 1.0
Content-Length: 46718
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en,*
User-Agent: Mozilla/5.0
Host: localhost.:5678
--boundary_.oOo._OTg2Ng==MzU3Mg==MjEwNzE=
Content-Type: text/plain
Content-Disposition: form-data; name="file_index"
3053020100044c304a02010002041cdc709b02032f56c10204a2e5e77302045b87dcfa0425617570696d675f356665376666383735333737623337355f313533353633303538353633390204010400020201000400
--boundary_.oOo._OTg2Ng==MzU3Mg==MjEwNzE=
Content-Type: image/jpeg
Content-Disposition: form-data; name="file";filename="6a0b2e8d81857cd9ac7cf4fcb6ac271fd409fc1d.jpg"
xxxxxxxxxxxxxxx..... //图片的二进制字节流
xxxxxxxxxxxxxxx.....
上传视频
Content-Type: multipart/form-data; boundary="boundary_.oOo._MTQ5NDU=Mjg1Nzk=MTAyNzE="
MIME-Version: 1.0
Content-Length: 1351338
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en,*
User-Agent: Mozilla/5.0
Host: localhost.:5678
--boundary_.oOo._MTQ5NDU=Mjg1Nzk=MTAyNzE=
Content-Type: text/plain
Content-Disposition: form-data; name="file_index"
306b0201000464306202010002041cdc709b02032f56c10204cde5e77302045b99fc32043d617570766964656f5f356665376666383735333737623337355f313533363831383232345f3137353730343133303931383637613066633434323433300204010400040201000400
--boundary_.oOo._MTQ5NDU=Mjg1Nzk=MTAyNzE=
Content-Type: video/mp4
Content-Disposition: form-data; name="file";filename="c899cebad9877280af73d4e595f5d1e41e7b1ed8.mp4"
xxxxxxxxxxxxxxx..... //视频文件的二进制字节流
xxxxxxxxxxxxxxx.....
上传语音
Content-Type: multipart/form-data; boundary="boundary_.oOo._NDM2NQ==NTkyNQ==MzE1ODQ="
MIME-Version: 1.0
Content-Length: 2993
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en,*
User-Agent: Mozilla/5.0
Host: localhost.:5678
--boundary_.oOo._NDM2NQ==NTkyNQ==MzE1ODQ=
Content-Type: text/plain
Content-Disposition: form-data; name="file_index"
4166303733643135323139616165340028224211291867a0fc48766102
--boundary_.oOo._NDM2NQ==NTkyNQ==MzE1ODQ=
Content-Type: audio/mpeg
Content-Disposition: form-data; name="file";filename="274cfbce78d88c83a9d0bd7d0cda9fe3c2da2d64.mp3"
xxxxxxxxxxxxxxx..... //mp3文件的二进制字节流
xxxxxxxxxxxxxxx.....
注意: 1.服务端的上传接口接收到wehub的request后需要取出 request中 file_index的值. 2.目前wehub支持上传图片/视频类型的文件,但wehub的文件上传功能并不是一个完全可靠的服务,当微信中的图片/视频没有下载完成时,wehub是无法上传这些文件的.
收到添加好友的请求(此时对方还不是我的好友,不能给对方发消息) 微信系统对每个账号每天通过的好友请求有限制(每天200左右) 服务端需要储存(v1,v2) 值, 以便通过任务下发的方式通过好友验证
request
{
"action" : "report_friend_add_request",
"appid": "xxxxxxx",
"wxid" : "wxid_fo1039029348sfj",
"data" : {
"v1":"xxxxxx", //若要自动通过,请在ack中回传
"v2":"xxxxxxx", //若要自动通过,请在ack中回传
"notice_word":"xxxxxxx", //新好友加我时的打招呼的内容,可能为空
"raw_msg":"xxxxxxxxxxx" //微信中的原始消息,xml格式
}
}
若要自动通过好友验证,可在reply_task_list字段中加入"通过好友验证"的任务(task_type为13)
respone格式为[common_ack格式]
当某个好友被删除了会上报该事件
request格式
{
"action":"report_friend_removed",
"appid": "xxxxxxx",
"wxid": "xxxxxxx",
"data":{
"wxid_removed":"xxxxxx" //被删除的好友的wxid
}
}
respone格式为[common_ack格式]
每当有新的好友时,上报新好友的个人信息(此时对方已经成为了我的好友)
request格式
{
"action" : "report_new_friend",
"appid": "xxxxxxx",
"wxid" : "xxxxxx",
"data" : {
"fans_wxid": "wxid_ljsdlfjslfjl", // 新好友的wxid
"nickname": "Jerry", // 新好友的昵称
"wx_alias": "jerry" // 新好友的微信号,可能为空
"head_img": "xxxxx", //头像url
"notice_word": "xxxxxxx" //新好友加我时的打招呼的内容,可能为空
"sourceusername": "xxxxx" //推荐人的wxid,可能为空
"sourcenickname":"xxxxxxx" //推荐人昵称,可能为空
}
}
respone格式为[common_ack格式]
{:#task}
回调接口在 respone中下发的任务格式
| 任务类型 | 类型值task_type |
|---|---|
| 发消息 | 1(只支持文字,图片,链接,视频,个人名片) |
| 踢人 | 2 |
| 邀请入群(发送入群邀请) | 3 |
| 上报群成员信息 | 4 |
| 加群成员为好友 | 5 |
| 修改好友备注 | 6 |
| 修改群昵称 | 7 |
| 退群 | 8 |
| 上传文件 | 9 |
| 发群公告 | 10 |
| 自动收账 | 11 |
| 删除好友 | 12 |
| 通过好友验证 | 13 |
| 重新上报当前好友列表和群列表 | 14 |
| 检测某个wxid是否是僵尸 | 15 |
| 获取指定wxid的详情 | 16 |
| 创建群 | 17 |
| 修改群名称 | 18 |
| 接受入群邀请 | 19 |
当你在微信中发送一个的静态的
(向一个微信群或一个微信号发一组消息单元)
{
"task_type": 1,
"task_dict":
{
"wxid_to":"xxxxxx", //消息发往的对象(群微信号或者个人微信号)
"at_list":['xxxx','xxxx'], //发群消息时,需要@的对象的wxid列表,可以为空
//at_list对msg_list里所有的文本消息生效
"msg_list":[$push_msgunit,$push_msgunit,....] //待发送的消息单元列表
"at_style": xx //0或者1, 默认为0. 该字段在0.4.2中新增.
}
}
发消息任务中的$push_msgunit格式
⑴文字消息
{
'msg_type':1,
'msg': "xxxxxx" //发送的文字(可以嵌入转义的静态表情文字,参阅上方的链接 静态表情转义对照表)
}
⑵图片消息
{
'msg_type':3,
'msg':"xxxx" //图片的url绝对地址:http://xxxxxxx/xx.jpg或png
}
⑶gif表情 //从0.3.0开始支持
{
"msg_type":47,
"msg":"http://xxxxxxx/xx.gif" //gif的url:必须是gif格式
}
⑷链接消息
{
"msg_type":49, //49 代表链接消息
"link_url":"http://xxxxx", //分享链接的url
"link_title":"标题", //链接标题
"link_desc": "副标题", //链接描述(副标题)
"link_img_url": "http://xxxxxxx" //链接的缩略图的的Url,jpg或者png格式
}
⑸视频消息
{
"msg_type":43,
"video_url":"http://xxxxxxx/xx.mp4" //视频的url地址(必须是mp4格式,其他格式会当成普通文件发送)
}
⑹文件消息
发文件消息(文件格式无限制)同发视频消息,只需将video_url的值换成要发送的文件的url的地址即可.
例如要发送某个pdf文件:https://archive.apache.org/dist/httpd/docs/httpd-docs-2.4.16.en.pdf
{
"msg_type":43,
"video_url":"https://archive.apache.org/dist/httpd/docs/httpd-docs-2.4.16.en.pdf" //文件的url地址
}
语音消息
暂时无法支持发送语音消息
⑺个人名片
{
"msg_type":42,
"wxid_card":"xxxxxx" //个人号/公众号的wxid
}
⑻发小程序
//前提:wehub所管理的微信客户端必须支持小程序
{
"msg_type":4901,
"raw_msg":"xxxxxxxx", //小程序的raw_msg是一串xml格式的文本 [见"上报的消息单元"-->"小程序"中的raw_msg字段]
//服务端可以存储这个raw_msg(不要做任何修改,这很重要!!!)之后用于小程序转发
"cover_url": "http://xxxxxxxx" //小程序的封面图片的的url
//请保证url有效能被正常下载,否则转发的小程序接受者将看不到封面
}
关于'@'符号的位置
只针对发往群的文本消息有效
在0.4.2版本之前,wehub是默认把@符号放在文本消息的最前面的.
从0.4.2版本开始,支持把'@'放在文本消息的任意位置,具体操作如下:
1.发消息任务中的at_style字段设置为1
2.文本消息的msg的内容中设置占位字符串 {$@},这些字符的位置就是最终的@符号所在的位置
{
"task_type": 1,
"task_dict":
{
"wxid_to":"xxxxxx",
"at_list":["wxid_a","wxid_b"], //假设这两个被@的微信号的群昵称分别为aa,bb
"msg_list":[
{
'msg_type':1,
'msg':"test,你好{$@},你好{$@}.早上好"
}
]
"at_style": 1 //注意这里必须为1.
}
}
则wehub收到后,则实际发送的内容为 "test,你好@ aa,你好@ bb.早上好"(占位符被替换了)
注意at_list不能为空,at_style必须为1,占位字符串的数量必须和at_list中的微信数量相等.
当at_style为0时仍然按照以往的方式(@符号放在文本最前面,此时发送文本总即使有{$@}占位符wehub也不会进行替换)进行发送
- 踢人任务:
(把一个微信号从指定的群踢出,当前微信必须有踢人权限(为群主或者群管理员))
{
"task_type":2,
"task_dict":
{
"room_wxid":"xxxxx@chatroom", //被踢者所在的群,如果为空,则从所有的群踢出
"wxid":"xxxxxxx" //被踢者的wxid
}
}
- 拉群任务:
(向一个好友发入群邀请,注意必须是自己的好友)
{
"task_type":3,
"task_dict":
{
"room_wxid":"xxxxx@chatroom", //目标群
"wxid":"xxxxxxx" //被拉进群的wxid
"flag":x //0.4.12新增.
//默认为0:向好友发入群邀请链接
//值为1:不发入群邀请链接,而是直接将好友拉到群里(当群人数超过40时,该方法会失败)
}
}
- 上报群成员信息:
(上报某个群里所有的群成员的详细信息,如果群成员比较多,上报的数据量会比较大)
{
"task_type":4,
"task_dict":
{
//要上报的群列表
"room_wxid_list":["xxxxx@chatroom","xxxxx2@chatroom"....]
}
}
wehub 通过report_room_member_info来主动上报,详情见[上报群成员详细信息]
- 加群成员为好友:
{
"task_type":5,
"task_dict":
{
"room_wxid":"xxxxx@chatroom", //群wxid,可以留空
"wxid":"xxxxxxx" //要加谁为好友,不能为空
"msg":"xxxxxx" //打招呼消息,文本
}
}
- 修改好友备注:
{
"task_type":6,
"task_dict":
{
"wxid":"xxxxxx", //好友微信
"remark_name":"xxxxxx" //好友备注
}
}
- 修改群昵称:
(修改当前微信号在某个群里的群昵称)
{
"task_type":7,
"task_dict":
{
"room_wxid":"xxxxxx", //微信群wxid
"room_nickname":"xxxxxx" //我在这个群里的昵称
}
}
- 退群:
{
"task_type":8,
"task_dict":
{
"room_wxid":"xxxxxx", //要退出的微信群wxid
}
}
- 上传文件
{
"task_type":9,
"task_dict":
{
"file_index":"xxxxxxx", //需要上传的文件的file_index
}
}
//第三方需要将wehub上传的文件保存起来,建立file_index与上传文件的对应关系
- 发群公告
{
"task_type":10,
"task_dict":
{
"room_wxid":"xxxxxx", //微信群
"msg":"xxxxxx" //群公告的内容
}
}
- 自动收账 (只能收取别人发给自己的转账)
{
"task_type":11,
"task_dict":
{
"wxid_from": "xxxxxx" //转账发起者wxid
"transferid":"xxxxxx" //transferid:自动收哪一笔转账
}
}
- 删除好友
{
"task_type":12,
"task_dict":
{
"wxid_delete": "xxxxx" //要被删除的好友的wxid
}
}
- 通过好友验证
{
"task_type":13,
"task_dict":
{
"v1": "xxxxx",
"v2": "xxxxx"
}
}
- 重新上报联系人 (wehub会重新发送report_contact)
{
"task_type":14,
"task_dict":{
"flag_report_contact": xxxxx //0.4.9中新增,含义与login_ack中flag_report_contact含义相同
}
}
- 僵死粉检测 (检测结果通过report_zoom_check_status上报)
{
"task_type":15
"task_dict":
{
"wxid":"xxxxx" //待检测的wxid
}
}
- 获取指定wxid的详情(结果通过report_user_info上报)
{
"task_type":16,
"task_dict":
{
"wxid":"xxxxx" //要获取其详情的个人号的wxid
}
}
- 创建群(新建群聊)
{
"task_type":17,
"task_dict":
{
"member_list":["xxxx","xxxx"....]
// member_list里面是要添加群聊的人员的微信id,如果不是微信id,可能添加失败
// member_list里不用包含自己的微信id(创建的群聊默认是包含当前微信id的)
// 由于群聊必须至少3个人, 因此member_list里必须包含至少2个好友的wxid.
}
注:每个微信号每天能创建的群是有上限的,无限制的创建群会带来封号风险,该任务只支持2.6.8.52及以上版本的微信.
- 给群重命名
{
"task_type":18,
"task_dict":
{
"room_wxid":"xxxxx@chatroom" //群的wxid
"room_name":"xxxxx" //新群名称
}
}
- 接受入群邀请
{
"task_type":19,
"task_dict":
{
"invite_url":"http://support.weixin.qq.com/xxxx" //入群链接的地址 (该值从上报的入群链接消息的link_url字段中获取)
}
}
注:为安全起见,不要在短时间内接收多个群的邀请.
- 操作标签(新增,删除标签)
{
"task_type":100,
"task_dict":
{
"tag_name":"xxxxx", //被操作的标签名
"wxid_list":["wxid_xxx","wxid_xxx"] //群或者好友的wxid(不能包含陌生人)
"op_code" : xx // 1:将wxid_list加入到tag_name标签中(如果没有这个标签则新建这个标签)
// 2:将wxid_list中的成员从tag_name标签中删除
// 3:删除tag_name标签(此时会忽略wxid_list参数)
}
}
- 重命名标签
(将old_tag_name标签重命名为new_tag_name)
{
"task_type":101,
"task_dict":
{
"old_tag_name": "xxxx",
"new_tag_name":"xxxx"
}
}
触发时机: 无论是操作客户端主动开始检测或者下发任务让客户端被动检测,都会上报检测到的结果.
request格式
{
"action":"report_zoom_check_status",
"appid": "xxxxxxx",
"wxid": "xxxxxxx",
"data":
{
"wxid":"xxxxxx",//被检测的wxid
"result": x //0 :正常状态(不是僵尸粉)
//1 :检测为僵尸粉(对方把我拉黑了)
//2 :检测为僵尸粉(对方把我从他的好友列表中删除了)
}
}
respone格式为[common_ack格式]
wehub在appid验证通过以后,每间隔x秒请求一次(时间间隔可在wehub后台设置.若无需轮询,则设置任务轮询间隔 为0秒) request格式
{
"action": "pull_task",
"appid": "xxxxxx",
"wxid" : "wxid_xxxxxxxx",
"data":{}
}
respone格式
{
"error_code": 0,
"error_reason": "",
"ack_type":"pull_task_ack",
"data":
{
//wehub通过task_id来识别不同的任务(task_id其值是由回调接口生成的字符串,请保证有唯一性)
"task_id": "任务id", //字符串
"task_data": $task //单个任务
}
}
注: $task是一个json对象,代表一个要下发给wehub执行的任务,格式见 [任务类型格式],wehub接收到任务以后,会立即开始执行,执行完成后会把结果异步地反馈给回调接口(通过report_task_result)
示例
通过pull_task_ack 向wehub下发一个任务(该任务将wxid_abc从群bcdef@chatroom 中踢出)
{
"error_code": 0,
"error_reason": "",
"ack_type":"pull_task_ack",
"data":
{
"task_id": "aaaa111222",
"task_data":
{
"task_type":2,
"task_dict":
{
"room_wxid":"bcdef@chatroom",
"wxid":"wxid_abc"
}
}
}
}
request格式
{
"action": "report_task_result",
"appid": "xxxxxxx",
"wxid" : "wxid_xxxxxxxx"
"data":
{
"task_id": "任务id",
"task_result": 1, //0,任务执行失败,1任务执行成功
"error_reason": "" //为什么执行失败,若任务执行成功则为空
}
}
任务执行成功只意味着wehub"调用了底层的相关接口向微信发送了数据"(wehub能做的也只能到这里). 但微信后台会对数据/(微信号的用户行为)做各种判断和过滤,若触发了微信的相关限制,最终的结果会是失败的(比如发送了一段含政治敏感的聊天文本,微信检测到了会拦截这则消息,对方会无法收到这则消息),这种行为的结果wehub是无法检测和无法影响到的.
respone格式为[common_ack格式]
上报具体某个微信的详情 request格式
{
"action":"report_user_info",
"appid": "xxxxxxx",
"wxid" : "wxid_xxxxxxxx"
"data":
{
"wxid": "xxxxx", //wxid
"wx_alias": "xxxxx", //有可能为空
"nickname":"xxxxx", //微信昵称
"remark_name" :"xxxx", //好友备注
"head_img":"http://xxxxxxxx" //头像的url地址(有可能获取不到为空)
"head_img_data":"xxxxxxxxxx" //头像的二进制数据(JPEG/JFIF格式)经过base64编码后的字符串
"sex" : xx , //性别:0未知,1 男, 2 女
"country":"xxx", //祖国(可能为空)
"province":"xxxx", //省份(可能为空)
"city":"xxxxx" //城市(可能为空)
"is_friend": x //是否是我的好友,0:不是;1:是
"room_list":["xx","xxx"] //该微信号所在的群的列表
}
}
如果能获取到头像的url地址(head_img),则head_img_data为空
-
wehub主动上报的消息与服务端下发的任务的区别
(1).前者是在http request中(通过report_xxxxx),数据从wehub流向server;后者是在http respone中(通过common_ack 或者pull_task_ack),数据由服务端流向wehub
(2).二者的格式不样,前者的消息格式见[上报的消息单元的格式];后者的任务格式见 [任务类型格式]
前者的消息主要是视觉可感知的数据(如文本,图片) ,而后者的任务除了发消息,还包括很多不可感知的事件(如踢人出群,删除好友等)
-
common_ack 与 pull_task_ack 的区别:
common_ack中可携带多个下发的任务(data中有reply_task_list字段),但不会上报任务执行的结果
pull_task_ack只能下发一个任务(data中没有reply_task_list字段),且必须有task_id字段,通过pull_task_ack 下发的任务会通report_task_result 上报任务执行的结果;
common_ack 与pull_task_ack中的任务格式都是一样的,见 [任务类型格式]
wehub会先发送login request到当前回调地址,然后尝试从respone中寻找extension_protocol字段, 并获取到要去连接的websocket服务器的真实ws地址(格式为ws://xxxx或者wss://xxxx,和原有的http回调地址不一样). 这样做的好处是把目前的回调接口当做跳板,并且可以配置多个ws地址进行负载均衡.
回调接口在收到wehub发送的login请求后返回如下(如果测试的话可以只对特定的wxid才返回这个ws地址)
{
"error_code": 0,
"error_reason": "",
"ack_type":"login_ack",
"data":
{
"signature":"xxxxxxxxxxx" //返回给wehub客户端的签名(同上)
"extension_protocol":
{
"type":"websocket", //目前只能是"websocket"
"param":
{
"ws_url":"ws://127.0.0.1:3456/ws", //ws服务地址
"heartbeat_interval":30 //心跳时间间隔(秒)
}
}
}
}
心跳包格式如下
{
"atcion":"heartbeat",
"appid": "xxxxx",
"wxid": "xxxx",
"data":{}
}
更多的问题请参考faq





