WinXin机器人实现

2024-06-23 17:08
文章标签 winxin 机器人 实现

本文主要是介绍WinXin机器人实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自csdn

陈国林

前辈的博客,非常感谢



一. 引言

      我们都知道,微信提供了多种登录的方式,包括手机端、电脑端以及web端。

      web端的登录,我们用Python程序完全可以模拟出来~~(如果你不知道,那也没关系,稍微了解下Python request session即可)

      而所谓的机器人实际上就是后台一个智能的程序,类似“微软小冰”,“iPhone siri”。今天我们要用的是一个开放的机器人API,“图灵机器人”

      下面就让我们一步步分析如何,通过模拟web端微信登录+“图灵机器人” 实现一个微信机器人


二. 深入分析

      1. web版微信不是用用户名密码而是用扫描二维码登录,如何实现的呢?

          让我们登录https://wx.qq.com/,查看此时的网络请求情况 如下图所示

          1). 实际上客户端会先发送一个js get请求,请求url为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&_=1469852355025

仔细分析这个请求,会发现有已下几个参数

appid: wx782c26e4c19acffb //这个值不变,表示来自微信网页版

redirect_uri: https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage //这个也是一个固定值

fun: new //固定值位new

lang: zh_CN //表示中文

_: 1469852355025 //13位时间戳

2).然后服务端返回数据,window.QRLogin.code = 200; window.QRLogin.uuid = "IatVataLfQ==";

2. 多刷新几次,你会发现服务端的返回值中window.QRLogin.uuid的值每次都在变化。

实际上uuid是服务端用来标识一次登录的通信id

       

       


        2. 当我们拿到uuid后,就需要获取二维码,继续查看当前的网络请求

            1). 客户端继续发送一个js get 请求,url为https://login.weixin.qq.com/qrcode/IatVataLfQ==

仔细分析这个请求,会发现qrcode后跟着的值就是从上一个请求拿到的uuid值

2). 当拿到二维码之后,还需用微信客户端进行扫描(god,都有客户端了为什么还需用用web登录~~~~)

        3. ok,拿出手机扫描屏幕的二维码,继续查看网络请求

           1).  当我们在APP上点击登录按钮之后,实际上客户端是向服务端发送了一个js的get 请求,url为https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=od5FW4ipFw==&tip=0&r=-979422099&_=1469857970642

仔细分析这个请求,会发现有以下几个参数

uuid: od5FW4ipFw== //从上面请求得到的数据

tip: 0 //表示等待用户扫描确认

r: -979422099 //随机9位数字

_: 1469857970642 //13位时间戳

2). 这个请求,返回结果如下所示

window.code=200;
window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AUyRV3zm5RBTWt-mEvvDz8oz@qrticket_0&uuid=od5FW4ipFw==&lang=zh_CN&scan=1469858238";

code=200表示的是成功,redirect_uri表示需要我们继续请求的url

      

      

       4. 继续上一个请求得到的redirect_uri

1). ok,分析这个uri请求https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AUyRV3zm5RBTWt-mEvvDz8oz@qrticket_0&uuid=od5FW4ipFw==&lang=zh_CN&scan=1469858238&fun=new&version=v2,对应参数如下所示

uuid: 同前面

scan: 1469858238 //表示用户扫描的时间戳,10位

其它参数保持不变即可

2). 这个请求会返回,我们登陆所需要的信息,返回值是一个xml数据,如下所示

<error><ret>0</ret><message>OK</message><skey>@crypt_b13bcf4_edeadfd5xxxxd5e6b289b614fac25e5ac</skey><wxsid>HON+SKvxxxxTihHV</wxsid><wxuin>8xxxx5640</wxuin><pass_ticket>um3UATy9MNzcwDDkVT4xxxxMn5B25G%2FcYIAVbpHnF8vU23yMflmUCFsZkMKbIJIP</pass_ticket><isgrayscale>1</isgrayscale></error>

(为了我的隐私,我把返回值做了一定的打码~~)

ret: 表示请求返回状态码,0表示成功

skey和wxsid以及wxuin都是具体微信用户的信息,不会变的,在后续的通信过程中需要用到

pass_ticket: 这个值在初始化登录页面的时候需要用到

      5. 现在我们已经拿到了用户认证相关的信息,包括skey和wxsid以及wxuin,需要初始化登录页面

什么是初始化登录页面,也就是我们平时登录APP客户端看到的那个页面,我们需要发送一个请求到服务端拿到数据,获取到常用的联系人和微信公众号

如下图所示,这个请求是一个post请求,需要我们带一些用户认证相关的信息到服务端

1). ok,让我们分析一下这个请求url: https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-979155549&pass_ticket=um3UATy9MNzcwDDkVT4xxxxMn5B25G%252FcYIAVbpHnF8vU23yMflmUCFsZkMKbIJIP

r: 随机的9位数据

pass_ticke: 从上一步请求返回值中获取的数据

2). post请求所需要的data,如下所示

{
          'BaseResponse': {
              'Uin': wxuin,
              'Sid': wxsid,
              'Skey': skey,
              'DeviceID': //15位随机串 'e'+str(random.random())[2:17]
          }
        }

3). 请求返回数据,如下所示

Ret: 0表示返回成功,ContactList表示的是联系人列表。

返回数据包含了当前登录账户的相关信息,比如wxuid,昵称 ...

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. {  
  2. "BaseResponse": {  
  3. "Ret": 0,  
  4. "ErrMsg": ""  
  5. }  
  6. ,  
  7. "Count": 10,  
  8. "ContactList": [{  
  9. "Uin": 0,  
  10. "UserName": "filehelper",  
  11. "NickName": "xxxx",  
  12. "HeadImgUrl": "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=653892799&username=filehelper&skey=@crypt_b13bcf4_edeadfd5615d5e6b289b614fac25e5ac",  
  13. "ContactFlag": 1,  
  14. "MemberCount": 0,  
  15. "MemberList": [],  
  16. "RemarkName": "",  
  17. "HideInputBarFlag": 0,  
  18. "Sex": 0,  
  19. "Signature": "",  
  20. "VerifyFlag": 0,  
  21. "OwnerUin": 0,  
  22. "PYInitial": "WJCSZS",  
  23. "PYQuanPin": "wenjianchuanshuzhushou",  
  24. "RemarkPYInitial": "",  
  25. "RemarkPYQuanPin": ""   
  26.  ...  

6. 登录成功,接下来我们要做的就是开启消息状态通知。

ok,继续看此时的网络请求,会发现客户端向服务端发送了一个post请求

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?pass_ticket=um3UATy9MNzcwDDkVT42sVxMn5xxxx%252FcYIAVbpHnF8vU23yMflmUCFsZkMKbIJIP

1). 对于这个请求,相信大家都不会感到陌生,就只有一个参数pass_ticket,同上

2). post请求,需要的data模式如下

{
          'BaseResponse': {
              'Uin': wxuin,
              'Sid': wxsid,
              'Skey': skey,
              'DeviceID': //15位随机串 'e'+str(random.random())[2:17]
          }
          'ClientMsgId': 13位时间戳,
          'Code': 3  //固定值
          'FromUserName':  userNmae, //从初始化登录信息那边取到
          'ToUserName': userNmae, //从初始化登录信息那边取到
       }

3. 请求返回一个json数据

{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
},
"MsgID": "4049260553244269433"
}

Ret:0表示的是请求返回成功状态

     

        7. ok,到目前为止我们以及成功登录了微信并且开启了消息通知

            让我继续查看网页客户端,会发现有非常多如下图所示的请求。从请求名称中,我们知道这些请求在进行 同步刷新,轮询检查服务端的消息

            1). 分析下,当前get请求,https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck?r=1469858460705&skey=%40crypt_b13bcf4_edeadfdxxxxx5e6b289b614fac25e5ac&sid=HON%2BSKxxxxxxxxxV&uin=828xxxx40&deviceid=e477405243870570&synckey=1_653921573%7C2_653921810%7C3_653921702%7C11_653919729%7C13_653890051%7C201_1469858241%7C1000_1469856425%7C1001_1469851411&_=1469857970652

a. r --> 13位时间戳
       b. skey 同上,需要url quote
       c. sid 同上
       d. devicedid 同上
       e. synckey由 初始化登录页面信息返回串中Sync的list列表组成, 需要url quote
       f. _ 13位时间戳

2). 请求返回json数据,如下所示window.synccheck={retcode:"0",selector:"0"}

retcode:
        a. 0 正常
        b. 1100 失败/登出微信
        c. 1101 从其它设备登录微信网页版
       selector:
        a. 0 正常
        b. 2 新的消息
        c. 7 手机操作了微信

        

        

       8. ok,万事具备,只需要知道如何获取消息和发送消息即可了。

           让我们先看一下,当我们在网页上收到消息的时候,不断轮询的同步刷新请求会返回,window.synccheck={retcode:"0",selector:"2"} 或者是 window.synccheck={retcode:"0",selector:"6"}

           1). 这个时候,我们发现客户端会向服务端发送一个post请求,拉取新的消息数据,如下图所示

                post请求: https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=HONxxxxxqSwTihHV&skey=@crypt_b13bcf4_edeadfd5615d5xxxxx9b614fac25e5ac&pass_ticket=um3UATy9MNzcwDDkVTxxxxxMn5B25G%252FcYI

请求所带的参数同上

2). 请求会返回json数据,包含具体的消息数据和类型

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. {  
  2. "BaseResponse": {  
  3. "Ret": 0,  
  4. "ErrMsg": ""  
  5. }  
  6. ,  
  7. "AddMsgCount": 1,  
  8. "AddMsgList": [{  
  9. "MsgId": "4937824389423381364",  
  10. "FromUserName": "@ca2e7ef4exxxxxd71ab5fd68ac405b70",  
  11. "ToUserName": "@c26fa48f87634xxxxxx1ada0a4fa30f",  
  12. "MsgType": 1,  
  13. "Content": "[投降]",  
  14. "Status": 3,  
  15. "ImgStatus": 1,  
  16. "CreateTime": 1469861910,  
  17. "VoiceLength": 0,  
  18. "PlayLength": 0,  
  19. "FileName": "",  
  20. "FileSize": "",  
  21. "MediaId": "",  
  22. "Url": "",  
  23. "AppMsgType": 0,  
  24. "StatusNotifyCode": 0,  
  25. "StatusNotifyUserName": "",  
  26. "RecommendInfo": {  
  27. "UserName": "",  
  28. "NickName": "",  
  29. "QQNum": 0,  
  30. "Province": "",  
  31. "City": "",  
  32. "Content": "",  
  33. "Signature": "",  
  34. "Alias": "",  
  35. "Scene": 0,  
  36. "VerifyFlag": 0,  
  37. "AttrStatus": 0,  
  38. "Sex": 0,  
  39. "Ticket": "",  
  40. "OpCode": 0  
  41. }  
  42. ,  
  43. "ForwardFlag": 0,  
  44. "AppInfo": {  
  45. "AppID": "",  
  46. "Type": 0  
  47. }  
  48. ,  
  49. "HasProductId": 0,  
  50. "Ticket": "",  
  51. "ImgHeight": 0,  
  52. "ImgWidth": 0,  
  53. "SubMsgType": 0,  
  54. "NewMsgId": 4937824389423381364  
  55. }  
  56. ],  
  57. "ModContactCount": 0,  
  58. "ModContactList": [],  
  59. "DelContactCount": 0,  
  60. "DelContactList": [],  
  61. "ModChatRoomMemberCount": 0,  
  62. "ModChatRoomMemberList": [],  
  63. "Profile": {  
  64. "BitFlag": 0,  
  65. "UserName": {  
  66. "Buff": ""  
  67. }  
  68. ,  
  69. "NickName": {  
  70. "Buff": ""  
  71. }  
  72. ,  
  73. "BindUin": 0,  
  74. "BindEmail": {  
  75. "Buff": ""  
  76. }  
  77. ,  
  78. "BindMobile": {  
  79. "Buff": ""  
  80. }  
  81. ,  
  82. "Status": 0,  
  83. "Sex": 0,  
  84. "PersonalCard": 0,  
  85. "Alias": "",  
  86. "HeadImgUpdateFlag": 0,  
  87. "HeadImgUrl": "",  
  88. "Signature": ""  
  89. }  
  90. ,  
  91. "ContinueFlag": 0,  
  92. "SyncKey": {  
  93. "Count": 8,  
  94. "List": [{  
  95. "Key": 1,  
  96. "Val": 653921573  
  97. }  
  98. ,{  
  99. "Key": 2,  
  100. "Val": 653921823  
  101. }  
  102. ,{  
  103. "Key": 3,  
  104. "Val": 653921702  
  105. }  
  106. ,{  
  107. "Key": 11,  
  108. "Val": 653919729  
  109. }  
  110. ,{  
  111. "Key": 13,  
  112. "Val": 653890051  
  113. }  
  114. ,{  
  115. "Key": 201,  
  116. "Val": 1469861910  
  117. }  
  118. ,{  
  119. "Key": 1000,  
  120. "Val": 1469856425  
  121. }  
  122. ,{  
  123. "Key": 1001,  
  124. "Val": 1469851411  
  125. }  
  126. ]  
  127. }  
  128. ,  
  129. "SKey": ""  
  130. }  
a. BaseResponse,Ret位0表示返回成功
       b. AddMsgCount 表示新消息个数
       c. AddMsgList 表示新消息列表
          MsgType   说明
          1     文本消息
          3     图片消息
          34    语音消息
          37    VERIFYMSG
          40    POSSIBLEFRIEND_MSG
          42    共享名片
          43    视频通话消息
          47    动画表情
          48    位置消息
          49    分享链接
          50    VOIPMSG
          51    微信初始化消息
          52    VOIPNOTIFY
          53    VOIPINVITE
          62    小视频
          9999  SYSNOTICE
          10000     系统消息
          10002     撤回消息



           10.  最后让我们来看一下,如何发送一个消息

                  1). 当我发送一个消息给好友的时候,实际是执行了一次post请求,如下图

                       url: https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket=um3UATy9MNzcwDDkVT42sVxxxxxxxxG%252FcYIAVbpHnF8vU23yMflmUCFsZkMKbIJIP

2). post请求需要的data如下所示

{
          'BaseResponse': {
              'Uin': wxuin,
              'Sid': wxsid,
              'Skey': skey,
              'DeviceID': //15位随机串 'e'+str(random.random())[2:17]
          }
          'Type': //消息类型,同上
          'Content': //消息内容
          'FromUserName':  //发送用户
          'ToUserName': //接受用户
          'LocalID':  //13位时间戳+4位随机数
          'ClientMsgId': //同LocalId
        }

3). 当发送成功之后,服务端返回json数据

{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
},
"MsgID": "2882629525509760458",
"LocalID": "14698626523310328"
}

Ret:0表示发送成功



  ok,到此我们就知道了整个微信网页版从登陆到数据发送的整个过程。

  现在我们只剩下最后一步,机器人了。

  我们要实现的是,收到消息后自动根据消息进行回复。

  这个我们只需要在收到消息的时候,利用收到的消息调用“图灵机器人”API获取智能回答的数据,然后发送给朋友即可。

 

  图灵机器人,http://www.tuling123.com/

  

  欢迎来拍砖,github源码: https://github.com/chenguolin/weixin_robot


二. 效果分析

     我申请了个图灵机器人,取名为[【呆萌小白】

     下面是简单的和机器人的对话(无聊~~)

     

     


这篇关于WinXin机器人实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1087761

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

利用Frp实现内网穿透(docker实现)

文章目录 1、WSL子系统配置2、腾讯云服务器安装frps2.1、创建配置文件2.2 、创建frps容器 3、WSL2子系统Centos服务器安装frpc服务3.1、安装docker3.2、创建配置文件3.3 、创建frpc容器 4、WSL2子系统Centos服务器安装nginx服务 环境配置:一台公网服务器(腾讯云)、一台笔记本电脑、WSL子系统涉及知识:docker、Frp

基于 Java 实现的智能客服聊天工具模拟场景

服务端代码 import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class Serv