This article doesn’t cover AI, so if you’re looking for AI, you might be disappointed.
A while ago a friend look for me, ask me to be able to make a micro letter automatically add friend’s software,(in the eyes of ordinary people, programmer is specialized in writing Trojan virus plug-in software third-rate hacker. If you can’t write, you’re not even third-rate.
So to prove that I was a third-rate hacker, I randomly googled two ready-made ones for him. Originally things should be over here, but in the spirit of exploration, want to incidentally understand the principle of this plug-in, so 100 Google degree, the final principle did not find, but found a few interesting Github warehouse, using the webpage version of wechat API to do third-party wechat.
Let’s see what happens first, okay?
steps
Let’s look at the general process
- Get UUID
- Obtain the QR code based on the UUID
- Scan code login, access to login information
- Exchange login information for initialization data
- Get data to initialize
- Gets a list of friends and messages
- Send a message
The following is the detailed process, those who are not interested can just drag to the end to view the source repository
It should be noted that the methods (POST/GET) and content-Type used in each step of the request are different. I have marked them below. If any request fails, please refer to the source code of GtiHub.
Obtain the UUID
Interface address wx.qq.com/jslogin
Request method POST
Content-type Application/X-www-form-urlencoded
parameter
{
appid: 'wx782c26e4c19acffb',
fun: 'new',
lang: 'zh_CN',
_: new Date().valueOf()
}
Copy the code
Qrlogin. code = 200; window.qrlogin. code = 200; window.qrlogin. code = 200; window.QRLogin.uuid = “obizONtqZA==”; Uuid = (window. Qrlogin. uuid =);
2. Obtain the QR code
This step is very simple, after a UUID, we can directly ask ‘https://wx.qq.com/qrcode/’ + UUID for the qr code. After obtaining the TWO-DIMENSIONAL code, don’t rush to scan the two-dimensional code, because we have to monitor the scanning state of the two-dimensional code first, so that we can know when to be logged in.
Request mode GET requires no parameters
Three, monitor the scanning results of the TWO-DIMENSIONAL code
Interface address wx.qq.com/cgi-bin/mmw…
Request method GET
Content-type Application/X-www-form-urlencoded
parameter
{
tip: 0,
uuid: 'obizONtqZA==',
_: new Date().valueOf(),
loginicon: true
}
Copy the code
Tip takes the value of 0 or 1. The monitoring can be divided into two stages. In the first stage, whether the monitoring user scans codes,tip is 0; in the second stage, whether the monitoring user clicks on wechat to confirm login,tip is 1.
The UUID is the one obtained in the first step
_ Current timestamp
Loginicon I guess whether to scan the code to return to the user’s avatar, both fill in true.
Return the result, when you scan the QR code, the interface will return you one of these objects
{
'window.code': 201,
'window.userAvatar': Base64 address of avatar}Copy the code
The obtained code is 201, indicating that the code has been scanned, but it does not mean that the user has logged in. It is still necessary to monitor whether to click the login confirmation button on wechat of the mobile phone (repeat the above steps and change the tip in the parameter to 1).
This step, if successful, returns the following object
{
'window.code': '200'.'window.redirect_uri': 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ARD37_ikx-Kakd2i0W-f-E7q@qrticket_0&uuid=4f6yOkV4AA==&la ng=zh_CN&scan=1548300672'}}Copy the code
4. Obtain initialization data (sensitive data)
The window. Redirect_uri contains a URL and some query parameters. It is not possible to request the url directly, so you need to split the URL and parameters and add other parameters
The interface address is the url above
Request method GET
Content-type Application/X-www-form-urlencoded
parameter
{ticket: ticket obtained above, uuid: uUID obtained above, lang:'zh_CN', // fix scan: get scan above, fun:'new'/ / fixed}Copy the code
In this step, you’re going to have a cookie in the header that you’re going to have to store, and then you’re going to have to store that cookie in the request header, and then you’re going to have to store sensitive information in XML.
XML formats can be converted to JSON using XML2JS.
5. Initialization
At this point, finally close to login success, just call the following interface, initialize the following
Interface address https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=${~(new Date().valueof ())}
Request method POST
Parameter Type (Content-type) Application /json
parameter
{
BaseRequest: {
DeviceID: 'e747337466044216'Sid: wxsid, U from the previous stepin: wxuin obtained in the previous step, Skey: Skey obtained in the previous step}}Copy the code
The first is that the address is followed by a timestamp, which is reversed by bit, and the second is that the request parameters are placed under the BaseRequest instead of the object’s first level properties.
Data. SyncKey and res.data.user. UserName are the ckey parameters that need to be saved
Now that you’ve logged in, if you don’t need a friend list, you can receive messages directly
Detect new messages
Interface address webpush.wx.qq.com/cgi-bin/mmw…
Request method GET
Parameter Type (Content-type) Application /json
parameter
let time = new Date().getTime()
let synckey = ' '
letSk = data. SyncKey. List | | [] / / data SyncKey is step on to get to thatfor (let i = 0; i < sk.length; i++) {
synckey += `${sk[i].Key}_${sk[i].Val}`
if(i ! == sk.length - 1) synckey +='|'} // pass parameters {r: time, sid: wxSID, uin: wxuin, skey: skey, deviceid:'e747337466044216', // Synckey: synckey, _: time}Copy the code
The data returned contains the following contents
window.synccheck={retcode:"0",selector:"2"}
Copy the code
If selector is 2, there’s a new message, so go to the next step and get the message content
Seven, get the message content
Interface address wx.qq.com/cgi-bin/mmw…
Request method POST
Parameter Type (Content-type) Application /json
parameter
{
BaseRequest: {
UinWxuin, Sid: wxSID, Skey: DeviceID: wxuin, Sid: Skey: DeviceID:'e747337466044216', // SyncKey: data.SyncKey, // Remember when we had to transform this material? Rr: ~(new Date().valueof ())}Copy the code
AddMsgList is the list of messages, and Data. SyncCheckKey is SyncKey for the next request, which changes each time.
AddMsgList is an array, which may contain multiple messages, messages are more automatic, I do not have to explain, here are two more important fields, other fields are interested in printing out their own look.
FromUserName is the wechat name of the other party. In fact, it is an internal ID that starts with @ or @@, which is completely unreadable. According to my guess, @ should start with ordinary friends, while @@ should start with group or public account
Content Message Content
Given the content of the message, and the person who sent it, we can reply to each other, but to what? Of course, it is impossible to write a lot of if else or switch cases to adapt to various situations, why not search online for ai code worth 100 million hahaha
8. Get the auto-reply content
Here I’m using the Turing robot API address, but you can use other ones as well.
The interface address openapi.tuling123.com/openapi/api…
Request method POST
Parameter Type (Content-type) Application /json
parameter
Perception: {perception: {inputText: {text: ‘message to be replied’}}, userInfo: {apiKey: tulingApiKey, // Apply userId on Turing’s official web site: TulingUserId}
If you’re too lazy to apply, you can copy it in my project, In SRC /global.js, data. Results [0].values.text (results is an array, multiple responses can be returned at once).
9. Reply to messages
Once we get an automatic reply, we just send it to your friends, completing an automatic conversation.
Interface address wx.qq.com/cgi-bin/mmw…
Request method POST
Parameter Type (Content-type) Application /json
parameter
let timeStamp = new Date().getTime() + ' ' + (9000 * Math.random() + 1000)
{
BaseRequest: {
UinSkey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey: Skey'Content of reply',
FromUserName: 'Your username, got in step 5.',
ToUserName: 'FromUserName in step 7',
LocalID: timeStamp,
ClientMsgId: timeStamp
}
Copy the code
If the message is sent successfully, the following information is displayed
{
BaseResponse: { Ret: 0, ErrMsg: ' ' },
MsgID: '2033517278669301361',
LocalID: ' '
}
Copy the code
Okay, so we’re done with one of our auto-reply robots. The full code is here
AD time
Our 40-person front end team is always recruiting, those in Xiamen and those who want to come to Xiamen, don’t spare your resume, hard hit the mailbox: ATOB (‘bnVveWFAZ2FvZGluZy5jb20=’), look forward to your contribution
If you have any comments or suggestions on this article, please make an issue on Github. Recently, you have been busy and do not visit the community much