现有情形下,选择一门适合自己的语言来编写QQ bot才是一个最好的选择。

编辑于 2021.7.16 转载请注明作者

简介

首先,我个人不是什么正经的开发者——甚至没有上过什么课,或者看过什么正经的教程,所需要的东西完全来自于网络星星点点的缝合,因此有很多地方的写法和语法都会非常的令人头大与迷惑。

但尽管如此,我还是希望通过这一篇文章让大部分明白——基于GOCQ开发QQ bot并非一件难事,只要假以时日都能有所进展。

本项目已上传github,如有需要可自行取用作为参考——虽然我觉得大部分人都不需要就是了。

思路

选取链接方式

GO CQHTTP允许采用POST、反向POST、正向Websocket和反向Websocket四种方式进行框架和程序的沟通;出于各种方便的考虑,我选用了websocket进行事件的监听,通过http post进行API的调用——这样的一个好处是,如果完全使用ws,那么你的API调用的回执会混杂在ws中,在高并发环境下分离这些回执信息变得有些复杂。

当选择完成后,则需要考虑使用python进行链接。
首先,我们的主线程一定是以监听事件为主的,因此:

这样的一个对接流程,便能够将接受到的所有信息,送入到mapping_flow模块下的main_process的一个匹配流函数中。

匹配

在匹配过程中,我们需要将多种不同的消息类型完全的分割开来,并且将不同的类型送入到不同的函数中。

根据GO-CQHTTP提供的事件数据,只需要解析json就可以通过一系列判断将其分离。

在实际开发时可以只选择自己需要的事件进行分离,其余不需要的直接丢弃——在每个elif后面,则是对json信息的一个校验,检查是否属于当前事件,如果是,那么就异步调用(await)后面的event函数。

这样,我们只需要定义event函数内部的内容,就可以控制bot在收到指定消息的时候进行相对应的处理。

比如上文中,当发生了戳一戳事件时(poke_event),则会直接调用setu模块的setu函数,其中传入的两个参数分别为接收到的消息数据data和一个是否r18的Flag。

调用API

那么我们已经接收到了事件,该如何回应呢?

如果我们调用print,那它只会从console里面发送出一段log,如果要让bot能够在QQ中进行回复,我们必须要调用POST方法,将自己需要回复的内容反馈给GOCQ框架提供的API。

因此我新建了一个api模块,专门用以储存封装GOCQ现有的API方案。

请注意,上文的代码只是一个简单的摘抄和举例!并不能真正的使用!如果想要得到完整版代码,还请前往github一探究竟。

回应

这是一个简单的程序,提供了一个向QQ群发送图片的示例。

去耦合

但是我们注意到,这样的匹配方案中,我们编写“插件”,每次都需要修改mapping_flow中的内容,这样的结果并不是我想要的——我希望能够通过一个方案,不修改mapping_flow的内容来达到增加可匹配关键词的结果——这不仅是一种去耦合的要求,也是一种灵活性的要求。

因此我采用了铃心的传统,将大部分的消息事件分为了私聊和群聊两类,并且进行了三种匹配方式的导入(正则、完全、前缀)

值得注意的是,因为python的特殊性,在api.py中加入了一个全局变量管理模块,用以在多文件间传递变量。

添加secret

对于公网上的服务器,请务必添加secret防止恶意攻击。


我什么都不懂,我只会现学现卖,谢谢配合。