1.chrome kit微信机器人简介(github:https://github.com/LinuxForYQH/chrome_kit)
- 借助chrome 插件 js注入来实现消息的发送
- chrome devtool api的调用来监听https请求
- 打开微信登录界面,在扫码登录前必须先打开toolbar(F12 或者 鼠标右键检查),如上所说因为借助了chrome devtool api所以需要打开toolbar才能执行相关dev域的js。
2.相关开发原理介绍
- https://developer.chrome.com/extensions/devtools 。(需要FQ)这个文档介绍了三个域之间的关系,了解对使用非常有帮助。
- content scripts 是注入域,可以注入javascript到打开的页面中。
- Backgroud 域在第一次加载插件就执行,可以用来做各类监听
- dev -tool是在打开toolbar调试的时候才会执行,它有很多对应自己的api,如network的api,可以监听所有的请求。
- 三个域之间如何通讯,该图也描述得很清楚了,具体内容不过多描述,看上面的文档或者我的代码例子即可。
3.使用操作说明
1.加载插件 , 如下
把我整个github文件夹下载下来加载即可:https://github.com/LinuxForYQH/chrome_kit
2.打开网页版微信登录界面,同时打开toolbar(记住这个非常重要,不然监听不到链接请求),如下图
3.扫码登录,等待5秒左右初始化,会有一个同步信号发送到手机微信的“同步助手”中,即表示成功登录。如果太久没有反应关掉浏览器从新来(非常小的概率),如下图
4.如何调试和进一步开发
1.content注入域的调试如下
2.backgroud域的调试如下
3.dev-tool域的调试说明:dev-tool没有控制台可以调试,而且出现错误也不会有提示,调试只能把相应的javascript注入到content层来查看输出,或者把消息发送到backgroud域查看执行结果。
5,我设计的原理图和代码如下
1.原理图如下
2代码如下:
devtools01.js
1 /** 2 * Created by hua on 2017/9/12. 3 */ 4 5 6 //联系人列表 7 var Contact; 8 //微信初始化 9 var wxInit; 10 //群联系 11 var webwxbatchgetcontact=null; 12 var webwxbatchgetcontact_si; 13 14 var signal_a; 15 16 var signal_b; 17 18 /** 19 * dev域用于toolbar的网络监听 20 * 21 * 22 */ 23 chrome.devtools.network.onRequestFinished.addListener( 24 function (request) { 25 26 27 //匹配地址 28 signal_a = request.request.url.indexOf(‘wx2.qq.com‘); 29 30 signal_b = request.request.url.indexOf(‘wx2.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact‘); 31 32 33 if (signal_b > 0&&request.request.url.indexOf("me=me")<0) {//me=me是循环标志 34 request.getContent(function (body) { 35 36 //判断数据来存储联系群 37 if (!webwxbatchgetcontact) { 38 webwxbatchgetcontact = body; 39 webwxbatchgetcontact_si=request.request; 40 } else if (JSON.parse(webwxbatchgetcontact).Count < JSON.parse(body).Count&&body!=null) { 41 webwxbatchgetcontact = body; 42 webwxbatchgetcontact_si=request.request; 43 } 44 45 //发送初始化好的消息给background层 46 chrome.extension.sendRequest({ 47 Contact: Contact, 48 tabId: chrome.devtools.inspectedWindow.tabId, 49 BaseRequest: request.request, 50 wxInit: wxInit, 51 webwxbatchgetcontact: webwxbatchgetcontact_si, 52 url: request.request.url, 53 }); 54 }); 55 } else if (signal_a > 0&&request.request.url.indexOf("me=me")<0) {//me=me是循环标志 56 request.getContent(function (body,base64) { 57 //初始化监听 58 if (request.request.url.indexOf("wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit") > 0&&body!=null) { 59 wxInit = request.request; 60 } 61 62 //获取联系人 63 if (request.request.url.indexOf("wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact") > 0&& 64 request.request.url.indexOf(‘skey‘)>0&&body!=null) { 65 Contact = request.request; 66 67 } 68 69 //所有消息均发送到background层 70 chrome.extension.sendRequest({ 71 tabId: chrome.devtools.inspectedWindow.tabId, 72 url: request.request.url, 73 params: request.request, 74 content: body, 75 base64:base64 76 }); 77 }); 78 } 79 });
backgroud01.js
1 /** 2 * Created by hua on 2017/9/11. 3 */ 4 5 6 var tabId; 7 8 /** 9 * 接收来自dev域的消息 10 * 11 * 12 */ 13 chrome.extension.onRequest.addListener(function (request) { 14 15 console.log(request); 16 tabId = request.tabId; 17 //发送消息content层 18 chrome.tabs.sendRequest(tabId, request , function (results) { 19 20 }) 21 22 });
content01.js
1 /** 2 * Created by hua on 2017/9/12. 3 */ 4 5 //联系人列表 6 var Contact; 7 //基础参数 8 var BaseRequest; 9 //最新的消息 10 var news; 11 //微信初始化 12 var wxInit; 13 //群联系 14 var webwxbatchgetcontact; 15 16 var Msg = { 17 Type: 1, 18 Content: "0", 19 FromUserName: "0", 20 ToUserName: "0", 21 LocalID: "0", 22 ClientMsgId: "0" 23 } 24 25 26 /** 27 * 接收来自background的消息 28 * 29 */ 30 chrome.extension.onRequest.addListener(function (request) { 31 32 console.log(request); 33 34 //监听最新的消息 35 if (request.url.indexOf("wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync") >= 0) { 36 if (!request.content) return; 37 news = JSON.parse(request.content); 38 if (news.AddMsgCount && news.AddMsgCount > 0 && wxInit != null && (news.AddMsgList[0].Content != ‘‘)) { 39 $.ajax({ 40 url: request.url + "&me=me",//避开循环标志 41 type: ‘POST‘, 42 contentType: ‘application/json;charset=UTF-8‘, 43 data: JSON.stringify(JSON.parse(request.params.postData.text)), 44 dataType: "json", 45 success: function (data) { 46 Msg.Content = "机器人:" + data.AddMsgList[0].Content; 47 Msg.ToUserName = "filehelper"; 48 Msg.FromUserName = wxInit.User.UserName; 49 webwxsendmsg(BaseRequest, Msg) 50 } 51 }) 52 } 53 } 54 55 //初始化监听 56 if (request.url.indexOf("wx2.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact") >= 0) { 57 if (!request.Contact || !request.BaseRequest || !request.wxInit || !request.webwxbatchgetcontact) return; 58 59 wxInit_a(request); 60 Contact_a(request); 61 webwxbatchgetcontact_a(request); 62 63 BaseRequest = JSON.parse(request.BaseRequest.postData.text) 64 } 65 66 67 }); 68 69 70 /** 71 *发送文字消息 72 *格式如下 73 { 74 BaseRequest: { Uin: xxx, Sid: xxx, Skey: xxx, DeviceID: xxx }, 75 Msg: { 76 Type: 1 文字消息, 77 Content: 要发送的消息, 78 FromUserName: 自己的ID, 79 ToUserName: 好友的ID, 80 LocalID: 与clientMsgId相同, 81 ClientMsgId: 时间戳左移4位随后补上4位随机数 82 } 83 } 84 */ 85 86 var clientMsgId; 87 function webwxsendmsg(BaseRequest, Msg) { 88 89 clientMsgId = new Date().getTime() 90 + (Math.random() + "").substring(2, 6); 91 Msg.LocalID = clientMsgId; 92 Msg.ClientMsgId = clientMsgId; 93 $.ajax({ 94 url: ‘https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg‘, 95 type: ‘POST‘, 96 contentType: ‘application/json;charset=UTF-8‘, 97 data: JSON.stringify({ 98 BaseRequest: BaseRequest.BaseRequest, 99 Msg: Msg, 100 Scene: 0 101 }), 102 dataType: "json", 103 success: function (data) { 104 console.log(data) 105 } 106 }) 107 108 } 109 110 /** 111 *初始化个个人 112 * @param request 113 */ 114 function wxInit_a(request) { 115 $.ajax({ 116 url: request.wxInit.url, 117 type: ‘POST‘, 118 contentType: ‘application/json;charset=UTF-8‘, 119 data: JSON.stringify(JSON.parse(request.wxInit.postData.text)), 120 dataType: "json", 121 success: function (data) { 122 wxInit = data 123 }, 124 timeout: 3000, 125 complete: function (XMLHttpRequest, status) { 126 if (status == ‘timeout‘) wxInit_a(request); 127 } 128 }) 129 } 130 /** 131 *初始化联系人 132 * @param request 133 */ 134 function Contact_a(request) { 135 $.ajax({ 136 url: request.Contact.url, 137 type: ‘GET‘, 138 contentType: ‘application/json;charset=UTF-8‘, 139 dataType: "json", 140 success: function (data) { 141 if (data.MemberCount == 0) Contact_a(request); 142 Contact = data 143 }, 144 timeout: 4000, 145 complete: function (XMLHttpRequest, status) { 146 if (status == ‘timeout‘) Contact_a(request); 147 } 148 }) 149 } 150 /** 151 *初始化联系人群 152 * @param request 153 */ 154 function webwxbatchgetcontact_a(request) { 155 $.ajax({ 156 url: request.webwxbatchgetcontact.url + "&me=me",//避开循环标志 157 type: ‘POST‘, 158 contentType: ‘application/json;charset=UTF-8‘, 159 data: JSON.stringify(JSON.parse(request.webwxbatchgetcontact.postData.text)), 160 dataType: "json", 161 success: function (data) { 162 if (data.Count == 0) webwxbatchgetcontact_a(request); 163 webwxbatchgetcontact = data 164 }, 165 timeout: 3000, 166 complete: function (XMLHttpRequest, status) { 167 if (status == ‘timeout‘) webwxbatchgetcontact_a(request); 168 } 169 }) 170 } 171 172 173 /** 174 * 用来保持在线 175 * 176 */ 177 var click=0; 178 function timedCount01() { 179 setTimeout("timedCount01()", 10000) 180 if (!wxInit || !BaseRequest) return; 181 //模拟点击 182 if(click==0) { 183 click=1; 184 $(‘.web_wechat_tab_chat‘).click() 185 }else { 186 click=0; 187 $(‘.web_wechat_tab_friends‘).click() 188 } 189 console.log("保持在线") 190 Msg.Content = "保持在线:" + new Date(); 191 Msg.ToUserName = "filehelper"; 192 Msg.FromUserName = wxInit.User.UserName; 193 webwxsendmsg(BaseRequest, Msg) 194 } 195 timedCount01()