Nonebot2插件高级
一、 工作流程
1、 概念
hook:钩子函数,它们可以在Nonebot处理事件的不同时刻进行拦截、修改或者扩展。在Nonebot中,事件钩子函数分为事件预处理、运行预处理、运行后预处理和事件后处理
Matcher: Matcher
并不是一个具体的实例 instance
,而是一个具有特定属性的类 class
。只有当 Matcher
响应事件时,才会实例化为具体的 instance
,也就是 matcher
。matcher
可以认为是 NoneBot 处理 Event
的基本单位,运行 matcher
是 NoneBot 工作的主要内容。
handler:事件处理函数,它们可以认为是 NoneBot 处理 Event
的最小单位。在不考虑 hook
的情况下,运行 matcher 就是顺序运行 matcher.handlers,这句话换种表达方式就是,handler
只有添加到 matcher.handlers
时,才可以参与到 NoneBot 的工作中来。
2、 简介
NoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人收到的事件进行解析和处理,并以插件化的形式,按优先级分发给事件所对应的事件响应器,来完成具体的功能。
在实际应用中,NoneBot 会充当一个高性能,轻量级的 Python 微服务框架。协议端可以通过 http、websocket 等方式与之通信,这个通信往往是双向的:一方面,协议端可以上报数据给 NoneBot,NoneBot 会处理数据并返回响应给协议端;另一方面,NoneBot 可以主动推送数据给协议端。而 NoneBot 便是围绕双向通信进行工作的。
Nonebot启动之前的准备工作:
- 运行
nonebot.init()
,读取配置文件,初始化Nonebot和Driver对象 - 注册协议适配器Adapter
- 加载插件
准备工作完成后,Nonebot会利用异步进行启动,并且会运行on_startup
钩子函数
随后,协议端与Nonebot进行连接,Driver将数据提交给Adapter,然后,实例化Bot,Nonebot会利用Bot开始工作:
- 事件处理:Bot会将协议端上报的数据转换为Event事件,之后Nonebot根据一套既定的流程来处理事件
- 调用API:在事件处理的过程中,Nonebot可以通过Bot调用协议端指定的API来获取更多数据,或者反馈响应给协议端;Nonebot也可以通过调用API向协议端主动请求数据获取主动推送数据
3、 事件处理
首先,我们来看一下事件处理的流程图:
总的可以分为三个阶段:
-
Driver 接收上报数据
协议端会通过 websocket 或 http 等方式与 NoneBot 的后端驱动
Driver
连接,协议端上报数据后,Driver
会将原始数据交给Adapter
处理 -
Adapter 处理原始数据
Adapter
检查授权许可,并获取self-id
作为唯一识别 id- 根据
self-id
实例化Adapter
相应的Bot
- 根据
Event Model
将原始数据转化为 NoneBot 可以处理的Event
对象 Bot
和Event
交由 NoneBot 进一步处理
-
Nonebot 处理Event
- 执行事件预处理 hook
- 按优先级升序选出同一优先级的 Matcher
- 根据 Matcher 定义的 Rule、Permission 判断是否运行
- 实例化 matcher 并执行运行预处理 hook
- 顺序运行 matcher 的所有 handlers
- 执行运行后处理 hook
- 判断是否停止事件传播
- 执行事件后处理 hook
同时,Nonebot中还有一些特殊异常处理,可以自行到官网查看:https://v2.nonebot.dev/docs/advanced/#%E7%89%B9%E6%AE%8A%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86
4、 调用协议端接口
NoneBot 调用 API
会有如下过程:
- 调用
calling_api_hook
预处理钩子 adapter
将信息处理为原始数据,并转交driver
,driver
交给协议端处理driver
接收协议端的结果,交给adapter
处理之后将结果反馈给 NoneBot- 调用
called_api_hook
后处理钩子
一般来说,我们可以用 bot.*
来调用 API
(*是 API
的 action
或者 endpoint
)。
对于发送消息而言,一方面可以调用既有的 API
;另一方面 NoneBot 实现了两个便捷方法,bot.send(event, message, **kwargs)
方法和可以在 handler
中使用的 Matcher.send(message, **kwargs)
方法,来向事件主体发送消息。
二、 定时任务
1、 安装插件
这个插件是在APScheduler
的基础上进行开发的,如果需要更加详细的使用方式,可以通过官方文档进行学习:https://apscheduler.readthedocs.io/en/3.x/,后面我会加一篇关于这个库的使用方式,欢迎大家关注哦!
这个定时任务的实现,是通过一个Nonebot插件来实现的
nb plugin install nonebot_plugin_apscheduler
使用poetry来安装:
poetry add nonebot-plugin-apscheduler
2、 快速使用
- 在需要设置定时任务的插件中,通过
nonebot.require
声明插件依赖 - 从 nonebot_plugin_apscheduler 导入
scheduler
对象 - 在该对象的基础上,根据
APScheduler
的使用方法进一步配置定时任务
from nonebot import require
require("nonebot_plugin_apscheduler")
from nonebot_plugin_apscheduler import scheduler
@scheduler.scheduled_job("cron", hour="*/2", id="xxx", args=[1], kwargs={
"arg2": 2})
async def run_every_2_hour(arg1, arg2):
pass
scheduler.add_job(run_every_day_from_program_start, "interval", days=1, id="xxx") # 使用这种方法添加也可以
可以使用装饰器来添加定时任务,也可以通过函数来添加定时任务
3、 配置插件
根据项目的 .env
文件设置,向 .env.*
或 bot.py
文件添加 nonebot_plugin_apscheduler 的可选配置项
apscheduler_autostart
:
- 类型:bool
- 默认值:True
- 是否自动启动
APScheduler
apscheduler_config
:
- 类型:dict
- 默认值:
{"apscheduler.timezone": "Asia/Shanghai"}
APScheduler
相关配置。修改/增加其中配置项需要确保prefix: apscheduler
。
三、 匹配规则
1、 创建规则
匹配规则可以是一个 Rule
对象,也可以是一个 RuleChecker
类型。Rule
是多个 RuleChecker
的集合,只有当所有 RuleChecker
检查通过时匹配成功。RuleChecker
是一个返回值为 Bool
类型的依赖函数,即,RuleChecker
支持依赖注入。
2、 创建RuleCheck
async def user_checker(event: Event) -> bool:
return event.get_user_id() == "123123" # 检测触发事件的用户的id是否为123123
matcher = on_message(rule=user_checker)
3、 创建Rule
async def user_checker(event