先說需求!有很多人是在做微商的,要是你把你的產品發到朋友圈,你所發的內容是有可能被掩蓋掉的!就是我們再使用手機版微信APP的時候,羣發是有一定人數限制的(這些都是廢話和鋪墊),這個時候就想到是不是可以用Java模擬web微Xin,寫個程序(後來知道,居然大家管這個東西叫機器人),然後發送消息,就可以解決了。
作爲程序猿的利器,chrome和fiddler,說做就做(其實是對web微信協議的自己分析)。
1.獲取二維碼:這肯定是最開始需要的
web版地址是這個 https://wx.qq.com/,打開這個地址,F12一下,
這裏我們看到加載了一大堆的js和圖片,我們關心的只要是標紅的三個就好了
1.1 獲取UUID換取二維碼
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&_=1497430023830
這個方法是第一步,jslogin 這是個get的請求方法,這個我們可以看他所需要的請求參數有4個
我開始做的時候,不管怎麼通過F12查看有返回appid的方法都沒有找到,後來我試了其他的微信號,發現這個appid都一樣,所以告訴大家,這個appid是固定的!至於149開頭的那個參數就很好猜了,就是時間戳,其他參數同樣固定。
這個請求發返回結果是這樣的
window.QRLogin.code = 200; window.QRLogin.uuid = "QY6pTM6Avw==";
我們再來對照F12下面的看下,
是不是發現了,這兩個的值是一樣的!jslogin返回的uuid,就是我們置換二維碼的參數,刷新下頁面,我們再看
1.2獲取二維碼
https://login.weixin.qq.com/qrcode/4aJWOM4Jpw==
這個方法同樣是get請求,沒有參數
這時候我們就可以在響應看到我們的二維碼了,
這個時候是response是沒值的,但是我們可以通過preview預顯示看到二維碼,這是因爲這個響應結果是以流的形式返回的,我們只需要將流生成響應的圖片就好了。
1.3長輪詢判斷手機端
https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=AaSwnCS2UQ==&tip=0&r=1512572422&_=1497430963219
請求方式是get
請求參數是
參數解釋,其中loginicon、tip是固定參數,uuid是jslogin返回的值,和換取二維碼參數一樣;_是時間戳;r這個參數,網上很多人說取反,我自己用Java代碼親測是不對的,沒有使用js測試,因爲js不是太熟悉,我可以明確告訴你們r=_/760,就是時間戳/760,就是參數r。
返回結果是 window.code=408;
我們看到這個方法一直在做長輪詢,25秒左右一次,返回結果就是window.code=408;這個是一直髮送的請求,是告訴你,服務器沒有收到你的掃碼或者掃碼之後的登錄確定;當然,這個掃碼和確定登錄時需要手機端配合的。
1.4長輪詢判斷手機端獲取頭像
https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=QbQnDRrWjg==&tip=0&r=1511576646&_=1497431985392
再看這個請求,長輪詢一直進行,參數和上面一樣,當我們用手機掃碼之後這時候再看返回結果
window.code=201;window.userAvatar
= 'data:img/jpg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/2wBDAAMCAgMCAgM..........'
code=201 然後後面緊跟的是個base64,這個大家肯定熟悉了,這個就是你自己微信的頭像,這樣我們就可以拿到自己的微信頭像,這時候大家要知道的是返回code是201,
1.5長輪詢判斷手機端
https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=QbQnDRrWjg==&tip=0&r=1511570443&_=1497431985393
還在繼續這個請求,我用自己的手機掃碼之後,然後手機鎖屏,這時候,我沒有點擊手機上的確認登錄,我們看到
這個請求還在一直繼續,然後返回的結果還是408,我們接着往下做。
1.6長輪詢判斷手機端確認登錄
https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=QbQnDRrWjg==&tip=0&r=1511545371&_=1497431985394
繼續這個請求,和上面幾個方法一樣,也是get請求,參數都和1.3一樣。我這時候在手機端點擊確認登錄網頁版
這個時候我們看到有新的返回,code是200了,然後還有個redirect_uri 重定向地址返回給我們,這個是個很重要的地址,也很符合mp文檔的規範,使用ticket作爲下次的請求,這個地址我們先不拆開,直接作爲下次使用的參數
1.7初始化頁面得到關鍵參數
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=.....&uuid=QbQnDRrWjg==&lang=zh_CN&scan=1497432010&fun=new&version=v2&lang=zh_CN
我這邊把ticket去掉用....代替,地址就是1.6返回的URI再在後面拼接fun、version、lang構成,
這個請求同樣是get請求,
請求參數可以直接在地址後面拼接就好
返回參數;
對這個請求是整個web微信中至關重要的一步,我做的時候就是這一步沒有認真,返回參數如下
這裏的返回skey,pass_ticket,wxsid,wxuin這些參數都會在後面的請求中使用到;在這裏先漏講2個重要的地方;後面大家有使用發現問題的時候可以直接問我,這2個點非常非常重要。可能有些人也能悟的出來
1.8 微信數據初始化
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=1511600827&lang=zh_CN&pass_ticket=...
這裏的pass_ticket我同樣使用...代替;
請求方式爲 post
請求參數
再看返回結果:
這兒是返回你最近聯繫的人的信息,其中User是你自己的個人信息,其中nickname是暱稱的意思,我們暫時先知道這麼多,user其中的username是自己在微信中發消息所使用的得名字,我們需要把這個解析出來;
1.9開啓微信接收消息通知狀態
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN&pass_ticket=...
請求方式post
請求參數
返回參數
{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"MsgID": "..."
}
這個是正確的返回參數,其中MsgID是下面所需要用到的;這裏的請求也需要用到上面漏講的重要2點的內容。
2.0獲取聯繫人
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=...&seq=0&skey=...
這一步使我們要獲取我們發送消息的先決條件,***(在這還有個獲取最近聯繫人的方法
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact?type=ex&r=1497432043736&lang=zh_CN&pass_ticket=...
只需要pass_ticket就可以,請求方式post,這是網上很多人所說的獲取聯繫人,這個我不推薦,和我們的出發點很遠,也不好用
)***
請求方式get
請求參數直接拼接就好
返回數據預覽
2.1置換圖片mediaId
https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json
這裏我們先說置換圖片mediaId,網上大部分人都沒有把這個說清楚,當時我去請教別人的時候,別人是要收我錢才肯告訴我的;
請求方式post
請求參數 使用fiddler攔截抓包這樣就很清晰了吧
這樣夠清晰了,這個就是一個form帶文件的表單提交,其中各個對應的參數我們需要自己構建,最終是以json的形式發送,其中
uploadmediarequest這個參數較爲特殊,我一樣使用...代替重要參數
{"UploadType":2,"BaseRequest":{"Uin":408216280,"Sid":"...","Skey":"...","DeviceID":"..."},"ClientMediaId":1497435635161,"TotalLen":318889,"StartPos":0,"DataLen":318889,"MediaType":4,"FromUserName":"...","ToUserName":"filehelper","FileMd5":"12dc0221652975df9723aae462794d77"}
相信大家看的懂,稍微解釋一下,UploadType是上傳的文件類型2,ClientMediaId時間戳,FromUserName自己的賬號,ToUserName發送對象的賬號,FileMd5這個也是我請教別人的點,他居然告訴我寫死,我自己研究了下,可以明確告訴大家,那傢伙瞎說,這個就是文件的MD5,MediaType也是固定的4,剩下的參數應該不是難度了,至於抓包出現的有個參數前面沒有出現,我暫時也不解釋;
返回參數
{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"MediaId": "...",
"StartPos": 318889,
"CDNThumbImgHeight": 56,
"CDNThumbImgWidth": 100
}
其中的mediaId就是我們發送圖片時所需要的參數
2.2發送圖片消息
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket=...
請求方式post
請求參數
返回參數
{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"MsgID": "...",
"LocalID": "..."
}
當ret爲0的時候這樣我們就發送成功,這邊我們以發送圖片爲例,暫時發送文字消息還有其他的消息就很簡單了!
2.3心跳包
https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck?r=1497436739199&skey=...&uin=408216280&deviceid=...&synckey=...
心跳包
請求方式get
每個25秒做一次請求
返回參數
window.synccheck={retcode:"0",selector:"0"}
這邊就不對其做深入講解,網上有着總結好的內容!