🔀 Merge pull request #769

Docs: Fix copywriting
This commit is contained in:
Ju4tCode 2022-02-08 10:50:59 +08:00 committed by GitHub
commit 58bceff175
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 321 additions and 332 deletions

View File

@ -8,7 +8,7 @@ slug: /
NoneBot2 是一个现代、跨平台、可扩展的 Python 聊天机器人框架,它基于 Python 的类型注解和异步特性,能够为你的需求实现提供便捷灵活的支持。 NoneBot2 是一个现代、跨平台、可扩展的 Python 聊天机器人框架,它基于 Python 的类型注解和异步特性,能够为你的需求实现提供便捷灵活的支持。
需要注意的是NoneBot 仅支持 **Python 3.7.3 以上版本** 需要注意的是NoneBot2 仅支持 **Python 3.7.3 以上版本**
## 特色 ## 特色
@ -18,15 +18,15 @@ NoneBot2 基于 Python [asyncio](https://docs.python.org/3/library/asyncio.html)
### 完整的类型注解 ### 完整的类型注解
NoneBot2 参考 [PEP 484](https://www.python.org/dev/peps/pep-0484/) 等 PEP 完整实现了类型注解,通过 `pyright`/`pylance` 检查。配合编辑器的类型推导功能,能将绝大多数的 Bug 杜绝在编辑器中 ([编辑器支持](./start/editor-support)) NoneBot2 参考 [PEP 484](https://www.python.org/dev/peps/pep-0484/) 等 PEP 完整实现了类型注解,通过 `pyright`/`pylance` 检查。配合编辑器的类型推导功能,能将绝大多数的 Bug 杜绝在编辑器中[编辑器支持](./start/editor-support)
### 开箱即用 ### 开箱即用
NoneBot2 提供了使用便捷、具有交互式功能的命令行工具 -- `nb-cli`,使得初次接触 NoneBot 时更容易上手。详细使用方法请参考各文档章节以及 [使用脚手架](./start/nb-cli)。 NoneBot2 提供了使用便捷、具有交互式功能的命令行工具--`nb-cli`,使得初次接触 NoneBot2 时更容易上手。详细使用方法请参考各文档章节以及[使用脚手架](./start/nb-cli)。
### 插件系统 ### 插件系统
插件系统是 NoneBot 的核心,通过它可以实现机器人的模块化以及功能扩展,便于维护和管理。 插件系统是 NoneBot2 的核心,通过它可以实现机器人的模块化以及功能扩展,便于维护和管理。
### 依赖注入系统 ### 依赖注入系统
@ -34,15 +34,15 @@ NoneBot2 采用了一套自行定义的依赖注入系统,可以让事件的
#### 什么是依赖注入 #### 什么是依赖注入
[**"依赖注入"**](https://zh.m.wikipedia.org/wiki/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC)意思是,在编程中,有一种方法可以让你的代码声明它工作和使用所需要的东西, 即"**依赖**" [**“依赖注入”**](https://zh.m.wikipedia.org/wiki/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC)意思是,在编程中,有一种方法可以让你的代码声明它工作和使用所需要的东西,即**“依赖”**
系统 (在这里是指 `NoneBot` ) 将负责做任何需要的事情,为你的代码提供这些必要依赖 (即"**注入**"依赖性) 系统(在这里是指 NoneBot2将负责做任何需要的事情为你的代码提供这些必要依赖即**“注入”**依赖性)
这在你有以下情形的需求时非常有用: 这在你有以下情形的需求时非常有用
- 这部分代码拥有共享的逻辑(同样的代码逻辑多次重复) - 这部分代码拥有共享的逻辑(同样的代码逻辑多次重复)
- 共享数据库以及网络请求连接会话 - 共享数据库以及网络请求连接会话
- 比如 `httpx.AsyncClient`, `aiohttp.ClientSession``sqlalchemy.Session` - 比如 `httpx.AsyncClient`、`aiohttp.ClientSession``sqlalchemy.Session`
- 用户权限检查以及认证 - 用户权限检查以及认证
- 还有更多... - 还有更多...

View File

@ -16,33 +16,33 @@ options:
## 它如何工作? ## 它如何工作?
如同[概览](../README.md)所言: 如同[概览](../README.md)所言
> NoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人收到的事件进行解析和处理,并以插件化的形式,按优先级分发给事件所对应的事件响应器,来完成具体的功能。 > NoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人收到的事件进行解析和处理,并以插件化的形式,按优先级分发给事件所对应的事件响应器,来完成具体的功能。
`Nonebot2` 是一个可以对机器人上报的事件进行处理并完成具体功能的机器人框架,在这里,我们将简要讲述它的工作内容。 NoneBot2 是一个可以对机器人上报的事件进行处理并完成具体功能的机器人框架,在这里,我们将简要讲述它的工作内容。
**便捷起见,以下内容对 `Nonebot2` 会被称为 `nonebot`,与 `Nonebot2` 交互的机器人实现会被称为 `协议端`**。 **便捷起见,以下内容对 NoneBot2 会被称为 NoneBot与 NoneBot2 交互的机器人实现会被称为协议端**。
在实际应用中,`nonebot` 会充当一个高性能,轻量级的 Python 微服务框架。协议端可以通过 `http`, `websocket` 等方式与之通信,这个通信往往是双向的:一方面,协议端可以上报数据给 `nonebot``nonebot` 会处理数据并返回响应给协议端;另一方面,`nonebot` 可以主动推送数据给协议端。而 `nonebot` 便是围绕双向通信进行工作的。 在实际应用中,NoneBot 会充当一个高性能,轻量级的 Python 微服务框架。协议端可以通过 http、websocket 等方式与之通信,这个通信往往是双向的:一方面,协议端可以上报数据给 NoneBotNoneBot 会处理数据并返回响应给协议端另一方面NoneBot 可以主动推送数据给协议端。而 NoneBot 便是围绕双向通信进行工作的。
在开始工作之前,`nonebot` 需要进行准备工作: 在开始工作之前,NoneBot 需要进行准备工作:
1. **运行 `nonebot.init` 初始化函数**,它会读取配置文件,并初始化 `nonebot` 和后端驱动 `driver` 对象。 1. **运行 `nonebot.init` 初始化函数**,它会读取配置文件,并初始化 NoneBot 和后端驱动 `Driver` 对象。
2. **注册协议适配器 `adapter`** 2. **注册协议适配器 `Adapter`**
3. **加载插件** 3. **加载插件**
准备工作完成后,`nonebot` 会利用 `uvicorn` 启动,并运行 `on_startup` 钩子函数。 准备工作完成后,NoneBot 会利用 uvicorn 启动,并运行 `on_startup` 钩子函数。
随后,倘若一个协议端与 `nonebot` 进行了连接,`nonebot` 的后端驱动 `driver` 就会将数据交给 `adapter` , 然后会实例化 `bot``nonebot` 便会利用 `bot` 开始工作,它的工作内容分为两个方面: 随后,倘若一个协议端与 NoneBot 进行了连接NoneBot 的后端驱动 `Driver` 就会将数据交给 `Adapter`,然后会实例化 `Bot`NoneBot 便会利用 `Bot` 开始工作,它的工作内容分为两个方面:
1. **事件处理**`bot` 会将协议端上报的数据转化为 `事件 `( `Event ` ),之后 `nonebot` 会根据一套既定流程来处理 `事件` 1. **事件处理**`Bot` 会将协议端上报的数据转化为 `Event`(事件),之后 NoneBot 会根据一套既定流程来处理事件
2. **调用 `API`**, 在**事件处理**的过程中,`nonebot` 可以通过 `bot` 调用协议端指定的 `API` 来获取更多数据,或者反馈响应给协议端; `nonebot` 也可以通过调用 `API` 向协议端主动请求数据或者主动推送数据。 2. **调用 `API`**,在**事件处理**的过程中NoneBot 可以通过 `Bot` 调用协议端指定的 `API` 来获取更多数据,或者反馈响应给协议端NoneBot 也可以通过调用 `API` 向协议端主动请求数据或者主动推送数据。
在**指南**模块, 我们已经叙述了[如何配置 nonebot](../tutorial/configuration.md), [如何注册协议适配器](../tutorial/register-adapter.md) [如何加载插件](../tutorial/plugin/load-plugin.md), 在这里便不再赘述。 在**指南**模块,我们已经叙述了[如何配置 NoneBot](../tutorial/configuration.md)、[如何注册协议适配器](../tutorial/register-adapter.md)以及[如何加载插件](../tutorial/plugin/load-plugin.md)这里便不再赘述。
下面,我们将对 **事件处理** **调用 API** 进行说明。 下面,我们将对**事件处理****调用 API** 进行说明。
## 事件处理 ## 事件处理
@ -50,59 +50,59 @@ options:
![handle-event](./images/Handle-Event.png) ![handle-event](./images/Handle-Event.png)
在流程图里,我们可以看到,`nonebot` 会有三个阶段来处理事件: 在流程图里,我们可以看到,NoneBot 会有三个阶段来处理事件:
1. **driver 接收上报数据** 1. **Driver 接收上报数据**
2. **adapter 处理原始数据** 2. **Adapter 处理原始数据**
3. **nonebot 处理 Event** 3. **NoneBot 处理 Event**
我们将顺序说明这三个阶段。其中,会将第三个阶段拆分成**概念解释****处理 Event****特殊异常处理**三个部分来说明。 我们将顺序说明这三个阶段。其中,会将第三个阶段拆分成**概念解释****处理 Event****特殊异常处理**三个部分来说明。
### driver 接收上报数据 ### Driver 接收上报数据
1. 协议端会通过 `websocket` 或者 `http` 等方式与 `nonebot` 的后端驱动 `driver` 连接,协议端上报数据后,`driver` 会将原始数据交给 `adapter` 处理。 1. 协议端会通过 websocket 或 http 等方式与 NoneBot 的后端驱动 `Driver` 连接,协议端上报数据后,`Driver` 会将原始数据交给 `Adapter` 处理。
:::warning :::warning
连接之前必须要注册 `adapter` 连接之前必须要注册 `Adapter`
::: :::
### adapter 处理原始数据 ### Adapter 处理原始数据
1. `adapter` 检查授权许可,并获取 `self-id` 作为唯一识别 id 。 1. `Adapter` 检查授权许可,并获取 `self-id` 作为唯一识别 id 。
:::tip :::tip
如果协议端通过 `websocket` 上报数据,这个步骤只会在建立连接时进行,并在之后运行 `on_bot_connect` 钩子函数;通过 `http` 方式连接时,会在协议端每次上报数据时都进行这个步骤。 如果协议端通过 websocket 上报数据,这个步骤只会在建立连接时进行,并在之后运行 `on_bot_connect` 钩子函数;通过 http 方式连接时,会在协议端每次上报数据时都进行这个步骤。
::: :::
:::warning :::warning
`self-id` 是帐号的唯一识别 ID这意味着不能出现相同的 `self-id` `self-id` 是帐号的唯一识别 ID这意味着不能出现相同的 `self-id`
::: :::
2. 根据 `self-id` 实例化 `adapter` 相应的 `bot` 。 2. 根据 `self-id` 实例化 `Adapter` 相应的 `Bot` 。
3. 根据 `Event Model` 将原始数据转化为 `nonebot` 可以处理的 `Event` 对象。 3. 根据 `Event Model` 将原始数据转化为 NoneBot 可以处理的 `Event` 对象。
:::tip :::tip
`adapter` 在转换数据格式的同时可以进行一系列的特殊操作,例如 `onebot` 会对 `reply` 信息进行提取。 `Adapter` 在转换数据格式的同时可以进行一系列的特殊操作,例如 OneBot 适配器会对 reply 信息进行提取。
::: :::
4. `bot` 和 `Event` 交由 `nonebot` 进一步处理。 4. `Bot` 和 `Event` 交由 NoneBot 进一步处理。
### nonebot 处理 Event ### NoneBot 处理 Event
在讲述这个阶段之前,我们需要先对几个概念进行解释。 在讲述这个阶段之前,我们需要先对几个概念进行解释。
#### 概念解释 #### 概念解释
1. **hook**,或者说**钩子函数**,它们可以在 `nonebot` 处理 `Event` 的不同时刻进行拦截,修改或者扩展,在 `nonebot` 中,事件钩子函数分为 `事件预处理hook``运行预处理hook``运行后处理hook` 和 `事件后处理hook` 1. **hook**,或者说**钩子函数**,它们可以在 NoneBot 处理 `Event` 的不同时刻进行拦截,修改或者扩展,在 NoneBot 中,事件钩子函数分为`事件预处理 hook`、`运行预处理 hook`、`运行后处理 hook` 和`事件后处理 hook`
:::tip :::tip
关于 `hook` 的更多信息,可以查阅[这里](./runtime-hook.md) 关于 `hook` 的更多信息,可以查阅[这里](./runtime-hook.md)
::: :::
2. **Matcher****matcher**,在**指南**中,我们讲述了[如何注册事件响应器](../tutorial/plugin/create-matcher.md),这里的事件响应器或者说 `Matcher` 并不是一个具体的实例 `instance`,而是一个具有特定属性的类 `class`。只有当 `Matcher` **响应事件**时,才会实例化为具体的 `instance`,也就是 `matcher` 。`matcher` 可以认为是 `nonebot` 处理 `Event` 的基本单位,运行 `matcher` 是`nonebot`工作的主要内容。 2. **Matcher****matcher**,在**指南**中,我们讲述了[如何注册事件响应器](../tutorial/plugin/create-matcher.md),这里的事件响应器或者说 `Matcher` 并不是一个具体的实例 `instance`,而是一个具有特定属性的类 `class`。只有当 `Matcher` **响应事件**时,才会实例化为具体的 `instance`,也就是 `matcher`。`matcher` 可以认为是 NoneBot 处理 `Event` 的基本单位,运行 `matcher` 是 NoneBot 工作的主要内容。
3. **handler**,或者说**事件处理函数**, 它们可以认为是 `nonebot` 处理 `Event` 的最小单位。在不考虑 `hook` 的情况下,**运行 matcher 就是顺序运行 matcher.handlers**,这句话换种表达方式就是,`handler` 只有添加到 `matcher.handlers` 时,才可以参与到 `nonebot` 的工作中来。 3. **handler**,或者说**事件处理函数**,它们可以认为是 NoneBot 处理 `Event` 的最小单位。在不考虑 `hook` 的情况下,**运行 matcher 就是顺序运行 matcher.handlers**,这句话换种表达方式就是,`handler` 只有添加到 `matcher.handlers` 时,才可以参与到 NoneBot 的工作中来。
:::tip :::tip
如何让 `handler` 添加到 `matcher.handlers` 如何让 `handler` 添加到 `matcher.handlers`
@ -112,45 +112,45 @@ options:
#### 处理 Event #### 处理 Event
1. **执行事件预处理 hook** `nonebot` 接收到 `Event` 后,会传入到 `事件预处理hook` 中进行处理。 1. **执行事件预处理 hook** NoneBot 接收到 `Event` 后,会传入到 `事件预处理 hook` 中进行处理。
:::warning :::warning
需要注意的是,执行多个 `事件预处理hook` 时并无顺序可言,它们是**并行运行**的。这个原则同样适用于其他的 `hook` 需要注意的是,执行多个 `事件预处理 hook` 时并无顺序可言,它们是**并行运行**的。这个原则同样适用于其他的 `hook`
::: :::
2. **按优先级升序选出同一优先级的 Matcher**`nonebot` 提供了一个全局字典 `matchers`,这个字典的 `key` 是优先级 `priority``value` 是一个 `list`,里面存放着同一优先级的 `Matcher`。在注册 `Matcher` 时,它和优先级 `priority` 会添加到里面。 2. **按优先级升序选出同一优先级的 Matcher**NoneBot 提供了一个全局字典 `matchers`,这个字典的 `key` 是优先级 `priority``value` 是一个 `list`,里面存放着同一优先级的 `Matcher`。在注册 `Matcher` 时,它和优先级 `priority` 会添加到里面。
在执行 `事件预处理hook` 后,`nonebot` 会对 `matchers``key` 升序排序并选择出当前最小优先级的 `Matcher` 在执行 `事件预处理 hook` 后NoneBot 会对 `matchers``key` 升序排序并选择出当前最小优先级的 `Matcher`
3. **根据 Matcher 定义的 Rule, Permission 判断是否运行**,在选出 `Matcher` 后,`nonebot` 会将 `bot``Event` 传入到 `Matcher.check_rule``Matcher.check_perm` 两个函数中,两个函数分别对 Matcher 定义的 `Rule`, `Permission` 进行 check当 check 通过后,这个 `Matcher` 就会响应事件。当同一个优先级的所有 `Matcher` 均没有响应时,`nonebot` 会返回到上一个步骤,选择出下一优先级的 `Matcher` 3. **根据 Matcher 定义的 Rule、Permission 判断是否运行**,在选出 `Matcher`NoneBot 会将 `bot``Event` 传入到 `Matcher.check_rule``Matcher.check_perm` 两个函数中,两个函数分别对 Matcher 定义的 `Rule`、`Permission` 进行 check当 check 通过后,这个 `Matcher` 就会响应事件。当同一个优先级的所有 `Matcher` 均没有响应时,NoneBot 会返回到上一个步骤,选择出下一优先级的 `Matcher`
4. **实例化 matcher 并执行运行预处理 hook**,当 `Matcher` 响应事件后,它便会实例化为 `matcher`,并执行 `运行预处理hook`。 4. **实例化 matcher 并执行运行预处理 hook**,当 `Matcher` 响应事件后,它便会实例化为 `matcher`,并执行 `运行预处理 hook`。
5. **顺序运行 matcher 的所有 handlers**`运行预处理hook` 执行完毕后,便会运行 `matcher`,也就是**顺序运行**它的 `handlers` 5. **顺序运行 matcher 的所有 handlers**`运行预处理 hook` 执行完毕后,便会运行 `matcher`,也就是**顺序运行**它的 `handlers`
:::tip :::tip
`matcher` 运行 `handlers` 的顺序是: 先运行该 `matcher` 的类 `Matcher` 注册时添加的 `handlers`(如果有的话),再按照装饰器装饰顺序运行装饰的 `handlers` `matcher` 运行 `handlers` 的顺序是先运行该 `matcher` 的类 `Matcher` 注册时添加的 `handlers`(如果有的话),再按照装饰器装饰顺序运行装饰的 `handlers`
::: :::
6. **执行运行后处理 hook**`matcher` 的 `handlers` 运行完毕后,会执行 `运行后处理hook`。 6. **执行运行后处理 hook**`matcher` 的 `handlers` 运行完毕后,会执行 `运行后处理 hook`。
7. **判断是否停止事件传播**`nonebot` 会根据当前优先级所有 `matcher``block` 参数或者 `StopPropagation` 异常判断是否停止传播 `Event`,如果事件没有停止传播,`nonebot` 便会返回到第 2 步, 选择出下一优先级的 `Matcher` 7. **判断是否停止事件传播**NoneBot 会根据当前优先级所有 `matcher``block` 参数或者 `StopPropagation` 异常判断是否停止传播 `Event`,如果事件没有停止传播,NoneBot 便会返回到第 2 步, 选择出下一优先级的 `Matcher`
8. **执行事件后处理 hook**,在 `Event` 停止传播或执行完所有响应的 `Matcher` 后,`nonebot` 会执行 `事件后处理hook`。 8. **执行事件后处理 hook**,在 `Event` 停止传播或执行完所有响应的 `Matcher` 后,NoneBot 会执行 `事件后处理 hook`。
`事件后处理hook` 执行完毕后,当前 `Event` 的处理周期就顺利结束了。 `事件后处理 hook` 执行完毕后,当前 `Event` 的处理周期就顺利结束了。
#### 特殊异常处理 #### 特殊异常处理
在这个阶段,`nonebot` 规定了几个特殊的异常,当 `nonebot` 捕获到它们时,会用特定的行为来处理它们。 在这个阶段,NoneBot 规定了几个特殊的异常,当 NoneBot 捕获到它们时,会用特定的行为来处理它们。
1. **IgnoredException** 1. **IgnoredException**
这个异常可以在 `事件预处理hook` 和 `运行预处理hook` 抛出。 这个异常可以在 `事件预处理 hook` 和 `运行预处理 hook` 抛出。
`事件预处理hook` 抛出它时,`nonebot` 会忽略当前的 `Event`,不进行处理。 `事件预处理 hook` 抛出它时NoneBot 会忽略当前的 `Event`,不进行处理。
`运行预处理hook` 抛出它时,`nonebot` 会忽略当前的 `matcher`,结束当前 `matcher` 的运行。 `运行预处理 hook` 抛出它时NoneBot 会忽略当前的 `matcher`,结束当前 `matcher` 的运行。
:::warning :::warning
`hook` 需要抛出这个异常时,要写明原因。 `hook` 需要抛出这个异常时,要写明原因。
@ -160,46 +160,46 @@ options:
这个异常可以在 `handler` 中由 `Matcher.pause` 抛出。 这个异常可以在 `handler` 中由 `Matcher.pause` 抛出。
`nonebot` 捕获到它时,会停止运行当前 `handler` 并结束当前 `matcher` 的运行,并将后续的 `handler` 交给一个临时 `Matcher` 来响应当前交互用户的下一个消息事件,当临时 `Matcher` 响应时,临时 `Matcher` 会运行后续的 `handler ` NoneBot 捕获到它时,会停止运行当前 `handler` 并结束当前 `matcher` 的运行,并将后续的 `handler` 交给一个临时 `Matcher` 来响应当前交互用户的下一个消息事件,当临时 `Matcher` 响应时,临时 `Matcher` 会运行后续的 `handler `
3. **RejectedException** 3. **RejectedException**
这个异常可以在 `handler` 中由 `Matcher.reject` 抛出。 这个异常可以在 `handler` 中由 `Matcher.reject` 抛出。
`nonebot` 捕获到它时,会停止运行当前 `handler` 并结束当前 `matcher` 的运行,并将当前 handler 和后续 `handler` 交给一个临时 `Matcher` 来响应当前交互用户的下一个消息事件,当临时 `Matcher` 响应时,临时 `Matcher` 会运行当前 `handler` 和后续的 `handler` NoneBot 捕获到它时,会停止运行当前 `handler` 并结束当前 `matcher` 的运行,并将当前 handler 和后续 `handler` 交给一个临时 `Matcher` 来响应当前交互用户的下一个消息事件,当临时 `Matcher` 响应时,临时 `Matcher` 会运行当前 `handler` 和后续的 `handler`
4. **FinishedException** 4. **FinishedException**
这个异常可以在 `handler` 中由 `Matcher.finish` 抛出。 这个异常可以在 `handler` 中由 `Matcher.finish` 抛出。
`nonebot` 捕获到它时,会停止运行当前 `handler` 并结束当前 `matcher` 的运行。 NoneBot 捕获到它时,会停止运行当前 `handler` 并结束当前 `matcher` 的运行。
5. **StopPropagation** 5. **StopPropagation**
这个异常一般会在执行 `运行后处理hook` 后抛出。 这个异常一般会在执行 `运行后处理 hook` 后抛出。
`nonebot` 捕获到它时, 会停止传播当前 `Event`,不再寻找下一优先级的 `Matcher`,直接执行 `事件后处理hook`。 NoneBot 捕获到它时, 会停止传播当前 `Event`,不再寻找下一优先级的 `Matcher`,直接执行 `事件后处理 hook`。
## 调用 API ## 调用 API
`nonebot` 可以通过 `bot` 来调用 `API` `API` 可以向协议端发送数据,也可以向协议端请求更多的数据。 NoneBot 可以通过 `bot` 来调用 `API``API` 可以向协议端发送数据,也可以向协议端请求更多的数据。
`nonebot` 调用 `API` 会有如下过程: NoneBot 调用 `API` 会有如下过程:
1. 调用 `calling_api_hook` 预处理钩子。 1. 调用 `calling_api_hook` 预处理钩子。
2. `adapter` 将信息处理为原始数据,并转交 `driver` , `driver` 交给协议端处理。 2. `adapter` 将信息处理为原始数据,并转交 `driver``driver` 交给协议端处理。
3. `driver` 接收协议端的结果,交给`adapter` 处理之后将结果反馈给 `nonebot` 3. `driver` 接收协议端的结果,交给`adapter` 处理之后将结果反馈给 NoneBot
4. 调用 `called_api_hook` 后处理钩子。 4. 调用 `called_api_hook` 后处理钩子。
在调用 `API` 时同样规定了特殊的异常,叫做 `MockApiException` 。该异常会由预处理钩子和后处理钩子触发,当预处理钩子触发时,`nonebot` 会跳过之后的调用过程,直接执行后处理钩子。 在调用 `API` 时同样规定了特殊的异常,叫做 `MockApiException` 。该异常会由预处理钩子和后处理钩子触发,当预处理钩子触发时,NoneBot 会跳过之后的调用过程,直接执行后处理钩子。
:::tip :::tip
不同 `adapter` 规定了不同的 API对应的 API 列表请参照协议规范。 不同 `adapter` 规定了不同的 API对应的 API 列表请参照协议规范。
::: :::
一般来说,我们可以用 `bot.*` 来调用 `API` (\*是 `API``action` 或者 `endpoint`) 一般来说,我们可以用 `bot.*` 来调用 `API`\*是 `API``action` 或者 `endpoint`
对于发送消息而言,一方面可以调用既有的 `API` ;另一方面 `nonebot` 实现了两个便捷方法,`bot.send(event, message, **kwargs)` 方法和可以在 `handler` 中使用的 `Matcher.send(message, **kwargs)` 方法,来向事件主体发送消息。 对于发送消息而言,一方面可以调用既有的 `API` ;另一方面 NoneBot 实现了两个便捷方法,`bot.send(event, message, **kwargs)` 方法和可以在 `handler` 中使用的 `Matcher.send(message, **kwargs)` 方法,来向事件主体发送消息。

View File

@ -10,7 +10,7 @@ options:
# 简介 # 简介
受 [`FastApi`](https://fastapi.tiangolo.com/tutorial/dependencies/) 启发NoneBot 同样编写了一个简易的依赖注入模块,使得开发者可以通过事件处理函数参数的类型标注来自动注入依赖。 受 [FastAPI](https://fastapi.tiangolo.com/tutorial/dependencies/) 启发NoneBot 同样编写了一个简易的依赖注入模块,使得开发者可以通过事件处理函数参数的类型标注来自动注入依赖。
## 什么是依赖注入? ## 什么是依赖注入?
@ -40,7 +40,7 @@ async def _(x: dict = Depends(depend)):
print(x) print(x)
``` ```
它和普通的事件处理函数并无区别,同样可以接 `bot`, `event` 等参数,你可以把它当作一个普通的事件处理函数但是去除了装饰器(没有使用 `matcher.handle()` 等来进行装饰),并且可以返回任何类型的值。 它和普通的事件处理函数并无区别,同样可以接 `bot`, `event` 等参数,你可以把它当作一个普通的事件处理函数但是去除了装饰器(没有使用 `matcher.handle()` 等来装饰),并且可以返回任何类型的值。
在这个例子中,依赖函数接受一个参数: 在这个例子中,依赖函数接受一个参数:
@ -48,7 +48,7 @@ async def _(x: dict = Depends(depend)):
并且返回了一个 `state` 的复制以及一个附加的键值 `depend` 并且返回了一个 `state` 的复制以及一个附加的键值 `depend`
### Import `Depends` ### 导入 `Depends`
```python {2} ```python {2}
from nonebot.log import logger from nonebot.log import logger

View File

@ -10,19 +10,17 @@ options:
# 事件处理函数重载 # 事件处理函数重载
当我们在编写 `nonebot2` 应用时,常常会遇到这样一个问题:该怎么让同一类型的不同事件执行不同的响应逻辑?又或者如何让不同的 `bot` 针对同一类型的事件作出不同响应? 当我们在编写 NoneBot2 应用时,常常会遇到这样一个问题:该怎么让同一类型的不同事件执行不同的响应逻辑?又或者如何让不同的 `bot` 针对同一类型的事件作出不同响应?
针对这个问题, `nonebot2` 提供一个便捷而高效的解决方案:事件处理函数重载机制。简单地说,`handler` (事件处理函数) 会根据其参数的 `type hints` ([PEP484 类型标注](https://www.python.org/dev/peps/pep-0484/)) 来对相对应的 `bot``Event` 进行响应,并且会忽略不符合其参数类型标注的情况。 针对这个问题, NoneBot2 提供一个便捷而高效的解决方案:事件处理函数重载机制。简单地说,`handler`(事件处理函数)会根据其参数的 `type hints`[PEP484 类型标注](https://www.python.org/dev/peps/pep-0484/))来对相对应的 `bot``event` 进行响应,并且会忽略不符合其参数类型标注的情况。
<!-- 必须要注意的是,该机制利用了 `inspect` 标准库获取到了事件处理函数的 `singnature` (签名) ,进一步获取到参数名称和类型标注。故而,我们在编写 `handler` 时,参数的名称和类型标注必须要符合 `T_Handler` 规定,详情可以参看 **指南** 中的[事件处理](../../guide/creating-a-handler)。 --> <!-- 必须要注意的是,该机制利用了 `inspect` 标准库获取到了事件处理函数的 `signature`(签名),进一步获取到参数名称和类型标注。故而,我们在编写 `handler` 时,参数的名称和类型标注必须要符合 `T_Handler` 规定,详情可以参看**指南**中的[事件处理](../../guide/creating-a-handler)。 -->
:::tip 提示 :::tip 提示
如果想了解更多关于 `inspect` 标准库的信息,可以查看[官方文档](https://docs.python.org/zh-cn/3.9/library/inspect.html)。 如果想了解更多关于 `inspect` 标准库的信息,可以查看[官方文档](https://docs.python.org/zh-cn/3.9/library/inspect.html)。
::: :::
下面,我们会以 `onebot` 中的 `群聊消息事件``私聊消息事件` 为例,对该机制的应用进行简单的介绍。 下面,我们会以 OneBot 适配器中的群聊消息事件和私聊消息事件为例,对该机制的应用进行简单的介绍。
## 一个例子 ## 一个例子
@ -33,13 +31,13 @@ from nonebot import on_command
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, PrivateMessageEvent from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, PrivateMessageEvent
``` ```
之后,我们可以注册一个 `Matcher` 来响应 `消息事件` 之后,我们可以注册一个 `Matcher` 来响应消息事件。
```python ```python
matcher = on_command("testoverload") matcher = on_command("test_overload")
``` ```
最后, 我们编写不同的 `handler` 并编写不同的类型标注来实现事件处理函数重载: 最后我们编写不同的 `handler` 并编写不同的类型标注来实现事件处理函数重载:
```python ```python
@matcher.handle() @matcher.handle()
@ -52,7 +50,7 @@ async def _(bot: Bot, event: PrivateMessageEvent):
await matcher.send("私聊消息事件响应成功!") await matcher.send("私聊消息事件响应成功!")
``` ```
此时,我们可以在群聊或私聊中对我们的机器人发送 `testoverload` ,它会在不同的场景做出不同的应答。 此时,我们可以在群聊或私聊中对我们的机器人发送 `test_overload`,它会在不同的场景做出不同的应答。
这样一个简单的事件处理函数重载就完成了。 这样一个简单的事件处理函数重载就完成了。

View File

@ -7,34 +7,32 @@ options:
# 跨插件访问 # 跨插件访问
由于 `nonebot2` 独特的插件加载机制,直接使用 python 原有的 import 机制来进行插件之间的访问时,很可能会有奇怪的或者意料以外的情况发生。为了避免这种情况的发生,您可以有如下方法来实现跨插件访问: 由于 NoneBot2 独特的插件加载机制,直接使用 Python 原生 import 机制来进行插件之间的访问时,很可能会发生奇怪或意料以外的情况。为了避免这种情况发生,您可以使用如下方法来实现跨插件访问:
1. 将插件间的要使用的公共代码剥离出来,作为公共文件或者文件夹,提供给插件加以调用。 1. 将插件间的要使用的公共代码剥离出来,作为公共文件或者文件夹,提供给插件加以调用。
2. 使用 `nonebot2` 提供的 `export``require` 机制,来实现插件间的互相调用。 2. 使用 NoneBot2 提供的 export 和 require 机制,来实现插件间的互相调用。
3. 在保证插件被加载的情况下,可以采用 `import` 来访问。 3. 在保证插件被加载的情况下,可以采用 import 来访问。
第一种方法比较容易理解和实现,这里不再赘述,但需要注意的是,请不要将公共文件或者公共文件夹作为**插件**被 `nonebot2` 加载。 第一种方法比较容易理解和实现,这里不再赘述,但需要注意的是,请不要将公共文件或者公共文件夹作为**插件**被 NoneBot2 加载。
第三种方法需要保证插件被加载,插件加载的方式可以参阅 [加载插件](../tutorial/plugin/load-plugin) 第三种方法需要保证插件被加载,插件加载的方式可以参阅[加载插件](../tutorial/plugin/load-plugin)。
下面将介绍第二种方法—— `export``require` 机制: 下面将介绍第二种方法——export 和 require 机制:
## 使用 export 和 require ## 使用 export 和 require
现在,假定有两个插件 `pluginA``pluginB`,需要在 `pluginB` 中调用 `pluginA` 中的一个变量 `varA` 和一个函数 `funcA` 现在,假定有两个插件 pluginA 和 pluginB需要在 pluginB 中调用 pluginA 中的一个变量 `varA` 和一个函数 `funcA`
在上面的条件中涉及到了两种操作:一种是在 `pluginA``导出对象` 操作;而另一种是在 `pluginB``导入对象` 操作。在 `nonebot2` 中,`导出对象` 的操作用 `export` 机制来实现,`导入对象` 的操作用 `require` 机制来实现。下面,我们将逐一进行介绍。 在上面的条件中涉及到了两种操作:一种是在 pluginA 的导出对象操作;而另一种是在 pluginB 的导入对象操作。在 NoneBot2 中,导出对象的操作用 export 机制来实现,导入对象的操作用 require 机制来实现。下面,我们将逐一进行介绍。
:::warning 警告 :::warning 警告
使用这个方法进行跨插件访问时,**需要先加载导出对象的插件,再加载导入对象的插件。**
使用这个方法进行跨插件访问时,**需要先加载`导出对象`的插件,再加载`导入对象`的插件。**
::: :::
### 使用 export ### 使用 export
`pluginA` 中,我们调用 `export` 机制 `导出对象` 在 pluginA 中,我们调用 export 机制 导出对象。
`export` 机制调用前,我们需要保证导出的对象已经被定义,比如: 在 export 机制调用前,我们需要保证导出的对象已经被定义,比如:
```python ```python
varA = "varA" varA = "varA"
@ -44,7 +42,7 @@ def funcA():
return "funcA" return "funcA"
``` ```
在确保定义之后,我们可以从 `nonebot.plugin` 导入 `export()` 方法, `export()` 方法会返回一个特殊的字典 `export` 在确保定义之后,我们可以从 `nonebot.plugin` 导入 `export()` 方法`export()` 方法会返回一个特殊的字典 `export`
```python ```python
from nonebot.plugin import export from nonebot.plugin import export
@ -52,21 +50,21 @@ from nonebot.plugin import export
export=export() export=export()
``` ```
这个字典可以用来装载导出的对象,它的 key 是对象导出后的命名value 是对象本身,我们可以直接创建新的 `key` - `value` 对导出对象: 这个字典可以用来装载导出的对象,它的 key 是对象导出后的命名value 是对象本身,我们可以直接创建新的 key - value 对导出对象:
```python ```python
export.vA = varA export.vA = varA
export.fA = funcA export.fA = funcA
``` ```
除此之外,也支持 `嵌套` 导出对象: 除此之外,也支持嵌套导出对象:
```python ```python
export.sub.vA = varA export.sub.vA = varA
export.sub.fA = funcA export.sub.fA = funcA
``` ```
特别地,对于 `函数对象` 而言,`export` 支持用 `装饰器` 的方法来导出,因此,我们可以这样定义 `funcA` 特别地对于函数对象而言export 支持用装饰器的方法来导出,因此,我们可以这样定义 `funcA`
```python ```python
@export.sub @export.sub
@ -74,7 +72,7 @@ def funcA():
return "funcA" return "funcA"
``` ```
或者: 或者
```python ```python
@export @export
@ -82,7 +80,7 @@ def funcA():
return "funcA" return "funcA"
``` ```
通过 `装饰器` 的方法导出函数时,命名固定为函数的命名,也就是说,上面的两个例子等同于: 通过装饰器的方法导出函数时,命名固定为函数的命名,也就是说,上面的两个例子等同于:
```python ```python
export.sub.funcA = funcA export.sub.funcA = funcA
@ -92,16 +90,14 @@ export.funcA = funcA
这样,我们就成功导出 `varA``funcA` 对象了。 这样,我们就成功导出 `varA``funcA` 对象了。
下面我们将介绍如何在 `pluginB` 中导入这些对象。 下面我们将介绍如何在 pluginB 中导入这些对象。
### 使用 require ### 使用 require
`pluginB` 中,我们调用 `require` 机制 `导入对象` 在 pluginB 中,我们调用 require 机制导入对象。
:::warning 警告 :::warning 警告
在导入来自其他插件的对象时,请确保导出该对象的插件在引用该对象的插件之前加载。如果该插件并未被加载,则会尝试加载,加载失败则会返回 `None`
在导入来自其他插件的对象时, 请确保导出该对象的插件在引用该对象的插件之前加载。如果该插件并未被加载,则会尝试加载,加载失败则会返回 `None`
::: :::
我们可以从 `nonebot.plugin` 中导入 `require()` 方法: 我们可以从 `nonebot.plugin` 中导入 `require()` 方法:
@ -110,17 +106,17 @@ export.funcA = funcA
from nonebot.plugin import require from nonebot.plugin import require
``` ```
`require()` 方法的参数是插件名, 它会返回在指定插件中,用 `export()` 方法创建的字典。 `require()` 方法的参数是插件名它会返回在指定插件中,用 `export()` 方法创建的字典。
```python ```python
require_A = require('pluginA') require_A = require('pluginA')
``` ```
在之前,这个字典已经存入了 `'vA'` - `varA`, `'fA'` - `funcA``'funcA'` - `funcA` 这样的 `key` - `value` 对。因此在这里我们直接用 `属性` 的方法来获取导入对象: 在之前,这个字典已经存入了 `'vA'` - `varA`、`'fA'` - `funcA``'funcA'` - `funcA` 这样的 key - value 对。因此在这里我们直接调用属性来获取导入对象:
```python ```python
varA = require_A.vA varA = require_A.vA
funcA = require_A.fA or require_A.funcA funcA = require_A.fA or require_A.funcA
``` ```
这样,我们就在 `pluginB` 中成功导入了 `varA``funcA` 对象了。 这样,我们就在 pluginB 中成功导入了 `varA``funcA` 对象了。

View File

@ -7,11 +7,11 @@ options:
# 权限控制 # 权限控制
**权限控制**是机器人在实际应用中需要解决的重点问题之一,`Nonebot` 提供了十分完善且灵活的权限控制机制—— `Permission` 机制。接下来我们将对这个机制进行简单的说明。 **权限控制**是机器人在实际应用中需要解决的重点问题之一,NoneBot2 提供了灵活的权限控制机制——`Permission`,接下来我们将简单说明。
## 应用 ## 应用
如同 `Rule` 一样, `Permission` 可以在[注册事件响应器](../tutorial/plugin/create-matcher.md)时添加 `permission` 参数来加以应用,这样 `Nonebot` 会在事件响应时检测事件主体的权限。下面我们以 `SUPERUSER` 为例,对该机制的应用做一下介绍。 如同 `Rule` 一样`Permission` 可以在[注册事件响应器](../tutorial/plugin/create-matcher.md)时添加 `permission` 参数来加以应用,这样 NoneBot2 会在事件响应时检测事件主体的权限。下面我们以 `SUPERUSER` 为例,对该机制的应用做一下介绍。
```python ```python
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
@ -28,20 +28,18 @@ async def _(bot: Bot):
@matcher.got("key1", "超管提问") @matcher.got("key1", "超管提问")
async def _(bot: Bot, event: Event): async def _(bot: Bot, event: Event):
await matcher.send("超管命令got成功") await matcher.send("超管命令 got 成功")
``` ```
在这段代码中,我们事件响应器指定了 `SUPERUSER` 这样一个权限,那么机器人只会响应超级管理员的 `测试超管` 命令,并且会响应该超级管理员的连续对话。 在这段代码中,我们事件响应器指定了 `SUPERUSER` 这样一个权限,那么机器人只会响应超级管理员的 `测试超管` 命令,并且会响应该超级管理员的连续对话。
:::tip 提示 :::tip 提示
在这里需要强调的是,`Permission` 与 `Rule` 的表现并不相同, `Rule` 只会在初次响应时生效,在余下的对话中并没有限制事件;但是 `Permission` 会持续生效,在连续对话中一直对事件主体加以限制。
在这里需要强调的是,`Permission` 与 `Rule` 的表现并不相同, `Rule` 只会在初次响应时生效,在余下的对话中并没有限制事件;但是 `Permission` 会持续生效,在连续对话中会一直对事件主体加以限制。
::: :::
## 进阶 ## 进阶
`Permission` 除了可以在注册事件响应器时加以应用,还可以在编写事件处理函数 `handler` 时主动调用,我们可以利用这个特性在一个 `handler` 里对不同权限的事件主体进行区别响应,下面我们以 `onebot` 中的 `GROUP_ADMIN` (普通管理员非群主)`GROUP_OWNER` 为例,说明下怎么进行主动调用。 `Permission` 除了可以在注册事件响应器时加以应用,还可以在编写事件处理函数 `handler` 时主动调用,我们可以利用这个特性在一个 `handler` 里对不同权限的事件主体进行区别响应,下面我们以 OneBot 适配器中的 `GROUP_ADMIN`(普通管理员非群主)`GROUP_OWNER` 为例,说明下怎么进行主动调用。
```python ```python
from nonebot import on_command from nonebot import on_command
@ -59,14 +57,13 @@ async def _(bot: Bot, event: GroupMessageEvent):
await matcher.send("群主测试成功") await matcher.send("群主测试成功")
else: else:
await matcher.send("群员测试成功") await matcher.send("群员测试成功")
``` ```
在这段代码里,我们并没有对命令的权限指定,这个命令会响应所有在群聊中的 `测试权限` 命令,但是在 `handler` 里,我们对两个 `Permission` 进行主动调用,从而可以对不同的角色进行不同的响应。 在这段代码里,我们并没有对命令的权限指定,这个命令会响应所有在群聊中的 `测试权限` 命令,但是在 `handler` 里,我们对两个 `Permission` 进行主动调用,从而可以对不同的角色进行不同的响应。
## 自定义 ## 自定义
如同 `Rule` 一样, `Permission` 也是由非负数个 `PermissionChecker` 组成的,但只需其中一个返回 `True` 时就会匹配成功。下面`PermissionChecker``Permission` 示例: 如同 `Rule` 一样`Permission` 也是由非负数个 `PermissionChecker` 组成的,但只需其中一个返回 `True` 时就会匹配成功。下面是自定义 `PermissionChecker``Permission` 示例:
```python ```python
from nonebot.adapters import Bot, Event from nonebot.adapters import Bot, Event
@ -86,7 +83,7 @@ def check(arg1, arg2):
return Permission(_checker) return Permission(_checker)
``` ```
`Permission``PermissionChecker` 之间可以使用 `或 |` 互相组合: `Permission``PermissionChecker` 之间可以使用 `|`(或符号)互相组合:
```python ```python
from nonebot.permission import Permission from nonebot.permission import Permission
@ -94,4 +91,4 @@ from nonebot.permission import Permission
Permission(async_checker1) | sync_checker | async_checker2 Permission(async_checker1) | sync_checker | async_checker2
``` ```
同样地,如果想用 `Permission(*checkers)` 包裹构造 `Permission` ,函数必须是异步的;但是在利用 `或 |` 符号连接构造时, `Nonebot` 会自动包裹同步函数为异步函数。 同样地,如果想用 `Permission(*checkers)` 包裹构造 `Permission`,函数必须是异步的;但是在利用 `|`或符号连接构造时NoneBot2 会自动包裹同步函数为异步函数。

View File

@ -9,61 +9,61 @@ options:
## 前注 ## 前注
本章节仅包含插件发布流程指导,插件开发请查阅 **[创建插件](../tutorial/plugin/introduction.md)** 章节与 **[Plugin API 文档](../api/plugin/index.md)** 本章节仅包含插件发布流程指导,插件开发请查阅[**创建插件**](../tutorial/plugin/introduction.md)章节与[**Plugin API 文档**](../api/plugin/index.md)
## 插件发布流程 ## 插件发布流程
### 发布到 PyPI ### 发布到 PyPI
您可以选择任意自己喜欢的方式将您的插件发布到 **[PyPI](https://pypi.org/)** ,如使用 **[setuptools](https://pypi.org/project/setuptools/)** 或 **[poetry](https://pypi.org/project/poetry/)** 进行 PyPI 发布 您可以选择自己喜欢的方式将插件发布到 [**PyPI**](https://pypi.org/),如使用 [**setuptools**](https://pypi.org/project/setuptools/) 或 [**Poetry**](https://pypi.org/project/poetry/)
发布时,请您为自己的插件取一个清晰易懂的名字。通常而言,一款 NoneBot2 插件名称使用 `nonebot-plugin-` 作为前缀(如`nonebot-plugin-foo`),以 `nonebot_plugin_` 作为导入名的前缀(如`nonebot_plugin_foo`),这并非是强制规范, 而是为了防止与其他 PyPI 包产生冲突, 所以我们推荐您在没有特殊需求的情况下这样做。 发布时,请您为自己的插件取一个清晰易懂的名字。通常而言,一款 NoneBot2 插件名称使用 `nonebot-plugin-` 作为前缀(如`nonebot-plugin-foo`),以 `nonebot_plugin_` 作为包名的前缀(如`nonebot_plugin_foo`),这并非强制规范,而是为了防止与其他 PyPI 包产生冲突,所以我们推荐您在没有特殊需求的情况下这样做。
发布后,请确保您的插件已能公开的从 PyPI 访问到,请检查您的插件在 PyPI 的地址:`https://pypi.org/project/<您的Nonebot2插件项目名>` 发布后,请确保您的插件已能公开的从 PyPI 访问到,试着检查您的插件在 PyPI 的地址,如 `https://pypi.org/project/<您的 NoneBot2 插件项目名>`
### 托管您的插件源代码 ### 托管您的插件源代码
将插件源代码及相关构建文件(如`pyproject.toml`或`setup.py`等与 PyPI 包构建相关的文件)托管在公开代码仓。 将插件源代码及相关构建文件(如 `pyproject.toml` `setup.py` 等与 PyPI 包构建相关的文件)托管在公开代码仓。
请确保您的代码仓地址能够被正确的访问,检查您的插件在代码仓的地址,如 `https://github.com/<您的Github用户名>/<您的插件Github项目名>` 请确保您的代码仓地址能够被正确的访问,检查您的插件在代码仓的地址,如 `https://github.com/<您的 Github 用户名>/<您的插件 Github 项目名>`。
### 申请发布到 Nonebot2 插件商店 ### 申请发布到 NoneBot2 插件商店
完成在 PyPI 的插件发布流程与源代码托管流程后,请您前往 **[NoneBot2 商店](https://v2.nonebot.dev/store.html)** 页面,切换到 **插件** 页签,点击 **发布插件** 按钮。 完成在 PyPI 的插件发布流程与源代码托管流程后,请您前往 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html)页面,切换到**插件**页签,点击**发布插件**按钮。
![插件发布界面](./images/plugin_store_publish.png) ![插件发布界面](./images/plugin_store_publish.png)
如图所示,在弹出的插件信息提交表单内,填入您所要发布的相应插件信息: 如图所示,在弹出的插件信息提交表单内,填入您所要发布的相应插件信息:
```text ```text
插件名称: 您的Nonebot2插件名称 插件名称:您的 NoneBot2 插件名称
插件介绍: 为您的插件提供的简短介绍信息 插件介绍:为您的插件提供的简短介绍信息
PyPI项目名 您的插件所在的PyPI Project名如 nonebot-plugin-xxxx PyPI 项目名:您的插件所在的 PyPI Project 名,如 nonebot-plugin-xxxx
import包名 您的插件通过Python导入时使用的包名如 nonebot_plugin_xxxx import 包名:您的插件通过 Python 导入时使用的包名,如 nonebot_plugin_xxxx
仓库/主页: 您的插件托管地址,如 https://github.com/<您的Github用户名>/nonebot-plugin-xxxx 仓库/主页:您的插件托管地址,如 https://github.com/<您的 Github 用户名>/nonebot-plugin-xxxx
标签: 一个或多个可选颜色的TAG每填写一个点击添加标签若要删除点击标签即可标签长度不超过10字符标签个数不超过3个 标签:一个或多个可选颜色的 TAG每填写一个点击添加标签若要删除点击标签即可标签长度不超过 10 字符,标签个数不超过 3
特定标签内容Adapter点击Type的Adapter将创建一个 a: 开头的标签填入内容以指定您插件使用的adapter 特定标签内容 Adapter点击 Type Adapter将创建一个 a: 开头的标签,填入内容以指定您插件使用的 adapter
特定标签内容Topic点击Type的Topic将创建一个 t: 开头的标签,填入内容以指定您插件的主题 特定标签内容 Topic点击 Type Topic将创建一个 t: 开头的标签,填入内容以指定您插件的主题
``` ```
![插件信息填写](./images/plugin_store_publish_2.png) ![插件信息填写](./images/plugin_store_publish_2.png)
完成填写后,请点击 **发布** 按钮,这将自动在 **[NoneBot2](https://github.com/nonebot/nonebot2)** 代码仓内创建发布您的插件的对应 Issue。 完成填写后,请点击**发布**按钮,这将自动在[**NoneBot2**](https://github.com/nonebot/nonebot2)代码仓内创建发布您的插件的对应 Issue。
### 等待插件发布处理 ### 等待插件发布处理
您的插件发布 Issue 创建后,将会经过*Nonebot2 Publish Bot*的检查,以确保插件信息正确无误。 您的插件发布 Issue 创建后,将会经过 _NoneBot2 Publish Bot_ 的检查,以确保插件信息正确无误。
若您的插件发布 Issue 未通过检查,您可以 **直接修改** Issue 内容以更新发布请求。*Nonebot2 Publish Bot*在您修改 Issue 内容后将会自动重新执行检查。您无需关闭、重新提交发布申请。 若您的插件发布 Issue 未通过检查,您可以**直接修改** Issue 内容以更新发布请求。_NoneBot2 Publish Bot_ 在您修改 Issue 内容后将会自动重新执行检查。您无需关闭、重新提交发布申请。
之后NoneBot2 的维护者们将会对插件进行进一步的检查,以确保用户能够正常安装并使用该插件。 之后NoneBot2 的维护者们将会对插件进行进一步的检查,以确保用户能够正常安装并使用该插件。
完成这些步骤后,您的插件将会被合并到 **[NoneBot2 商店](https://v2.nonebot.dev/store.html)** ,而您也将成为 **[NoneBot2 贡献者](https://github.com/nonebot/nonebot2/graphs/contributors)** 的一员。 完成这些步骤后,您的插件将会被合并到 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html),而您也将成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors)中的一员。
## 完成 ## 完成
恭喜您,经过上述的发布流程,您的插件已经成功发布到 Nonebot2 商店了。 恭喜您,经过上述的发布流程,您的插件已经成功发布到 NoneBot2 商店了。
此时,您可以在 **[NoneBot2 商店](https://v2.nonebot.dev/store.html)** 的插件页签查找到您的插件。同时,欢迎您成为 **[NoneBot2 贡献者](https://github.com/nonebot/nonebot2/graphs/contributors)** 此时,您可以在 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html)的插件页签查找到您的插件。同时,欢迎您成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors)
**Congratulations!** **Congratulations!**

View File

@ -7,17 +7,17 @@ options:
# 钩子函数 # 钩子函数
[`钩子编程`](https://zh.wikipedia.org/wiki/%E9%92%A9%E5%AD%90%E7%BC%96%E7%A8%8B) [钩子编程](https://zh.wikipedia.org/wiki/%E9%92%A9%E5%AD%90%E7%BC%96%E7%A8%8B)
> 钩子编程hooking也称作“挂钩”是计算机程序设计术语指通过拦截软件模块间的函数调用、消息传递、事件传递来修改或扩展操作系统、应用程序或其他软件组件的行为的各种技术。处理被拦截的函数调用、事件、消息的代码被称为钩子hook > 钩子编程hooking也称作“挂钩”是计算机程序设计术语指通过拦截软件模块间的函数调用、消息传递、事件传递来修改或扩展操作系统、应用程序或其他软件组件的行为的各种技术。处理被拦截的函数调用、事件、消息的代码被称为钩子hook
`nonebot2` 中有一系列预定义的钩子函数,分为两类:`全局钩子函数` 和 `事件钩子函数` ,这些钩子函数可以用装饰器的形式来使用。 NoneBot2 中有一系列预定义的钩子函数,分为两类:**全局钩子函数**和**事件钩子函数**,这些钩子函数可以用装饰器的形式来使用。
## 全局钩子函数 ## 全局钩子函数
全局钩子函数是指 `nonebot2` 针对其本身运行过程的钩子函数。 全局钩子函数是指 NoneBot2 针对其本身运行过程的钩子函数。
这些钩子函数是由其后端驱动 `driver`来运行的,故需要先获得全局 `driver` 对象: 这些钩子函数是由其后端驱动 `Driver` 来运行的,故需要先获得全局 `Driver` 对象:
```python ```python
from nonebot import get_driver from nonebot import get_driver
@ -30,7 +30,7 @@ driver=get_driver()
### 启动准备 ### 启动准备
这个钩子函数会在 `nonebot2` 启动时运行。 这个钩子函数会在 NoneBot2 启动时运行。
```python ```python
@driver.on_startup @driver.on_startup
@ -40,7 +40,7 @@ async def do_something():
### 终止处理 ### 终止处理
这个钩子函数会在 `nonebot2` 终止时运行。 这个钩子函数会在 NoneBot2 终止时运行。
```python ```python
@driver.on_shutdown @driver.on_shutdown
@ -48,9 +48,9 @@ async def do_something():
pass pass
``` ```
### bot 连接处理 ### Bot 连接处理
这个钩子函数会在 `bot` 通过 `websocket` 连接到 `nonebot2` 时运行。 这个钩子函数会在 `Bot` 通过 websocket 连接到 NoneBot2 时运行。
```python ```python
@driver.on_bot_connect @driver.on_bot_connect
@ -60,7 +60,7 @@ async def do_something(bot: Bot):
### bot 断开处理 ### bot 断开处理
这个钩子函数会在 `bot` 断开与 `nonebot2``websocket` 连接时运行。 这个钩子函数会在 `Bot` 断开与 NoneBot2 的 websocket 连接时运行。
```python ```python
@driver.on_bot_disconnect @driver.on_bot_disconnect
@ -94,15 +94,13 @@ async def handle_api_result(bot: Bot, exception: Optional[Exception], api: str,
## 事件钩子函数 ## 事件钩子函数
这些钩子函数指的是影响 `nonebot2` 进行 `事件处理` 的函数。 这些钩子函数指的是影响 NoneBot2 进行**事件处理**的函数。
:::tip 提示 :::tip 提示
关于**事件处理**的流程,可以在[这里](./README.md)查阅。
关于 `事件处理` 的流程,可以在[这里](./README.md)查阅。
::: :::
:::warning 注意 :::warning
1.在事件处理钩子函数中,与 `matcher` 运行状态相关的函数将不可用,如 `matcher.finish()` 1.在事件处理钩子函数中,与 `matcher` 运行状态相关的函数将不可用,如 `matcher.finish()`
@ -123,7 +121,7 @@ async def do_something(bot: Bot, event: Event, state: T_State):
### 事件预处理 ### 事件预处理
这个钩子函数会在 `Event` 上报到 `nonebot2` 时运行 这个钩子函数会在 `Event` 上报到 NoneBot2 时运行
```python ```python
from nonebot.message import event_preprocessor from nonebot.message import event_preprocessor
@ -135,7 +133,7 @@ async def do_something(bot: Bot, event: Event, state: T_State):
### 事件后处理 ### 事件后处理
这个钩子函数会在 `nonebot2` 处理 `Event` 后运行 这个钩子函数会在 NoneBot2 处理 `Event` 后运行
```python ```python
from nonebot.message import event_postprocessor from nonebot.message import event_postprocessor
@ -147,7 +145,7 @@ async def do_something(bot: Bot, event: Event, state: T_State):
### 运行预处理 ### 运行预处理
这个钩子函数会在 `nonebot2`运行 `matcher` 前运行。 这个钩子函数会在 NoneBot2 运行 `matcher` 前运行。
```python ```python
from nonebot.message import run_preprocessor from nonebot.message import run_preprocessor
@ -159,7 +157,7 @@ async def do_something(matcher: Matcher, bot: Bot, event: Event, state: T_State)
### 运行后处理 ### 运行后处理
这个钩子函数会在 `nonebot2`运行 `matcher` 后运行。 这个钩子函数会在 NoneBot2 运行 `matcher` 后运行。
```python ```python
from nonebot.message import run_postprocessor from nonebot.message import run_postprocessor

View File

@ -7,33 +7,33 @@ options:
# 定时任务 # 定时任务
[`APScheduler`](https://apscheduler.readthedocs.io/en/3.x/) —— Advanced Python Scheduler [APScheduler](https://apscheduler.readthedocs.io/en/3.x/) —— Advanced Python Scheduler
> Advanced Python Scheduler (APScheduler) is a Python library that lets you schedule your Python code to be executed later, either just once or periodically. You can add new jobs or remove old ones on the fly as you please. If you store your jobs in a database, they will also survive scheduler restarts and maintain their state. When the scheduler is restarted, it will then run all the jobs it should have run while it was offline. > Advanced Python Scheduler (APScheduler) is a Python library that lets you schedule your Python code to be executed later, either just once or periodically. You can add new jobs or remove old ones on the fly as you please. If you store your jobs in a database, they will also survive scheduler restarts and maintain their state. When the scheduler is restarted, it will then run all the jobs it should have run while it was offline.
## 从 NoneBot v1 迁移 ## 从 NoneBot v1 迁移
`APScheduler` 作为 `nonebot` v1 的可选依赖,为众多 bot 提供了方便的定时任务功能。`nonebot2` 已将 `APScheduler` 独立为 `nonebot_plugin_apscheduler` 插件,你可以在 [商店](https://v2.nonebot.dev/store.html) 中找到它。 `APScheduler` 作为 NoneBot v1 的可选依赖,为众多 bot 提供了方便的定时任务功能。NoneBot2 已将 `APScheduler` 独立为 nonebot_plugin_apscheduler 插件,你可以在[商店](https://v2.nonebot.dev/store.html)中找到它。
相比于 `nonebot` v1`nonebot` v2 只需要安装插件并修改 `scheduler` 的导入方式即可完成迁移。 相比于 NoneBot v1NoneBot v2 只需要安装插件并修改 `scheduler` 的导入方式即可完成迁移。
## 安装插件 ## 安装插件
### 通过 nb-cli ### 通过 nb-cli
如正在使用 `nb-cli` 构建项目,你可以从插件市场复制安装命令或手动输入以下命令以添加 `nonebot_plugin_apscheduler` 如正在使用 nb-cli 构建项目,你可以从插件市场复制安装命令或手动输入以下命令以添加 nonebot_plugin_apscheduler。
```bash ```bash
nb plugin install nonebot_plugin_apscheduler nb plugin install nonebot_plugin_apscheduler
``` ```
:::tip 提示 :::tip 提示
`nb-cli` 默认通过 `pypi` 安装,你可以添加命令参数 `-i [mirror]``--index [mirror]` 以使用镜像源安装。 nb-cli 默认通过 PyPI 安装,你可以添加命令参数 `-i [mirror]``--index [mirror]` 以使用镜像源安装。
::: :::
### 通过 poetry ### 通过 Poetry
执行以下命令以添加 `nonebot_plugin_apscheduler` 执行以下命令以添加 nonebot_plugin_apscheduler
```bash ```bash
poetry add nonebot-plugin-apscheduler poetry add nonebot-plugin-apscheduler
@ -45,7 +45,7 @@ poetry add nonebot-plugin-apscheduler
## 快速上手 ## 快速上手
1. 在需要设置定时任务的插件中,通过 `nonebot.require``nonebot_plugin_apscheduler` 导入 `scheduler` 对象 1. 在需要设置定时任务的插件中,通过 `nonebot.require` 从 nonebot_plugin_apscheduler 导入 `scheduler` 对象
2. 在该对象的基础上,根据 `APScheduler` 的使用方法进一步配置定时任务 2. 在该对象的基础上,根据 `APScheduler` 的使用方法进一步配置定时任务
@ -69,11 +69,11 @@ scheduler.add_job(run_every_day_from_program_start, "interval", days=1, id="xxx"
为了使插件能够实现定时任务,需要先将 `scheduler` 对象导入插件。 为了使插件能够实现定时任务,需要先将 `scheduler` 对象导入插件。
`nonebot2` 提供了 `nonebot.require` 方法来实现导入其他插件的内容,此处我们使用这个方法来导入 `scheduler` 对象。 NoneBot2 提供了 `nonebot.require` 方法来实现导入其他插件的内容,此处我们使用这个方法来导入 `scheduler` 对象。
`nonebot` 使用的 `scheduler` 对象为 `AsyncScheduler` NoneBot2 使用的 `scheduler` 对象为 `AsyncScheduler`
> 使用该方法传入的插件本身也需要有对应实现,关于该方法的更多介绍可以参阅 [这里](./export-and-require.md) > 使用该方法传入的插件本身也需要有对应实现,关于该方法的更多介绍可以参阅[这里](./export-and-require.md)
```python ```python
from nonebot import require from nonebot import require
@ -87,10 +87,10 @@ scheduler = require("nonebot_plugin_apscheduler").scheduler
### 配置插件选项 ### 配置插件选项
根据项目的 `.env` 文件设置,向 `.env.*``bot.py` 文件添加 `nonebot_plugin_apscheduler` 的可选配置项 根据项目的 `.env` 文件设置,向 `.env.*``bot.py` 文件添加 nonebot_plugin_apscheduler 的可选配置项
:::warning 注意 :::warning 注意
`.env.*` 文件的编写应遵循 nonebot2 对 `.env.*` 文件的编写要求 `.env.*` 文件的编写应遵循 NoneBot2 对 `.env.*` 文件的编写要求
::: :::
#### `apscheduler_autostart` #### `apscheduler_autostart`
@ -101,7 +101,7 @@ scheduler = require("nonebot_plugin_apscheduler").scheduler
是否自动启动 `APScheduler` 是否自动启动 `APScheduler`
对于大多数情况,我们需要在 `nonebot2` 项目被启动时启动定时任务,则此处设为 `true` 对于大多数情况,我们需要在 NoneBot2 项目被启动时启动定时任务,则此处设为 `true`
##### 在 `.env` 中添加 ##### 在 `.env` 中添加

View File

@ -5,7 +5,7 @@ description: 编辑器支持
# 编辑器支持 # 编辑器支持
框架基于 [PEP484](https://www.python.org/dev/peps/pep-0484/), [PEP 561](https://www.python.org/dev/peps/pep-0517/), [PEP8](https://www.python.org/dev/peps/pep-0008/) 等规范进行开发并且是 **Fully Typed**。框架使用 `pyright` (`pylance`) 工具进行类型检查,确保代码可以被编辑器正确解析。 框架基于 [PEP484](https://www.python.org/dev/peps/pep-0484/)、[PEP 561](https://www.python.org/dev/peps/pep-0517/)、[PEP8](https://www.python.org/dev/peps/pep-0008/) 等规范进行开发并且是 **Fully Typed**。框架使用 `pyright``pylance`工具进行类型检查,确保代码可以被编辑器正确解析。
## 编辑器推荐配置 ## 编辑器推荐配置

View File

@ -1,6 +1,6 @@
--- ---
sidebar_position: 2 sidebar_position: 2
description: 通过脚手架, pip 安装适配器 description: 通过脚手架 pip 安装适配器
--- ---
import Asciinema from "@site/src/components/Asciinema"; import Asciinema from "@site/src/components/Asciinema";
@ -9,9 +9,9 @@ import Asciinema from "@site/src/components/Asciinema";
## 查看 ## 查看
前往 [商店](/store) 即可查看所有协议适配器。 前往[商店](/store)即可查看所有协议适配器。
或者使用 `nb-cli` 命令行查看: 或者使用 nb-cli 命令行查看:
```bash ```bash
nb adapter list nb adapter list
@ -19,7 +19,7 @@ nb adapter list
## 安装 ## 安装
前往 [商店](/store) 点击复制 `nb-cli` 安装命令至命令行执行即可安装。 前往[商店](/store)点击复制 nb-cli 安装命令至命令行执行即可安装。
或者自行输入命令安装: 或者自行输入命令安装:
@ -33,7 +33,7 @@ nb adapter install <adapter-name>
nb adapter install nb adapter install
``` ```
也可以使用 `pip` 安装 也可以使用 pip 安装
```bash ```bash
pip install <adapter-name> pip install <adapter-name>

View File

@ -1,19 +1,19 @@
--- ---
sidebar_position: 1 sidebar_position: 1
description: 通过脚手架, pip 安装驱动器 description: 通过脚手架 pip 安装驱动器
--- ---
import Asciinema from "@site/src/components/Asciinema"; import Asciinema from "@site/src/components/Asciinema";
# 安装驱动器 # 安装驱动器
NoneBot 在默认安装情况下内置了 `fastapi` 服务端驱动器,其他驱动器如 `httpx`, `aiohttp` 则需要额外安装。 NoneBot 在默认安装情况下内置了 `fastapi` 服务端驱动器,其他驱动器如 `httpx``aiohttp` 则需要额外安装。
## 查看 ## 查看
前往 [商店](/store) 即可查看所有驱动器。 前往[商店](/store)即可查看所有驱动器。
或者使用 `nb-cli` 命令行查看: 或者使用 nb-cli 命令行查看:
```bash ```bash
nb driver list nb driver list
@ -21,7 +21,7 @@ nb driver list
## 安装 ## 安装
前往 [商店](/store) 点击复制 `nb-cli` 安装命令至命令行执行即可安装。 前往[商店](/store)点击复制 nb-cli 安装命令至命令行执行即可安装。
或者自行输入命令安装: 或者自行输入命令安装:
@ -35,7 +35,7 @@ nb driver install <driver-name>
nb driver install nb driver install
``` ```
也可以使用 `pip` 安装 也可以使用 pip 安装
```bash ```bash
pip install <driver-name> pip install <driver-name>

View File

@ -1,6 +1,6 @@
--- ---
sidebar_position: 3 sidebar_position: 3
description: 通过脚手架, pip 安装插件 description: 通过脚手架 pip 安装插件
--- ---
import Asciinema from "@site/src/components/Asciinema"; import Asciinema from "@site/src/components/Asciinema";
@ -9,9 +9,9 @@ import Asciinema from "@site/src/components/Asciinema";
## 查看 ## 查看
前往 [商店](/store) 即可查看所有发布的插件。 前往[商店](/store)即可查看所有发布的插件。
或者使用 `nb-cli` 命令行查看: 或者使用 nb-cli 命令行查看:
```bash ```bash
nb plugin list nb plugin list
@ -19,7 +19,7 @@ nb plugin list
## 安装 ## 安装
前往 [商店](/store) 点击复制 `nb-cli` 安装命令至命令行执行即可安装。 前往[商店](/store)点击复制 nb-cli 安装命令至命令行执行即可安装。
或者自行输入命令安装: 或者自行输入命令安装:
@ -33,7 +33,7 @@ nb plugin install <plugin-name>
nb plugin install nb plugin install
``` ```
也可以使用 `pip` 安装 也可以使用 pip 安装
```bash ```bash
pip install <plugin-name> pip install <plugin-name>

View File

@ -1,6 +1,6 @@
--- ---
sidebar_position: 0 sidebar_position: 0
description: 通过脚手架, PyPI, GitHub 安装 NoneBot description: 通过脚手架、PyPI 或 GitHub 安装 NoneBot2
options: options:
menu: menu:
@ -10,7 +10,7 @@ options:
import Asciinema from "@site/src/components/Asciinema"; import Asciinema from "@site/src/components/Asciinema";
# 安装 NoneBot # 安装 NoneBot2
:::warning 注意 :::warning 注意
请确保你的 Python 版本 >= 3.7.3。 请确保你的 Python 版本 >= 3.7.3。
@ -25,10 +25,10 @@ pip uninstall nonebot
::: :::
## 通过脚手架安装 (推荐) ## 通过脚手架安装(推荐)
1. (可选) 使用你喜欢的 Python 环境管理工具 (如 `poetry`, `venv`, `conda` 等) 创建新的虚拟环境 1. (可选)使用你喜欢的 Python 环境管理工具(如 Poetry、venv、Conda 等)创建新的虚拟环境
2. 使用 `pip` 或 其他包管理工具 安装 `nb-cli``nonebot2` 会作为其依赖被一起安装 2. 使用 pip 或其他包管理工具安装 nb-cliNoneBot2 会作为其依赖被一起安装
```bash ```bash
pip install nb-cli pip install nb-cli
@ -40,16 +40,16 @@ pip uninstall nonebot
/> />
:::important 提示 :::important 提示
`nb-cli` 的使用方法详见 [使用脚手架](./nb-cli.md) nb-cli 的使用方法详见[使用脚手架](./nb-cli.md)
::: :::
## 不使用脚手架 (纯净安装) ## 不使用脚手架(纯净安装)
如果你不想使用脚手架,可以直接安装 `nonebot2`,并自行完成开发配置。 如果你不想使用脚手架,可以直接安装 NoneBot2,并自行完成开发配置。
```bash ```bash
pip install nonebot2 pip install nonebot2
# 也可以通过 poetry 安装 # 也可以通过 Poetry 安装
poetry add nonebot2 poetry add nonebot2
``` ```
@ -58,12 +58,12 @@ poetry add nonebot2
如果你需要使用最新的(可能**尚未发布**的)特性,可以直接从 GitHub 仓库安装: 如果你需要使用最新的(可能**尚未发布**的)特性,可以直接从 GitHub 仓库安装:
:::warning 注意 :::warning 注意
直接从 Github 仓库中安装意味着你将使用最新提交的代码,它们并没有进行充分的稳定性测试 直接从 GitHub 仓库中安装意味着你将使用最新提交的代码,它们并没有进行充分的稳定性测试
在任何情况下请不要将其应用于生产环境! 在任何情况下请不要将其应用于生产环境!
::: :::
```bash title="Install From Github" ```bash title="Install From GitHub"
# master分支 # master分支
poetry add git+https://github.com/nonebot/nonebot2.git#master poetry add git+https://github.com/nonebot/nonebot2.git#master
# dev分支 # dev分支

View File

@ -18,12 +18,12 @@ pip install nb-cli
## 初次使用 ## 初次使用
在安装完成之后,即可在命令行使用 `nb-cli` 的命令 `nb` 进行开发: 在安装完成之后,即可在命令行使用 nb-cli 的命令 `nb` 进行开发:
```bash ```bash
# 直接使用 nb 命令 # 直接使用 nb 命令
nb nb
# 或使用 python 执行 module # 或使用 Python 执行 module
python -m nb_cli python -m nb_cli
``` ```
@ -33,7 +33,7 @@ python -m nb_cli
## 使用方式 ## 使用方式
`nb-cli` 具有两种使用方式: nb-cli 具有两种使用方式:
1. 命令行指令 1. 命令行指令

View File

@ -7,22 +7,22 @@ description: 如何获取帮助
如果在安装或者开发过程中遇到了任何问题,可以通过以下方式解决: 如果在安装或者开发过程中遇到了任何问题,可以通过以下方式解决:
1. 点击下方链接前往 GitHub ~~点击 star~~ ,前往 Issues 页面,在 `New Issue` Template 中选择 `Question` 1. 点击下方链接前往 GitHub前往 Issues 页面,在 `New Issue` Template 中选择 `Question`
NoneBot2: [![nonebot2](https://img.shields.io/github/stars/nonebot/nonebot2?style=social)](https://github.com/nonebot/nonebot2) NoneBot2[![NoneBot2](https://img.shields.io/github/stars/nonebot/nonebot2?style=social)](https://github.com/nonebot/nonebot2)
2. 通过 QQ 群 (点击下方链接直达) 2. 通过 QQ 群(点击下方链接直达)
[![QQ Chat](https://img.shields.io/badge/QQ%E7%BE%A4-768887710-orange?style=social)](https://jq.qq.com/?_wv=1027&k=5OFifDh) [![QQ Chat](https://img.shields.io/badge/QQ%E7%BE%A4-768887710-orange?style=social)](https://jq.qq.com/?_wv=1027&k=5OFifDh)
3. 通过 QQ 频道 3. 通过 QQ 频道
前往 QQ 频道搜索 `NoneBot` 点击加入 前往 QQ 频道搜索 NoneBot 点击加入
4. 通过 Telegram 群 (点击下方链接直达) 4. 通过 Telegram 群(点击下方链接直达)
[![Telegram Chat](https://img.shields.io/badge/telegram-cqhttp-blue?style=social)](https://t.me/cqhttp) [![Telegram Chat](https://img.shields.io/badge/telegram-cqhttp-blue?style=social)](https://t.me/cqhttp)
5. 通过 Discord 服务器 (点击下方链接直达) 5. 通过 Discord 服务器(点击下方链接直达)
[![Discord Server](https://discordapp.com/api/guilds/847819937858584596/widget.png?style=shield)](https://discord.gg/VKtE6Gdc4h) [![Discord Server](https://discordapp.com/api/guilds/847819937858584596/widget.png?style=shield)](https://discord.gg/VKtE6Gdc4h)

View File

@ -15,17 +15,17 @@ options:
::: :::
:::tip 提示 :::tip 提示
如何**安装**驱动器请参考 [安装驱动器](../start/install-driver.mdx) 如何**安装**驱动器请参考[安装驱动器](../start/install-driver.mdx)
如何**使用**驱动器请参考 [配置](./configuration.md#driver) 如何**使用**驱动器请参考[配置](./configuration.md#driver)
::: :::
## 驱动器的类型 ## 驱动器的类型
驱动器的类型有两种: 驱动器的类型有两种:
- `ForwardDriver`: 即客户端类型驱动器,多用于使用 HTTP 轮询WebSocket 连接服务器的情形。 - `ForwardDriver`即客户端类型驱动器,多用于使用 HTTP 轮询WebSocket 连接服务器的情形。
- `ReverseDriver`: 即服务端类型驱动器,多用于使用 WebHook 情形。 - `ReverseDriver`即服务端类型驱动器,多用于使用 WebHook 情形。
其中 `ReverseDriver` 可以配合 `ForwardDriver` 一起使用,即可以同时使用客户端功能和服务端功能。 其中 `ReverseDriver` 可以配合 `ForwardDriver` 一起使用,即可以同时使用客户端功能和服务端功能。
@ -35,8 +35,8 @@ options:
### ForwardDriver ### ForwardDriver
1. 异步发送 HTTP 请求,自定义 `HTTP Method`, `URL`, `Header`, `Body`, `Cookie`, `Proxy`, `Timeout` 等。 1. 异步发送 HTTP 请求,自定义 `HTTP Method`、`URL`、`Header`、`Body`、`Cookie`、`Proxy`、`Timeout` 等。
2. 异步建立 WebSocket 连接上下文,自定义 `WebSocket URL`, `Header`, `Cookie`, `Proxy`, `Timeout` 等。 2. 异步建立 WebSocket 连接上下文,自定义 `WebSocket URL`、`Header`、`Cookie`、`Proxy`、`Timeout` 等。
### ReverseDriver ### ReverseDriver
@ -46,17 +46,17 @@ options:
## 内置驱动器 ## 内置驱动器
### FastAPI (默认) ### FastAPI默认
类型: `ReverseDriver` 类型`ReverseDriver`
> FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints. > FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
FastAPI 是一个易上手、高性能的异步 Web 框架,具有极佳的编写体验,可以挂载其他 ASGI, WSGI 应用。 FastAPI 是一个易上手、高性能的异步 Web 框架,具有极佳的编写体验,可以挂载其他 ASGIWSGI 应用。
FastAPI: [文档](https://fastapi.tiangolo.com/), [仓库](https://github.com/tiangolo/fastapi) FastAPI[文档](https://fastapi.tiangolo.com/)、[仓库](https://github.com/tiangolo/fastapi)
驱动器: [API](../api/drivers/fastapi.md), [源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/fastapi.py) 驱动器[API](../api/drivers/fastapi.md)、[源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/fastapi.py)
```env ```env
DRIVER=~fastapi DRIVER=~fastapi
@ -66,33 +66,33 @@ DRIVER=~fastapi
##### `fastapi_openapi_url` ##### `fastapi_openapi_url`
类型: `Optional[str]` 类型`Optional[str]`
默认值: `None` 默认值`None`
说明: `FastAPI` 提供的 `OpenAPI` JSON 定义地址,如果为 `None`,则不提供 `OpenAPI` JSON 定义。 说明`FastAPI` 提供的 `OpenAPI` JSON 定义地址,如果为 `None`,则不提供 `OpenAPI` JSON 定义。
##### `fastapi_docs_url` ##### `fastapi_docs_url`
类型: `Optional[str]` 类型`Optional[str]`
默认值: `None` 默认值`None`
说明: `FastAPI` 提供的 `Swagger` 文档地址,如果为 `None`,则不提供 `Swagger` 文档。 说明`FastAPI` 提供的 `Swagger` 文档地址,如果为 `None`,则不提供 `Swagger` 文档。
##### `fastapi_redoc_url` ##### `fastapi_redoc_url`
类型: `Optional[str]` 类型`Optional[str]`
默认值: `None` 默认值`None`
说明: `FastAPI` 提供的 `ReDoc` 文档地址,如果为 `None`,则不提供 `ReDoc` 文档。 说明`FastAPI` 提供的 `ReDoc` 文档地址,如果为 `None`,则不提供 `ReDoc` 文档。
##### `fastapi_include_adapter_schema` ##### `fastapi_include_adapter_schema`
类型: `bool` 类型`bool`
默认值: `True` 默认值`True`
说明: `FastAPI` 提供的 `OpenAPI` JSON 定义中是否包含适配器路由的 `Schema` 说明`FastAPI` 提供的 `OpenAPI` JSON 定义中是否包含适配器路由的 `Schema`
##### `fastapi_reload` ##### `fastapi_reload`
类型: `bool` 类型`bool`
默认值: `False` 默认值`False`
说明: 是否开启 `uvicorn``reload` 功能,需要提供 asgi 应用路径。 说明是否开启 `uvicorn``reload` 功能,需要提供 asgi 应用路径。
```python title=bot.py ```python title=bot.py
app = nonebot.get_asgi() app = nonebot.get_asgi()
@ -101,39 +101,39 @@ nonebot.run(app="bot:app")
##### `fastapi_reload_dirs` ##### `fastapi_reload_dirs`
类型: `Optional[List[str]]` 类型`Optional[List[str]]`
默认值: `None` 默认值`None`
说明: 重载监控文件夹列表,默认为 uvicorn 默认值 说明重载监控文件夹列表,默认为 uvicorn 默认值
##### `fastapi_reload_delay` ##### `fastapi_reload_delay`
类型: `Optional[float]` 类型`Optional[float]`
默认值: `None` 默认值`None`
说明: 重载延迟,默认为 uvicorn 默认值 说明重载延迟,默认为 uvicorn 默认值
##### `fastapi_reload_includes` ##### `fastapi_reload_includes`
类型: `Optional[List[str]]` 类型`Optional[List[str]]`
默认值: `None` 默认值`None`
说明: 要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值 说明要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值
##### `fastapi_reload_excludes` ##### `fastapi_reload_excludes`
类型: `Optional[List[str]]` 类型`Optional[List[str]]`
默认值: `None` 默认值`None`
说明: 不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值 说明不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值
### Quart ### Quart
类型: `ReverseDriver` 类型`ReverseDriver`
> Quart is an asyncio reimplementation of the popular Flask microframework API. > Quart is an asyncio reimplementation of the popular Flask microframework API.
Quart 是一个类 Flask 的异步版本,拥有与 Flask 非常相似的接口和使用方法。 Quart 是一个类 Flask 的异步版本,拥有与 Flask 非常相似的接口和使用方法。
Quart: [文档](https://pgjones.gitlab.io/quart/), [仓库](https://gitlab.com/pgjones/quart) Quart[文档](https://pgjones.gitlab.io/quart/)、[仓库](https://gitlab.com/pgjones/quart)
驱动器: [API](../api/drivers/quart.md), [源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/quart.py) 驱动器[API](../api/drivers/quart.md)、[源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/quart.py)
```env ```env
DRIVER=~quart DRIVER=~quart
@ -143,9 +143,9 @@ DRIVER=~quart
##### `quart_reload` ##### `quart_reload`
类型: `bool` 类型`bool`
默认值: `False` 默认值`False`
说明: 是否开启 `uvicorn``reload` 功能,需要提供 asgi 应用路径。 说明是否开启 `uvicorn``reload` 功能,需要提供 asgi 应用路径。
```python title=bot.py ```python title=bot.py
app = nonebot.get_asgi() app = nonebot.get_asgi()
@ -154,31 +154,31 @@ nonebot.run(app="bot:app")
##### `quart_reload_dirs` ##### `quart_reload_dirs`
类型: `Optional[List[str]]` 类型`Optional[List[str]]`
默认值: `None` 默认值`None`
说明: 重载监控文件夹列表,默认为 uvicorn 默认值 说明重载监控文件夹列表,默认为 uvicorn 默认值
##### `quart_reload_delay` ##### `quart_reload_delay`
类型: `Optional[float]` 类型`Optional[float]`
默认值: `None` 默认值`None`
说明: 重载延迟,默认为 uvicorn 默认值 说明重载延迟,默认为 uvicorn 默认值
##### `quart_reload_includes` ##### `quart_reload_includes`
类型: `Optional[List[str]]` 类型`Optional[List[str]]`
默认值: `None` 默认值`None`
说明: 要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值 说明要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值
##### `quart_reload_excludes` ##### `quart_reload_excludes`
类型: `Optional[List[str]]` 类型`Optional[List[str]]`
默认值: `None` 默认值`None`
说明: 不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值 说明不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值
### HTTPX ### HTTPX
类型: `ForwardDriver` 类型`ForwardDriver`
:::warning 注意 :::warning 注意
本驱动器仅支持 HTTP 请求,不支持 WebSocket 请求。 本驱动器仅支持 HTTP 请求,不支持 WebSocket 请求。
@ -186,9 +186,9 @@ nonebot.run(app="bot:app")
> HTTPX is a fully featured HTTP client for Python 3, which provides sync and async APIs, and support for both HTTP/1.1 and HTTP/2. > HTTPX is a fully featured HTTP client for Python 3, which provides sync and async APIs, and support for both HTTP/1.1 and HTTP/2.
HTTPX: [文档](https://www.python-httpx.org/), [仓库](https://github.com/encode/httpx/) HTTPX[文档](https://www.python-httpx.org/)、[仓库](https://github.com/encode/httpx/)
驱动器: [API](../api/drivers/httpx.md), [源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/httpx.py) 驱动器[API](../api/drivers/httpx.md)、[源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/httpx.py)
```env ```env
DRIVER=~httpx DRIVER=~httpx
@ -200,7 +200,7 @@ DRIVER=~httpx
### websockets ### websockets
类型: `ForwardDriver` 类型`ForwardDriver`
:::warning 注意 :::warning 注意
本驱动器仅支持 WebSocket 请求,不支持 HTTP 请求。 本驱动器仅支持 WebSocket 请求,不支持 HTTP 请求。
@ -208,9 +208,9 @@ DRIVER=~httpx
> websockets is a library for building WebSocket servers and clients in Python with a focus on correctness, simplicity, robustness, and performance. > websockets is a library for building WebSocket servers and clients in Python with a focus on correctness, simplicity, robustness, and performance.
websockets: [文档](https://websockets.readthedocs.io/en/stable/), [仓库](https://github.com/aaugustin/websockets) websockets[文档](https://websockets.readthedocs.io/en/stable/)、[仓库](https://github.com/aaugustin/websockets)
驱动器: [API](../api/drivers/websockets.md), [源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/websockets.py) 驱动器[API](../api/drivers/websockets.md)、[源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/websockets.py)
```env ```env
DRIVER=~websockets DRIVER=~websockets
@ -222,13 +222,13 @@ DRIVER=~websockets
### AIOHTTP ### AIOHTTP
类型: `ForwardDriver` 类型`ForwardDriver`
> Asynchronous HTTP Client/Server for asyncio and Python. > Asynchronous HTTP Client/Server for asyncio and Python.
AIOHTTP: [文档](https://docs.aiohttp.org/en/stable/), [仓库](https://github.com/aio-libs/aiohttp) AIOHTTP[文档](https://docs.aiohttp.org/en/stable/)、[仓库](https://github.com/aio-libs/aiohttp)
驱动器: [API](../api/drivers/aiohttp.md), [源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/aiohttp.py) 驱动器[API](../api/drivers/aiohttp.md)、[源码](https://github.com/nonebot/nonebot2/blob/master/nonebot/drivers/aiohttp.py)
```env ```env
DRIVER=~aiohttp DRIVER=~aiohttp

View File

@ -20,12 +20,12 @@ options:
### .env 文件 ### .env 文件
NoneBot 在启动时将会从系统环境变量或者 `.env` 文件中寻找变量 `ENVIRONMENT` (大小写不敏感),默认值为 `prod` NoneBot 在启动时将会从系统环境变量或者 `.env` 文件中寻找变量 `ENVIRONMENT`(大小写不敏感),默认值为 `prod`
这将引导 NoneBot 从系统环境变量或者 `.env.{ENVIRONMENT}` 文件中进一步加载具体配置。 这将引导 NoneBot 从系统环境变量或者 `.env.{ENVIRONMENT}` 文件中进一步加载具体配置。
`.env` 文件是基础环境配置文件,该文件中的配置项在不同环境下都会被加载,但会被 `.env.{ENVIRONMENT}` 文件中的配置所覆盖。 `.env` 文件是基础环境配置文件,该文件中的配置项在不同环境下都会被加载,但会被 `.env.{ENVIRONMENT}` 文件中的配置所覆盖。
NoneBot 使用 [pydantic](https://pydantic-docs.helpmanual.io/) 进行配置处理,并对 `pydantic` 的行为做出了更改,详见下方说明。 NoneBot 使用 [Pydantic](https://pydantic-docs.helpmanual.io/) 进行配置处理,并对 Pydantic 的行为做出了更改,详见下方说明。
现在,我们在 `.env` 文件中写入当前环境信息: 现在,我们在 `.env` 文件中写入当前环境信息:
@ -42,29 +42,29 @@ CUSTOM_CONFIG=common config # 这个配置项在任何环境中都会被加载
::: :::
:::warning 提示 :::warning 提示
由于 `pydantic` 使用 JSON 解析配置项,请确保配置项值为 JSON 格式的数据。如: 由于 Pydantic 使用 JSON 解析配置项,请确保配置项值为 JSON 格式的数据。如:
```bash ```bash
list=["123456789", "987654321", 1] list=["123456789", "987654321", 1]
test={"hello": "world"} test={"hello": "world"}
``` ```
如果配置项值解析失败将作为 **字符串** 处理。 如果配置项值解析失败将作为**字符串**处理。
特别的,如果配置项 **为空** ,则会从 **系统环境变量** 中获取值,如果不存在则为空字符串。 特别的,如果配置项**为空**,则会从**系统环境变量**中获取值,如果不存在则为空字符串。
::: :::
### .env.\* 文件 ### .env.\* 文件
NoneBot 默认会从 `.env.{ENVIRONMENT}` 文件加载配置,但是可以在 NoneBot 初始化时指定加载某个环境配置文件: `nonebot.init(_env_file=".env.dev")`,这将忽略你在 `.env` 中设置的 `ENVIRONMENT` NoneBot 默认会从 `.env.{ENVIRONMENT}` 文件加载配置,但是可以在 NoneBot 初始化时指定加载某个环境配置文件`nonebot.init(_env_file=".env.dev")`,这将忽略你在 `.env` 中设置的 `ENVIRONMENT`
配置语法与 `.env` 文件相同。 配置语法与 `.env` 文件相同。
示例及说明: 示例及说明:
```bash ```bash
HOST=0.0.0.0 # 配置 NoneBot 监听的 IP/主机名 HOST=0.0.0.0 # 配置 NoneBot2 监听的 IP/主机名
PORT=8080 # 配置 NoneBot 监听的端口 PORT=8080 # 配置 NoneBot2 监听的端口
SUPERUSERS=["123456789", "987654321"] # 配置 NoneBot 超级用户 SUPERUSERS=["123456789", "987654321"] # 配置 NoneBot 超级用户
NICKNAME=["awesome", "bot"] # 配置机器人的昵称 NICKNAME=["awesome", "bot"] # 配置机器人的昵称
COMMAND_START=["/", ""] # 配置命令起始字符 COMMAND_START=["/", ""] # 配置命令起始字符
@ -75,7 +75,7 @@ CUSTOM_CONFIG1="config in env file"
CUSTOM_CONFIG2= # 留空则从系统环境变量读取,如不存在则为空字符串 CUSTOM_CONFIG2= # 留空则从系统环境变量读取,如不存在则为空字符串
``` ```
详细的配置项可以参考 [配置项](#详细配置项) 详细的配置项可以参考[配置项](#详细配置项)。
### 系统环境变量 ### 系统环境变量
@ -100,11 +100,11 @@ config.custom_config4 = "new config after init"
## 配置优先级 ## 配置优先级
`bot.py` 文件( `nonebot.init` ) > 系统环境变量 > `.env`, `.env.*` 文件 `bot.py` 文件`nonebot.init`> 系统环境变量 > `.env`、`.env.*` 文件
## 读取配置项 ## 读取配置项
配置项可以通过三种类型的对象获取:`driver`, `adapter`, `bot` 配置项可以通过三种类型的对象获取:`driver`、`adapter`、`bot`
```python ```python
import nonebot import nonebot
@ -125,13 +125,13 @@ nonebot.get_driver()._adapters["adapter_name"].config.custom_config
- **类型**: `str` - **类型**: `str`
- **默认值**: `"~fastapi"` - **默认值**: `"~fastapi"`
NoneBot 运行所使用的驱动器。主要分为 `ForwardDriver`, `ReverseDriver` 即客户端和服务端两类。 NoneBot2 运行所使用的驱动器。主要分为 `ForwardDriver`、`ReverseDriver` 即客户端和服务端两类。
配置格式采用特殊语法:`<module>[:<Driver>][+<module>[:<Mixin>]]*` 配置格式采用特殊语法:`<module>[:<Driver>][+<module>[:<Mixin>]]*`
其中 `<module>` 为驱动器模块名,可以使用 `~` 作为 `nonebot.drivers.` 的简写;`<Driver>` 为驱动器类名,默认为 `Driver``<Mixin>` 为驱动器混入的类名,默认为 `Mixin` 其中 `<module>` 为驱动器模块名,可以使用 `~` 作为 `nonebot.drivers.` 的简写;`<Driver>` 为驱动器类名,默认为 `Driver``<Mixin>` 为驱动器混入的类名,默认为 `Mixin`
NoneBot 内置了几个常用驱动器,包括了各类常用功能,常见驱动器配置如下: NoneBot2 内置了几个常用驱动器,包括了各类常用功能,常见驱动器配置如下:
```env ```env
DRIVER=~fastapi DRIVER=~fastapi
@ -140,14 +140,14 @@ DRIVER=~fastapi+~httpx+~websockets
DRIVER=~fastapi+~aiohttp DRIVER=~fastapi+~aiohttp
``` ```
各驱动器的功能与区别请参考 [选择驱动器](./choose-driver.md) 各驱动器的功能与区别请参考[选择驱动器](./choose-driver.md)。
### Host ### Host
- **类型**: `IPvAnyAddress` - **类型**: `IPvAnyAddress`
- **默认值**: `127.0.0.1` - **默认值**: `127.0.0.1`
使用 `ReversedDriver`NoneBot 监听的 IP/主机名。 使用 `ReversedDriver`NoneBot2 监听的 IP/主机名。
```env ```env
HOST=127.0.0.1 HOST=127.0.0.1
@ -158,7 +158,7 @@ HOST=127.0.0.1
- **类型**: `int` - **类型**: `int`
- **默认值**: `8080` - **默认值**: `8080`
使用 `ReversedDriver`NoneBot 监听的端口。 使用 `ReversedDriver`NoneBot2 监听的端口。
```env ```env
PORT=8080 PORT=8080
@ -169,7 +169,7 @@ PORT=8080
- **类型**: `int | str` - **类型**: `int | str`
- **默认值**: `INFO` - **默认值**: `INFO`
NoneBot 日志输出等级,可以为 `int` 类型等级或等级名称 NoneBot2 日志输出等级,可以为 `int` 类型等级或等级名称
参考 [`loguru 日志等级`](https://loguru.readthedocs.io/en/stable/api/logger.html#levels)。 参考 [`loguru 日志等级`](https://loguru.readthedocs.io/en/stable/api/logger.html#levels)。
@ -233,7 +233,7 @@ COMMAND_SEP={".", "/"}
- **类型**: `timedelta` - **类型**: `timedelta`
- **默认值**: `timedelta(minutes=2)` - **默认值**: `timedelta(minutes=2)`
用户会话超时时间,配置格式参考 [`Pydantic Field`](https://pydantic-docs.helpmanual.io/usage/types/#datetime-types) 用户会话超时时间,配置格式参考 [Datetime Types](https://pydantic-docs.helpmanual.io/usage/types/#datetime-types)。
```env ```env
SESSION_EXPIRE_TIMEOUT=120 SESSION_EXPIRE_TIMEOUT=120

View File

@ -41,10 +41,10 @@ nb create
``` ```
- `awesome_bot/plugins` 或 `src/plugins`: 用于存放编写的 bot 插件 - `awesome_bot/plugins` 或 `src/plugins`: 用于存放编写的 bot 插件
- `.env`, `.env.dev`, `.env.prod`: 各环境配置文件 - `.env`、`.env.dev`、`.env.prod`: 各环境配置文件
- `bot.py`: bot 入口文件 - `bot.py`: bot 入口文件
- `pyproject.toml`: 项目插件配置文件 - `pyproject.toml`: 项目插件配置文件
- `Dockerfile`, `docker-compose.yml`: Docker 镜像配置文件 - `Dockerfile``docker-compose.yml`: Docker 镜像配置文件
## 启动 Bot ## 启动 Bot
@ -55,7 +55,7 @@ nb create
::: :::
1. 通过 `nb-cli` 1. 通过 nb-cli
```bash ```bash
nb run [--file=bot.py] [--app=app] nb run [--file=bot.py] [--app=app]
@ -68,12 +68,12 @@ nb create
options={{ theme: "monokai", startAt: 15.3, poster: "npt:20.3" }} options={{ theme: "monokai", startAt: 15.3, poster: "npt:20.3" }}
/> />
2. 直接通过 `python` 启动 2. 直接通过 Python 启动
```bash ```bash
python bot.py python bot.py
``` ```
:::tip 提示 :::tip 提示
如果在 bot 入口文件内定义了 asgi server `nb-cli` 将会为你启动**冷重载模式**(当文件发生变动时自动重启 NoneBot 实例) 如果在 bot 入口文件内定义了 asgi servernb-cli 将会为你启动**冷重载模式**(当文件发生变动时自动重启 NoneBot2 实例)
::: :::

View File

@ -5,7 +5,7 @@ description: 修改日志级别与输出
# 自定义日志 # 自定义日志
NoneBot 使用 [loguru](https://loguru.readthedocs.io/) 进行日志记录,并提供了一些内置的格式和过滤器等。 NoneBot 使用 [Loguru](https://loguru.readthedocs.io/) 进行日志记录,并提供了一些内置的格式和过滤器等。
## 默认日志 ## 默认日志
@ -40,7 +40,7 @@ from nonebot.log import LoguruHandler
## 自定义日志记录 ## 自定义日志记录
如果需要移除 NoneBot 的默认日志 handler可以在 `nonebot.init` 之前进行如下操作: 如果需要移除 NoneBot 的默认日志 handler可以在 `nonebot.init` 之前进行如下操作
```python ```python
from nonebot.log import logger, logger_id from nonebot.log import logger, logger_id
@ -50,7 +50,7 @@ logger.remove(logger_id)
如果需要添加自定义的日志 handler可以在 `nonebot.init` 之前添加 handler参考 [loguru 文档](https://loguru.readthedocs.io/)。 如果需要添加自定义的日志 handler可以在 `nonebot.init` 之前添加 handler参考 [loguru 文档](https://loguru.readthedocs.io/)。
示例: 示例
```python ```python
from nonebot.log import logger, default_format from nonebot.log import logger, default_format

View File

@ -9,7 +9,7 @@ description: 规范定义插件配置项
## 定义配置模型 ## 定义配置模型
在 NoneBot 中,我们使用强大高效的 [Pydantic](https://pydantic-docs.helpmanual.io/) 来定义配置模型,这个模型可以被用于配置的读取和类型检查等。例如,我们可以定义一个配置模型包含一个 string 类型的配置项: 在 NoneBot2 中,我们使用强大高效的 [Pydantic](https://pydantic-docs.helpmanual.io/) 来定义配置模型,这个模型可以被用于配置的读取和类型检查等。例如,我们可以定义一个配置模型包含一个 string 类型的配置项:
```python title=config.py {3,4} ```python title=config.py {3,4}
from pydantic import BaseModel, Extra from pydantic import BaseModel, Extra
@ -19,7 +19,7 @@ class Config(BaseModel, extra=Extra.ignore):
``` ```
:::important 参考 :::important 参考
更多丰富的模型定义方法(默认值自定义 validator 等),请参考 [Pydantic](https://pydantic-docs.helpmanual.io/) 文档。 更多丰富的模型定义方法(默认值自定义 validator 等),请参考 [Pydantic](https://pydantic-docs.helpmanual.io/) 文档。
::: :::
## 读取配置 ## 读取配置

View File

@ -14,7 +14,7 @@ options:
## 添加一个处理依赖 ## 添加一个处理依赖
在事件响应器中,事件处理流程由一个或多个处理依赖组成,每个处理依赖都是一个 `Dependent`,详情可以参考 [进阶 - 依赖注入](../../advanced/di/dependency-injection.md)。下面介绍如何添加一个处理依赖。 在事件响应器中,事件处理流程由一个或多个处理依赖组成,每个处理依赖都是一个 `Dependent`,详情可以参考[进阶 - 依赖注入](../../advanced/di/dependency-injection.md)。下面介绍如何添加一个处理依赖。
### 使用 `handle` 装饰器 ### 使用 `handle` 装饰器
@ -28,7 +28,7 @@ async def handle_func():
如上方示例所示,我们使用 `matcher` 响应器的 `handle` 装饰器装饰了一个函数 `handle_func` 。`handle_func` 函数会被自动转换为 `Dependent` 对象,并被添加到 `matcher` 的事件处理流程中。 如上方示例所示,我们使用 `matcher` 响应器的 `handle` 装饰器装饰了一个函数 `handle_func` 。`handle_func` 函数会被自动转换为 `Dependent` 对象,并被添加到 `matcher` 的事件处理流程中。
`handle_func` 函数中,我们可以编写任何事件响应逻辑,如:操作数据库,发送消息等。上下文信息可以通过依赖注入的方式获取,参考:[获取上下文信息](#获取上下文信息)。发送消息可以通过 [事件响应器操作](./matcher-operation.md) 或者直接调用 Bot 的方法( API 等,由协议适配器决定)。 `handle_func` 函数中,我们可以编写任何事件响应逻辑,如:操作数据库,发送消息等。上下文信息可以通过依赖注入的方式获取,参考:[获取上下文信息](#获取上下文信息)。发送消息可以通过[事件响应器操作](./matcher-operation.md)或者直接调用 Bot 的方法( API 等,由协议适配器决定)。
:::warning 注意 :::warning 注意
`handle_func` 函数虽然会被装饰器自动转换为 `Dependent` 对象,但 `handle_func` 仍然为原本的函数,因此 `handle_func` 函数可以进行复用。如: `handle_func` 函数虽然会被装饰器自动转换为 `Dependent` 对象,但 `handle_func` 仍然为原本的函数,因此 `handle_func` 函数可以进行复用。如:
@ -57,9 +57,9 @@ async def handle_func(e: Event = Received("id")):
`receive` 装饰器与 `handle` 装饰器一样,可以装饰一个函数添加到事件响应器的事件处理流程中。但与 `handle` 装饰器不同的是,`receive` 装饰器会中断当前事件处理流程,等待接收一个新的事件,就像是会话状态等待用户一个新的事件。可以接收的新的事件类型取决于事件响应器的 [`type`](./create-matcher.md#事件响应器类型-type) 更新值以及 [`permission`](./create-matcher.md#事件触发权限-permission) 更新值,可以通过自定义更新方法来控制会话响应(如进行非消息交互、多人会话、跨群会话等)。 `receive` 装饰器与 `handle` 装饰器一样,可以装饰一个函数添加到事件响应器的事件处理流程中。但与 `handle` 装饰器不同的是,`receive` 装饰器会中断当前事件处理流程,等待接收一个新的事件,就像是会话状态等待用户一个新的事件。可以接收的新的事件类型取决于事件响应器的 [`type`](./create-matcher.md#事件响应器类型-type) 更新值以及 [`permission`](./create-matcher.md#事件触发权限-permission) 更新值,可以通过自定义更新方法来控制会话响应(如进行非消息交互、多人会话、跨群会话等)。
`receive` 装饰器接受一个可选参数 `id` ,用于标识当前需要接收的事件,如果不指定,则默认为空 `""` `receive` 装饰器接受一个可选参数 `id`,用于标识当前需要接收的事件,如果不指定,则默认为空 `""`
`handle_func` 函数中,可以通过依赖注入的方式来获取接收到的事件,参考:[`Received`](#received), [`LastReceived`](#lastreceived)。 `handle_func` 函数中,可以通过依赖注入的方式来获取接收到的事件,参考:[`Received`](#received)、[`LastReceived`](#lastreceived)。
:::important 提示 :::important 提示
`receive` 装饰器可以和自身与 `got` 装饰器嵌套使用 `receive` 装饰器可以和自身与 `got` 装饰器嵌套使用
@ -93,7 +93,7 @@ async def handle_func(key: Message = Arg()):
`got` 装饰器接受一个参数 `key` 和一个可选参数 `prompt`,当 `key` 不存在时,会向用户发送 `prompt` 消息,并等待用户回复。 `got` 装饰器接受一个参数 `key` 和一个可选参数 `prompt`,当 `key` 不存在时,会向用户发送 `prompt` 消息,并等待用户回复。
`handle_func` 函数中,可以通过依赖注入的方式来获取接收到的消息,参考:[`Arg`](#arg), [`ArgStr`](#argstr), [`ArgPlainText`](#argplaintext)。 `handle_func` 函数中,可以通过依赖注入的方式来获取接收到的消息,参考:[`Arg`](#arg)、[`ArgStr`](#argstr)、[`ArgPlainText`](#argplaintext)。
:::important 提示 :::important 提示
`got` 装饰器可以和自身与 `receive` 装饰器嵌套使用 `got` 装饰器可以和自身与 `receive` 装饰器嵌套使用
@ -113,7 +113,7 @@ matcher = on_message(
## 事件处理流程 ## 事件处理流程
在一个事件响应器中,事件被添加的处理依赖依次执行,直到所有处理依赖都执行完毕,或者遇到了某个处理依赖需要更多的事件来进行下一步的处理。在下一个事件到来并符合响应要求时,继续执行。更多有关 NoneBot 事件分发与处理流程的详细信息,请参考 [进阶 - 深入](../../advanced/README.md)。 在一个事件响应器中,事件被添加的处理依赖依次执行,直到所有处理依赖都执行完毕,或者遇到了某个处理依赖需要更多的事件来进行下一步的处理。在下一个事件到来并符合响应要求时,继续执行。更多有关 NoneBot 事件分发与处理流程的详细信息,请参考[进阶 - 深入](../../advanced/README.md)。
## 获取上下文信息 ## 获取上下文信息

View File

@ -10,15 +10,15 @@ options:
# 定义事件响应器 # 定义事件响应器
事件响应器 (`Matcher`) 是对接收到的事件进行响应的基本单元,所有的事件响应器都继承自 `Matcher` 基类。为方便编写插件NoneBot 在 `nonebot.plugin` 模块中为插件开发定义了一些辅助函数,以便插件开发者可以简化插件开发。首先,让我们来了解一下 `Matcher` 由哪些部分组成。 事件响应器`Matcher`是对接收到的事件进行响应的基本单元,所有的事件响应器都继承自 `Matcher` 基类。为方便开发者编写插件NoneBot2`nonebot.plugin` 模块中为插件开发定义了一些辅助函数。首先,让我们来了解一下 `Matcher` 由哪些部分组成。
## 事件响应器的基本组成 ## 事件响应器的基本组成
### 事件响应器类型 `type` ### 事件响应器类型 `type`
事件响应器的类型即是该响应器所要响应的事件类型,只有在接收到的事件类型与该响应器的类型相同时,才会触发该响应器。如果类型留空,该响应器将会响应所有类型的事件。 事件响应器的类型即是该响应器所要响应的事件类型,只有在接收到的事件类型与该响应器的类型相同时,才会触发该响应器。如果类型留空,该响应器将会响应所有类型的事件。
NoneBot 内置了四种主要类型:`meta_event`, `message`, `notice`, `request`。通常情况下,协议适配器会将事件合理的分类至这四种类型中。如果有其他类型的事件需要响应,可以自行定义新的类型。 NoneBot 内置了四种主要类型:`meta_event`、`message`、`notice`、`request`。通常情况下,协议适配器会将事件合理地分类至这四种类型中。如果有其他类型的事件需要响应,可以自行定义新的类型。
<!-- TODO: move session updater to advanced --> <!-- TODO: move session updater to advanced -->
@ -37,11 +37,11 @@ async def update_type():
::: :::
### 事件匹配规则 `rule` ### 事件匹配规则
事件响应器的匹配规则是一个 `Rule` 对象,它是一系列 `checker` 的集合,当所有的 `checker` 都返回 `True` 时,才会触发该响应器。 事件响应器的匹配规则是一个 `Rule` 对象,它是一系列 `checker` 的集合,当所有的 `checker` 都返回 `True` 时,才会触发该响应器。
规则编写方法参考 [自定义规则](#自定义规则)。 规则编写方法参考[自定义规则](#自定义规则)。
:::warning 注意 :::warning 注意
当会话状态更新时,`rule` 会被清空,以便会话收到新事件时能够正确匹配。 当会话状态更新时,`rule` 会被清空,以便会话收到新事件时能够正确匹配。
@ -51,12 +51,12 @@ async def update_type():
事件响应器的触发权限是一个 `Permission` 对象,它也是一系列 `checker` 的集合,当其中一个 `checker` 返回 `True` 时,就会触发该响应器。 事件响应器的触发权限是一个 `Permission` 对象,它也是一系列 `checker` 的集合,当其中一个 `checker` 返回 `True` 时,就会触发该响应器。
权限编写方法参考 [自定义权限](#自定义权限)。 权限编写方法参考[自定义权限](#自定义权限)。
:::warning 注意 :::warning 注意
`rule` 不同的是,`permission` 不会在会话状态更新时丢失,因此 `permission` 通常用于会话的响应控制。 `rule` 不同的是,`permission` 不会在会话状态更新时丢失,因此 `permission` 通常用于会话的响应控制。
并且, 当会话状态更新时,会执行 `permission_updater` 以更新 `permission`。默认情况下,`permission_updater` 会在原有的 `permission` 基础上添加一个 `USER` 条件,以检查事件的 `session_id` 是否与当前会话一致。 并且当会话状态更新时,会执行 `permission_updater` 以更新 `permission`。默认情况下,`permission_updater` 会在原有的 `permission` 基础上添加一个 `USER` 条件,以检查事件的 `session_id` 是否与当前会话一致。
你可以自行定义 `permission_updater` 来控制会话的响应权限更新。`permission_updater` 是一个返回 `Permission` 的函数,可选依赖注入参数参考类型 `T_PermissionUpdater` 你可以自行定义 `permission_updater` 来控制会话的响应权限更新。`permission_updater` 是一个返回 `Permission` 的函数,可选依赖注入参数参考类型 `T_PermissionUpdater`
@ -75,7 +75,7 @@ async def update_type(matcher: Matcher):
事件响应器的优先级代表事件响应器的执行顺序 事件响应器的优先级代表事件响应器的执行顺序
:::warning 警告 :::warning 警告
同一优先级的事件响应器会 **同时执行**,优先级数字 **越小** 越先响应!优先级请从 `1` 开始排序! 同一优先级的事件响应器会**同时执行**,优先级数字**越小**越先响应!优先级请从 `1` 开始排序!
::: :::
### 阻断 `block` ### 阻断 `block`
@ -94,7 +94,7 @@ async def handle(matcher: Matcher):
matcher.stop_propagation() matcher.stop_propagation()
``` ```
### 有效期 `temp` / `expire_time` ### 有效期 `temp`/`expire_time`
事件响应器可以设置有效期,当事件响应器超过有效期时,将会被移除。 事件响应器可以设置有效期,当事件响应器超过有效期时,将会被移除。
@ -111,7 +111,7 @@ from nonebot import on_message
matcher = on_message() matcher = on_message()
``` ```
用于定义事件响应器的辅助函数已经在 `nonebot` 主模块中被 `re-export` ,所以直接从 `nonebot` 导入即可。 用于定义事件响应器的辅助函数已经在 `nonebot` 主模块中被 `re-export`,所以直接从 `nonebot` 导入即可。
辅助函数有以下几种: 辅助函数有以下几种:

View File

@ -9,13 +9,13 @@ description: 插件入门
在编写插件之前,首先我们需要了解一下插件的概念。 在编写插件之前,首先我们需要了解一下插件的概念。
在 NoneBot 中,插件可以是 Python 的一个模块 `module` ,也可以是一个包 `package` 。NoneBot 会在导入时对这些模块或包做一些特殊的处理使得他们成为一个插件。插件间应尽量减少耦合可以进行有限制的插件间调用NoneBot 能够正确解析插件间的依赖关系。 在 NoneBot 中,插件可以是 Python 的一个模块 `module`,也可以是一个包 `package` 。NoneBot 会在导入时对这些模块或包做一些特殊的处理使得他们成为一个插件。插件间应尽量减少耦合可以进行有限制的插件间调用NoneBot 能够正确解析插件间的依赖关系。
下面详细介绍两种插件的结构: 下面详细介绍两种插件的结构:
### 模块插件(单文件形式) ### 模块插件(单文件形式)
在合适的路径创建一个 `.py` 文件即可。例如在 [创建项目](../create-project.mdx) 中创建的项目中,我们可以在 `awesome_bot/plugins/` 目录中创建一个文件 `foo.py` 在合适的路径创建一个 `.py` 文件即可。例如在[创建项目](../create-project.mdx)中创建的项目中,我们可以在 `awesome_bot/plugins/` 目录中创建一个文件 `foo.py`
```tree title=Project {4} ```tree title=Project {4}
📦 AweSome-Bot 📦 AweSome-Bot
@ -37,7 +37,7 @@ description: 插件入门
### 包插件(文件夹形式) ### 包插件(文件夹形式)
在合适的路径创建一个文件夹,并在文件夹内创建文件 `__init__.py` 即可。例如在 [创建项目](../create-project.mdx) 中创建的项目中,我们可以在 `awesome_bot/plugins/` 目录中创建一个文件夹 `foo`,并在这个文件夹内创建一个文件 `__init__.py` 在合适的路径创建一个文件夹,并在文件夹内创建文件 `__init__.py` 即可。例如在[创建项目](../create-project.mdx)中创建的项目中,我们可以在 `awesome_bot/plugins/` 目录中创建一个文件夹 `foo`,并在这个文件夹内创建一个文件 `__init__.py`
```tree title=Project {4,5} ```tree title=Project {4,5}
📦 AweSome-Bot 📦 AweSome-Bot
@ -64,7 +64,7 @@ description: 插件入门
请注意,插件名称不能存在重复,即所有模块插件的文件名和所有包插件的文件夹名不能存在相同。 请注意,插件名称不能存在重复,即所有模块插件的文件名和所有包插件的文件夹名不能存在相同。
::: :::
除了通过手动创建的方式以外,还可以通过 `nb-cli` 来创建插件,`nb-cli` 会为你在合适的位置创建一个模板包插件。 除了通过手动创建的方式以外,还可以通过 nb-cli 来创建插件nb-cli 会为你在合适的位置创建一个模板包插件。
```bash ```bash
nb plugin create nb plugin create

View File

@ -11,10 +11,10 @@ options:
# 加载插件 # 加载插件
:::danger 警告 :::danger 警告
请勿在插件被加载前 `import` 插件模块,这会导致 NoneBot 无法将其转换为插件而损失部分功能。 请勿在插件被加载前 `import` 插件模块,这会导致 NoneBot2 无法将其转换为插件而损失部分功能。
::: :::
加载插件通常在机器人的入口文件进行,例如在 [创建项目](../create-project.mdx) 中创建的项目中的 `bot.py` 文件。在 NoneBot 初始化完成后即可加载插件。 加载插件通常在机器人的入口文件进行,例如在[创建项目](../create-project.mdx)中创建的项目中的 `bot.py` 文件。在 NoneBot2 初始化完成后即可加载插件。
```python title=bot.py {5} ```python title=bot.py {5}
import nonebot import nonebot
@ -50,7 +50,7 @@ nonebot.load_plugins("src/plugins", "path/to/your/plugins")
## `load_all_plugins` ## `load_all_plugins`
这种加载方式是以上两种方式的合,加载所有传入的插件模块名称,以及所有给定目录下的插件。例如: 这种加载方式是以上两种方式的合,加载所有传入的插件模块名称,以及所有给定目录下的插件。例如:
```python ```python
nonebot.load_all_plugins(["path.to.your.plugin"], ["path/to/your/plugins"]) nonebot.load_all_plugins(["path.to.your.plugin"], ["path/to/your/plugins"])

View File

@ -16,7 +16,7 @@ options:
向用户回复一条消息。回复的方式或途径由协议适配器自行实现。 向用户回复一条消息。回复的方式或途径由协议适配器自行实现。
可以是 `str`, [`Message`](../../api/adapters/index.md#Message), [`MessageSegment`](../../api/adapters/index.md#MessageSegment) 或 [`MessageTemplate`](../../api/adapters/index.md#MessageTemplate)。 可以是 `str`、[`Message`](../../api/adapters/index.md#Message)、[`MessageSegment`](../../api/adapters/index.md#MessageSegment) 或 [`MessageTemplate`](../../api/adapters/index.md#MessageTemplate)。
这个操作等同于使用 `bot.send(event, message, **kwargs)` 但不需要自行传入 `event` 这个操作等同于使用 `bot.send(event, message, **kwargs)` 但不需要自行传入 `event`

View File

@ -11,20 +11,20 @@ options:
# 使用适配器 # 使用适配器
:::tip 提示 :::tip 提示
如何**安装**协议适配器请参考 [安装协议适配器](../start/install-adapter.mdx) 如何**安装**协议适配器请参考[安装协议适配器](../start/install-adapter.mdx)
::: :::
## 协议适配器的功能 ## 协议适配器的功能
由于 NoneBot 的跨平台特性,需要支持不同的协议,因此需要对特定的平台协议编写一个转换器。 由于 NoneBot2 的跨平台特性,需要支持不同的协议,因此需要对特定的平台协议编写一个转换器。
协议适配器即是充当中间人的转换器,它将驱动器所收到的数据转换为可以被 NoneBot 处理的事件 Event并将事件传递给 NoneBot。 协议适配器即是充当中间人的转换器,它将驱动器所收到的数据转换为可以被 NoneBot2 处理的事件 Event并将事件传递给 NoneBot2
同时,协议适配器还会处理 API 调用,转换为可以被驱动器处理的数据发送出去。 同时,协议适配器还会处理 API 调用,转换为可以被驱动器处理的数据发送出去。
## 注册协议适配器 ## 注册协议适配器
NoneBot 在默认情况下并不会加载任何协议适配器,需要自己手动注册。下方是个加载协议适配器的例子: NoneBot2 在默认情况下并不会加载任何协议适配器,需要自己手动注册。下方是个加载协议适配器的例子:
```python title=bot.py ```python title=bot.py
import nonebot import nonebot
@ -56,7 +56,7 @@ nonebot.run()
### 获得驱动器实例 ### 获得驱动器实例
加载协议适配器需要通过驱动器来进行,因此,你需要先初始化 NoneBot并获得驱动器实例。 加载协议适配器需要通过驱动器来进行,因此,你需要先初始化 NoneBot2,并获得驱动器实例。
```python title=bot.py {4,5} ```python title=bot.py {4,5}
import nonebot import nonebot