相信大家都注意到了,我们班级的每日健康打卡提醒由之前的生活委员换成了新的打卡机器人。
xmu-check-2022-09-14-15-09-22

那么,肯定会有同学会好奇这是怎么设计出来以及实现的呢?这里只是给一个范例,可以实现一些别的机器人,比如抓取教务处的通知,或者是抓取学院的通知之类的。

总体思路

一共分成三个步骤,获取未打卡人员的名单,根据名字获取对应的QQ号,使用QQ机器人的API在班级群里@对应的班级成员。
xmu-check-2022-09-14-15-24-41

获取名单

首先要明确的是,这里的名单只有有权限的账号才可以获得。

登陆统一身份认证,这里的登陆方式以及算法来自于https://github.com/F5Soft/xmu-check,参考这里的代码。

登陆之后,在浏览器查看获取未打卡名单的get请求

1
https://xmuxg.xmu.edu.cn/table-data/formEngine/business/2382/formInstances?playerId=player_1588410007354&timeStamp=1661226484454&pageIndex=0&pageSize=10&lang=&pageParams[f_select_1584240106785]=否&inRangeOption=

可以看到这个请求是由一系列的请求参数组成,
其中business后面的2382是系统内部的日期标识,每天一个不同的id
playerId是用户身份标识,就是你的账户是属于哪个类的就标识为哪个类
timeStamp是时间戳,也就是识别请求的时间
pageIndex和pageSize是请求列表的页码和大小
pageParams[f_select_1584240106785]=否 筛选该选项为否的成员名单,这个是内部提供的方法,f_select_1584240106785就是打卡的那个选项

可以看到,要想获取名单,只需要构造两个参数,一个是business和timeStamp就可以得到我们需要的名单了。

名字和QQ号对应

因为是一个比较简单的功能,所以直接使用SQLite数据库存储同学们的基本信息,名字和QQ号对应的信息就可以了,需要调用的时候,直接查询数据库就可以。

1
2
3
4
5
6
import sqlite3

conn=sqlite3.connect('./class_qq.db')
cursor = conn.cursor()
class_qq = cursor.execute("SELECT CLASS_QQ FROM CLASS_TABLE WHERE CLASS_NAME LIKE 'XXX';")
conn.close()

QQ机器人的实现

这里我使用的QQ机器人是nonebot,这是一个跨平台 PYTHON 异步机器人框架。注意:由于使用了python的异步架构,所以要求python>=3.7.3
这个机器人是从幼稚园园长这里看到的,感觉还不错,就借鉴过来了。
这里给一个简化版本的安装步骤,详细版本的可以看这里
这里使用的内容有OneBot v11协议的QQ机器人是使用go-cqhttp实现的。

1.新建一个nonebot文件夹,里面再新建两个文件夹,nonebot和gocqhttp
xmu-check-2022-09-14-16-29-51

2.安装脚手架

1
pip install nb-cli

3.安装go-cqhttp
打开go-cqhttp,下载对应的系统版本,使用包管理器安装就可以了。

4.初始化go-cqhttp

1
2
3
4
5
6
7
# 打开目录
cd gocqhttp
# 执行go-cqhttp
go-cqhttp
# 选择反向WebSocket
# 打开config.yml
vim config.yml

5.配置QQ号及密码 还有反向ws地址
第4、5行写QQ号和密码
第96行 universal: ws://your_websocket_universal.server 替换为 universal: ws://127.0.0.1:8080/onebot/v11/ws

6.登陆QQ
执行go-cqhttp命令就可以成功登陆QQ了,可以使用无后台启动或者是screen命令启动。

1
2
3
4
# 创建cqhttp视窗
screen -S cqhttp
# 启动cqhttp
go-cqhttp

按住Ctrl键不放,接着连续按下A和D,就可以切换视窗了。回到视窗使用screen -r cqhttp命令。

7.创建nonebot机器人

1
2
cd nonebot
nb create

输入项目名称 -> 使用 ↓ 选择src文件夹 -> 按空格激活内置插件echo -> 按空格选择noebot v11回车

8.配置机器人

具体的配置方法可以参考官网的配置信息
机器人会自动加载.dev里面的ENVIRONMENT配置项对应的配置文件,例如ENVIRONMENT=dev,则加载.env.dev配置文件。
配置信息示例如下:

1
2
3
4
5
6
7
8
9
10
HOST=0.0.0.0  # 配置 NoneBot2 监听的 IP/主机名
PORT=8080 # 配置 NoneBot2 监听的端口
SUPERUSERS=["123456789", "987654321"] # 配置 NoneBot 超级用户
NICKNAME=["awesome", "bot"] # 配置机器人的昵称
COMMAND_START=["/", ""] # 配置命令起始字符
COMMAND_SEP=["."] # 配置命令分割字符

# Custom Configs
CUSTOM_CONFIG1="config in env file"
CUSTOM_CONFIG2= # 留空则从系统环境变量读取,如不存在则为空字符串

9.启动机器人

1
2
3
4
# 创建nonebot视窗
screen -S nonebot
# 启动机器人
nb run

按住Ctrl键不放,接着连续按下A和D,就可以切换视窗了。回到视窗使用screen -r nonebot命令。

编写机器人脚本

这个需要查阅官方文档实现,这里需要用到的是定时启动机器人和发送信息方法。
定时任务:https://v2.nonebot.dev/docs/advanced/scheduler
发送消息:

1
2
3
msg = MessageSegment.text("记得健康打卡哦!\n")
msg += MessageSegment.at("1742747655")
bot.send_group_msg(group_id=int('********'), message=msg)

大概就是这样的形式就可以了。
当然,如果想要机器人能够稳定运行,最好是使用docker来部署机器人。
其他部署方法参考官网

结尾

最好的其实还是大家能够自觉完成每日健康打卡,而不需要班委/辅导员来提醒,但是我自己也会总是有因为各种原因忘记打卡的,所以弄了这个机器人希望可以帮助到大家。

FAQ

1.为啥不弄微信的?
微信官方对于机器人抓的比较紧,有一个就封一个,估计是以前被微商弄怕了,也是很无奈。
2.其他形式的推送方式?
可以考虑公众号或者邮件推送的形式。IOS用户可以考虑弄一个IOS的自助推送服务。