手把手教你编写-微信机器人

简介: 一. 引言      我们都知道,微信提供了多种登录的方式,包括手机端、电脑端以及web端。      web端的登录,我们用Python程序完全可以模拟出来~~(如果你不知道,那也没关系,稍微了解下Python request session即可)      而所谓的机器人实际上就是后台一个智能的程序,类似“微软小冰”,“iPhone siri”。

一. 引言

      我们都知道微信提供了多种登录的方式包括手机端、电脑端以及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昵称 ...

{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"Count": 10,
"ContactList": [{
"Uin": 0,
"UserName": "filehelper",
"NickName": "xxxx",
"HeadImgUrl": "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=653892799&username=filehelper&skey=@crypt_b13bcf4_edeadfd5615d5e6b289b614fac25e5ac",
"ContactFlag": 1,
"MemberCount": 0,
"MemberList": [],
"RemarkName": "",
"HideInputBarFlag": 0,
"Sex": 0,
"Signature": "",
"VerifyFlag": 0,
"OwnerUin": 0,
"PYInitial": "WJCSZS",
"PYQuanPin": "wenjianchuanshuzhushou",
"RemarkPYInitial": "",
"RemarkPYQuanPin": "" 
 ...

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数据包含具体的消息数据和类型

{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"AddMsgCount": 1,
"AddMsgList": [{
"MsgId": "4937824389423381364",
"FromUserName": "@ca2e7ef4exxxxxd71ab5fd68ac405b70",
"ToUserName": "@c26fa48f87634xxxxxx1ada0a4fa30f",
"MsgType": 1,
"Content": "[投é™]",
"Status": 3,
"ImgStatus": 1,
"CreateTime": 1469861910,
"VoiceLength": 0,
"PlayLength": 0,
"FileName": "",
"FileSize": "",
"MediaId": "",
"Url": "",
"AppMsgType": 0,
"StatusNotifyCode": 0,
"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": 4937824389423381364
}
],
"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": 8,
"List": [{
"Key": 1,
"Val": 653921573
}
,{
"Key": 2,
"Val": 653921823
}
,{
"Key": 3,
"Val": 653921702
}
,{
"Key": 11,
"Val": 653919729
}
,{
"Key": 13,
"Val": 653890051
}
,{
"Key": 201,
"Val": 1469861910
}
,{
"Key": 1000,
"Val": 1469856425
}
,{
"Key": 1001,
"Val": 1469851411
}
]
}
,
"SKey": ""
}
a. BaseResponseRet位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"
}

Ret0表示发送成功



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

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

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

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

 

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

  

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


二. 效果分析

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

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

     

     


目录
相关文章
|
10月前
|
存储 监控 机器人
不论微信钉钉还是什么软件,我写了个通用的消息监控处理机器人
不论微信钉钉还是什么软件,我写了个通用的消息监控处理机器人
|
12月前
|
机器人 数据安全/隐私保护 Windows
云桌面上跑微信机器人,不需要一直开着windows系统了(部署运行机器人)
接上篇文章,本文主要介绍如何在云桌面上部署运行微信机器人
171 1
云桌面上跑微信机器人,不需要一直开着windows系统了(部署运行机器人)
|
运维 机器人 Java
Springboot 整合 企业微信机器人助手推送消息
Springboot 整合 企业微信机器人助手推送消息
900 0
Springboot 整合 企业微信机器人助手推送消息
|
监控 机器人 API
利用itchat搭建微信机器人详解(附三个实用示例)(中)
2011年1月21日,微信推出第一个正式版本,到现在已有7个年头。从一开始的不被看到好,到现在的用户量超10亿,大众的日常生活越来越离不开微信。人生苦短我用Python,有没有办法通过Python来对我们使用微信提供一些便利呢? 答案肯定是有的,在Github上有一个基于微信网页版接口微信开源库:itchat,通过几十行的代码就能轻松实现一个微信机器人。本章我们就来了解学习这个库,然后通过三个实用案例来帮大家玩转这个库。
1073 0
|
机器人 中间件 Linux
一步一步教你用wechaty+百度云主机打造一个带你穿越星际的微信机器人
一步一步教你用wechaty+百度云主机打造一个带你穿越星际的微信机器人
508 0
一步一步教你用wechaty+百度云主机打造一个带你穿越星际的微信机器人
|
资源调度 机器人
微信接入ChatGPT,使用Node+ChatGPT+Wechaty做一个微信机器人
微信接入ChatGPT,使用Node+ChatGPT+Wechaty做一个微信机器人
3794 4
微信接入ChatGPT,使用Node+ChatGPT+Wechaty做一个微信机器人
|
机器人 API Python
Python基于PC版微信实现机器人
Python基于PC版微信实现机器人
1781 0
Python基于PC版微信实现机器人
|
SQL 机器学习/深度学习 JSON
钉钉/企业微信机器人:“Github触发器”与“Issue机器人”
众所周知,在Serverless领域中,触发器是FaaS必不可少的一部分;一个FaaS平台,他的触发器数量、质量以及类型,很可能会决定这个FaaS平台是否能成为“主流”平台;因为触发器不仅仅是一种功能的体现,更是解决普遍性业务诉求的一个重要途径;目前来看,各个云厂商所提供的触发器基本上都会包括API网关触发器、对象存储触发器、时间触发器等,当然也有厂商提供一定的消息触发器、日志触发器、甚至是一些SQL相关的触发器、CDN触发器等,那么在我们的实际生产生活中,这些表面上看起来“很基础”的触发器,是否可以升级成为一个有趣的“高级触发器”呢?
497 0
|
机器人 Python
Python + Wxpy 搭建简单微信机器人
Python + Wxpy 搭建简单微信机器人

热门文章

最新文章