Nonebot beta1教程
Nonebot2在更新到beta1版本后许多地方和alpha16版本有许多差异,包括但不限于适配器、依赖的更改。
- Python版本 ≥ 3.7
- 基于Windows 10版本(Win11也可以但我只能说快逃)
- 使用了pip用于安装
- 使用了脚手架nb-cli
- 使用了onebot.v11适配器
创建项目之前
在创建机器人项目前需要安装:
而这些都会讲到,已经安装过了的建议空降。
下载Python
进入Python官网。
选择3.7.3版本以上的进行下载。
我的Python版本是3.9.9,选择上图中的 Windows installer (64-bit) 进行下载。
下载完成后点进 python-3.9.9-amd64.exe,勾选 Add Python 3.9 to PATH 后点击 Install Now。
当然,你也可以自定义路径,但一定要勾选PATH。
- 等待下载……
下载完毕后开个CMD输入python --version
,出现Python 3.9.9
就代表能用了。
安装pip
pip是Python包管理工具,用来下载Python的包。
- 进入PyPI,选择最新版本的pip。
- 选择 Download Files,下载 pip-22.0.2.tar.gz 进行解压。
解压后进入文件夹内,右键空白处打开CMD,输入
python setup.py install
等待安装……
安装完成后开个CMD输入pip --version
,出现pip 22.0.2 from 路径……
时就代表能用了。
安装nb-cli
Nonebot2提供了相当便利的工具nb-cli,安装它也会直接安装nonebot 2.0.0-beta1。
开个CMD输入
pip install nb-cli
出现
Successfully installed nb-cli……
就代表pip安装nb-cli成功了。
下载go-cqhttp
做机器人只有Nonebot2是不足够的,Nonebot2仅能做到处理机器人上报的事件。
机器人的实际工作流程为:
- 协议端 上报数据给 后端驱动;
- 后端驱动 将原始数据转交给 协议适配 处理;
- 协议适配,或称为bot,将数据转化为event转交给Nonebot2;
- Nonebot2处理event。
很显然,我们只有处理event的Nonebot2。
获取数据的工作便交到了go-cqhttp身上:它相当于你的另一个QQ,接收到信息后便转交到Nonebot2手上等着处理完和发送。
- 进入go-cqhttp仓库,下载最新版本的releases。
- 选择 go-cqhttp_windows_amd64.exe 进行下载和备用。
—
创建项目
现在该下的都下载完了,是时候创建机器人项目了:
新建项目
新建一个文件夹,右键打开CMD,输入
nb create
。Project Name:
,输入你想给你机器人取的名字。Where to store the plugin?
,这意味着机器人插件的存放路径,建议选择In a "src" folder
。Which builtin plugin(s)……巴拉巴拉
,这就是在问你你的机器人要不要Nonebot2内嵌的插件,建议只选择echo
插件。
Which adapter(s)……巴拉巴拉
,选择你想要的协议适配,这里要选择OneBot V11
,别忘了空格再回车。期间会进行适配器等的安装,结束后你的文件夹内便会出现机器人名字的文件夹,差不多长这样:
机器人名字 ├── src │ └── plugins ├── .env ├── .env.dev ├── .env.prod ├── .gitignore ├── bot.py ├── docker-compose.yml ├── Dockerfile ├── pyproject.toml └── README.md
src/plugins
为Nonebot2插件存放处,插件则是Nonebot2的核心,可以实现模块化、功能扩展等.env.*
等文件是项目的配置文件,内存有变量ENVIRONMENT
,是Nonebot2启动时就会寻找的系统环境变量.gitignore
,如果不上传到git仓库的话可以无视bot.py
是是启动Nonebot2时默认的入口文件pyproject.toml
是项目插件配置文件Dockerfile
和docker-compose.yml
皆为Docker镜像配置文件
配置项目
.env
文件是基础的环境配置文件,不管是什么环境都会被加载,不过还是会被 .env.{环境}
文件所覆盖。
而环境有:
- 开发环境 development或dev
- 生产环境 production或prod
等等等等,就不一一列举了。
打开
.env
文件写入:ENVIRONMENT=dev
。
开发环境将会报告错误日志,这也会将环境变量的加载导向.env.dev
文件。打开
.env.dev
文件,写入以下配置:HOST=127.0.0.1 PORT=xxxx SUPERUSERS=["xxxxx"] NICKNAME=["xxx"] COMMAND_START=["/",""] COMMAND_SEP=["x"]
- 其中,
HOST
为Nonebot2监听的IP/主机名 PORT
为监听的端口,这里可以随意选择一个四位数SUPERUSERS
为超级用户,后面会说作用。值是一个QQ号,建议使用大号NICKNAME
为机器人的昵称COMMAND_START
为命令起始字符,后面会说作用,这里先用”/“COMMAND_SEP
为命令分割字符
第2步完成后对Nonebot2的基础配置就完成了,但我们还未配置go-cqhttp。
再新建一个文件夹,里边存放我们之前下载的 go-cqhttp_windows_amd64.exe,同时我建议将该exe文件重命名为 go-cqhttp.exe。新建一个
config.yml
文件,作为go-cqhttp的配置文件。
- 配置信息前往go-cqhttp文档内进行复制粘贴
servers
下面选择ws-reverse
,如下图
- 修改配置信息:
account
下的uin
需要填写机器人所用的QQ账号password
需要填写QQ账号的密码servers
下的port
需要填写配置Nonebot2时填写的四位数PORT
- 启动go-cqhttp.exe。百分百会弹出生成.bat文件的窗口,直接关闭后会发现文件夹内多出了一个 go-cqhttp.bat,以后启动go-cqhttp都需要用到这个文件。
启动后go-cqhttp会进行登录,出现[INFO]: アトリは、高性能ですから!
时便是登陆成功,要开始连接到Nonebot2了。
因为我们Nonebot2还未开启,此时的go-cqhttp只会一直弹出黄色的连接失败。
用下机器人
一切准备成功,机器人已经可以使用了!
使用机器人时,Nonebot2和go-cqhttp都需要 一直开启。对于不想长期开着电脑的小伙伴,建议使用云服务器。
打开存放 bot.py 的文件夹,右键开启CMD,输入
nb run
。打开存放 go-cqhttp.bat 的文件夹,左键打开。
等待第1步的CMD出现了
[INFO] nonebot | OneBot V11 | Bot QQ账号 connected [INFO] websockets | connection open
便意味着机器人可以使用了。
快马加鞭通过大号给机器人账号发送
/echo 喵
这边是因为我的机器人命令起始字符为"hoka",你也可以修改成自己喜欢的 机器人一旦复读了,便真正的代表着,你成功的搭建了一个QQ机器人。
好了,现在新手教程结束了,来试试这些插件吧.jpg
深入插件
咳咳,恭喜你获得了一个刚出生的QQ机器人!但它九年义务教育还未完成……
对于一个功能完善的机器人而言,完善的插件系统 是不可缺少的。
我们接下来的才是Nonebot2的重头戏:插件讲解。
什么是插件
仔细读的都知道,插件是Nonebot2的核心。插件既可以是一个模块,也可以是一个包。
插件的存放路径是 src/plugins
,在这个路径下,任何 .py文件 或 有__init__.py文件的文件夹 都算为插件。
多说不如少做,瞅一眼插件实例,说不定能够更理解插件的用处。
创建插件
在机器人文件夹里右键开启CMD,输入
nb plugin create
。Project Name:
,输入插件的名称Where to store the plugin?
,自处是询问插件存放的路径,选择src/plugins
即可。Do you want to load……巴拉巴拉
。如果你想在你创建的这个插件里再套娃一个插件,就选y
;反之就n
。正常都是不用套娃。没了,你的插件创建完成噜。
进入src/plugins
里边,就能看到插件名称的文件夹,里边分别躺着 init.py 和 config.py 文件。
前者用于编写插件内容,相当于插件的入口文件;后者则是插件的配置文件。
其实直接在文件夹内新建也可以,就提一嘴。
用别人的插件
要是自己代码写不明白,岂不是永远都没法整一个机器人了?
没有的事。Nonebot2具有一个专属的商店,其包含了开源的
- 驱动器
- 适配器
- 插件
- 机器人
使用他人的插件很简易,方法也多,就是别忘了用了后给他们一个 STAR~
pip安装法:
举例:NoneBot离线文档【nonebot_plugin_docs】
这个插件在加载后会输出一个可以 离线打开 的Nonebot2网址。开个CMD,输入
pip install nonebot_plugin_docs
等待安装完成……
来到机器人文件夹下的 bot.py,找到上图这个位置。
nonebot.load_builtin_plugins("echo")
意思便是Nonebot2加载了内嵌的echo插件,也就是我们之前试用机器人时用的echo功能。nonebot.load_from_toml("pyproject.toml")
加载了配置内插件存放路径下所有的插件,也就是src/plugins
。
实际上,插件的加载也有前后之分。按照上图的顺序来说,机器人启动时都会事先加载echo插件,其次才是src/plugins
下的插件。按照你想要的顺序,在 bot.py 里加入
nonebot.load_plugin("nonebot_plugin_docs")
注意,一定要是_
,而不是-
。启动机器人,加载插件时应当会出现一句
[INFO] nonebot_plugin_docs | Nonebot docs will be running at: http://localhost:端口/website/
有了便是加载成功,没有也没关系,必定会有一大串红红绿绿的错误日志等待着你。回头看看哪里疏漏,修复了就成。
脚手架安装法:
举例:定时任务【nonebot_plugin_apscheduler】
该插件为定时任务插件,使用方式见其仓库。进入有 pyproject.toml 的机器人文件夹内,右键开启CMD,输入
nb plugin install nonebot_plugin_apscheduler
- 等待安装完成……
完成后便能在 pyproject.toml 里面发现多了一句plugins = ["nonebot_plugin_apscheduler"]
要是没有也没关系,还是那句话,一大串错误日志等待着你。看看哪里出了问题,修复了就成。
Github下载法:
- 这个法子的好处是可以自行修改源代码,不过手要勤奋点了。
Github账号如何注册这里就不写了。喂明明连Python怎么安装都写了
举例:Nonebot2 消息撤回插件【nonebot_plugin_withdraw】
- 进入其仓库,找到上图这个地方,选择 Download ZIP。
单单解压上图选中的这个文件夹在你的
src/plugins
下。
解压时如果出现同名文件夹套文件夹,将被套的文件夹移上一级即可。启动机器人,出现
[SUCCESS] nonebot | Succeeded to import "nonebot_plugin_withdraw"
这句便代表成功力。
没有的话,错误日志.jpg如果文件不是很多的话,可以直接复制粘贴文件内容。
事件响应器
事件响应器,或Matcher,是响应接收到的事件的单元。
多说不如少做,我们来写一个 接收到“hi”这个词时就作出响应 的事件响应器吧。
定义辅助函数即可在插件内创建事件响应器。
不过事先我们得从nonebot主模块里导出辅助函数。按照上边的教程,随便建立一个插件,进入其 init.py 文件,写入
from nonebot import on_command
on_command
就是这里我们要用的辅助函数,它会创建命令消息事件响应器。
因为我们要在接收到“hi”时就有响应,“hi”就是这里的命令消息。写入
from nonebot.permission import SUPERUSER
该步骤实际为可选,SUPERUSER我们在上边配置.env文件时有提到过,即超级用户。
在Nonebot2中,超级用户就像是QQ群聊中的管理员,享受着高贵的特权。
被设置了超级用户权限的事件响应器 只会 对超级用户账号作出响应。
- 写入
matcher = on_command("hi", permission=SUPERUSER, priority=10)
matcher
在这里是事件响应器的名称,可以随便取,就是在同个文件里不能重名。"hi"
指定了“hi”为命令消息,只有在接收到命令消息时机器人才会响应。permission=SUPERUSER
设置了超级用户权限,只有在超级用户发送“hi”时机器人才会响应。priority=10
定义了该事件响应器的优先级。优先级数字越小越先响应,以1开始。可以不填,这边提一嘴。
和优先级一样可选的变量还有:匹配规则、阻断等等。
辅助函数大全可见官方网址。
不过现在只是建立了一个 可以响应 的事件响应器,处理流程还没写呢。
处理流程
事件的处理流程由处理依赖组成,即 Dependent。
而装饰器能够装饰一个函数,让其自动转换为Dependent对象并加入事件响应器的处理流程中。
装饰器分为:
- handle;最基本的装饰器
- receive;在handle的基础上会中断当前事件处理流程,并等待一个新的事件
- got;和receive相似但用于接收消息,贴近于对话形式会话
由于我们的例子是 接收到“hi”这个词时就作出响应,这里用handle装饰器即可。
在事件响应器下面写入
@matcher.handle()
matcher
依旧是事件响应器的名称。
这里的handle为装饰器。写入
async def func():
我们定义了一个名为func的函数,而在handle装饰器下,func函数已经变成了Dependent对象。
- 在QQ里面,我们要如何才能知道发了“hi”后,机器人到底有没有作出响应?
我的建议是让机器人也发送什么,比如“喵”。
在func函数内写入await matcher.send("喵")
,即这个名为matcher的事件响应器响应后发送了“喵”。
到这里,处理流程也写好了,不过还是缺些什么才能作为一个可运作的插件。
插件实例
虽然处理流程写出模子来了,但问题也来了:这么写是 没法获取上下文信息 的。
获取上下文信息的重点就在func函数里,该函数需要从Onebot.11适配器里导出的 Bot
参数。
分别添加
from nonebot.params import State
from nonebot.typing import T_State
from nonebot.adapters.onebot.v11 import Bot, Event
在func函数括号内添加
bot: Bot, event: Event, state: T_State = State()
对于更多的参数,见官方网址。Bot
基类用于处理上报消息、提供API调用接口。Event
基类提供了关键信息的方法,如获取事件消息内容。T_State
表明了该事件处理状态为State类型。State
则是Nonebot2 beta1版本新添的依赖,T_State
必须要陪着一个State
。
对于我们的例子来说,除了Bot
实际都是可选项,只是提一嘴。
上图便是一个小型插件的完整样貌。
启动机器人,快马加鞭使用大号向机器人账号发送“hi”,便会收获一个你自己写出来的猫咪女仆聊天机器人。
尾声
感谢看完!
个人对Nonebot2的理解不是非常透彻,码来码去也只是码了一个创建聊天机器人的基础教程。想必通篇下来错误也不少,哪里有问题建议直接爆破我。
也许抽空会把聊天机器人的其他东西给码码?当然,我说的是也许。鸽了
电脑添加或手机添加我自己的机器人Hoka-Bot,臭不要脸来宣传噜。
鸣谢
更新
02/04:
- 添加了超级用户、触发权限的描述
- 添加了event、state的简单描述
- 添加了手机QQ添加Hoka-Bot的超级链接