1. 快速创建QQ机器人
WebQQ介绍
WebQQ腾讯公司推出的使用网页方式上QQ的服务,特点是无需下载和安装QQ软件,只要能打开WebQQ的网站就可以登录QQ与好友保持联系。具有Web产品固有的便利性,同时在Web上最大限度的保持了客户端软件的操作习惯。
通过WebQQ利用爬虫类的脚本,我们能够接受已登录用户所有好友信息,并且相应的聊天信息。但是2018年12月12日,QQ发布公告,称由于业务调整,webQQ已经于2019年1月1日停止服务,并提示用户下载QQ客户端。
采用Python语言制作方案
要实现用python发送 / 接收消息,要用requests发送http请求之外,还要用flask在本地搭建一个flask服务端,告知插件flask服务器的地址和端口,这样所有的qq消息都会自动传递给flask,我们可以根据消息的来源,内容,自动判断是否要回复即可。
1.1 相关官方文档介绍
官方参考文档介绍
nonebot框架官方文档:https://v2.nonebot.dev/docs/api
go-cqhttp通信规范API参考文档:
https://docs.go-cqhttp.org/
go-cqhttp安装下载网址:https://github.com/Mrs4s/go-cqhttp/releases/tag/v1.0.0-beta2
在github下载go-cqhttp,根据你的操作系统选择相应的版本
windows64位选择:go-cqhttp_windows_amd64.exe
linux选择:go-cqhttp_0.9.40-fix5_linux_amd64.deb
1.2 go-cqhttp安装部署操作
配置 CQHTTP 协议端(以 QQ 为例)
单纯运行 NoneBot 实例并不会产生任何效果,因为此刻 QQ 这边还不知道 NoneBot 的存在,也就无法把消息发送给它,因此现在需要使用一个无头 QQ 来把消息等事件上报给 NoneBot。
这里以 go-cqhttp (opens new window)为例
如果下载的zip压缩包,那么需要进行解压:
将go-cqhttp.exe可执行文件用Powershell窗口进行执行
Powershell窗口怎么打开呢?按住shift切换键键,然后鼠标右击,选中在此处打开Powershell窗口。
Windows PowerShell 是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NETFramework的强大功能。它引入了许多非常有用的新概念,从而进一步扩展了在 Windows 命令提示符和 Windows Script Host 环境中获得的知识和创建的脚本。
powershell是一个shell,定义好了一些命令操作系统,特别是与文件系统交互,能够启动应用程序,甚至操纵应用程序。PowerShell还能允许将几个命令组合起来放到文件里执行,实现文件级的重用,PowerShell 能够充分利用copy.Net类型和 COM 对象,来简单地与各种系统交互,完成各种复杂的、自动化的操作。
执行go-cqhttp.exe
PS [go-cqhttp_windows_amd64解压后的目录]>.go-cqhttp.exe
执行go-cqhttp.exe文件,会出现如下的选择:
执行完成后,再go-cqhttp.exe的同级目录下会生成config.yml配置文件
通过vscode打开可以看见,是QQ登录连接相关的配置,我们需要对其部分根据我们的需求进行修改,部分截取如下:
配置文件config.yml的最后几行是关于Server服务相关的配置
1.3 go-cqhttp协议端配置
配置go-cqhttp的config.yml文件,登录QQ机器人
account:
uin: 机器人QQ号
password: "机器人密码"
message:
post-format: array
servers:
- ws-reverse:
universal: ws://127.0.0.1:8080/cqhttp/ws
其中 ws://127.0.0.1:8080/cqhttp/ws 中的 127.0.0.1 和 8080 应分别对应 nonebot 配置的 HOST 和 PORT。
cqhttp 是前述 register_adapter 时传入的第一个参数,代表设置的 CQHTTPBot 适配器的路径,你可以对不同的适配器设置不同路径以作区别。
配置QQ号与密码如下:
uin: 1233456 # QQ账号 改成你的QQ机器人的号码
password: '' # 密码为空时使用扫码登录
我们先启动测试下:继续打开Powershell窗口,进行运行go-cqhttp.exe,然后会出现相应的授权登录的二维码,我们把需要制作成QQ机器人的QQ号进行扫码授权登录。
扫码成功后出现的结果如下所示:
1.4 nonebot搭建反向服务器
搭建Websocket Universal 反向服务器
我们可以借助安装nonebot脚手架,方便搭建反向服务器。
官方教程网址:https://v2.nonebot.dev/docs/start/installation
如果安装后执行,提示报错缺少nonebot依赖的其他第三方库,自行根据提示进行安装即可。
安装nonebot脚手架
PS [你的项目目录]> pip install nonebot2
安装驱动器
NoneBot 在默认安装情况下内置了 fastapi 服务端驱动器,其他驱动器如 httpx, aiohttp 则需要额外安装。
PS C:Users16204PycharmProjectswristqq> nb driver list
FastAPI () - FastAPI 驱动器
Quart (quart) - Quart 驱动器
HTTPX (httpx) - HTTPX 驱动器
websockets (websockets) - websockets 驱动器
AIOHTTP (aiohttp) - AIOHTTP 驱动器
安装nonebot相关的第三方库之后,pip list,看到如下的相应的库,就可以满足条件了。
nb-cli选择0.5.0版本即可,如果要使用nb-cli==0.6.5版本,那么nonebot2要使用beta.1的版本。
nonebot22.0.0a16可能会与nb-cli0.6.5版本不匹配:nb-cli 0.6.5 requires nonebot2<3.0.0,>=2.0.0-beta.1, but you have nonebot2 2.0.0a16 which is incompatible.
借助nonebot框架,创建项目
在terminal窗口启动,创建nonebot工程
如果你已经按照推荐方式安装了 nb-cli,使用它创建一个空项目:
PS [你的项目目录]>> nb create
根据引导进行项目配置,完成后会在当前目录下创建一个项目目录,项目目录内包含 bot.py。
如果未安装 nb-cli,使用你最熟悉的编辑器或 IDE,创建一个名为 bot.py 的文件,内容如下(这里以 CQHTTP 适配器为例):
import nonebot
from nonebot.adapters.cqhttp import Bot as CQHTTPBot
nonebot.init()
driver = nonebot.get_driver()
driver.register_adapter("cqhttp", CQHTTPBot)
nonebot.load_builtin_plugins()
if __name__ == "__main__":
nonebot.run()
在上方 bot.py 中,这几行高亮代码将依次:
-
使用默认配置初始化 NoneBot
-
加载 NoneBot 内置的 CQHTTP 协议适配组件
register_adapter 的第一个参数我们传入了一个字符串,该字符串将会在后文 配置 CQHTTP 协议端 时使用。
-
加载 NoneBot 内置的插件
-
在地址 127.0.0.1:8080 运行 NoneBot
在命令行使用如下命令即可运行这个 NoneBot 实例:
nb run # nb-cli
python bot.py # 其他
运行后会产生如下日志:
09-14 21:02:00 [INFO] nonebot | Succeeded to import "nonebot.plugins.base"
09-14 21:02:00 [INFO] nonebot | Running NoneBot...
09-14 21:02:00 [INFO] uvicorn | Started server process [1234]
09-14 21:02:00 [INFO] uvicorn | Waiting for application startup.
09-14 21:02:00 [INFO] uvicorn | Application startup complete.
09-14 21:02:00 [INFO] uvicorn | Uvicorn running on http://127.0.0.1:8080 (Press CTRL+C to quit)
1.5 创建nonebot客户端项目
友情提示:有同学可能会遇到,nb-cli==0.5.0的版本,再创建项目的时候遇到adapter协议适配器选择时候发生报错,可能是版本原因
解决方案,先安装beta.1,安装nb-cli==0.6.5,用0.6.5创建项目,然后卸载beta.1版本,重装nonebot2仍然使用a16。(最主要原因beta.1版本在加载cq-http时候会出现版本问题,beta.1使用的是bot11
我们通过控制台终端进行创建:
[?] Project Name: wrist
[?] Where to store the plugin? 2) In a "src" folder
[?] Which builtin plugin(s) would you like to use? echo
[?] Which adapter(s) would you like to use?
[?] You haven't chosen any adapter. Please confirm. y
创建完成之后可以看到有项目的文件夹生成:
然后修改下我们的bot.py,引入我们的cq-http协议适配器:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import nonebot
from nonebot.adapters.cqhttp import Bot as CQHTTPBot
nonebot.init()
app = nonebot.get_asgi()
driver = nonebot.get_driver()
driver.register_adapter("cqhttp", CQHTTPBot)
nonebot.load_builtin_plugins()
# 加载我们的插件(一般是自定义的插件)
if __name__ == "__main__":
nonebot.logger.warning("Always use `nb run` to start the bot instead of manually running!")
nonebot.run(app="__mp_main__:app")
生成的项目文件夹中,会有一个env.dev文件,bot.py运行启动的配置文件:
HOST=127.0.0.1 # 运行主机的ip地址
PORT=8080 # 反向服务器的端口号
LOG_LEVEL=DEBUG
FASTAPI_RELOAD=true
1.6 运行项目测试
接下来,我们启动运行bot.py文件,开启我们的反向服务器,根据之前cq-http的目录,打开Powershell窗口,进行运行go-cqhttp.exe,开启协议端的服务,让两者成功连接。运行结果如下所示:
接下来我们简单测试下:用另一个QQ打开与机器人的聊天窗口,测试如下:
1.7 自定义Plugins插件
在运行bot.py文件的时候在控制台会出现如下日志:这个就是插件,echo是nonebot内置插件,我们可以直接使用,如果想加强我们的机器人的功能,则需要我们自定义插件去实现。
02-06 14:07:08 [SUCCESS] nonebot | Succeeded to import "nonebot.plugins.echo"
我们在项目目录src/plugins下开发自己的插件:
举例让机器人发送语音:
from nonebot.adapters.cqhttp import Message
from nonebot import on_keyword
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
test = on_keyword({'语音'})
# on_keyword是接收某关键词的意思,api
@test.handle()
async def send_audio(bot: Bot, event: Event, state: T_State):
audio = "[CQ:record,file=http://music.163.com/song/media/outer/url?id=504924216.mp3]"
await test.send(Message(audio))
当我们自定义的插件写完之后,并没有直接被调用,所以我们要在我们的启动文件bot.py中进行引入,方法如下:
nonebot.load_plugins('src/plugins')
效果图如下所示:
然后打开与机器人的会话窗口,进行测试:
2. QQ机器人插件拓展
在上节已经介绍了QQ机器人的开发,已经简单小案例的测试,接下来我们要加强它的功能,学习方式是查看官方文档的规范来进行拓展它的功能。
也可以借助我们以往的知识,Python的web开发,以及爬虫的实现进行整合到我们的QQ机器人中,让它的功能更加的丰富。
CQ码官方文档:https://docs.go-cqhttp.org/cqcode/
2.1 插件开发知识点
首先介绍下基本插件开发的固定格式,展示如下所示:
from nonebot.adapters.cqhttp import Message
from nonebot import on_keyword
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
test = on_keyword({'[关键词]'})
@test.handle()
async def test_fun(bot: Bot, event: Event, state: T_State):
test_msg = "[CQ码]"
await test.send(Message(test_msg))
介绍下event事件对象的相关参数与方法:
print(event.get_message())
# 本次事件接受到的消息内容,只有内容包含关键词就会执行test_fun事件处理函数
print(event.get_user_id())
# 本次事件接受到的消息内容的发送者id,这边指的就是发送者的QQ号
print(event.get_session_id())
# 本次事件接受到的消息当前会话id
# 如果私聊就是发送者的QQ号
# 如果是群聊的接收就是 group_群号_QQ号
接下介绍下,问答形式的轮询事件的定义,当发送者发送命令后,QQ机器人进行回复,再次接收先前发送者的回答进行判断抉择。
@eng.got("key", prompt="请问你要翻译的句子是?")
async def res_test(bot: Bot, event: Event, state: T_State):
translate = state["key"]
print(translate)
print(event.get_message())
# 上面两者的输出结果是一致的。
2.2 发送QQ表情与图片
QQ机器人发送QQ表情的实现
QQ表情CQ码文档:QQ表情CQ码官方文档
为了减少试验,这里总结了一个 QQ 表情的 CQ 码对应表情的表格,对应的是 [CQ:face,id={id}]
实现随机发送QQ表情,CQ码的范围是0~221(其中小黄脸的范围是0 ~ 39),随机获取整数来发送CQ编号对应的QQ表情。
random.random()
: 生成一个随机的浮点数,在0 ~ 1之间
random.randint()
: 随机生成一个int类型的数,可以指定这个数的范围。
from nonebot.adapters.cqhttp import Message
from nonebot import on_keyword
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
emoji = on_keyword({'发表情'})
@emoji.handle()
async def send_emoji(bot: Bot, event: Event, state: T_State):
emoji_msg = "[CQ:face,id=12]"
await emoji.send(Message(emoji_msg))
开启与QQ机器人的聊天窗口,运行测试如下所示: