Nonebot2 在更新到 beta1 版本后许多地方和 alpha16 版本有许多差异,包括但不限于适配器、依赖的更改。

Nonebot2

Nonebot2 是 Python 聊天机器人框架,目前仅支持 Python 3.7.3 以上的版本

开始本教程前,需要知道该教程:

  • Python 版本 ≥ 3.7
  • 基于 Windows 10 版本(Win11 也可以但我只能说快逃)
  • 使用了 pip 用于安装
  • 使用了脚手架 nb-cli
  • 使用了 onebot.v11 适配器

创建项目之前

在创建机器人项目前需要安装:

而这些都会讲到,已经安装过了的建议空降

————————

下载Python

  1. 进入 Python 官网

  2. 选择 3.7.3 版本以上的进行下载。

    python 3.9.9

  3. 我的 Python 版本是 3.9.9,选择上图中的 Windows installer (64-bit) 进行下载。

  4. 下载完成后点进 python-3.9.9-amd64.exe,勾选 Add Python 3.9 to PATH 后点击 Install Now
    当然,你也可以自定义路径,但一定要勾选 PATH。

    python --version

  5. 等待下载……

    下载完毕后开个CMD输入 python --version,出现 Python 3.9.9 就代表能用了。

————————

安装pip

pip 是 Python 包管理工具,用来下载 Python 的包。

  1. 进入 PyPI,选择最新版本的 pip。

    pip

  2. 选择 Download Files,下载 pip-22.0.2.tar.gz 进行解压。

    pip解压

  3. 解压后进入文件夹内,右键空白处打开CMD,输入 python setup.py install

  4. 等待安装……
    安装完成后开个 CMD 输入 pip --version,出现 pip 22.0.2 from 路径…… 时就代表能用了。

————————

安装nb-cli

Nonebot2 提供了相当便利的工具 nb-cli,安装它也会直接安装 nonebot 2.0.0-beta1。

  1. 开个 CMD 输入 pip install nb-cli

  2. 出现 Successfully installed nb-cli…… 就代表 pip 安装 nb-cli 成功了。

————————

下载go-cqhttp

做机器人只有 Nonebot2 是不足够的,Nonebot2 仅能做到处理机器人上报的事件。
机器人的实际工作流程为:

  1. 协议端 上报数据给 后端驱动
  2. 后端驱动 将原始数据转交给 协议适配 处理;
  3. 协议适配,或称为 bot,将数据转化为 event 转交给 Nonebot2;
  4. Nonebot2 处理 event。

很显然,我们只有处理 event 的 Nonebot2。

获取数据的工作便交到了 go-cqhttp 身上:它相当于你的另一个 QQ,接收到信息后便转交到 Nonebot2 手上等着处理完和发送。

  1. 进入 go-cqhttp仓库,下载最新版本的 releases。

  2. 选择 go-cqhttp_windows_amd64.exe 进行下载和备用。

————————

创建项目

现在该下的都下载完了,是时候创建机器人项目了:

  1. 新建项目
  2. 配置项目
  3. 用下机器人
————————

新建项目

  1. 新建一个文件夹,右键打开 CMD,输入 nb create

  2. Project Name:,输入你想给你机器人取的名字。

  3. Where to store the plugin?,这意味着机器人插件的存放路径,建议选择 In a "src" folder

  4. Which builtin plugin(s)……巴拉巴拉,这就是在问你你的机器人要不要 Nonebot2 内嵌的插件,建议只选择 echo 插件。

    echo

    需要注意的是,选择内嵌插件时要按下空格再回车继续。

  5. Which adapter(s)……巴拉巴拉,选择你想要的协议适配,这里要选择 OneBot V11,别忘了空格再回车。

  6. 期间会进行适配器等的安装,结束后你的文件夹内便会出现机器人名字的文件夹,差不多长这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    机器人名字
    ├── 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 是项目插件配置文件
  • Dockerfiledocker-compose.yml 皆为 Docker 镜像配置文件
————————

配置项目

.env 文件是基础的环境配置文件,不管是什么环境都会被加载,不过还是会被 .env.{环境} 文件所覆盖。

而环境有:

  • 开发环境 development 或 dev
  • 生产环境 production 或 prod
    等等等等,就不一一列举了。
  1. 打开 .env 文件写入:ENVIRONMENT=dev
    开发环境将会报告错误日志,这也会将环境变量的加载导向 .env.dev 文件。

  2. 打开 .env.dev 文件,写入以下配置:

    1
    2
    3
    4
    5
    6
    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 为命令分割字符
  3. 第 2 步完成后对 Nonebot2 的基础配置就完成了,但我们还未配置 go-cqhttp。

    再新建一个文件夹,里边存放我们之前下载的 go-cqhttp_windows_amd64.exe,同时我建议将该 exe 文件重命名为 go-cqhttp.exe

  4. 新建一个 config.yml 文件,作为 go-cqhttp 的配置文件。

    • 配置信息前往 go-cqhttp 文档内进行复制粘贴
    • servers 下面选择 ws-reverse,如下图

    ws-reverse

  5. 修改配置信息:

    • account 下的 uin 需要填写机器人所用的 QQ 账号
    • password 需要填写 QQ 账号的密码
    • servers 下的 port 需要填写配置 Nonebot2 时填写的四位数 PORT
  6. 启动 go-cqhttp.exe。百分百会弹出生成 .bat 文件的窗口,直接关闭后会发现文件夹内多出了一个 go-cqhttp.bat,以后启动 go-cqhttp 都需要用到这个文件。

    启动后 go-cqhttp 会进行登录,出现 [INFO]: アトリは、高性能ですから! 时便是登陆成功,要开始连接到 Nonebot2 了。

    因为我们 Nonebot2 还未开启,此时的 go-cqhttp 只会一直弹出黄色的连接失败。

————————

用下机器人

一切准备成功,机器人已经可以使用了!

使用机器人时,Nonebot2 和 go-cqhttp 都需要 一直开启。对于不想长期开着电脑的小伙伴,建议使用云服务器。

  1. 打开存放 bot.py 的文件夹,右键开启 CMD,输入 nb run

  2. 打开存放 go-cqhttp.bat 的文件夹,左键打开。

  3. 等待第 1 步的 CMD 出现了

    1
    2
    [INFO] nonebot | OneBot V11 | Bot QQ账号 connected
    [INFO] websockets | connection open

    便意味着机器人可以使用了。

  4. 快马加鞭通过大号给机器人账号发送 /echo 喵

    echo

    这边是因为我的机器人命令起始字符为"hoka",你也可以修改成自己喜欢的

  5. 机器人一旦复读了,便真正的代表着,你成功的搭建了一个 QQ 机器人。

    好了,现在新手教程结束了,来试试这些插件吧.jpg

————————

深入插件

咳咳,恭喜你获得了一个刚出生的 QQ 机器人!但它九年义务教育还未完成……
对于一个功能完善的机器人而言,完善的插件系统 是不可缺少的。

我们接下来的才是 Nonebot2 的重头戏:插件讲解

————————

什么是插件

仔细读的都知道,插件是 Nonebot2 的核心。插件既可以是一个模块,也可以是一个包。

插件的存放路径是 src/plugins,在这个路径下,任何 .py文件有__init__.py文件的文件夹 都算为插件。

插件名称不可以重复。

多说不如少做,瞅一眼插件实例,说不定能够更理解插件的用处。

————————

创建插件

  1. 在机器人文件夹里右键开启 CMD,输入 nb plugin create

  2. Project Name:,输入插件的名称

  3. Where to store the plugin?,自处是询问插件存放的路径,选择 src/plugins 即可。

  4. Do you want to load……巴拉巴拉。如果你想在你创建的这个插件里再套娃一个插件,就选 y;反之就 n。正常都是不用套娃。

  5. 没了,你的插件创建完成噜。

    进入 src/plugins 里边,就能看到插件名称的文件夹,里边分别躺着 init.pyconfig.py 文件。

    前者用于编写插件内容,相当于插件的入口文件;后者则是插件的配置文件。

    其实直接在文件夹内新建也可以,就提一嘴。

————————

用别人的插件

要是自己代码写不明白,岂不是永远都没法整一个机器人了?

没有的事。Nonebot2 具有一个专属的商店,其包含了开源的

  • 驱动器
  • 适配器
  • 插件
  • 机器人

使用他人的插件很简易,方法也多,就是别忘了用了后给他们一个 STAR~

......

pip安装法:

docs

  1. 举例:NoneBot 离线文档【nonebot_plugin_docs】

    这个插件在加载后会输出一个可以 离线打开 的 Nonebot2 网址。

  2. 开个 CMD,输入 pip install nonebot_plugin_docs

  3. 等待安装完成……

    bot.py

  4. 来到机器人文件夹下的 bot.py,找到上图这个位置。

    nonebot.load_builtin_plugins("echo") 意思便是Nonebot2加载了内嵌的echo插件,也就是我们之前试用机器人时用的echo功能。

    nonebot.load_from_toml("pyproject.toml") 加载了配置内插件存放路径下所有的插件,也就是 src/plugins

    实际上,插件的加载也有前后之分。按照上图的顺序来说,机器人启动时都会事先加载echo插件,其次才是 src/plugins 下的插件。

  5. 按照你想要的顺序,在 bot.py 里加入 nonebot.load_plugin("nonebot_plugin_docs")

    注意,一定要是 _,而不是-

  6. 启动机器人,加载插件时应当会出现一句 [INFO] nonebot_plugin_docs | Nonebot docs will be running at: http://localhost:端口/website/

    有了便是加载成功,没有也没关系,必定会有一大串红红绿绿的错误日志等待着你。回头看看哪里疏漏,修复了就成。

......

脚手架安装法:

apscheduler

  1. 举例:定时任务【nonebot_plugin_apscheduler】

    该插件为定时任务插件,使用方式见其仓库

  2. 进入有 pyproject.toml 的机器人文件夹内,右键开启CMD,输入 nb plugin install nonebot_plugin_apscheduler

    pyproject

  3. 等待安装完成……

    完成后便能在 pyproject.toml 里面发现多了一句 plugins = ["nonebot_plugin_apscheduler"]

    要是没有也没关系,还是那句话,一大串错误日志等待着你。看看哪里出了问题,修复了就成。

......

Github下载法:

withdraw

  1. 这个法子的好处是可以自行修改源代码,不过手要勤奋点了。

    Github 账号如何注册这里就不写了。喂明明连 Python 怎么安装都写了

    举例:Nonebot2 消息撤回插件【nonebot_plugin_withdraw】

    download

  2. 进入其仓库,找到上图这个地方,选择 Download ZIP。

    zip

  3. 单单解压上图选中的这个文件夹在你的 src/plugins 下。

    解压时如果出现同名文件夹套文件夹,将被套的文件夹移上一级即可。

  4. 启动机器人,出现 [SUCCESS] nonebot | Succeeded to import "nonebot_plugin_withdraw" 这句便代表成功力。

    没有的话,错误日志.jpg

  5. 如果文件不是很多的话,可以直接复制粘贴文件内容。

————————

事件响应器

事件响应器,或 Matcher,是响应接收到的事件的单元。

多说不如少做,我们来写一个 接收到"hi"这个词时就作出响应 的事件响应器吧。

  1. 定义辅助函数即可在插件内创建事件响应器。

    不过事先我们得从 nonebot 主模块里导出辅助函数。

  2. 按照上边的教程,随便建立一个插件,进入其 init.py 文件,写入 from nonebot import on_command

    on_command 就是这里我们要用的辅助函数,它会创建命令消息事件响应器。

    因为我们要在接收到"hi"时就有响应,"hi"就是这里的命令消息。

  3. 写入 from nonebot.permission import SUPERUSER

    该步骤实际为可选,SUPERUSER 我们在上边配置 .env 文件时有提到过,即超级用户。

    在 Nonebot2 中,超级用户就像是 QQ 群聊中的管理员,享受着高贵的特权。

    被设置了超级用户权限的事件响应器 只会 对超级用户账号作出响应。

    hi

  4. 写入 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 装饰器即可。

  1. 在事件响应器下面写入 @matcher.handle()

    matcher 依旧是事件响应器的名称。

    这里的 handle 为装饰器。

  2. 写入 async def func():

    我们定义了一个名为 func 的函数,而在 handle 装饰器下,func 函数已经变成了 Dependent 对象。

    await

  3. 在 QQ 里面,我们要如何才能知道发了"hi"后,机器人到底有没有作出响应?

    我的建议是让机器人也发送什么,比如"喵"。

    在 func 函数内写入 await matcher.send("喵"),即这个名为 matcher 的事件响应器响应后发送了"喵"。

到这里,处理流程也写好了,不过还是缺些什么才能作为一个可运作的插件。

————————

插件实例

虽然处理流程写出模子来了,但问题也来了:这么写是 没法获取上下文信息 的。

获取上下文信息的重点就在 func 函数里,该函数需要从 Onebot.11 适配器里导出的 Bot 参数。

  1. 分别添加 from nonebot.params import State

    from nonebot.typing import T_State

    from nonebot.adapters.onebot.v11 import Bot, Event

  2. 在 func 函数括号内添加 bot: Bot, event: Event, state: T_State = State()

    对于更多的参数,见官方网址

  3. Bot 基类用于处理上报消息、提供 API 调用接口。

    Event 基类提供了关键信息的方法,如获取事件消息内容。

    T_State 表明了该事件处理状态为 State 类型。

    State 则是 Nonebot2 beta1 版本新添的依赖,T_State 必须要陪着一个 State

    对于我们的例子来说,除了 Bot 实际都是可选项,只是提一嘴。

test_plugin

上图便是一个小型插件的完整样貌。

启动机器人,快马加鞭使用大号向机器人账号发送"hi",便会收获一个你自己写出来的猫咪女仆聊天机器人。