88 Star 175 Fork 0

Allen / wechat4j

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
web-weixin-api.md 31.36 KB
一键复制 编辑 原始数据 按行查看 历史
Allen 提交于 2019-04-18 17:11 . [update] 微信API文档修正

Web微信API文档

1、登录

Web微信登录页面是https://wx.qq.com,以下内容以此页开始。

1.1、获取登录uuid

进入Web微信登录页面后,在开发者工具中查看网络请求情况,可以发现在二维码图片加载之前,浏览器发送了一次 GET 请求:

https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=1532078129220

该请求用于获取登录uuid,分析发现有如下URL参数:

参数名 示例值 描述
appid wx782c26e4c19acffb 这个值不变,表示来自Web版微信;
redirect_uri https%3A%2F%2Fwx2.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage 跳转页面;非必须值;
fun new 固定值;
lang zh_CN 语言;zh_CN表示中文;
_ 1532078129220 13位时间戳;

然后服务器返回数据:

window.QRLogin.code = 200; window.QRLogin.uuid = "wcXrINkB9Q==";
  • window.QRLogin.code的值为200时表示成功,为其它值均表示失败。
  • window.QRLogin.uuid的值为获取到的uuid,每次刷新会获取到不同的uuid,实际上uuid是服务端用来标识每一次登录的。

1.2、获取二维码

接着会发现如下 GET 请求:

https://login.weixin.qq.com/qrcode/wcXrINkB9Q==

该url为二维码图片的链接,url尾部的字符串即是上面获取到的uuid。

1.3、等待确认登录

在获取二维码的请求之后,会发现如下 GET 请求:

https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=wcXrINkB9Q==&tip=0&r=1223005686&_=1532080293141

这是等待扫描登录并获取跳转url的请求。如果没有及时扫描二维码,一定时间后该请求会重复出现,表示浏览器在轮询请求。

URL参数分析:

数名 示例值 描述
loginicon true 固定值;
uid wcXrINkB9Q== 同前面的uuid;
tip 0或1 0表示等待用户扫码确认;1表示等待用户直接确认,用于push登陆时;
r 1223005686 10位随机数
_ 1532080293141 13位时间戳;

如果没有及时扫描二维码,服务器返回数据:

window.code=408;
  • 表示没有轮询到认证信息,此时需要再次发送该请求。

如果一直没有扫描二维码,服务器返回数据:

window.code=400;
  • 表示该次登录uuid失效,即二维码失效,此时会停止轮询,需要重新获取uuid才能继续。

及时扫码认证之后,在点击确认登录之前,服务器返回数据:

window.code=201;
  • 表示微信APP端已经扫码,但还没有点击确认。

及时扫码并点击确认之后,服务器返回:

window.code=200;
window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A51bGY49nxxxxxxx1wNPC3@qrticket_0&uuid=wcXrINkB9Q==&lang=zh_CN&scan=1532083897";
  • window.code的值为200表示APP端认证成功。
  • window.redirect_uri为需要跳转的url。

1.4、获取登录认证码

微信APP端认证后,会产生的新的 GET 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A51bGY49nxxxxxxx1wNPC3@qrticket_0&uuid=wcXrINkB9Q==&lang=zh_CN&scan=1532083897&fun=new&version=v2

我们发现该请求即是上一步认证成功之后得到的redirect_uri再拼上&fun=new&version=v2。 该请求发送之后,其它web或pc端登录的微信会被踢下线。

URL参数分析:

数名 示例值 描述
ticket A51bGY49nxxxxxxx1wNPC3@qrticket_0 保存不变即可;
uuid wcXrINkB9Q== 同前面的uuid;
lang zh_CN 语言;zh_CN表示中文;
scan 1532083897 用户扫描的时间戳;
fun new 固定值;
version v2 固定值;

服务器返回数据:

<error>
    <ret>0</ret>
    <message></message>
    <skey>@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp</skey>
    <wxsid>8rwxxxxxxxxxHq2P</wxsid>
    <wxuin>26xxx7</wxuin>
    <pass_ticket>AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn=</pass_ticket>
    <isgrayscale>1</isgrayscale>
</error>

(为了个人隐私,以上返回数据有打码)

  • ret表示请求返回状态,0表示成功。
  • skey、wxsid和wxuin都是具体微信用户的信息,不会变化,在后续的通讯中需要用到。
  • pass_ticket在初始化页面时需要用到。

1.5、退出登录

如果点击退出,我们会发现先后出现如下两个 POST 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=0&skey=%40crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1&skey=%40crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp

这两个请求唯一的区别就是type的值,先是0再是1。

URL参数分析:

数名 示例值 描述
redirect 1 固定值;
type 0或1 0或1,固定值;
skey %40crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp 登录时获取的;需要urlencode。

FORM表单参数分析:

参数名 示例值 描述
sid 登录时获取的;
uin 登录时获取的;

服务器返回数据:

  • 该请求会导致页面跳转,没有返回数据。

1.6、push登录

点击退出后,页面会出现点击直接登录的页面,点击登录之后,会发现产生一个叫webwxpushloginurl的 GET 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxpushloginurl?uin=26xxx7

该请求是不扫码获取uuid的方式,仅用在手动退出登录之后,uuid获取之后还是继续1.3的等待确认。

URL参数分析:

数名 示例值 描述
uin 26xxx7 同前面获取的uin;

服务器返回数据:

{
    "ret": "0",
    "msg": "all ok",
    "uuid": "A_1_xxxw=="
}
  • ret为0表示成功,为1表示uin错误等失败。
  • uuid为新的uuid。经过反复“退出-push登录-退出-push登录”测试发现,全程uin保持不变,uuid会变化。

2、数据同步

2.1、页面初始化

上面已经拿到了用户认证码,接着需要登录并初始化页面。

初始化页面就是向服务端请求常用的联系人等信息,如下 POST 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=1219172280&lang=zh_CN&pass_ticket=AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn=

URL参数分析:

数名 示例值 描述
r 1219172280 10位随机数;
lang zh_CN 语言;zh_CN表示中文;
pass_ticket AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn= 上一步获取到的;

POST的数据(JSON):

{
    "BaseRequest": {
        "DeviceID": "e659xxxxxxxx3006",
        "Sid": "8rwxxxxxxxxxHq2P",
        "Skey": "@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
        "Uin": "26xxx7"
    }
}

POST参数分析:

数名 示例值 描述
BaseRequest.DeviceID e659xxxxxxxx3006 设备ID,e拼上15位随机串;
BaseRequest.Sid rwxxxxxxxxxHq2P 上一步获取到的wxsid;
BaseRequest.Skey crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp 上一步获取到的skey;
BaseRequest.Uin 6xxx7 上一步获取到的wxuin;

服务器返回数据:

{
    "BaseResponse": {
        "Ret": 0,
        "ErrMsg": ""
    },
    "Count": 11,
    "ContactList": [{
        "Uin": 0,
        "UserName": "filehelper",
        "NickName": "...",
        "HeadImgUrl": "...",
        "ContactFlag": 5,
        "MemberCount": 0,
        "MemberList": [],
        "RemarkName": "",
        "HideInputBarFlag": 0,
        "Sex": 0,
        "Signature": "",
        "VerifyFlag": 0,
        "OwnerUin": 0,
        "PYInitial": "WJCSZS",
        "PYQuanPin": "wenjianchuanshuzhushou",
        "RemarkPYInitial": "",
        "RemarkPYQuanPin": "",
        "StarFriend": 0,
        "AppAccountFlag": 0,
        "Statues": 0,
        "AttrStatus": 0,
        "Province": "",
        "City": "",
        "Alias": "",
        "SnsFlag": 0,
        "UniFriend": 0,
        "DisplayName": "",
        "ChatRoomId": 0,
        "KeyWord": "fil",
        "EncryChatRoomId": "",
        "IsOwner": 0
    }],
    "SyncKey": {
        "Count": 4,
        "List": [{
            "Key": 1,
            "Val": 704152857
        }, {
            "Key": 2,
            "Val": 704152894
        }, {
            "Key": 3,
            "Val": 704152870
        }, {
            "Key": 1000,
            "Val": 1532075042
        }]
    },
    "User": {
        ...
    },
    "ChatSet": "...",
    "SKey": "@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
    "ClientVersion": 3697797,
    "SystemTime": 1132000000,
    "GrayScale": 1,
    "InviteStartCount": 40,
    "MPSubscribeMsgCount": 0,
    "MPSubscribeMsgList": [],
    "ClickReportInterval": 600000
}
  • BaseResponse.Ret表示请求返回状态,0表示成功。
  • ContactList为最近联系人列表。联系人的UserName以一个@开头为好友,两个@为群组。
  • MPSubscribeMsg为公众号订阅消息。
  • User是当前登录账户信息。

2.2、开启消息状态通知

接着需要开启消息状态通知。我们可以看到如下 POST 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN&pass_ticket=AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn=

URL参数分析:

数名 示例值 描述
lang zh_CN 语言;zh_CN表示中文;
pass_ticket AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn= 同前面;

POST的数据(JSON):

{
	"BaseRequest": {
		"DeviceID": "e81xxxxxxxxx7686",
		"Sid": "8rwxxxxxxxxxHq2P",
        "Skey": "@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
        "Uin": "26xxx7"
	},
	"ClientMsgId": 1532xxxxx3374,
	"Code": 3,
	"FromUserName": "@56a0a9xxxxxxxxxxxxx54w0dxxxxbfab",
	"ToUserName": "@56a0a9xxxxxxxxxxxxx54w0dxxxxbfab"
}

POST参数分析:

参数名 示例值 描述
BaseRequestB {
"DeviceID":"e81xxxxxxxxx7686",
"Sid":"8rwxxxxxxxxxHq2P",
"Skey":"@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
"Uin":"26xxx7"
}
每一次POST请求都会发送BaseRequest;其中DeviceID是字母e拼上15位随机字符串,其余三个都是前面获取到的认证信息。
ClientMsgId 1532xxxxx3374 13位时间戳;
Code 3 固定值;
FromUserName @56a0a9xxxxxxxxxxxxx54w0dxxxxbfab 页面加载时获取到的User.UserName;
ToUserName @56a0a9xxxxxxxxxxxxx54w0dxxxxbfab 同FromUserName;

服务器返回数据:

{
    "BaseResponse": {
        "Ret": 0,
        "ErrMsg": ""
    },
    "MsgID": "2271xxxxxxxxxxxxx44"
}
  • BaseResponse.Ret表示请求返回状态,0表示成功。

2.3、服务端状态同步

继续观察,我们没间隔一定的时间,浏览器会想服务器发送一个重复的 GET 请求:

https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck?r=1532145313248&skey=%40crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp&sid=8rwxxxxxxxxxHq2P&uin=26xxx7&deviceid=e35077xxxx772148&synckey=1_704152857%7C2_704152996%7C3_704152955%7C1000_1532127722&_=1532145290777

该请求是轮询向服务器获取最新在线、消息等状态的。

URL参数分析:

数名 示例值 描述
r 1532145313248 13位时间戳;
skey %40crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp 同前面;需要urlencode;
sid 8rwxxxxxxxxxHq2P 同前面;
uin 26xxx7 同前面;
deviceid e35077xxxx772148 设备ID,e拼上15位随机串;
synckey 1_704152857%7C2_704152996%7C3_704152955%7C1000_1532127722 由初始化登录页面信息返回串中Sync的list列表组成;需要urlencode;
_ 1532145290777 13位时间戳;

服务器返回数据:

window.synccheck={retcode:"0",selector:"2"}

返回数据分析:

名称 示例值 描述
retcode 0 表示当前在线状态。
0:正常
1100:失败/登出微信
1101:从其它设备登录微信
selector 2 表示消息状态。
0:正常
2:有新消息
4:目前发现修改了联系人备注会出现
7:手机操作了微信

3、联系人管理

3.1、获取全部联系人列表

接着可以看到获取全部联系人列表的 GET 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn%253D&r=1532190636970&seq=0&skey=@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp

URL参数分析:

参数名 示例值 描述
lang zh_CN 语言;
pass_ticket AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn%253D 同前面获取到的;
r 1532190636970 13位时间戳;
seq 0 固定值;
skey @crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp 同前面获取到的;

服务器返回数据:

{
    "BaseResponse": {
        "Ret": 0,
        "ErrMsg": ""
    },
    "MemberCount": 1,
    "MemberList": [{
        "Uin": 0,
        "UserName": "weixin",
        "NickName": "微信团队",
        "HeadImgUrl": "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=1&username=weixin&skey=@crypt_4fb399da_91a345e0be9deca5d61b183fc36a3a93",
        "ContactFlag": 1,
        "MemberCount": 0,
        "MemberList": [],
        "RemarkName": "",
        "HideInputBarFlag": 0,
        "Sex": 0,
        "Signature": "微信团队官方帕啷",
        "VerifyFlag": 56,
        "OwnerUin": 0,
        "PYInitial": "WXTD",
        "PYQuanPin": "weixintuandui",
        "RemarkPYInitial": "",
        "RemarkPYQuanPin": "",
        "StarFriend": 0,
        "AppAccountFlag": 0,
        "Statues": 0,
        "AttrStatus": 4,
        "Province": "",
        "City": "",
        "Alias": "",
        "SnsFlag": 0,
        "UniFriend": 0,
        "DisplayName": "",
        "ChatRoomId": 0,
        "KeyWord": "wei",
        "EncryChatRoomId": "",
        "IsOwner": 0
    }],
    "Seq": 0
}
  • BaseResponse.Ret为0表示请求成功。
  • MemberCount表示联系人总数。
  • MemberList表示联系人列表。这个列表中同时包含好友、群组、公众号。好友和公众号是通过ContactFlag来区分的,1是好友,2是群组,3是公众号。
  • User内部字段介绍:
   "Uin": 0,
   "UserName": 用户名称一个"@"为好友两个"@"为群组
   "NickName": 昵称
   "HeadImgUrl":头像图片链接地址
   "ContactFlag": 1-好友 2-群组 3-公众号
   "MemberCount": 成员数量只有在群组信息中才有效,
   "MemberList": 成员列表,
   "RemarkName": 备注名称
   "HideInputBarFlag": 0,
   "Sex": 性别0-未设置公众号保密),1-2-
   "Signature": 公众号的功能介绍 or 好友的个性签名
   "VerifyFlag": 0,
   "OwnerUin": 0,
   "PYInitial": 用户名拼音缩写
   "PYQuanPin": 用户名拼音全拼
   "RemarkPYInitial":备注拼音缩写
   "RemarkPYQuanPin": 备注拼音全拼
   "StarFriend": 是否为星标朋友  0-  1-
   "AppAccountFlag": 0,
   "Statues": 0,
   "AttrStatus": 119911,
   "Province": 
   "City": 
   "Alias": 
   "SnsFlag": 17,
   "UniFriend": 0,
   "DisplayName": "",
   "ChatRoomId": 0,
   "KeyWord": 
   "EncryChatRoomId": ""

3.2、批量获取指定用户信息

然后可以看到批量获取指定联系人信息的 POST 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact?type=ex&r=1532246093335&lang=zh_CN&pass_ticket=AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn%253D

该请求用于批量获取好友信息,或者批量获取群聊中的成员信息。

URL参数分析:

参数名 示例值 描述
type ex 不知道什么意思;
r 1532246093335 13位时间戳;
lang zh_CN 语言;
pass_ticket AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn%253D 前面获取到的;

POST的数据(JSON):

{
	"BaseRequest": {
		"DeviceID": "e81xxxxxxxxx7686",
		"Sid": "8rwxxxxxxxxxHq2P",
		"Skey": "@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
		"Uin": "26xxx7"
	},
	"Count": 2,
	"List": [
        {
			"EncryChatRoomId": "",
			"UserName": "@@76feaa87c63576aaxxxxxxxxeaaa7030c60a09d33"

		},
		{
			"ChatRoomId": "",
			"UserName": "@@55664b9ab69bbe5e6aaxxxxxxxxx778c17e11e9dab09c9a1"

		}
	]
}

POST参数分析:

参数名 示例值 描述
BaseRequest 基本请求参数,同前面;
Count 要进行批量查询的用户数;
List 批量指定要查询的UserName的列表;如果要获取好友信息,EncryChatRoomId或ChatRoomId为空,UserName为好友的UserName;如果要获取群聊成员的信息,EncryChatRoomId或ChatRoomId为群聊的UserName,UserName为成员的UserName。

服务器返回数据:

{
    "BaseResponse": {
        "Ret": 0,
        "ErrMsg": ""
    },
    "Count": 2,
    "ContactList": [{
        "Uin": 0,
        "UserName": "@@76feaa87c635763438059aaeaaa7030c60a09d33",
        "NickName": "一啣ç<span class=\"emoji emoji1f525\"></span>¾¤)",
        "HeadImgUrl": "/cgi-bin/mmwebwx-bin/webwxgetheadimg?seq=704138898&username=@@76feaa87c635763438059aaeaaa7030c60a09d33&skey=",
        "ContactFlag": 3,
        "MemberCount": 80,
        "MemberList": [{
            "Uin": 0,
            "UserName": "@3a13860046f9f5cac66faba26f2bd0537f535",
            "NickName": "龎",
            "AttrStatus": 2147437,
            "PYInitial": "",
            "PYQuanPin": "",
            "RemarkPYInitial": "",
            "RemarkPYQuanPin": "",
            "MemberStatus": 0,
            "DisplayName": "",
            "KeyWord": ""
        }, ...],
        "RemarkName": "",
        "HideInputBarFlag": 0,
        "Sex": 0,
        "Signature": "",
        "VerifyFlag": 0,
        "OwnerUin": 0,
        "PYInitial": "",
        "PYQuanPin": "",
        "RemarkPYInitial": "",
        "RemarkPYQuanPin": "",
        "StarFriend": 0,
        "AppAccountFlag": 0,
        "Statues": 0,
        "AttrStatus": 0,
        "Province": "",
        "City": "",
        "Alias": "",
        "SnsFlag": 0,
        "UniFriend": 0,
        "DisplayName": "",
        "ChatRoomId": 0,
        "KeyWord": "",
        "EncryChatRoomId": "@5fd8877457351e3a697",
        "IsOwner": 0
    }, {
        "Uin": 0,
        "UserName": "@f7dee38d1c3626c0e421c1f66deac0906559ac",
        "NickName": "尕娅",
        "HeadImgUrl": "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=686458815&username=@f7dee38d1c3626c0e421c1f66deac0906559ac&skey=",
        "ContactFlag": 259,
        "MemberCount": 0,
        "MemberList": [],
        "RemarkName": "啢潧",
        "HideInputBarFlag": 0,
        "Sex": 2,
        "Signature": "ä½ è<span class=\"emoji emoji1f48b\"></span>",
        "VerifyFlag": 0,
        "OwnerUin": 0,
        "PYInitial": "XY",
        "PYQuanPin": "",
        "RemarkPYInitial": "",
        "RemarkPYQuanPin": "",
        "StarFriend": 0,
        "AppAccountFlag": 0,
        "Statues": 0,
        "AttrStatus": 1047,
        "Province": "å京",
        "City": "",
        "Alias": "",
        "SnsFlag": 49,
        "UniFriend": 0,
        "DisplayName": "",
        "ChatRoomId": 0,
        "KeyWord": "",
        "EncryChatRoomId": "0",
        "IsOwner": 0
    }]
}
  • ContactList即是获取到的指定的联系人信息。

3.3、修改联系人备注

当我们修改联系人备注的时候,会发现浏览器发送了如下 POST 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxoplog

POST的数据(JSON):

{
    "BaseRequest": {
        "DeviceID": "e81xxxxxxxxx7686",
        "Sid": "8rwxxxxxxxxxHq2P",
        "Skey": "@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
        "Uin": "26xxx7"
    },
    "CmdId": 2,
    "RemarkName": "新的备注名",
    "UserName": "@07a2e8b4a1f98eb78a7xxxxxxxxxxxx5b7bc4908376xxx05917b"
}

POST参数分析:

参数名 示例值 描述
BaseRequest 基本请求参数,同其它;
CmdId 2 固定值;有可能还有其它值来表示不同类型操作。
RemarkName 新的备注名;
UserName 要修改的联系人的UserName;

服务器返回数据:

{
    "BaseResponse": {
        "Ret": 0,
        "ErrMsg": ""
    }
}
  • BaseResponse.Ret表示操作成功。

4、收发消息

4.1、从服务端拉取新消息

我们发现2.4中的轮询请求每一次返回的数据中selector为2或者6时,都会发生如下的 POST 请求来从服务端获取新消息:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=8rwxxxxxxxxxHq2P&skey=@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp&pass_ticket=AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn%253D

URL参数分析:

参数名 示例值 描述
sid 8rwxxxxxxxxxHq2P 同前面获取的;
skey @crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp 同前面获取的;
pass_ticket AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn%253D 同前面获取的;

POST的数据(JSON):

{
    "BaseRequest": {
        "DeviceID": "e2089xxxxx902803",
        "Sid": "8rwxxxxxxxxxHq2P",
        "Skey": "@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
        "Uin": 26xxx7
    },
    "SyncKey": {
        "Count": 4,
        "List": [{
                "Key": 1,
                "Val": 704153081
            },
            {
                "Key": 2,
                "Val": 704153167
            },
            {
                "Key": 3,
                "Val": 704153152
            },
            {
                "Key": 1000,
                "Val": 1532180042
            }
        ]
    },
    "rr": 1112687259
}

POST参数分析:

参数名 示例值 描述
BaseRequest {
"DeviceID": "e81xxxxxxxxx7686",
 "Sid": "8rwxxxxxxxxxHq2P",
 "Skey": "@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
 "Uin": "26xxx7"
}
每一次POST请求都会发送
BaseRequest;其中DeviceID是字母e拼上15位随机字符串,其余三个都是前面获取到的认证信息。
SyncKey {
 "Count": ...,
 "List": [...]
}
前一次获取到的SyncKey;首次是初始化数据时获取的,zhiy之后都是通过本请求更新;

服务端返回数据:

{
    "BaseResponse": {
        "Ret": 0,
        "ErrMsg": ""
    },
    "AddMsgCount": 1,
    "AddMsgList": [{
        "MsgId": "462399962004142457",
        "FromUserName": "@56a0a9xxxxxxxxxxxxx54w0dxxxxbfab",
        "ToUserName": "@56a0a9xxxxxxxxxxxxx54w0dxxxxbfab",
        "MsgType": 51,
        "Content": "",
        "Status": 3,
        "ImgStatus": 1,
        "CreateTime": 1532190642,
        "VoiceLength": 0,
        "PlayLength": 0,
        "FileName": "",
        "FileSize": "",
        "MediaId": "",
        "Url": "",
        "AppMsgType": 0,
        "StatusNotifyCode": 4,
        "StatusNotifyUserName": "...",
        "RecommendInfo": {
            "UserName": "",
            "NickName": "",
            "QQNum": 0,
            "Province": "",
            "City": "",
            "Content": "",
            "Signature": "",
            "Alias": "",
            "Scene": 0,
            "VerifyFlag": 0,
            "AttrStatus": 0,
            "Sex": 0,
            "Ticket": "",
            "OpCode": 0
        },
        "ForwardFlag": 0,
        "AppInfo": {
            "AppID": "",
            "Type": 0
        },
        "HasProductId": 0,
        "Ticket": "",
        "ImgHeight": 0,
        "ImgWidth": 0,
        "SubMsgType": 0,
        "NewMsgId": 462399962004142457,
        "OriContent": "",
        "EncryFileName": ""
    }],
    "ModContactCount": 0,
    "ModContactList": [],
    "DelContactCount": 0,
    "DelContactList": [],
    "ModChatRoomMemberCount": 0,
    "ModChatRoomMemberList": [],
    "Profile": {
        "BitFlag": 0,
        "UserName": {
            "Buff": ""
        },
        "NickName": {
            "Buff": ""
        },
        "BindUin": 0,
        "BindEmail": {
            "Buff": ""
        },
        "BindMobile": {
            "Buff": ""
        },
        "Status": 0,
        "Sex": 0,
        "PersonalCard": 0,
        "Alias": "",
        "HeadImgUpdateFlag": 0,
        "HeadImgUrl": "",
        "Signature": ""
    },
    "ContinueFlag": 0,
    "SyncKey": {
        "Count": 7,
        "List": [{
            "Key": 1,
            "Val": 704153081
        }, {
            "Key": 2,
            "Val": 704153169
        }, {
            "Key": 3,
            "Val": 704153152
        }, {
            "Key": 11,
            "Val": 704152941
        }, {
            "Key": 201,
            "Val": 1532190642
        }, {
            "Key": 1000,
            "Val": 1532190561
        }, {
            "Key": 1001,
            "Val": 1532180114
        }]
    },
    "SKey": "",
    "SyncCheckKey": {
        "Count": 7,
        "List": [{
            "Key": 1,
            "Val": 704153081
        }, {
            "Key": 2,
            "Val": 704153169
        }, {
            "Key": 3,
            "Val": 704153152
        }, {
            "Key": 11,
            "Val": 704152941
        }, {
            "Key": 201,
            "Val": 1532190642
        }, {
            "Key": 1000,
            "Val": 1532190561
        }, {
            "Key": 1001,
            "Val": 1532180114
        }]
    }
}
  • AddMsgCount为新消息数目。
  • AddMsgList为新消息列表。
    • MsgType说明:
      • 1:文本消息
      • 3:图片消息
      • 34:语音消息
      • 37:VERIFYMSG(验证消息)
      • 40:POSSIBLEFRIEND_MSG(可能的朋友的消息)
      • 42:共享名片
      • 43:视频通话消息
      • 47:动画表情
      • 48:位置消息
      • 49:分享链接
      • 50:VOIPMSG(VoIP消息)
      • 51:微信初始化消息
      • 52:VOIPNOTIFY(VoIP通知)
      • 53:VOIPINVITE(VoIP邀请)
      • 62:小视频
      • 9999:SYSNOTICE(系统通知)
      • 10000:系统消息
      • 10002:撤回消息
  • SyncKey会暂存起来作为下一次请求的参数。

4.2、发送文本消息

打开一个聊天界面,向好友发送一条消息,会发现产生如下 POST 请求:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket=AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn%253D

URL参数分析:

参数名 示例值 描述
pass_ticket AFsdZ7eHxxxxxxxxxxxxxxxxfr1vjHPn%253D 同前面获取的;

POST的数据(JSON):

{
	"BaseRequest": {
		"DeviceID": "e57xxxxxxx94xx27",
		"Sid": "8rwxxxxxxxxxHq2P",
        "Skey": "@crypt_jkde99da_b4xxxxxxxxxxxxxxx76d9yualp",
        "Uin": "26xxx7"
	},
	"Msg": {
		"ClientMsgId": "15321964202620841",
		"Content": "这里是消息内容",
		"FromUserName": "@da9d7631177b3c54492954010eb7",
		"LocalID": "15321964202620841",
		"ToUserName": "@d946a2006c12e85deda45c26b8cd42dbd3f03fa67be",
		"Type": 1
	},
	"Scene": 0
}

POST参数分析:

Key 示例值 描述
BaseRequest 同上;
Msg.ClientMsgId 同LocalID;
Msg.Content 消息内容;消息为媒体时,该值为媒体ID。
Msg.FromUserName 发送用户;
Msg.LocalID 13位时间戳+4位随机数;
Msg.ToUserName 接收用户;
Msg.Type 1 消息类型;同3.1中接收的消息类型;
Scene 0 固定值;

服务端返回数据:

{
    "BaseResponse": {
        "Ret": 0,
        "ErrMsg": ""
    },
    "MsgID": "7650884298732299102",
    "LocalID": "15321964202620841"
}
  • LocalID是发送时指定的LocalID。
  • MsgID是服务端的消息ID。

4.3、上传媒体到服务器

如果我们发送一个图片、文件等媒体类消息,会看到在发送消息请求前有如下 POST 请求:

https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json

若文件较小,则只会产生一个该请求,若文件较大,则会产生多个该请求。多个请求表示以分片的方式发送文件数据,分片大小约为524288。

FORM表单参数分析:

参数名 示例值 描述
id WU_FILE_0 页面文件组件ID;非必须;
name bd00c8eed5c2cd522e69f38317b46903.jpg 文件名;非必须;
type image/jpeg 文件的MimeType;非必须;
lastModifieDate 文件最后修改时间;非必须;
size 99785 文件大小;非必须;
chunks 3 文件分片数量;文件较大需要分片时必须;
chunk 0 文件分片序号;从0开始;文件较大需要分片时必须;
mediatype pic 文件类型;图片为pic,视频为video,其它文件为doc;必须;
uploadmediarequest JSON字符串;必须;
webwx_data_ticket cookie中的数据;必须;
pass_ticket 登录时获取的;必须;
filename 文件二进制数据;必须;

uploadmediarequest结构示例:

{
	"UploadType": 2,
	"BaseRequest": {
		"Uin": 1245,
		"Sid": "zxaODbK4ed",
		"Skey": "@crypt_4f399da_3c7a87e93b7872bce",
		"DeviceID": "e69688819413"
	},
	"ClientMediaId": 153686311,
	"TotalLen": 87508,
	"StartPos": 0,
	"DataLen": 87508,
	"MediaType": 4,
	"FromUserName": "@6feb88ee01067121479f686",
	"ToUserName": "@6feb88ee0106f67121479f686",
	"FileMd5": "717d1dbb9833c7cdbdd09ac"
}

服务端返回数据:

{
	"BaseResponse": {
		"Ret": 0,
		"ErrMsg": ""
	},
	"MediaId": "@crypt_17ab5.................39bd9cfa9ab",
	"StartPos": 99785,
	"CDNThumbImgHeight": 56,
	"CDNThumbImgWidth": 100,
	"EncryFileName": "bd00c8e.....38317b46903.jpg"
}

上传成功后,返回数据中会有MediaId,如果是分片上传的,则最后一个请求会返回MediaId。

4.4、发送图片消息

发送图片后,紧接着4.3的是如下POST请求:

https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket=xFAjPcq0eXh.......TYHHdHgVL52eHo%253D

URL参数分析:

数名 示例值 描述
pass_ticket xFAjPcq0eXh.......TYHHdHgVL52eHo%253D 同前面获取的;

POST的数据(JSON):

{
	"BaseRequest": {
		"Uin": 16...245,
		"Sid": "KvCP..../TNqh8",
		"Skey": "@crypt_4fb399da......9f1b3d997c4b5eef82",
		"DeviceID": "e2825...3652448"
	},
	"Msg": {
		"Type": 3,
		"MediaId": "@crypt_17ab5.................39bd9cfa9ab",
		"Content": "",
		"FromUserName": "@3641f45.......69bed57642",
		"ToUserName": "@3641f454....9bed57642",
		"LocalID": "153691....0527",
		"ClientMsgId": "1536....390527"
	},
	"Scene": 0
}

POST参数分析:

Key 示例值 描述
BaseRequest 同上;
Msg.ClientMsgId 同LocalID;
Msg.Content 消息内容;消息为媒体时,该值为媒体ID。
Msg.FromUserName 发送用户;
Msg.LocalID 13位时间戳+4位随机数;
Msg.ToUserName 接收用户;
Msg.Type 3 消息类型;同3.1中接收的消息类型;
Msg.MediaId 4.3接口中返回的MediaId;
Scene 0 固定值;

服务端返回数据:

{
	"BaseResponse": {
		"Ret": 0,
		"ErrMsg": ""
	},
	"MsgID": "28832......8291836",
	"LocalID": "1536.....54390527"
}

Web微信发送图片,需要先调4.3的接口将媒体文件上传到服务器,然后再调4.4的接口发送图片的相关信息。

Java
1
https://gitee.com/hotlcc/wechat4j.git
git@gitee.com:hotlcc/wechat4j.git
hotlcc
wechat4j
wechat4j
master

搜索帮助