微信机器人vbot原理、源码分析及微信签到demo实例代码

微信机器人vbot签到原理:微信手机端和微信网页版可以同时在线,利用微信网页版提供的http接口,通过程序模拟发送对应的接口请求数据,从而实现微信机器人对微信消息的自动应答。

微信机器人vbot原理

假设有个微信号:xxx,那么微信机器人的工作流程如下:

  1. 微信号xxx在手机上通过扫描vbot命令行上请求得到的登录二维码模拟登录微信网页版
  2. 登录成功后,微信机器人vbot便可以根据程序的设定操作该微信号xxx,比如可以在收到对应群消息时自动回复或者收到特定关键词时回复特定的消息

微信机器人vbot运行结果

不过因为 web 的限制,微信机器人这种模拟登录的方法无法获取每个账号的唯一ID。不管是微信好友还是微信群,都只会在模拟登录成功后返回一个临时的UserName,这个UserName将作为本次登录成功后所有通信的唯一标识id,可以认为UserName就是微信好友或者微信群的id,能够唯一标识当前帐号中的一个用户或者群

因此,微信机器人无法真实地唯一标识一个微信帐号,当一次模拟登录失效后再重新模拟登录拿到的同一个帐号的UserName也将会不同。这应该是出于安全的考虑,微信团队将微信用户的主键id隐藏了起来。类似于在微信公众号开发中只能拿到open_id而无法拿到用户的wxid_xxxxxxx。

微信机器人vbot签到

前面提到模拟登录成功后,通过特定接口获取微信服务器返回的数据中包含了UserName字段来标识用户。

对于微信群而言,其UserName以@@前缀开头,而对于普通微信用户的UserName则是以@开头。通过这个差异就可以区分接收到的消息是群消息还是好友消息。

如果要基于vbot实现类似vbot体验群内的签到功能,理论上是不可行的。因为机器人帐号不可能一直在线,一旦重新登录,则之前的登录积分都将会被重置,也即无法实现真正意义上的用户签到积分积累。

如果要实现一个简化版的签到功能,其实也很简单。下面就是一个简单的demo代码。

微信机器人vbot签到demo代码

修改vbot2.0中example文件夹中的MessageHandler.php中的代码,加入以下代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
if ($message['fromType'] === 'Group' /*||
strstr($message['from']['UserName'], '@@')*/) {

$group_name = $message['from']['NickName'];
$group_id = $message['from']['UserName'];
$sender_name = $message['sender']['NickName'];
$sender_id = $message['sender']['UserName'];

if ($group_name === '这是测试群') {
if (strstr($message['message'], '签到') !== false) {
// 连db
$con = mysqli_connect("localhost", "root", "xxxxxxx", 'db_name');
if (!$con) {
die('Could not connect: ' . mysqli_connect_errno());
} else {
// 先判断该sender_id是否已经签过到
// ……
// 如果是第一次签到,则增加该用户的积分总数
$update = 'UPDATE user SET score= score+1 WHERE `user_id`="' . $sender_id . '"';
mysqli_query($con, $update);
// 发送群消息,@用户 签到成功
Text::send($group_id, "@" . $sender_name . " 签到成功");
}
}
mysqli_close($con);
}
}

本文来自微博视频下载工具

在MessageHandler.php中接收到的message数组已经是vbot代码经过处理后的数据,fromType表示该消息的类型,其值可能是Group,Self等多种。

$message['fromType'] === 'Group'表示接收到的微信消息来自于群,此外还可以使用$message['from']['UserName']来判断收到的消息类型。该字段表示发送当前微信消息的UserName(即唯一id),如果$message['from']['UserName']以@@开头,也可以说明收到的是群消息

不过$message['from']['UserName']以@@开头时,收到的群消息有可能是当前登录了机器人的帐号自己发送的(即$message['fromType']=Self),这时候$message['sender']['NickName']为空

因此$message['fromType'] === 'Group'才是真正表明当前帐号收到的消息是群里面的其他成员发送过来的消息,此时当前作为机器人帐号登录的微信号就可以自动统计其签到信息啦。

下面是vbot签到Demo的几张运行截图

微信机器人vbot源码分析

微信机器人vbot签到