📝 archive doc

This commit is contained in:
yanyongyu 2021-03-31 21:37:01 +08:00
parent f1ed783776
commit afba90838f
50 changed files with 544 additions and 156 deletions

View File

@ -1,60 +0,0 @@
# 钩子函数
[`钩子编程`](https://zh.wikipedia.org/wiki/%E9%92%A9%E5%AD%90%E7%BC%96%E7%A8%8B)
> 钩子编程hooking也称作“挂钩”是计算机程序设计术语指通过拦截软件模块间的函数调用、消息传递、事件传递来修改或扩展操作系统、应用程序或其他软件组件的行为的各种技术。处理被拦截的函数调用、事件、消息的代码被称为钩子hook
`nonebot2` 中有一系列预定义的钩子函数,这些函数位于 [`nonebot.message`](https://v2.nonebot.dev/api/message.html) 模块下,我们可以以装饰器的形式利用这些函数,进行以下四种操作:
:::warning 注意
1.在钩子函数中,与 `matcher` 运行状态相关的函数将不可用,如 `matcher.finish()`
2.如果需要在钩子函数中打断整个对话的执行,请参考以下范例:
```python
from nonebot.exception import IgnoredException
@event_preprocessor
async def do_something(bot: Bot, event: Event, state: T_State):
raise IgnoredException("reason")
```
:::
## 事件预处理
```python
from nonebot.message import event_preprocessor
@event_preprocessor
async def do_something(bot: Bot, event: Event, state: T_State):
pass
```
## 事件后处理
```python
from nonebot.message import event_postprocessor
@event_postprocessor
async def do_something(bot: Bot, event: Event, state: T_State):
pass
```
## 运行预处理
```python
from nonebot.message import run_preprocessor
@run_preprocessor
async def do_something(matcher: Matcher, bot: Bot, event: Event, state: T_State):
pass
```
## 运行后处理
```python
from nonebot.message import run_postprocessor
@run_postprocessor
async def do_something(matcher: Matcher, exception: Optional[Exception], bot: Bot, event: Event, state: T_State):
pass
```

View File

@ -10,9 +10,17 @@
**便捷起见,以下内容对 `Nonebot2` 会被称为 `nonebot`,与 `Nonebot2` 交互的机器人实现会被称为 `协议端`**。 **便捷起见,以下内容对 `Nonebot2` 会被称为 `nonebot`,与 `Nonebot2` 交互的机器人实现会被称为 `协议端`**。
在实际应用中,`nonebot` 会充当一个高性能,轻量级的 Python 微服务框架。协议端可以通过 `http`, `websocket` 等方式与之通信,这个通信往往是双向的:一方面,协议端可以上报数据给 `nonebot``nonebot` 会处理数据并返回响应给协议端;另一方面,`nonebot` 可以主动推送数据给协议端。而 `nonebot` 便是围绕上述的双向通信进行工作的。 在实际应用中,`nonebot` 会充当一个高性能,轻量级的 Python 微服务框架。协议端可以通过 `http`, `websocket` 等方式与之通信,这个通信往往是双向的:一方面,协议端可以上报数据给 `nonebot``nonebot` 会处理数据并返回响应给协议端;另一方面,`nonebot` 可以主动推送数据给协议端。而 `nonebot` 便是围绕双向通信进行工作的。
在开始工作之前,`nonebot` 会依照**配置文件或初始化配置**启动,并会注册**协议适配器** `adapter`,之后便会加载**插件** 随后,倘若一个协议端与 `nonebot` 进行了连接,`nonebot` 的后端驱动 `driver` 就会将 `adapter` 实例化为 `bot``nonebot` 便会利用 `bot` 开始工作,它的工作内容分为两个方面: 在开始工作之前,`nonebot` 需要进行准备工作:
1. **运行 `nonebot.init` 初始化函数**,它会读取配置文件,并初始化 `nonebot` 和后端驱动 `driver` 对象。
2. **注册协议适配器 `adapter`**
3. **加载插件**
准备工作完成后,`nonebot` 会利用 `uvicorn` 启动,并运行 `on_startup` 钩子函数。
随后,倘若一个协议端与 `nonebot` 进行了连接,`nonebot` 的后端驱动 `driver` 就会将 `adapter` 实例化为 `bot``nonebot` 便会利用 `bot` 开始工作,它的工作内容分为两个方面:
1. **事件处理**`bot` 会将协议端上报的数据转化为 `事件`(`Event`),之后 `nonebot` 会根据一套既定流程来处理 `事件` 1. **事件处理**`bot` 会将协议端上报的数据转化为 `事件`(`Event`),之后 `nonebot` 会根据一套既定流程来处理 `事件`
@ -41,7 +49,7 @@
1. 协议端会通过 `websocket` 或者 `http` 等方式与 `nonebot` 的后端驱动 `driver` 连接,`driver` 会根据之前注册的 `adapter` 和配置文件的内容来进行鉴权,从而获得这个连接的唯一识别 id `self-id`,随后 `adapter` 就会利用 `self-id` 实例化为 `bot` 对象。 1. 协议端会通过 `websocket` 或者 `http` 等方式与 `nonebot` 的后端驱动 `driver` 连接,`driver` 会根据之前注册的 `adapter` 和配置文件的内容来进行鉴权,从而获得这个连接的唯一识别 id `self-id`,随后 `adapter` 就会利用 `self-id` 实例化为 `bot` 对象。
::: tip ::: tip
需要注意的是,如果协议端通过 `websocket``nonebot` 连接,这个步骤只会在建立连接时进行;通过 `http` 方式连接时,会在协议端每次上报数据时都进行这个步骤。 需要注意的是,如果协议端通过 `websocket``nonebot` 连接,这个步骤只会在建立连接时进行,并在之后运行 `on_bot_connect` 钩子函数;通过 `http` 方式连接时,会在协议端每次上报数据时都进行这个步骤。
::: :::
::: warning ::: warning
@ -142,7 +150,7 @@
这个异常可以在 `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**
@ -158,7 +166,7 @@
## 调用 API ## 调用 API
`nonebot` 可以通过 `bot` 来调用 APIAPI 可以向协议端发送数据,也可以向协议端请求更多的数据。 `nonebot` 可以通过 `bot` 来调用 `API` `API` 可以向协议端发送数据,也可以向协议端请求更多的数据。
::: tip ::: tip
不同 `adapter` 规定了不同的 API对应的 API 列表请参照协议规范。 不同 `adapter` 规定了不同的 API对应的 API 列表请参照协议规范。

View File

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

View File

@ -19,6 +19,9 @@
* [nonebot.matcher](matcher.html) * [nonebot.matcher](matcher.html)
* [nonebot.handler](handler.html)
* [nonebot.rule](rule.html) * [nonebot.rule](rule.html)

View File

@ -27,6 +27,21 @@ Driver 对象
Config 配置对象 Config 配置对象
### `_call_api_hook`
* **类型**
`Set[T_CallingAPIHook]`
* **说明**
call_api 时执行的函数
### _abstract_ `__init__(connection_type, self_id, *, websocket=None)` ### _abstract_ `__init__(connection_type, self_id, *, websocket=None)`
@ -93,7 +108,7 @@ Adapter 类型
* `headers: dict`: 请求头 * `headers: dict`: 请求头
* `body: Optional[dict]`: 请求数据WebSocket 连接该部分为空 * `body: Optional[bytes]`: 请求数据WebSocket 连接该部分为 None
@ -127,7 +142,26 @@ Adapter 类型
### _abstract async_ `call_api(api, **data)` ### _abstract async_ `_call_api(api, **data)`
* **说明**
`adapter` 实际调用 api 的逻辑实现函数,实现该方法以调用 api。
* **参数**
* `api: str`: API 名称
* `**data`: API 数据
### _async_ `call_api(api, **data)`
* **说明** * **说明**
@ -142,6 +176,9 @@ Adapter 类型
* `api: str`: API 名称 * `api: str`: API 名称
* `self_id: Optional[str]`: 指定调用 API 的机器人
* `**data`: API 数据 * `**data`: API 数据

View File

@ -129,6 +129,9 @@ sidebarDepth: 0
* `api: str`: API 名称 * `api: str`: API 名称
* `event: Optional[MessageEvent]`: Event 对象
* `**data: Any`: API 参数 * `**data: Any`: API 参数
@ -150,7 +153,7 @@ sidebarDepth: 0
### _async_ `send(event, message, at_sender=False, **kwargs)` ### _async_ `send(event, message, at_sender=False, webhook=None, secret=None, **kwargs)`
* **说明** * **说明**
@ -171,6 +174,12 @@ sidebarDepth: 0
* `at_sender: bool`: 是否 @ 事件主体 * `at_sender: bool`: 是否 @ 事件主体
* `webhook: Optional[str]`: 该条消息将调用的 webhook 地址。不传则将使用 sessionWebhook若其也不存在该条消息不发送使用自定义 webhook 时注意你设置的安全方式如加关键词IP地址加签等等。
* `secret: Optional[str]`: 如果你使用自定义的 webhook 地址,推荐使用加签方式对消息进行验证,将 机器人安全设置页面加签一栏下面显示的SEC开头的字符串 传入这个参数即可。
* `**kwargs`: 覆盖默认参数 * `**kwargs`: 覆盖默认参数

View File

@ -28,7 +28,7 @@ FastAPI 驱动框架设置,详情参考 FastAPI 文档
* **说明** * **说明**
openapi.json 地址,默认为 None 即关闭 `openapi.json` 地址,默认为 `None` 即关闭
@ -43,7 +43,7 @@ FastAPI 驱动框架设置,详情参考 FastAPI 文档
* **说明** * **说明**
swagger 地址,默认为 None 即关闭 `swagger` 地址,默认为 `None` 即关闭
@ -58,7 +58,22 @@ FastAPI 驱动框架设置,详情参考 FastAPI 文档
* **说明** * **说明**
redoc 地址,默认为 None 即关闭 `redoc` 地址,默认为 `None` 即关闭
### `fastapi_reload_dirs`
* **类型**
`List[str]`
* **说明**
`debug` 模式下重载监控文件夹列表,默认为 uvicorn 默认值

View File

@ -0,0 +1,111 @@
---
contentSidebar: true
sidebarDepth: 0
---
# NoneBot.handler 模块
## 事件处理函数
该模块实现事件处理函数的封装,以实现动态参数等功能。
## _class_ `Handler`
基类:`object`
事件处理函数类
### `__init__(func)`
装饰事件处理函数以便根据动态参数运行
### `func`
* **类型**
`T_Handler`
* **说明**
事件处理函数
### `signature`
* **类型**
`inspect.Signature`
* **说明**
事件处理函数签名
### _property_ `bot_type`
* **类型**
`Union[Type["Bot"], inspect.Parameter.empty]`
* **说明**
事件处理函数接受的 Bot 对象类型
### _property_ `event_type`
* **类型**
`Optional[Union[Type[Event], inspect.Parameter.empty]]`
* **说明**
事件处理函数接受的 event 类型 / 不需要 event 参数
### _property_ `state_type`
* **类型**
`Optional[Union[T_State, inspect.Parameter.empty]]`
* **说明**
事件处理函数是否接受 state 参数
### _property_ `matcher_type`
* **类型**
`Optional[Union[Type["Matcher"], inspect.Parameter.empty]]`
* **说明**
事件处理函数是否接受 matcher 参数

View File

@ -7,7 +7,7 @@ sidebarDepth: 0
## 事件响应器 ## 事件响应器
该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行 对话 。 该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行对话 。
## `matchers` ## `matchers`
@ -202,7 +202,7 @@ sidebarDepth: 0
* **类型** * **类型**
`Optional[T_ArgsParser]` `Optional[T_TypeUpdater]`
@ -217,7 +217,7 @@ sidebarDepth: 0
* **类型** * **类型**
`Optional[T_ArgsParser]` `Optional[T_PermissionUpdater]`
@ -237,7 +237,7 @@ sidebarDepth: 0
* **类型** * **类型**
`List[T_Handler]` `List[Handler]`

View File

@ -25,38 +25,6 @@ sidebarDepth: 0
## _class_ `Export`
基类:`dict`
* **说明**
插件导出内容以使得其他插件可以获得。
* **示例**
```python
nonebot.export().default = "bar"
@nonebot.export()
def some_function():
pass
# this doesn't work before python 3.9
# use
# export = nonebot.export(); @export.sub
# instead
# See also PEP-614: https://www.python.org/dev/peps/pep-0614/
@nonebot.export().sub
def something_else():
pass
```
## _class_ `Plugin` ## _class_ `Plugin`
基类:`object` 基类:`object`
@ -82,15 +50,6 @@ def something_else():
* **说明**: 插件模块对象 * **说明**: 插件模块对象
### `matcher`
* **类型**: `Set[Type[Matcher]]`
* **说明**: 插件内定义的 `Matcher`
### `export` ### `export`
@ -100,6 +59,15 @@ def something_else():
* **说明**: 插件内定义的导出内容 * **说明**: 插件内定义的导出内容
### _property_ `matcher`
* **类型**: `Set[Type[Matcher]]`
* **说明**: 插件内定义的 `Matcher`
## `on(type='', rule=None, permission=None, *, handlers=None, temp=False, priority=1, block=False, state=None, state_factory=None)` ## `on(type='', rule=None, permission=None, *, handlers=None, temp=False, priority=1, block=False, state=None, state_factory=None)`
@ -121,7 +89,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -162,7 +130,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则 * `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -206,7 +174,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -247,7 +215,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则 * `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -288,7 +256,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则 * `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -335,7 +303,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -382,7 +350,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -429,7 +397,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -481,7 +449,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -538,7 +506,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -590,7 +558,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -767,7 +735,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -808,7 +776,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则 * `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -852,7 +820,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -893,7 +861,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则 * `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -934,7 +902,7 @@ def something_else():
* `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则 * `rule: Optional[Union[Rule, T_RuleChecker]]`: 事件响应规则
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -981,7 +949,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1028,7 +996,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1075,7 +1043,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1127,7 +1095,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1184,7 +1152,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1236,7 +1204,7 @@ def something_else():
* `permission: Optional[Permission]`: 事件响应权限 * `permission: Optional[Permission]`: 事件响应权限
* `handlers: Optional[List[T_Handler]]`: 事件处理函数列表 * `handlers: Optional[List[Union[T_Handler, Handler]]]`: 事件处理函数列表
* `temp: bool`: 是否为临时事件响应器(仅执行一次) * `temp: bool`: 是否为临时事件响应器(仅执行一次)
@ -1442,22 +1410,6 @@ def something_else():
## `export()`
* **说明**
获取插件的导出内容对象
* **返回**
* `Export`
## `require(name)` ## `require(name)`
@ -1478,3 +1430,51 @@ def something_else():
* `Optional[Export]` * `Optional[Export]`
## _class_ `Export`
基类:`dict`
* **说明**
插件导出内容以使得其他插件可以获得。
* **示例**
```python
nonebot.export().default = "bar"
@nonebot.export()
def some_function():
pass
# this doesn't work before python 3.9
# use
# export = nonebot.export(); @export.sub
# instead
# See also PEP-614: https://www.python.org/dev/peps/pep-0614/
@nonebot.export().sub
def something_else():
pass
```
## `export()`
* **说明**
获取插件的导出内容对象
* **返回**
* `Export`

View File

@ -11,6 +11,10 @@
- [群机器人概述](https://developers.dingtalk.com/document/app/overview-of-group-robots) - [群机器人概述](https://developers.dingtalk.com/document/app/overview-of-group-robots)
- [开发企业内部机器人](https://developers.dingtalk.com/document/app/develop-enterprise-internal-robots) - [开发企业内部机器人](https://developers.dingtalk.com/document/app/develop-enterprise-internal-robots)
钉钉官方机器人教程Java
- [开发一个钉钉机器人](https://developers.dingtalk.com/document/tutorial/create-a-robot)
## 安装 NoneBot 钉钉 适配器 ## 安装 NoneBot 钉钉 适配器
```bash ```bash
@ -93,6 +97,58 @@ async def raw_handler(bot: DingBot, event: MessageEvent):
其他消息格式请查看 [钉钉适配器的 MessageSegment](https://github.com/nonebot/nonebot2/blob/dev/nonebot/adapters/ding/message.py#L8),里面封装了很多有关消息的方法,比如 `code`、`image`、`feedCard` 等。 其他消息格式请查看 [钉钉适配器的 MessageSegment](https://github.com/nonebot/nonebot2/blob/dev/nonebot/adapters/ding/message.py#L8),里面封装了很多有关消息的方法,比如 `code`、`image`、`feedCard` 等。
## 发送到特定群聊
钉钉也支持通过 Webhook 的方式直接将消息推送到某个群聊([参考链接](https://developers.dingtalk.com/document/app/custom-robot-access/title-zob-eyu-qse)),你可以在机器人的设置中看到当前群的 Webhook 地址。
![机器人所在群的 Webhook 地址](./images/ding/webhook.png)
获取到Webhook地址后用户可以向这个地址发起HTTP POST 请求,即可实现给该钉钉群发送消息。
对于这种通过 Webhook 推送的消息钉钉需要开发者进行安全方面的设置目前有3种安全设置方式请根据需要选择一种如下
1. **自定义关键词:** 最多可以设置10个关键词消息中至少包含其中1个关键词才可以发送成功。
例如添加了一个自定义关键词:监控报警,则这个机器人所发送的消息,必须包含监控报警这个词,才能发送成功。
2. **加签:** 发送请求时带上验签的值,可以在机器人设置里看到密钥。
![加签密钥](./images/ding/jiaqian.png)
3. **IP地址** 设定后只有来自IP地址范围内的请求才会被正常处理。支持两种设置方式IP地址和IP地址段暂不支持IPv6地址白名单。
如果你选择 1/3 两种安全设置,你需要自己确认当前网络和发送的消息能被钉钉接受,然后使用 `bot.send` 的时候将 webhook 地址传入 webhook 参数即可。
如我设置了 `打卡` 为关键词:
```python
message = MessageSegment.text("打卡成功XXXXXX")
await hello.send(
message,
webhook=
"https://oapi.dingtalk.com/robot/send?access_token=XXXXXXXXXXXXXX",
)
```
对于第二种加签方式,你可以在 `bot.send` 的时候把 `secret` 参数传进去Nonebot 内部会自动帮你计算发送该消息的签名并发送,如:
这里的 `secret` 参数就是加签选项给出的那个密钥。
```python
message = MessageSegment.raw({
"msgtype": "text",
"text": {
"content": 'hello from webhook,一定要注意安全方式的鉴权哦,否则可能发送失败的'
},
})
message += MessageSegment.atDingtalkIds(event.senderId)
await hello.send(
message,
webhook="https://oapi.dingtalk.com/robot/send?access_token=XXXXXXXXXXXXXX",
secret="SECXXXXXXXXXXXXXXXXXXXXXXXXX",
)
```
然后就可以发送成功了。
![测试 Webhook 发送](images/ding/test_webhook.png)
## 创建机器人并连接 ## 创建机器人并连接
在钉钉官方文档 [「开发企业内部机器人 -> 步骤一:创建机器人应用」](https://developers.dingtalk.com/document/app/develop-enterprise-internal-robots/title-ufs-4gh-poh) 中有详细介绍,这里就省去创建的步骤,介绍一下如何连接上程序。 在钉钉官方文档 [「开发企业内部机器人 -> 步骤一:创建机器人应用」](https://developers.dingtalk.com/document/app/develop-enterprise-internal-robots/title-ufs-4gh-poh) 中有详细介绍,这里就省去创建的步骤,介绍一下如何连接上程序。

View File

@ -4,6 +4,5 @@
- 请千万注意事件处理器的优先级设定 - 请千万注意事件处理器的优先级设定
- 在匹配规则中请勿使用耗时极长的函数 - 在匹配规则中请勿使用耗时极长的函数
- 同一个用户可以**跨群**(**私聊**)继续他的事件处理(除非做出权限限制,将在后续介绍)
如果「指南」还不能满足你,前往 [进阶](../advanced/README.md) 查看更多的功能信息。 如果「指南」还不能满足你,前往 [进阶](../advanced/README.md) 查看更多的功能信息。

View File

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -68,6 +68,7 @@ pip install . # 不推荐
``` ```
## 安装适配器 ## 安装适配器
适配器可以通过 `nb-cli` 在创建项目时根据你的选择自动安装,也可以自行使用 `pip` 安装 适配器可以通过 `nb-cli` 在创建项目时根据你的选择自动安装,也可以自行使用 `pip` 安装
```bash ```bash
@ -99,6 +100,7 @@ nb plugin install xxx
- [NoneBot-Plugin-Docs](https://github.com/nonebot/nonebot2/tree/master/packages/nonebot-plugin-docs) 离线文档插件 - [NoneBot-Plugin-Docs](https://github.com/nonebot/nonebot2/tree/master/packages/nonebot-plugin-docs) 离线文档插件
- [NoneBot-Plugin-Test](https://github.com/nonebot/plugin-test) 本地机器人测试前端插件 - [NoneBot-Plugin-Test](https://github.com/nonebot/plugin-test) 本地机器人测试前端插件
- [NoneBot-Plugin-APScheduler](https://github.com/nonebot/plugin-apscheduler) 定时任务插件 - [NoneBot-Plugin-APScheduler](https://github.com/nonebot/plugin-apscheduler) 定时任务插件
- [NoneBot-Plugin-LocalStore](https://github.com/nonebot/plugin-localstore) 本地数据文件存储插件
- [NoneBot-Plugin-Sentry](https://github.com/cscs181/QQ-GitHub-Bot/tree/master/src/plugins/nonebot_plugin_sentry) Sentry 在线日志分析插件 - [NoneBot-Plugin-Sentry](https://github.com/cscs181/QQ-GitHub-Bot/tree/master/src/plugins/nonebot_plugin_sentry) Sentry 在线日志分析插件
- [NoneBot-Plugin-Status](https://github.com/cscs181/QQ-GitHub-Bot/tree/master/src/plugins/nonebot_plugin_status) 服务器状态查看插件 - [NoneBot-Plugin-Status](https://github.com/cscs181/QQ-GitHub-Bot/tree/master/src/plugins/nonebot_plugin_status) 服务器状态查看插件

View File

@ -119,6 +119,10 @@
"title": "nonebot.matcher 模块", "title": "nonebot.matcher 模块",
"path": "matcher" "path": "matcher"
}, },
{
"title": "nonebot.handler 模块",
"path": "handler"
},
{ {
"title": "nonebot.rule 模块", "title": "nonebot.rule 模块",
"path": "rule" "path": "rule"

View File

@ -1,5 +1,5 @@
[ [
"2.0.0a11", "2.0.0a12",
"2.0.0a10", "2.0.0a10",
"2.0.0a8.post2", "2.0.0a8.post2",
"2.0.0a7" "2.0.0a7"

View File

@ -1430,3 +1430,51 @@ sidebarDepth: 0
* `Optional[Export]` * `Optional[Export]`
## _class_ `Export`
基类:`dict`
* **说明**
插件导出内容以使得其他插件可以获得。
* **示例**
```python
nonebot.export().default = "bar"
@nonebot.export()
def some_function():
pass
# this doesn't work before python 3.9
# use
# export = nonebot.export(); @export.sub
# instead
# See also PEP-614: https://www.python.org/dev/peps/pep-0614/
@nonebot.export().sub
def something_else():
pass
```
## `export()`
* **说明**
获取插件的导出内容对象
* **返回**
* `Export`

View File

@ -10,3 +10,8 @@ NoneBot.plugin 模块
:members: :members:
:show-inheritance: :show-inheritance:
:special-members: __init__ :special-members: __init__
.. automodule:: nonebot.plugin.export
:members:
:show-inheritance:
:special-members: __init__