Compare commits
125 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
70c400da7f | ||
|
2a5cfe712f | ||
|
533a045622 | ||
|
93aa1791c9 | ||
|
06c76cc096 | ||
|
04df0e5f51 | ||
|
f99e029567 | ||
|
71ee9aee21 | ||
|
d9ea95c67e | ||
|
af7f42ac60 | ||
|
15e59a1778 | ||
|
22962d55e1 | ||
|
70c7927006 | ||
|
89c3aa38a6 | ||
|
2eb330b8a8 | ||
|
383c0031a5 | ||
|
06f20281a5 | ||
|
a40f1a453c | ||
|
5d9f354209 | ||
|
c3bd8ebf57 | ||
|
c9c615c8cb | ||
|
47f491039c | ||
|
dc5c35a9ed | ||
|
c636186321 | ||
|
aafc3dd060 | ||
|
38469611a4 | ||
|
59a8bd8c97 | ||
|
50cfd3c9b5 | ||
|
5d08d53c27 | ||
|
4f6f99146c | ||
|
32388d070d | ||
|
d9f8bf38c6 | ||
|
4e2b74af75 | ||
|
c2c28cebf5 | ||
|
24141b1a4b | ||
|
c85e50d73d | ||
|
444156766a | ||
|
308824d0b1 | ||
|
c3ed962837 | ||
|
2c13303d89 | ||
|
1304b94b61 | ||
|
8ca677c271 | ||
|
7c17412106 | ||
|
26207f762b | ||
|
8db70dbb0c | ||
|
1b6924a104 | ||
|
c5a30a8a79 | ||
|
56c9c24dc6 | ||
|
9ad629841b | ||
|
78433bdae9 | ||
|
5f44212faa | ||
|
df517b6b36 | ||
|
6afe9b6f4f | ||
|
1d79ac232f | ||
|
0a64959973 | ||
|
1e4b058681 | ||
|
3c5d06a2de | ||
|
1ee7c792e8 | ||
|
39a950ea80 | ||
|
5bb41395d8 | ||
|
a68ba09910 | ||
|
b4e0034876 | ||
|
e58174f6ec | ||
|
1377f7337d | ||
|
96ce29fd52 | ||
|
f164d85c5c | ||
|
ce758a2231 | ||
|
05c3a4b84f | ||
|
1d31e646ad | ||
|
927a963d4f | ||
|
727eef9a34 | ||
|
9f8d009309 | ||
|
734d3cd333 | ||
|
2e989b5fe1 | ||
|
781d0cf654 | ||
|
0a11bd3e8e | ||
|
2574ef3e7a | ||
|
b80f0bf202 | ||
|
c7f1859d99 | ||
|
d71260ed68 | ||
|
3e4dc1a123 | ||
|
a308f4d4ee | ||
|
1aac3d562d | ||
|
5b9e86275a | ||
|
1016986663 | ||
|
ef29280585 | ||
|
5b0083c0a8 | ||
|
d823b1733b | ||
|
921acff09e | ||
|
edc3aadbb5 | ||
|
f3986ace51 | ||
|
0eafedefa1 | ||
|
73e6062a1b | ||
|
00f22e5f05 | ||
|
35ed536cdf | ||
|
e13561c374 | ||
|
2921ba0120 | ||
|
4e4d494ffd | ||
|
b955024818 | ||
|
1952d93324 | ||
|
e0cba7c20c | ||
|
2042097f83 | ||
|
3dc95b904f | ||
|
ecbe465232 | ||
|
2e87c40434 | ||
|
3467eb3c29 | ||
|
457fdfb057 | ||
|
44fef77288 | ||
|
bbeea86fd5 | ||
|
8bd1aa0662 | ||
|
8b09c0be35 | ||
|
dee86ae607 | ||
|
f8231ec7e9 | ||
|
3bd9a9cc73 | ||
|
9171894a15 | ||
|
1d7180e6cd | ||
|
1045e6a797 | ||
|
68795c36f2 | ||
|
2319ab7d20 | ||
|
541dce6c54 | ||
|
4306d12f83 | ||
|
b4d7fded7f | ||
|
0a8a53a764 | ||
|
2089c773ac | ||
|
310aeb8447 |
33
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a bug report to help us improve
|
||||||
|
title: 'Bug: Something went wrong'
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**描述问题:**
|
||||||
|
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**如何复现?**
|
||||||
|
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**期望的结果**
|
||||||
|
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**环境信息:**
|
||||||
|
|
||||||
|
- OS: [e.g. Linux]
|
||||||
|
- Python Version: [e.g. 3.8]
|
||||||
|
- Nonebot Version [e.g. 2.0.0]
|
||||||
|
|
||||||
|
**截图**
|
||||||
|
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
16
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: 'Feature: Something you want'
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**是否在使用中遇到某些问题而需要新的特性?请描述:**
|
||||||
|
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**描述你所需要的特性:**
|
||||||
|
|
||||||
|
A clear and concise description of what you want to happen.
|
36
.github/ISSUE_TEMPLATE/plugin-publish.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
name: Plugin Publish
|
||||||
|
about: Publish your plugin to nonebot homepage and nb-cli
|
||||||
|
title: "Plugin: blabla 的插件"
|
||||||
|
labels: Plugin
|
||||||
|
assignees: ""
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**你的插件名称:**
|
||||||
|
|
||||||
|
例:复读机
|
||||||
|
|
||||||
|
**简短描述插件功能:**
|
||||||
|
|
||||||
|
例:复读群友的消息
|
||||||
|
|
||||||
|
**插件 import 使用的名称**
|
||||||
|
|
||||||
|
例:nonebot-plugin-example
|
||||||
|
|
||||||
|
**插件 install 使用的名称**
|
||||||
|
|
||||||
|
例 1:nonebot-plugin-example
|
||||||
|
|
||||||
|
通过 pypi 安装
|
||||||
|
|
||||||
|
> 请事先发布插件到[pypi](https://pypi.org/)
|
||||||
|
|
||||||
|
例 2:git+https://github.com/nonebot/nonebot-plugin-example
|
||||||
|
|
||||||
|
从 github 仓库安装
|
||||||
|
|
||||||
|
**插件项目仓库/主页链接**
|
||||||
|
|
||||||
|
例:nonebot/nonebot2(默认 github )或其他链接
|
31
.github/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
name-template: 'v$RESOLVED_VERSION 🌈'
|
||||||
|
tag-template: 'v$RESOLVED_VERSION'
|
||||||
|
categories:
|
||||||
|
- title: '🚀 Features'
|
||||||
|
labels:
|
||||||
|
- 'feature'
|
||||||
|
- 'enhancement'
|
||||||
|
- title: '🐛 Bug Fixes'
|
||||||
|
labels:
|
||||||
|
- 'fix'
|
||||||
|
- 'bugfix'
|
||||||
|
- 'bug'
|
||||||
|
- title: '🧰 Maintenance'
|
||||||
|
label: 'chore'
|
||||||
|
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||||
|
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
||||||
|
version-resolver:
|
||||||
|
major:
|
||||||
|
labels:
|
||||||
|
- 'major'
|
||||||
|
minor:
|
||||||
|
labels:
|
||||||
|
- 'minor'
|
||||||
|
patch:
|
||||||
|
labels:
|
||||||
|
- 'patch'
|
||||||
|
default: patch
|
||||||
|
template: |
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
$CHANGES
|
42
.github/workflows/api_docs.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
name: Build API Doc
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [ opened, synchronize, reopened ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
token: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
architecture: "x64"
|
||||||
|
|
||||||
|
- name: Install Dependences
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install poetry
|
||||||
|
poetry install
|
||||||
|
|
||||||
|
- name: Build Doc
|
||||||
|
run: poetry run sphinx-build -M markdown ./docs_build ./build
|
||||||
|
|
||||||
|
- name: Copy Files
|
||||||
|
run: cp -r ./build/markdown/* ./docs/api/
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
git config user.name nonebot
|
||||||
|
git config user.email nonebot@nonebot.dev
|
||||||
|
git add .
|
||||||
|
git diff-index --quiet HEAD || git commit -m ":memo: update api docs"
|
||||||
|
git remote -vv
|
||||||
|
git remote add target ${{github.event.pull_request.head.repo.clone_url}}
|
||||||
|
git push target HEAD:${{github.event.pull_request.head.ref}}
|
14
.github/workflows/release-draft.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
name: Release Drafter
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_release_draft:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: release-drafter/release-drafter@v5
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
54
README.md
@@ -1,22 +1,47 @@
|
|||||||
<div align=center>
|
<p align="center">
|
||||||
<img src="docs/.vuepress/public/logo.png" width="200" height="200">
|
<a href="https://v2.nonebot.dev/"><img src="https://raw.githubusercontent.com/nonebot/nonebot2/master/docs/.vuepress/public/logo.png" width="200" height="200" alt="nonebot"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
# NoneBot
|
# NoneBot
|
||||||
|
|
||||||
[](LICENSE)
|
_✨ Python 异步机器人框架 ✨_
|
||||||
[](https://pypi.python.org/pypi/nonebot)
|
|
||||||

|
|
||||||

|
|
||||||
[](https://jq.qq.com/?_wv=1027&k=5OFifDh)
|
|
||||||
[](https://t.me/cqhttp)
|
|
||||||
[](https://jq.qq.com/?_wv=1027&k=5Nl0zhE)
|
|
||||||
[](https://t.me/cqhttp_release)
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## 简介
|
<p align="center">
|
||||||
|
<a href="https://raw.githubusercontent.com/nonebot/nonebot2/master/LICENSE">
|
||||||
|
<img src="https://img.shields.io/github/license/nonebot/nonebot2.svg" alt="license">
|
||||||
|
</a>
|
||||||
|
<a href="https://pypi.python.org/pypi/nonebot2">
|
||||||
|
<img src="https://img.shields.io/pypi/v/nonebot2.svg" alt="pypi">
|
||||||
|
</a>
|
||||||
|
<img src="https://img.shields.io/badge/python-3.7+-blue.svg" alt="python">
|
||||||
|
<img src="https://img.shields.io/badge/cqhttp-11+-black.svg" alt="cqhttp"><br />
|
||||||
|
<a href="https://jq.qq.com/?_wv=1027&k=5OFifDh">
|
||||||
|
<img src="https://img.shields.io/badge/qq%E7%BE%A4-768887710-orange.svg" alt="QQ Chat">
|
||||||
|
</a>
|
||||||
|
<a href="https://t.me/cqhttp">
|
||||||
|
<img src="https://img.shields.io/badge/telegram-chat-blue.svg" alt="Telegram Chat">
|
||||||
|
</a>
|
||||||
|
<a href="https://jq.qq.com/?_wv=1027&k=5Nl0zhE">
|
||||||
|
<img src="https://img.shields.io/badge/%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E7%BE%A4-218529254-green.svg" alt="QQ Release">
|
||||||
|
</a>
|
||||||
|
<a href="https://t.me/cqhttp_release">
|
||||||
|
<img src="https://img.shields.io/badge/版本发布频道-join-green.svg" alt="Telegram Release">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
**NoneBot2 尚在开发中**
|
<p align="center">
|
||||||
|
<a href="https://v2.nonebot.dev/">文档</a>
|
||||||
|
·
|
||||||
|
<a href="https://v2.nonebot.dev/guide/installation.html">安装</a>
|
||||||
|
·
|
||||||
|
<a href="https://v2.nonebot.dev/guide/getting-started.html">开始使用</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
NoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人收到的消息进行解析和处理,并以插件化的形式,分发给消息所对应的命令处理器和自然语言处理器,来完成具体的功能。
|
NoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人收到的消息进行解析和处理,并以插件化的形式,分发给消息所对应的命令处理器和自然语言处理器,来完成具体的功能。
|
||||||
|
|
||||||
@@ -28,6 +53,11 @@ NoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人
|
|||||||
|
|
||||||
需要注意的是,NoneBot 仅支持 Python 3.7+ 及 CQHTTP(OneBot) 插件 v11+。
|
需要注意的是,NoneBot 仅支持 Python 3.7+ 及 CQHTTP(OneBot) 插件 v11+。
|
||||||
|
|
||||||
|
此外,NoneBot2 还有可配套使用的额外脚手架/框架:
|
||||||
|
|
||||||
|
- [NB-CLI](https://github.com/nonebot/nb-cli)
|
||||||
|
- [NoneBot-Test](https://github.com/nonebot/nonebot-test)
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
文档目前尚未完成,「API」部分由 sphinx 自动生成,你可以在 [这里](https://v2.nonebot.dev/) 查看。
|
文档目前尚未完成,「API」部分由 sphinx 自动生成,你可以在 [这里](https://v2.nonebot.dev/) 查看。
|
||||||
|
@@ -1,122 +0,0 @@
|
|||||||
---
|
|
||||||
contentSidebar: true
|
|
||||||
sidebarDepth: 0
|
|
||||||
---
|
|
||||||
|
|
||||||
# NoneBot.rule 模块
|
|
||||||
|
|
||||||
## 规则
|
|
||||||
|
|
||||||
每个 `Matcher` 拥有一个 `Rule` ,其中是 **异步** `RuleChecker` 的集合,只有当所有 `RuleChecker` 检查结果为 `True` 时继续运行。
|
|
||||||
|
|
||||||
:::tip 提示
|
|
||||||
`RuleChecker` 既可以是 async function 也可以是 sync function
|
|
||||||
:::
|
|
||||||
|
|
||||||
|
|
||||||
## _class_ `Rule`
|
|
||||||
|
|
||||||
基类:`object`
|
|
||||||
|
|
||||||
|
|
||||||
* **说明**
|
|
||||||
|
|
||||||
`Matcher` 规则类,当事件传递时,在 `Matcher` 运行前进行检查。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* **示例**
|
|
||||||
|
|
||||||
|
|
||||||
```python
|
|
||||||
Rule(async_function) & sync_function
|
|
||||||
# 等价于
|
|
||||||
from nonebot.utils import run_sync
|
|
||||||
Rule(async_function, run_sync(sync_function))
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### `__init__(*checkers)`
|
|
||||||
|
|
||||||
|
|
||||||
* **参数**
|
|
||||||
|
|
||||||
|
|
||||||
* `*checkers: Callable[[Bot, Event, dict], Awaitable[bool]]`: **异步** RuleChecker
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### `checkers`
|
|
||||||
|
|
||||||
|
|
||||||
* **说明**
|
|
||||||
|
|
||||||
存储 `RuleChecker`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* **类型**
|
|
||||||
|
|
||||||
|
|
||||||
* `Set[Callable[[Bot, Event, dict], Awaitable[bool]]]`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### _async_ `__call__(bot, event, state)`
|
|
||||||
|
|
||||||
|
|
||||||
* **说明**
|
|
||||||
|
|
||||||
检查是否符合所有规则
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* **参数**
|
|
||||||
|
|
||||||
|
|
||||||
* `bot: Bot`: Bot 对象
|
|
||||||
|
|
||||||
|
|
||||||
* `event: Event`: Event 对象
|
|
||||||
|
|
||||||
|
|
||||||
* `state: dict`: 当前 State
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* **返回**
|
|
||||||
|
|
||||||
|
|
||||||
* `bool`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## `startswith(msg)`
|
|
||||||
|
|
||||||
|
|
||||||
* **说明**
|
|
||||||
|
|
||||||
匹配消息开头
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* **参数**
|
|
||||||
|
|
||||||
|
|
||||||
* `msg: str`: 消息开头字符串
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## `endswith(msg)`
|
|
||||||
|
|
||||||
|
|
||||||
* **说明**
|
|
||||||
|
|
||||||
匹配消息结尾
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* **参数**
|
|
||||||
|
|
||||||
|
|
||||||
* `msg: str`: 消息结尾字符串
|
|
@@ -7,16 +7,13 @@
|
|||||||
* [nonebot](nonebot.html)
|
* [nonebot](nonebot.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.typing](typing.html)
|
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.config](config.html)
|
* [nonebot.config](config.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.sched](sched.html)
|
* [nonebot.plugin](plugin.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.log](log.html)
|
* [nonebot.matcher](matcher.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.rule](rule.html)
|
* [nonebot.rule](rule.html)
|
||||||
@@ -25,7 +22,28 @@
|
|||||||
* [nonebot.permission](permission.html)
|
* [nonebot.permission](permission.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.sched](sched.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.log](log.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.utils](utils.html)
|
* [nonebot.utils](utils.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.typing](typing.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.exception](exception.html)
|
* [nonebot.exception](exception.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.drivers](drivers/)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.drivers.fastapi](drivers/fastapi.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.adapters](adapters/)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.adapters.cqhttp](adapters/cqhttp.html)
|
323
archive/2.0.0a4/api/adapters/README.md
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.adapters 模块
|
||||||
|
|
||||||
|
## 协议适配基类
|
||||||
|
|
||||||
|
各协议请继承以下基类,并使用 `driver.register_adapter` 注册适配器
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseBot`
|
||||||
|
|
||||||
|
基类:`abc.ABC`
|
||||||
|
|
||||||
|
Bot 基类。用于处理上报消息,并提供 API 调用接口。
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `__init__(driver, connection_type, config, self_id, *, websocket=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `driver: Driver`: Driver 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `connection_type: str`: http 或者 websocket
|
||||||
|
|
||||||
|
|
||||||
|
* `config: Config`: Config 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `self_id: str`: 机器人 ID
|
||||||
|
|
||||||
|
|
||||||
|
* `websocket: Optional[WebSocket]`: Websocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `driver`
|
||||||
|
|
||||||
|
Driver 对象
|
||||||
|
|
||||||
|
|
||||||
|
### `connection_type`
|
||||||
|
|
||||||
|
连接类型
|
||||||
|
|
||||||
|
|
||||||
|
### `config`
|
||||||
|
|
||||||
|
Config 配置对象
|
||||||
|
|
||||||
|
|
||||||
|
### `self_id`
|
||||||
|
|
||||||
|
机器人 ID
|
||||||
|
|
||||||
|
|
||||||
|
### `websocket`
|
||||||
|
|
||||||
|
Websocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `type`
|
||||||
|
|
||||||
|
Adapter 类型
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `handle_message(message)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
处理上报消息的函数,转换为 `Event` 事件后调用 `nonebot.message.handle_event` 进一步处理事件。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `message: dict`: 收到的上报消息
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `call_api(api, **data)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
调用机器人 API 接口,可以通过该函数或直接通过 bot 属性进行调用
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `api: str`: API 名称
|
||||||
|
|
||||||
|
|
||||||
|
* `**data`: API 数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **示例**
|
||||||
|
|
||||||
|
|
||||||
|
```python
|
||||||
|
await bot.call_api("send_msg", data={"message": "hello world"})
|
||||||
|
await bot.send_msg(message="hello world")
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `send(event, message, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
调用机器人基础发送消息接口
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: 上报事件
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, Message, MessageSegment]`: 要发送的消息
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseEvent`
|
||||||
|
|
||||||
|
基类:`abc.ABC`
|
||||||
|
|
||||||
|
Event 基类。提供上报信息的关键信息,其余信息可从原始上报消息获取。
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(raw_event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `raw_event: dict`: 原始上报消息
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `raw_event`
|
||||||
|
|
||||||
|
原始上报消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `id`
|
||||||
|
|
||||||
|
事件 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `name`
|
||||||
|
|
||||||
|
事件名称
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `self_id`
|
||||||
|
|
||||||
|
机器人 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `time`
|
||||||
|
|
||||||
|
事件发生时间
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `type`
|
||||||
|
|
||||||
|
事件主类型
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `detail_type`
|
||||||
|
|
||||||
|
事件详细类型
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `sub_type`
|
||||||
|
|
||||||
|
事件子类型
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `user_id`
|
||||||
|
|
||||||
|
触发事件的主体 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `group_id`
|
||||||
|
|
||||||
|
触发事件的主体群 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `to_me`
|
||||||
|
|
||||||
|
事件是否为发送给机器人的消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `message`
|
||||||
|
|
||||||
|
消息内容
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `reply`
|
||||||
|
|
||||||
|
回复的消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `raw_message`
|
||||||
|
|
||||||
|
原始消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `plain_text`
|
||||||
|
|
||||||
|
纯文本消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `sender`
|
||||||
|
|
||||||
|
消息发送者信息
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseMessageSegment`
|
||||||
|
|
||||||
|
基类:`abc.ABC`
|
||||||
|
|
||||||
|
消息段基类
|
||||||
|
|
||||||
|
|
||||||
|
### `type`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息段类型
|
||||||
|
|
||||||
|
|
||||||
|
### `data`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Dict[str, Union[str, list]]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息段数据
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseMessage`
|
||||||
|
|
||||||
|
基类:`list`, `abc.ABC`
|
||||||
|
|
||||||
|
消息数组
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(message=None, *args, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, dict, list, MessageSegment, Message]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `append(obj)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
添加一个消息段到消息数组末尾
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `obj: Union[str, MessageSegment]`: 要添加的消息段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `extend(obj)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
拼接一个消息数组或多个消息段到消息数组末尾
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `obj: Union[Message, Iterable[MessageSegment]]`: 要添加的消息数组
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `reduce()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
缩减消息数组,即拼接相邻纯文本消息段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `extract_plain_text()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
提取消息内纯文本消息
|
415
archive/2.0.0a4/api/adapters/cqhttp.md
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.adapters.cqhttp 模块
|
||||||
|
|
||||||
|
## CQHTTP (OneBot) v11 协议适配
|
||||||
|
|
||||||
|
协议详情请看: [CQHTTP](http://cqhttp.cc/) | [OneBot](https://github.com/howmanybots/onebot)
|
||||||
|
|
||||||
|
|
||||||
|
## `log(level, message)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
用于打印 CQHTTP 日志。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `level: str`: 日志等级
|
||||||
|
|
||||||
|
|
||||||
|
* `message: str`: 日志信息
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `escape(s, *, escape_comma=True)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
对字符串进行 CQ 码转义。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `s: str`: 需要转义的字符串
|
||||||
|
|
||||||
|
|
||||||
|
* `escape_comma: bool`: 是否转义逗号(`,`)。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `unescape(s)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
对字符串进行 CQ 码去转义。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `s: str`: 需要转义的字符串
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `_b2s(b)`
|
||||||
|
|
||||||
|
转换布尔值为字符串。
|
||||||
|
|
||||||
|
|
||||||
|
## _async_ `_check_reply(bot, event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查消息中存在的回复,去除并赋值 `event.reply`, `event.to_me`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `_check_at_me(bot, event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查消息开头或结尾是否存在 @机器人,去除并赋值 `event.to_me`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `_check_nickname(bot, event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查消息开头是否存在,去除并赋值 `event.to_me`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `_handle_api_result(result)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
处理 API 请求返回值。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `result: Optional[Dict[str, Any]]`: API 返回数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Any`: API 调用返回数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **异常**
|
||||||
|
|
||||||
|
|
||||||
|
* `ActionFailed`: API 调用失败
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Bot`
|
||||||
|
|
||||||
|
基类:[`nonebot.adapters.BaseBot`](#None)
|
||||||
|
|
||||||
|
CQHTTP 协议 Bot 适配。继承属性参考 [BaseBot](./#class-basebot) 。
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `type`
|
||||||
|
|
||||||
|
|
||||||
|
* 返回: `"cqhttp"`
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `handle_message(message)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
调用 [_check_reply](#async-check-reply-bot-event), [_check_at_me](#check-at-me-bot-event), [_check_nickname](#check-nickname-bot-event) 处理事件并转换为 [Event](#class-event)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `call_api(api, **data)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
调用 CQHTTP 协议 API
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `api: str`: API 名称
|
||||||
|
|
||||||
|
|
||||||
|
* `**data: Any`: API 参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Any`: API 调用返回数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **异常**
|
||||||
|
|
||||||
|
|
||||||
|
* `NetworkError`: 网络错误
|
||||||
|
|
||||||
|
|
||||||
|
* `ActionFailed`: API 调用失败
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `send(event, message, at_sender=False, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
根据 `event` 向触发事件的主体发送消息。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, Message, MessageSegment]`: 要发送的消息
|
||||||
|
|
||||||
|
|
||||||
|
* `at_sender: bool`: 是否 @ 事件主体
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 覆盖默认参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Any`: API 调用返回数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **异常**
|
||||||
|
|
||||||
|
|
||||||
|
* `ValueError`: 缺少 `user_id`, `group_id`
|
||||||
|
|
||||||
|
|
||||||
|
* `NetworkError`: 网络错误
|
||||||
|
|
||||||
|
|
||||||
|
* `ActionFailed`: API 调用失败
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Event`
|
||||||
|
|
||||||
|
基类:[`nonebot.adapters.BaseEvent`](#None)
|
||||||
|
|
||||||
|
CQHTTP 协议 Event 适配。继承属性参考 [BaseEvent](./#class-baseevent) 。
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `id`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[int]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件/消息 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `name`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件名称,由类型与 `.` 组合而成
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `self_id`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 机器人自身 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `time`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `int`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件发生时间
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `type`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件类型
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `detail_type`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件详细类型
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `sub_type`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[str]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件子类型
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `user_id`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[int]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件主体 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `group_id`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[int]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件主体群 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `to_me`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[bool]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息是否与机器人相关
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `message`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[Message]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `reply`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[dict]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 回复消息详情
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `raw_message`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[str]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 原始消息
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `plain_text`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[str]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 纯文本消息内容
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `sender`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[dict]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息发送者信息
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `MessageSegment`
|
||||||
|
|
||||||
|
基类:[`nonebot.adapters.BaseMessageSegment`](#None)
|
||||||
|
|
||||||
|
CQHTTP 协议 MessageSegment 适配。具体方法参考协议消息段类型或源码。
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Message`
|
||||||
|
|
||||||
|
基类:[`nonebot.adapters.BaseMessage`](#None)
|
||||||
|
|
||||||
|
CQHTTP 协议 Message 适配。
|
@@ -194,10 +194,10 @@ SUPER_USERS=[12345789]
|
|||||||
### `nickname`
|
### `nickname`
|
||||||
|
|
||||||
|
|
||||||
* 类型: `Union[str, Set[str]]`
|
* 类型: `Set[str]`
|
||||||
|
|
||||||
|
|
||||||
* 默认值: `""`
|
* 默认值: `set()`
|
||||||
|
|
||||||
|
|
||||||
* 说明:
|
* 说明:
|
246
archive/2.0.0a4/api/drivers/README.md
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.drivers 模块
|
||||||
|
|
||||||
|
## 后端驱动适配基类
|
||||||
|
|
||||||
|
各驱动请继承以下基类
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseDriver`
|
||||||
|
|
||||||
|
基类:`abc.ABC`
|
||||||
|
|
||||||
|
Driver 基类。将后端框架封装,以满足适配器使用。
|
||||||
|
|
||||||
|
|
||||||
|
### `_adapters`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[str, Type[Bot]]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
已注册的适配器列表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `__init__(env, config)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `env: Env`: 包含环境信息的 Env 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `config: Config`: 包含配置信息的 Config 对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `env`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`str`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
环境名称
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `config`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Config`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
配置对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `_clients`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[str, Bot]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
已连接的 Bot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `register_adapter(name, adapter)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个协议适配器
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `name: str`: 适配器名称,用于在连接时进行识别
|
||||||
|
|
||||||
|
|
||||||
|
* `adapter: Type[Bot]`: 适配器 Class
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `type`
|
||||||
|
|
||||||
|
驱动类型名称
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `server_app`
|
||||||
|
|
||||||
|
驱动 APP 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `asgi`
|
||||||
|
|
||||||
|
驱动 ASGI 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `logger`
|
||||||
|
|
||||||
|
驱动专属 logger 日志记录器
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `bots`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[str, Bot]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
获取当前所有已连接的 Bot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `on_startup(func)`
|
||||||
|
|
||||||
|
注册一个在驱动启动时运行的函数
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `on_shutdown(func)`
|
||||||
|
|
||||||
|
注册一个在驱动停止时运行的函数
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `run(host=None, port=None, *args, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
启动驱动框架
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `host: Optional[str]`: 驱动绑定 IP
|
||||||
|
|
||||||
|
|
||||||
|
* `post: Optional[int]`: 驱动绑定端口
|
||||||
|
|
||||||
|
|
||||||
|
* `*args`
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `_handle_http()`
|
||||||
|
|
||||||
|
用于处理 HTTP 类型请求的函数
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `_handle_ws_reverse()`
|
||||||
|
|
||||||
|
用于处理 WebSocket 类型请求的函数
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseWebSocket`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
WebSocket 连接封装,统一接口方便外部调用。
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `__init__(websocket)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `websocket: Any`: WebSocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `websocket`
|
||||||
|
|
||||||
|
WebSocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `closed`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
连接是否已经关闭
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `accept()`
|
||||||
|
|
||||||
|
接受 WebSocket 连接请求
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `close(code)`
|
||||||
|
|
||||||
|
关闭 WebSocket 连接请求
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `receive()`
|
||||||
|
|
||||||
|
接收一条 WebSocket 信息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `send(data)`
|
||||||
|
|
||||||
|
发送一条 WebSocket 信息
|
125
archive/2.0.0a4/api/drivers/fastapi.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.drivers.fastapi 模块
|
||||||
|
|
||||||
|
## FastAPI 驱动适配
|
||||||
|
|
||||||
|
后端使用方法请参考: [FastAPI 文档](https://fastapi.tiangolo.com/)
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Driver`
|
||||||
|
|
||||||
|
基类:[`nonebot.drivers.BaseDriver`](#None)
|
||||||
|
|
||||||
|
FastAPI 驱动框架
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(env, config)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* `env: Env`: 包含环境信息的 Env 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `config: Config`: 包含配置信息的 Config 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `type`
|
||||||
|
|
||||||
|
驱动名称: `fastapi`
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `server_app`
|
||||||
|
|
||||||
|
`FastAPI APP` 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `asgi`
|
||||||
|
|
||||||
|
`FastAPI APP` 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `logger`
|
||||||
|
|
||||||
|
fastapi 使用的 logger
|
||||||
|
|
||||||
|
|
||||||
|
### `on_startup(func)`
|
||||||
|
|
||||||
|
参考文档: [Events](https://fastapi.tiangolo.com/advanced/events/#startup-event)
|
||||||
|
|
||||||
|
|
||||||
|
### `on_shutdown(func)`
|
||||||
|
|
||||||
|
参考文档: [Events](https://fastapi.tiangolo.com/advanced/events/#startup-event)
|
||||||
|
|
||||||
|
|
||||||
|
### `run(host=None, port=None, *, app=None, **kwargs)`
|
||||||
|
|
||||||
|
使用 `uvicorn` 启动 FastAPI
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `_handle_http(adapter, data=Body(Ellipsis), x_self_id=Header(None), x_signature=Header(None), auth=Depends(get_auth_bearer))`
|
||||||
|
|
||||||
|
用于处理 HTTP 类型请求的函数
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `_handle_ws_reverse(adapter, websocket, x_self_id=Header(None), auth=Depends(get_auth_bearer))`
|
||||||
|
|
||||||
|
用于处理 WebSocket 类型请求的函数
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `WebSocket`
|
||||||
|
|
||||||
|
基类:[`nonebot.drivers.BaseWebSocket`](#None)
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(websocket)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* `websocket: Any`: WebSocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `closed`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
连接是否已经关闭
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `accept()`
|
||||||
|
|
||||||
|
接受 WebSocket 连接请求
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `close(code=1000)`
|
||||||
|
|
||||||
|
关闭 WebSocket 连接请求
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `receive()`
|
||||||
|
|
||||||
|
接收一条 WebSocket 信息
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `send(data)`
|
||||||
|
|
||||||
|
发送一条 WebSocket 信息
|
497
archive/2.0.0a4/api/matcher.md
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.matcher 模块
|
||||||
|
|
||||||
|
## 事件响应器
|
||||||
|
|
||||||
|
该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行 对话 。
|
||||||
|
|
||||||
|
|
||||||
|
## `matchers`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[int, List[Type[Matcher]]]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
用于存储当前所有的事件响应器
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Matcher`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
事件响应器类
|
||||||
|
|
||||||
|
|
||||||
|
### `module`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Optional[str]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器所在模块名称
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `type`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`str`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器类型
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `rule`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Rule`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器匹配规则
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `permission`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Permission`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器触发权限
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `priority`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`int`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `block`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器是否阻止事件传播
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `temp`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器是否为临时
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `expire_time`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Optional[datetime]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器过期时间点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `_default_state`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`dict`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器默认状态
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `_default_parser`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Optional[ArgsParser]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器默认参数解析函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__()`
|
||||||
|
|
||||||
|
实例化 Matcher 以便运行
|
||||||
|
|
||||||
|
|
||||||
|
### `handlers`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`List[Handler]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器拥有的事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `new(type_='', rule=None, permission=None, handlers=None, temp=False, priority=1, block=False, *, module=None, default_state=None, expire_time=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
创建一个新的事件响应器,并存储至 [matchers](#matchers)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `type_: str`: 事件响应器类型,与 `event.type` 一致时触发,空字符串表示任意
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Rule]`: 匹配规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器,即触发一次后删除
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 响应优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级的响应器传播
|
||||||
|
|
||||||
|
|
||||||
|
* `module: Optional[str]`: 事件响应器所在模块名称
|
||||||
|
|
||||||
|
|
||||||
|
* `default_state: Optional[dict]`: 默认状态 `state`
|
||||||
|
|
||||||
|
|
||||||
|
* `expire_time: Optional[datetime]`: 事件响应器最终有效时间点,过时即被删除
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`: 新的事件响应器类
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `check_perm(bot, event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查是否满足触发权限
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: 上报事件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `bool`: 是否满足权限
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `check_rule(bot, event, state)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查是否满足匹配规则
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: 上报事件
|
||||||
|
|
||||||
|
|
||||||
|
* `state: dict`: 当前状态
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `bool`: 是否满足匹配规则
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `args_parser(func)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
装饰一个函数来更改当前事件响应器的默认参数解析函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `func: ArgsParser`: 参数解析函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `handle()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
装饰一个函数来向事件响应器直接添加一个处理函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* 无
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `receive()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
装饰一个函数来指示 NoneBot 在接收用户新的一条消息后继续运行该函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* 无
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `got(key, prompt=None, args_parser=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
装饰一个函数来指示 NoneBot 当要获取的 `key` 不存在时接收用户新的一条消息并经过 `ArgsParser` 处理后再运行该函数,如果 `key` 已存在则直接继续运行
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `key: str`: 参数名
|
||||||
|
|
||||||
|
|
||||||
|
* `prompt: Optional[Union[str, Message, MessageSegment]]`: 在参数不存在时向用户发送的消息
|
||||||
|
|
||||||
|
|
||||||
|
* `args_parser: Optional[ArgsParser]`: 可选参数解析函数,空则使用默认解析函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `send(message, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
发送一条消息给当前交互用户
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, Message, MessageSegment]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `finish(message=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
发送一条消息给当前交互用户并结束当前事件响应器
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, Message, MessageSegment]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `pause(prompt=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续下一个处理函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `prompt: Union[str, Message, MessageSegment]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `reject(prompt=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后重新运行当前处理函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `prompt: Union[str, Message, MessageSegment]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `MatcherGroup`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
事件响应器组合,统一管理。用法同 `Matcher`
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(type_='', rule=None, permission=None, handlers=None, temp=False, priority=1, block=False, *, module=None, default_state=None, expire_time=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
创建一个事件响应器组合,参数为默认值,与 `Matcher.new` 一致
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `matchers`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`List[Type[Matcher]]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
组内事件响应器列表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `new(type_='', rule=None, permission=None, handlers=None, temp=False, priority=1, block=False, *, module=None, default_state=None, expire_time=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
在组中创建一个新的事件响应器,参数留空则使用组合默认值
|
||||||
|
|
||||||
|
|
||||||
|
:::danger 警告
|
||||||
|
如果使用 handlers 参数覆盖组合默认值则该事件响应器不会随组合一起添加新的事件处理函数
|
||||||
|
:::
|
@@ -5,6 +5,55 @@ sidebarDepth: 0
|
|||||||
|
|
||||||
# NoneBot 模块
|
# NoneBot 模块
|
||||||
|
|
||||||
|
## 快捷导入
|
||||||
|
|
||||||
|
为方便使用,`nonebot` 模块从子模块导入了部分内容
|
||||||
|
|
||||||
|
|
||||||
|
* `on_message` => `nonebot.plugin.on_message`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_notice` => `nonebot.plugin.on_notice`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_request` => `nonebot.plugin.on_request`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_metaevent` => `nonebot.plugin.on_metaevent`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_startswith` => `nonebot.plugin.on_startswith`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_endswith` => `nonebot.plugin.on_endswith`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_command` => `nonebot.plugin.on_command`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_regex` => `nonebot.plugin.on_regex`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_regex` => `nonebot.plugin.on_regex`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_regex` => `nonebot.plugin.on_regex`
|
||||||
|
|
||||||
|
|
||||||
|
* `CommandGroup` => `nonebot.plugin.CommandGroup`
|
||||||
|
|
||||||
|
|
||||||
|
* `load_plugin` => `nonebot.plugin.load_plugin`
|
||||||
|
|
||||||
|
|
||||||
|
* `load_plugins` => `nonebot.plugin.load_plugins`
|
||||||
|
|
||||||
|
|
||||||
|
* `load_builtin_plugins` => `nonebot.plugin.load_builtin_plugins`
|
||||||
|
|
||||||
|
|
||||||
|
* `get_loaded_plugins` => `nonebot.plugin.get_loaded_plugins`
|
||||||
|
|
||||||
|
|
||||||
## `get_driver()`
|
## `get_driver()`
|
||||||
|
|
629
archive/2.0.0a4/api/plugin.md
Normal file
@@ -0,0 +1,629 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.plugin 模块
|
||||||
|
|
||||||
|
## 插件
|
||||||
|
|
||||||
|
为 NoneBot 插件开发提供便携的定义函数。
|
||||||
|
|
||||||
|
|
||||||
|
## `plugins`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[str, Plugin]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
已加载的插件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Plugin`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
存储插件信息
|
||||||
|
|
||||||
|
|
||||||
|
### `name`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 插件名称,使用 文件/文件夹 名称作为插件名
|
||||||
|
|
||||||
|
|
||||||
|
### `module`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `ModuleType`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 插件模块对象
|
||||||
|
|
||||||
|
|
||||||
|
### `matcher`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `Set[Type[Matcher]]`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 插件内定义的 `Matcher`
|
||||||
|
|
||||||
|
|
||||||
|
## `on(type='', rule=None, permission=None, *, handlers=None, temp=False, priority=1, block=False, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个基础事件响应器,可自定义类型。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `type: str`: 事件响应器类型
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_metaevent(rule=None, *, handlers=None, temp=False, priority=1, block=False, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个元事件响应器。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_message(rule=None, permission=None, *, handlers=None, temp=False, priority=1, block=True, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_notice(rule=None, *, handlers=None, temp=False, priority=1, block=False, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个通知事件响应器。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_request(rule=None, *, handlers=None, temp=False, priority=1, block=False, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个请求事件响应器。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_startswith(msg, rule=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息的\*\*文本部分\*\*以指定内容开头时响应。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `msg: str`: 指定消息开头内容
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_endswith(msg, rule=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息的\*\*文本部分\*\*以指定内容结尾时响应。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `msg: str`: 指定消息结尾内容
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_keyword(keywords, rule=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息纯文本部分包含关键词时响应。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `keywords: Set[str]`: 关键词列表
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_command(cmd, rule=None, aliases=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息以指定命令开头时响应。
|
||||||
|
|
||||||
|
命令匹配规则参考: [命令形式匹配](rule.html#command-command)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `cmd: Union[str, Tuple[str, ...]]`: 指定命令内容
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `aliases: Optional[Set[Union[str, Tuple[str, ...]]]]`: 命令别名
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_regex(pattern, flags=0, rule=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息匹配正则表达式时响应。
|
||||||
|
|
||||||
|
命令匹配规则参考: [正则匹配](rule.html#regex-regex-flags-0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `pattern: str`: 正则表达式
|
||||||
|
|
||||||
|
|
||||||
|
* `flags: Union[int, re.RegexFlag]`: 正则匹配标志
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `CommandGroup`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
命令组,用于声明一组有相同名称前缀的命令。
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(cmd, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `cmd: Union[str, Tuple[str, ...]]`: 命令前缀
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `on_command` 的参数默认值,参考 [on_command](#on-command-cmd-rule-none-aliases-none-kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `basecmd`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `Tuple[str, ...]`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 命令前缀
|
||||||
|
|
||||||
|
|
||||||
|
### `base_kwargs`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `Dict[str, Any]`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 其他传递给 `on_command` 的参数默认值
|
||||||
|
|
||||||
|
|
||||||
|
### `command(cmd, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个新的命令。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `cmd: Union[str, Tuple[str, ...]]`: 命令前缀
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `on_command` 的参数,将会覆盖命令组默认值
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `load_plugin(module_path)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
使用 `importlib` 加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `module_path: str`: 插件名称 `path.to.your.plugin`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Optional[Plugin]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `load_plugins(*plugin_dir)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
导入目录下多个插件,以 `_` 开头的插件不会被导入!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `*plugin_dir: str`: 插件路径
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Set[Plugin]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `load_builtin_plugins()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
导入 NoneBot 内置插件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Plugin`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `get_loaded_plugins()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
获取当前已导入的插件。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Set[Plugin]`
|
210
archive/2.0.0a4/api/rule.md
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.rule 模块
|
||||||
|
|
||||||
|
## 规则
|
||||||
|
|
||||||
|
每个事件响应器 `Matcher` 拥有一个匹配规则 `Rule` ,其中是 **异步** `RuleChecker` 的集合,只有当所有 `RuleChecker` 检查结果为 `True` 时继续运行。
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
`RuleChecker` 既可以是 async function 也可以是 sync function,但在最终会被 `nonebot.utils.run_sync` 转换为 async function
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Rule`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
`Matcher` 规则类,当事件传递时,在 `Matcher` 运行前进行检查。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **示例**
|
||||||
|
|
||||||
|
|
||||||
|
```python
|
||||||
|
Rule(async_function) & sync_function
|
||||||
|
# 等价于
|
||||||
|
from nonebot.utils import run_sync
|
||||||
|
Rule(async_function, run_sync(sync_function))
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(*checkers)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `*checkers: Callable[[Bot, Event, dict], Awaitable[bool]]`: **异步** RuleChecker
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `checkers`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
存储 `RuleChecker`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
|
||||||
|
* `Set[Callable[[Bot, Event, dict], Awaitable[bool]]]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `__call__(bot, event, state)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查是否符合所有规则
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `state: dict`: 当前 State
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `startswith(msg)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
匹配消息开头
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `msg: str`: 消息开头字符串
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `endswith(msg)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
匹配消息结尾
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `msg: str`: 消息结尾字符串
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `keyword(*keywords)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
匹配消息关键词
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `*keywords: str`: 关键词
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `command(*cmds)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
命令形式匹配,根据配置里提供的 `command_start`, `command_sep` 判断消息是否为命令。
|
||||||
|
|
||||||
|
可以通过 `state["_prefix"]["command"]` 获取匹配成功的命令(例:`("test",)`),通过 `state["_prefix"]["raw_command"]` 获取匹配成功的原始命令文本(例:`"/test"`)。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `*cmds: Union[str, Tuple[str, ...]]`: 命令内容
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **示例**
|
||||||
|
|
||||||
|
使用默认 `command_start`, `command_sep` 配置
|
||||||
|
|
||||||
|
命令 `("test",)` 可以匹配:`/test` 开头的消息
|
||||||
|
命令 `("test", "sub")` 可以匹配”`/test.sub` 开头的消息
|
||||||
|
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
命令内容与后续消息间无需空格!
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
## `regex(regex, flags=0)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
根据正则表达式进行匹配。
|
||||||
|
|
||||||
|
可以通过 `state["_matched"]` 获取正则表达式匹配成功的文本。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `regex: str`: 正则表达式
|
||||||
|
|
||||||
|
|
||||||
|
* `flags: Union[int, re.RegexFlag]`: 正则标志
|
||||||
|
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
正则表达式匹配使用 search 而非 match,如需从头匹配请使用 `r"^xxx"` 来确保匹配开头
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
## `to_me()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
通过 `event.to_me` 判断消息是否是发送给机器人
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* 无
|
@@ -142,6 +142,22 @@ sidebarDepth: 0
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `MatcherGroup`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`MatcherGroup`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
MatcherGroup 为 Matcher 的集合。可以共享 Handler。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## `Rule`
|
## `Rule`
|
||||||
|
|
||||||
|
|
@@ -6,6 +6,29 @@ sidebarDepth: 0
|
|||||||
# NoneBot.utils 模块
|
# NoneBot.utils 模块
|
||||||
|
|
||||||
|
|
||||||
|
## `escape_tag(s)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
用于记录带颜色日志时转义 `<tag>` 类型特殊标签
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `s: str`: 需要转义的字符串
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `str`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## `run_sync(func)`
|
## `run_sync(func)`
|
||||||
|
|
||||||
|
|
@@ -20,11 +20,9 @@ NoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人
|
|||||||
|
|
||||||
## 它如何工作?
|
## 它如何工作?
|
||||||
|
|
||||||
NoneBot 的运行离不开 酷 Q 和 CQHTTP 插件。酷 Q 扮演着「无头 QQ 客户端」的角色,它进行实际的消息、通知、请求的接收和发送,当 酷 Q 收到消息时,它将这个消息包装为一个事件(通知和请求同理),并通过它自己的插件机制将事件传送给 CQHTTP 插件,后者再根据其配置中的 `post_url` 或 `ws_reverse_url` 等项来将事件发送至 NoneBot。
|
<!-- TODO: how to work -->
|
||||||
|
|
||||||
在 NoneBot 收到事件前,它底层的 aiocqhttp 实际已经先看到了事件,aiocqhttp 根据事件的类型信息,通知到 NoneBot 的相应函数。特别地,对于消息类型的事件,还将消息内容转换成了 `aiocqhttp.message.Message` 类型,以便处理。
|
~~未填坑~~
|
||||||
|
|
||||||
NoneBot 的事件处理函数收到通知后,对于不同类型的事件,再做相应的预处理和解析,然后调用对应的插件,并向其提供适合此类事件的会话(Session)对象。NoneBot 插件的编写者要做的,就是利用 Session 对象中提供的数据,在插件的处理函数中实现所需的功能。
|
|
||||||
|
|
||||||
## 特色
|
## 特色
|
||||||
|
|
@@ -136,11 +136,11 @@ QQ 协议端举例:
|
|||||||
现在,尝试向你的 QQ 机器人账号发送如下内容:
|
现在,尝试向你的 QQ 机器人账号发送如下内容:
|
||||||
|
|
||||||
```default
|
```default
|
||||||
/say 你好,世界
|
/echo 你好,世界
|
||||||
```
|
```
|
||||||
|
|
||||||
到这里如果一切 OK,你应该会收到机器人给你回复了 `你好,世界`。这一历史性的对话标志着你已经成功地运行了一个 NoneBot 的最小实例,开始了编写更强大的 QQ 机器人的创意之旅!
|
到这里如果一切 OK,你应该会收到机器人给你回复了 `你好,世界`。这一历史性的对话标志着你已经成功地运行了一个 NoneBot 的最小实例,开始了编写更强大的 QQ 机器人的创意之旅!
|
||||||
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<Messenger :messages="[{ position: 'right', msg: '/say 你好,世界' }, { position: 'left', msg: '你好,世界' }]"/>
|
<Messenger :messages="[{ position: 'right', msg: '/echo 你好,世界' }, { position: 'left', msg: '你好,世界' }]"/>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
@@ -6,7 +6,10 @@
|
|||||||
请确保你的 Python 版本 >= 3.7。
|
请确保你的 Python 版本 >= 3.7。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
请在安装 nonebot2 之前卸载 nonebot 1.x
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
pip uninstall nonebot
|
||||||
pip install nonebot2
|
pip install nonebot2
|
||||||
```
|
```
|
||||||
|
|
@@ -159,7 +159,7 @@ weather = on_command("天气", rule=to_me(), permission=Permission(), priority=5
|
|||||||
- `on_startswith(str)` ~ `on("message", startswith(str))`: 消息开头匹配处理器
|
- `on_startswith(str)` ~ `on("message", startswith(str))`: 消息开头匹配处理器
|
||||||
- `on_endswith(str)` ~ `on("message", endswith(str))`: 消息结尾匹配处理器
|
- `on_endswith(str)` ~ `on("message", endswith(str))`: 消息结尾匹配处理器
|
||||||
- `on_command(str|tuple)` ~ `on("message", command(str|tuple))`: 命令处理器
|
- `on_command(str|tuple)` ~ `on("message", command(str|tuple))`: 命令处理器
|
||||||
- `on_regax(pattern_str)` ~ `on("message", regax(pattern_str))`: 正则匹配处理器
|
- `on_regex(pattern_str)` ~ `on("message", regex(pattern_str))`: 正则匹配处理器
|
||||||
|
|
||||||
#### 匹配规则 rule
|
#### 匹配规则 rule
|
||||||
|
|
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"sidebar": {},
|
||||||
"locales": {
|
"locales": {
|
||||||
"/": {
|
"/": {
|
||||||
"label": "简体中文",
|
"label": "简体中文",
|
||||||
@@ -17,6 +18,10 @@
|
|||||||
{
|
{
|
||||||
"text": "API",
|
"text": "API",
|
||||||
"link": "/api/"
|
"link": "/api/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "插件广场",
|
||||||
|
"link": "/plugin-store"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sidebarDepth": 2,
|
"sidebarDepth": 2,
|
||||||
@@ -47,21 +52,17 @@
|
|||||||
"title": "nonebot 模块",
|
"title": "nonebot 模块",
|
||||||
"path": "nonebot"
|
"path": "nonebot"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"title": "nonebot.typing 模块",
|
|
||||||
"path": "typing"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"title": "nonebot.config 模块",
|
"title": "nonebot.config 模块",
|
||||||
"path": "config"
|
"path": "config"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "nonebot.sched 模块",
|
"title": "nonebot.plugin 模块",
|
||||||
"path": "sched"
|
"path": "plugin"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "nonebot.log 模块",
|
"title": "nonebot.matcher 模块",
|
||||||
"path": "log"
|
"path": "matcher"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "nonebot.rule 模块",
|
"title": "nonebot.rule 模块",
|
||||||
@@ -71,13 +72,41 @@
|
|||||||
"title": "nonebot.permission 模块",
|
"title": "nonebot.permission 模块",
|
||||||
"path": "permission"
|
"path": "permission"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "nonebot.sched 模块",
|
||||||
|
"path": "sched"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "nonebot.log 模块",
|
||||||
|
"path": "log"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "nonebot.utils 模块",
|
"title": "nonebot.utils 模块",
|
||||||
"path": "utils"
|
"path": "utils"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "nonebot.typing 模块",
|
||||||
|
"path": "typing"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "nonebot.exception 模块",
|
"title": "nonebot.exception 模块",
|
||||||
"path": "exception"
|
"path": "exception"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "nonebot.drivers 模块",
|
||||||
|
"path": "drivers/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "nonebot.drivers.fastapi 模块",
|
||||||
|
"path": "drivers/fastapi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "nonebot.adapters 模块",
|
||||||
|
"path": "adapters/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "nonebot.adapters.cqhttp 模块",
|
||||||
|
"path": "adapters/cqhttp"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="qq-chat">
|
<div class="qq-chat">
|
||||||
<v-app
|
<v-app>
|
||||||
><v-main>
|
<v-main>
|
||||||
<v-card class="elevation-6">
|
<v-card class="elevation-6">
|
||||||
<v-toolbar color="primary" dark dense flat>
|
<v-toolbar color="primary" dark dense flat>
|
||||||
<v-row no-gutters>
|
<v-row no-gutters>
|
||||||
@@ -139,19 +139,15 @@ export default {
|
|||||||
default: () => []
|
default: () => []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: () => ({
|
|
||||||
wow: null
|
|
||||||
}),
|
|
||||||
methods: {
|
methods: {
|
||||||
initWOW: function() {
|
initWOW: function() {
|
||||||
this.wow = new WOW({
|
new WOW({
|
||||||
noxClass: "wow",
|
noxClass: "wow",
|
||||||
animateClass: "animate__animated",
|
animateClass: "animate__animated",
|
||||||
offset: 0,
|
offset: 0,
|
||||||
mobile: true,
|
mobile: true,
|
||||||
live: true
|
live: true
|
||||||
});
|
}).init();
|
||||||
this.wow.init();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -167,6 +163,7 @@ export default {
|
|||||||
|
|
||||||
.chat {
|
.chat {
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
.chat-bg {
|
.chat-bg {
|
||||||
background-color: #f3f6f9;
|
background-color: #f3f6f9;
|
||||||
@@ -214,3 +211,9 @@ export default {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.v-application--wrap {
|
||||||
|
min-height: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
162
docs/.vuepress/components/Plugins.vue
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
<template>
|
||||||
|
<div class="plugins">
|
||||||
|
<v-app>
|
||||||
|
<v-main>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12" sm="4">
|
||||||
|
<v-text-field
|
||||||
|
v-model="filterText"
|
||||||
|
dense
|
||||||
|
rounded
|
||||||
|
outlined
|
||||||
|
clearable
|
||||||
|
hide-details
|
||||||
|
label="Filter Plugin"
|
||||||
|
>
|
||||||
|
<template v-slot:prepend-inner>
|
||||||
|
<div class="v-input__icon v-input__icon--prepend-inner">
|
||||||
|
<v-icon small>fa-filter</v-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="12" sm="4">
|
||||||
|
<v-btn
|
||||||
|
block
|
||||||
|
color="primary"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href="https://github.com/nonebot/nonebot2/issues/new?template=plugin-publish.md"
|
||||||
|
>Publish Your Plugin
|
||||||
|
</v-btn>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="12" sm="4">
|
||||||
|
<v-pagination
|
||||||
|
v-model="page"
|
||||||
|
:length="pageNum"
|
||||||
|
prev-icon="fa-caret-left"
|
||||||
|
next-icon="fa-caret-right"
|
||||||
|
></v-pagination>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<hr />
|
||||||
|
<v-row>
|
||||||
|
<v-col
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
v-for="(plugin, index) in filteredPlugins"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
{{ plugin.name }}
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<a
|
||||||
|
class="repo-link"
|
||||||
|
v-if="repoLink(plugin.repo)"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
:title="plugin.repo"
|
||||||
|
:href="repoLink(plugin.repo)"
|
||||||
|
>
|
||||||
|
<v-icon>fab fa-github</v-icon>
|
||||||
|
</a>
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text>{{ plugin.desc }}</v-card-text>
|
||||||
|
<v-card-text>
|
||||||
|
<v-icon x-small>fa-fingerprint</v-icon>
|
||||||
|
{{ plugin.id }}
|
||||||
|
<v-icon x-small class="ml-2">fa-user</v-icon>
|
||||||
|
{{ plugin.author }}
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn
|
||||||
|
block
|
||||||
|
depressed
|
||||||
|
class="btn-copy"
|
||||||
|
@click="copyCommand(plugin)"
|
||||||
|
>
|
||||||
|
copy nb-cli command
|
||||||
|
<v-icon right small>fa-copy</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<v-snackbar v-model="snackbar">Copied!</v-snackbar>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-pagination
|
||||||
|
v-model="page"
|
||||||
|
:length="pageNum"
|
||||||
|
prev-icon="fa-caret-left"
|
||||||
|
next-icon="fa-caret-right"
|
||||||
|
></v-pagination>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-main>
|
||||||
|
</v-app>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import copy from "copy-to-clipboard";
|
||||||
|
import plugins from "../public/plugins.json";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Plugins",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
plugins: plugins,
|
||||||
|
snackbar: false,
|
||||||
|
filterText: "",
|
||||||
|
page: 1
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pageNum() {
|
||||||
|
return Math.ceil(this.filteredPlugins.length / 10);
|
||||||
|
},
|
||||||
|
filteredPlugins() {
|
||||||
|
return this.plugins.filter(plugin => {
|
||||||
|
return (
|
||||||
|
plugin.id.indexOf(this.filterText) != -1 ||
|
||||||
|
plugin.name.indexOf(this.filterText) != -1 ||
|
||||||
|
plugin.desc.indexOf(this.filterText) != -1 ||
|
||||||
|
plugin.author.indexOf(this.filterText) != -1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
repoLink(repo) {
|
||||||
|
if (repo) {
|
||||||
|
return /^https?:/.test(repo) ? repo : `https://github.com/${repo}`;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
copyCommand(plugin) {
|
||||||
|
copy(`nb plugin install ${plugin.id}`, {
|
||||||
|
format: "text/plain"
|
||||||
|
});
|
||||||
|
this.snackbar = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.v-application--wrap {
|
||||||
|
min-height: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.repo-link {
|
||||||
|
text-decoration: none !important;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.repo-link:hover i {
|
||||||
|
color: #ea5252;
|
||||||
|
}
|
||||||
|
</style>
|
@@ -13,7 +13,8 @@ module.exports = context => ({
|
|||||||
*/
|
*/
|
||||||
head: [
|
head: [
|
||||||
["link", { rel: "icon", href: "/logo.png" }],
|
["link", { rel: "icon", href: "/logo.png" }],
|
||||||
["meta", { name: "theme-color", content: "#d32f2f" }],
|
["link", { rel: "manifest", href: "/manifest.json" }],
|
||||||
|
["meta", { name: "theme-color", content: "#ea5252" }],
|
||||||
["meta", { name: "application-name", content: "NoneBot" }],
|
["meta", { name: "application-name", content: "NoneBot" }],
|
||||||
["meta", { name: "apple-mobile-web-app-title", content: "NoneBot" }],
|
["meta", { name: "apple-mobile-web-app-title", content: "NoneBot" }],
|
||||||
["meta", { name: "apple-mobile-web-app-capable", content: "yes" }],
|
["meta", { name: "apple-mobile-web-app-capable", content: "yes" }],
|
||||||
@@ -21,6 +22,26 @@ module.exports = context => ({
|
|||||||
"meta",
|
"meta",
|
||||||
{ name: "apple-mobile-web-app-status-bar-style", content: "black" }
|
{ name: "apple-mobile-web-app-status-bar-style", content: "black" }
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"link",
|
||||||
|
{ rel: "apple-touch-icon", href: "/icons/apple-touch-icon-180x180.png" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"link",
|
||||||
|
{
|
||||||
|
rel: "mask-icon",
|
||||||
|
href: "/icons/safari-pinned-tab.svg",
|
||||||
|
color: "#ea5252"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"meta",
|
||||||
|
{
|
||||||
|
name: "msapplication-TileImage",
|
||||||
|
content: "/icons/mstile-150x150.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
["meta", { name: "msapplication-TileColor", content: "#ea5252" }],
|
||||||
[
|
[
|
||||||
"link",
|
"link",
|
||||||
{
|
{
|
||||||
@@ -38,12 +59,12 @@ module.exports = context => ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
theme: "titanium",
|
theme: "nonebot",
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
logo: "/logo.png",
|
logo: "/logo.png",
|
||||||
repo: "nonebot/nonebot",
|
repo: "nonebot/nonebot2",
|
||||||
docsDir: "docs",
|
docsDir: "docs",
|
||||||
docsBranch: "dev2",
|
docsBranch: "dev",
|
||||||
docsDirVersioned: "archive",
|
docsDirVersioned: "archive",
|
||||||
docsDirPages: "pages",
|
docsDirPages: "pages",
|
||||||
editLinks: true,
|
editLinks: true,
|
||||||
@@ -58,7 +79,8 @@ module.exports = context => ({
|
|||||||
nav: [
|
nav: [
|
||||||
{ text: "主页", link: "/" },
|
{ text: "主页", link: "/" },
|
||||||
{ text: "指南", link: "/guide/" },
|
{ text: "指南", link: "/guide/" },
|
||||||
{ text: "API", link: "/api/" }
|
{ text: "API", link: "/api/" },
|
||||||
|
{ text: "插件广场", link: "/plugin-store" }
|
||||||
],
|
],
|
||||||
sidebarDepth: 2,
|
sidebarDepth: 2,
|
||||||
sidebar: {
|
sidebar: {
|
||||||
@@ -88,21 +110,17 @@ module.exports = context => ({
|
|||||||
title: "nonebot 模块",
|
title: "nonebot 模块",
|
||||||
path: "nonebot"
|
path: "nonebot"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "nonebot.typing 模块",
|
|
||||||
path: "typing"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "nonebot.config 模块",
|
title: "nonebot.config 模块",
|
||||||
path: "config"
|
path: "config"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "nonebot.sched 模块",
|
title: "nonebot.plugin 模块",
|
||||||
path: "sched"
|
path: "plugin"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "nonebot.log 模块",
|
title: "nonebot.matcher 模块",
|
||||||
path: "log"
|
path: "matcher"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "nonebot.rule 模块",
|
title: "nonebot.rule 模块",
|
||||||
@@ -112,13 +130,41 @@ module.exports = context => ({
|
|||||||
title: "nonebot.permission 模块",
|
title: "nonebot.permission 模块",
|
||||||
path: "permission"
|
path: "permission"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "nonebot.sched 模块",
|
||||||
|
path: "sched"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "nonebot.log 模块",
|
||||||
|
path: "log"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "nonebot.utils 模块",
|
title: "nonebot.utils 模块",
|
||||||
path: "utils"
|
path: "utils"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "nonebot.typing 模块",
|
||||||
|
path: "typing"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "nonebot.exception 模块",
|
title: "nonebot.exception 模块",
|
||||||
path: "exception"
|
path: "exception"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "nonebot.drivers 模块",
|
||||||
|
path: "drivers/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "nonebot.drivers.fastapi 模块",
|
||||||
|
path: "drivers/fastapi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "nonebot.adapters 模块",
|
||||||
|
path: "adapters/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "nonebot.adapters.cqhttp 模块",
|
||||||
|
path: "adapters/cqhttp"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -131,6 +177,16 @@ module.exports = context => ({
|
|||||||
plugins: [
|
plugins: [
|
||||||
"@vuepress/plugin-back-to-top",
|
"@vuepress/plugin-back-to-top",
|
||||||
"@vuepress/plugin-medium-zoom",
|
"@vuepress/plugin-medium-zoom",
|
||||||
|
[
|
||||||
|
"@vuepress/pwa",
|
||||||
|
{
|
||||||
|
serviceWorker: true,
|
||||||
|
updatePopup: {
|
||||||
|
message: "发现新内容",
|
||||||
|
buttonText: "刷新"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"versioning",
|
"versioning",
|
||||||
{
|
{
|
||||||
|
BIN
docs/.vuepress/public/icons/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
docs/.vuepress/public/icons/android-chrome-384x384.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
docs/.vuepress/public/icons/apple-touch-icon-180x180.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
docs/.vuepress/public/icons/favicon-16x16.png
Normal file
After Width: | Height: | Size: 626 B |
BIN
docs/.vuepress/public/icons/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1008 B |
BIN
docs/.vuepress/public/icons/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
docs/.vuepress/public/icons/mstile-150x150.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
29
docs/.vuepress/public/icons/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="500.000000pt" height="500.000000pt" viewBox="0 0 500.000000 500.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<metadata>
|
||||||
|
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||||
|
</metadata>
|
||||||
|
<g transform="translate(0.000000,500.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
<path d="M2478 4525 c-2 -1 -57 -5 -122 -9 -65 -4 -122 -8 -125 -10 -3 -2 -30
|
||||||
|
-7 -60 -11 -141 -18 -404 -102 -561 -180 -68 -34 -238 -132 -250 -145 -3 -3
|
||||||
|
-32 -25 -65 -49 -246 -182 -465 -442 -604 -719 -212 -422 -271 -933 -159
|
||||||
|
-1377 11 -44 21 -88 23 -97 8 -38 86 -238 120 -308 206 -415 542 -749 952
|
||||||
|
-945 90 -43 265 -111 309 -119 11 -2 48 -12 84 -21 82 -21 94 -24 155 -31 28
|
||||||
|
-4 53 -8 56 -10 11 -6 172 -17 264 -17 88 -1 239 9 282 17 11 3 43 8 70 12
|
||||||
|
280 40 611 181 855 363 118 87 221 181 311 284 173 195 309 424 392 657 14 41
|
||||||
|
28 82 30 90 2 8 13 51 25 95 25 93 27 103 34 159 3 22 8 52 11 65 9 46 16 166
|
||||||
|
17 276 1 704 -363 1359 -960 1728 -201 125 -484 234 -677 263 -16 3 -52 9 -79
|
||||||
|
15 -27 5 -92 12 -145 15 -53 3 -115 7 -138 8 -23 2 -43 2 -45 1z m162 -89
|
||||||
|
c691 -39 1330 -482 1622 -1121 74 -163 137 -364 152 -490 4 -27 9 -63 11 -80
|
||||||
|
17 -106 21 -305 10 -430 -8 -84 -49 -307 -60 -325 -2 -4 -6 -20 -9 -36 -3 -17
|
||||||
|
-23 -77 -44 -135 -194 -521 -605 -937 -1124 -1135 -562 -214 -1202 -155 -1713
|
||||||
|
160 -317 195 -564 466 -735 806 -60 120 -141 358 -156 465 -3 17 -9 55 -15 85
|
||||||
|
-11 61 -23 217 -22 295 3 525 201 1002 571 1373 340 340 782 542 1247 568 55
|
||||||
|
3 101 7 102 8 2 1 20 1 40 0 21 -2 76 -5 123 -8z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
20
docs/.vuepress/public/manifest.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "NoneBot",
|
||||||
|
"short_name": "NoneBot",
|
||||||
|
"background-color": "#ffffff",
|
||||||
|
"theme-color": "#ea5252",
|
||||||
|
"description": "An asynchronous python bot framework.",
|
||||||
|
"display": "standalone",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/icons/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/icons/android-chrome-384x384.png",
|
||||||
|
"sizes": "384x384",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
10
docs/.vuepress/public/plugins.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "nonebot-plugin-status",
|
||||||
|
"link": "nonebot-plugin-status",
|
||||||
|
"name": "状态监控",
|
||||||
|
"desc": "通过戳一戳获取服务器状态",
|
||||||
|
"author": "nonebot",
|
||||||
|
"repo": "nonebot/nonebot2"
|
||||||
|
}
|
||||||
|
]
|
@@ -1,3 +1,3 @@
|
|||||||
[
|
[
|
||||||
"2.0.0a1"
|
"2.0.0a4"
|
||||||
]
|
]
|
@@ -7,16 +7,13 @@
|
|||||||
* [nonebot](nonebot.html)
|
* [nonebot](nonebot.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.typing](typing.html)
|
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.config](config.html)
|
* [nonebot.config](config.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.sched](sched.html)
|
* [nonebot.plugin](plugin.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.log](log.html)
|
* [nonebot.matcher](matcher.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.rule](rule.html)
|
* [nonebot.rule](rule.html)
|
||||||
@@ -25,7 +22,28 @@
|
|||||||
* [nonebot.permission](permission.html)
|
* [nonebot.permission](permission.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.sched](sched.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.log](log.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.utils](utils.html)
|
* [nonebot.utils](utils.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.typing](typing.html)
|
||||||
|
|
||||||
|
|
||||||
* [nonebot.exception](exception.html)
|
* [nonebot.exception](exception.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.drivers](drivers/)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.drivers.fastapi](drivers/fastapi.html)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.adapters](adapters/)
|
||||||
|
|
||||||
|
|
||||||
|
* [nonebot.adapters.cqhttp](adapters/cqhttp.html)
|
||||||
|
323
docs/api/adapters/README.md
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.adapters 模块
|
||||||
|
|
||||||
|
## 协议适配基类
|
||||||
|
|
||||||
|
各协议请继承以下基类,并使用 `driver.register_adapter` 注册适配器
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseBot`
|
||||||
|
|
||||||
|
基类:`abc.ABC`
|
||||||
|
|
||||||
|
Bot 基类。用于处理上报消息,并提供 API 调用接口。
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `__init__(driver, connection_type, config, self_id, *, websocket=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `driver: Driver`: Driver 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `connection_type: str`: http 或者 websocket
|
||||||
|
|
||||||
|
|
||||||
|
* `config: Config`: Config 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `self_id: str`: 机器人 ID
|
||||||
|
|
||||||
|
|
||||||
|
* `websocket: Optional[WebSocket]`: Websocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `driver`
|
||||||
|
|
||||||
|
Driver 对象
|
||||||
|
|
||||||
|
|
||||||
|
### `connection_type`
|
||||||
|
|
||||||
|
连接类型
|
||||||
|
|
||||||
|
|
||||||
|
### `config`
|
||||||
|
|
||||||
|
Config 配置对象
|
||||||
|
|
||||||
|
|
||||||
|
### `self_id`
|
||||||
|
|
||||||
|
机器人 ID
|
||||||
|
|
||||||
|
|
||||||
|
### `websocket`
|
||||||
|
|
||||||
|
Websocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `type`
|
||||||
|
|
||||||
|
Adapter 类型
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `handle_message(message)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
处理上报消息的函数,转换为 `Event` 事件后调用 `nonebot.message.handle_event` 进一步处理事件。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `message: dict`: 收到的上报消息
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `call_api(api, **data)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
调用机器人 API 接口,可以通过该函数或直接通过 bot 属性进行调用
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `api: str`: API 名称
|
||||||
|
|
||||||
|
|
||||||
|
* `**data`: API 数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **示例**
|
||||||
|
|
||||||
|
|
||||||
|
```python
|
||||||
|
await bot.call_api("send_msg", data={"message": "hello world"})
|
||||||
|
await bot.send_msg(message="hello world")
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `send(event, message, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
调用机器人基础发送消息接口
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: 上报事件
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, Message, MessageSegment]`: 要发送的消息
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseEvent`
|
||||||
|
|
||||||
|
基类:`abc.ABC`
|
||||||
|
|
||||||
|
Event 基类。提供上报信息的关键信息,其余信息可从原始上报消息获取。
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(raw_event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `raw_event: dict`: 原始上报消息
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `raw_event`
|
||||||
|
|
||||||
|
原始上报消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `id`
|
||||||
|
|
||||||
|
事件 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `name`
|
||||||
|
|
||||||
|
事件名称
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `self_id`
|
||||||
|
|
||||||
|
机器人 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `time`
|
||||||
|
|
||||||
|
事件发生时间
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `type`
|
||||||
|
|
||||||
|
事件主类型
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `detail_type`
|
||||||
|
|
||||||
|
事件详细类型
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `sub_type`
|
||||||
|
|
||||||
|
事件子类型
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `user_id`
|
||||||
|
|
||||||
|
触发事件的主体 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `group_id`
|
||||||
|
|
||||||
|
触发事件的主体群 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `to_me`
|
||||||
|
|
||||||
|
事件是否为发送给机器人的消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `message`
|
||||||
|
|
||||||
|
消息内容
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `reply`
|
||||||
|
|
||||||
|
回复的消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `raw_message`
|
||||||
|
|
||||||
|
原始消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `plain_text`
|
||||||
|
|
||||||
|
纯文本消息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `sender`
|
||||||
|
|
||||||
|
消息发送者信息
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseMessageSegment`
|
||||||
|
|
||||||
|
基类:`abc.ABC`
|
||||||
|
|
||||||
|
消息段基类
|
||||||
|
|
||||||
|
|
||||||
|
### `type`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息段类型
|
||||||
|
|
||||||
|
|
||||||
|
### `data`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Dict[str, Union[str, list]]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息段数据
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseMessage`
|
||||||
|
|
||||||
|
基类:`list`, `abc.ABC`
|
||||||
|
|
||||||
|
消息数组
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(message=None, *args, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, dict, list, MessageSegment, Message]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `append(obj)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
添加一个消息段到消息数组末尾
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `obj: Union[str, MessageSegment]`: 要添加的消息段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `extend(obj)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
拼接一个消息数组或多个消息段到消息数组末尾
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `obj: Union[Message, Iterable[MessageSegment]]`: 要添加的消息数组
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `reduce()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
缩减消息数组,即拼接相邻纯文本消息段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `extract_plain_text()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
提取消息内纯文本消息
|
415
docs/api/adapters/cqhttp.md
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.adapters.cqhttp 模块
|
||||||
|
|
||||||
|
## CQHTTP (OneBot) v11 协议适配
|
||||||
|
|
||||||
|
协议详情请看: [CQHTTP](http://cqhttp.cc/) | [OneBot](https://github.com/howmanybots/onebot)
|
||||||
|
|
||||||
|
|
||||||
|
## `log(level, message)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
用于打印 CQHTTP 日志。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `level: str`: 日志等级
|
||||||
|
|
||||||
|
|
||||||
|
* `message: str`: 日志信息
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `escape(s, *, escape_comma=True)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
对字符串进行 CQ 码转义。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `s: str`: 需要转义的字符串
|
||||||
|
|
||||||
|
|
||||||
|
* `escape_comma: bool`: 是否转义逗号(`,`)。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `unescape(s)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
对字符串进行 CQ 码去转义。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `s: str`: 需要转义的字符串
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `_b2s(b)`
|
||||||
|
|
||||||
|
转换布尔值为字符串。
|
||||||
|
|
||||||
|
|
||||||
|
## _async_ `_check_reply(bot, event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查消息中存在的回复,去除并赋值 `event.reply`, `event.to_me`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `_check_at_me(bot, event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查消息开头或结尾是否存在 @机器人,去除并赋值 `event.to_me`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `_check_nickname(bot, event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查消息开头是否存在,去除并赋值 `event.to_me`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `_handle_api_result(result)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
处理 API 请求返回值。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `result: Optional[Dict[str, Any]]`: API 返回数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Any`: API 调用返回数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **异常**
|
||||||
|
|
||||||
|
|
||||||
|
* `ActionFailed`: API 调用失败
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Bot`
|
||||||
|
|
||||||
|
基类:[`nonebot.adapters.BaseBot`](#None)
|
||||||
|
|
||||||
|
CQHTTP 协议 Bot 适配。继承属性参考 [BaseBot](./#class-basebot) 。
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `type`
|
||||||
|
|
||||||
|
|
||||||
|
* 返回: `"cqhttp"`
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `handle_message(message)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
调用 [_check_reply](#async-check-reply-bot-event), [_check_at_me](#check-at-me-bot-event), [_check_nickname](#check-nickname-bot-event) 处理事件并转换为 [Event](#class-event)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `call_api(api, **data)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
调用 CQHTTP 协议 API
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `api: str`: API 名称
|
||||||
|
|
||||||
|
|
||||||
|
* `**data: Any`: API 参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Any`: API 调用返回数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **异常**
|
||||||
|
|
||||||
|
|
||||||
|
* `NetworkError`: 网络错误
|
||||||
|
|
||||||
|
|
||||||
|
* `ActionFailed`: API 调用失败
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `send(event, message, at_sender=False, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
根据 `event` 向触发事件的主体发送消息。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: Event 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, Message, MessageSegment]`: 要发送的消息
|
||||||
|
|
||||||
|
|
||||||
|
* `at_sender: bool`: 是否 @ 事件主体
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 覆盖默认参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Any`: API 调用返回数据
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **异常**
|
||||||
|
|
||||||
|
|
||||||
|
* `ValueError`: 缺少 `user_id`, `group_id`
|
||||||
|
|
||||||
|
|
||||||
|
* `NetworkError`: 网络错误
|
||||||
|
|
||||||
|
|
||||||
|
* `ActionFailed`: API 调用失败
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Event`
|
||||||
|
|
||||||
|
基类:[`nonebot.adapters.BaseEvent`](#None)
|
||||||
|
|
||||||
|
CQHTTP 协议 Event 适配。继承属性参考 [BaseEvent](./#class-baseevent) 。
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `id`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[int]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件/消息 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `name`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件名称,由类型与 `.` 组合而成
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `self_id`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 机器人自身 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `time`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `int`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件发生时间
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `type`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件类型
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `detail_type`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件详细类型
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `sub_type`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[str]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件子类型
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `user_id`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[int]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件主体 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `group_id`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[int]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 事件主体群 ID
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `to_me`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[bool]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息是否与机器人相关
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `message`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[Message]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `reply`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[dict]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 回复消息详情
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `raw_message`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[str]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 原始消息
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `plain_text`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[str]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 纯文本消息内容
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `sender`
|
||||||
|
|
||||||
|
|
||||||
|
* 类型: `Optional[dict]`
|
||||||
|
|
||||||
|
|
||||||
|
* 说明: 消息发送者信息
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `MessageSegment`
|
||||||
|
|
||||||
|
基类:[`nonebot.adapters.BaseMessageSegment`](#None)
|
||||||
|
|
||||||
|
CQHTTP 协议 MessageSegment 适配。具体方法参考协议消息段类型或源码。
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Message`
|
||||||
|
|
||||||
|
基类:[`nonebot.adapters.BaseMessage`](#None)
|
||||||
|
|
||||||
|
CQHTTP 协议 Message 适配。
|
@@ -194,10 +194,10 @@ SUPER_USERS=[12345789]
|
|||||||
### `nickname`
|
### `nickname`
|
||||||
|
|
||||||
|
|
||||||
* 类型: `Union[str, Set[str]]`
|
* 类型: `Set[str]`
|
||||||
|
|
||||||
|
|
||||||
* 默认值: `""`
|
* 默认值: `set()`
|
||||||
|
|
||||||
|
|
||||||
* 说明:
|
* 说明:
|
||||||
|
246
docs/api/drivers/README.md
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.drivers 模块
|
||||||
|
|
||||||
|
## 后端驱动适配基类
|
||||||
|
|
||||||
|
各驱动请继承以下基类
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseDriver`
|
||||||
|
|
||||||
|
基类:`abc.ABC`
|
||||||
|
|
||||||
|
Driver 基类。将后端框架封装,以满足适配器使用。
|
||||||
|
|
||||||
|
|
||||||
|
### `_adapters`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[str, Type[Bot]]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
已注册的适配器列表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `__init__(env, config)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `env: Env`: 包含环境信息的 Env 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `config: Config`: 包含配置信息的 Config 对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `env`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`str`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
环境名称
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `config`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Config`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
配置对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `_clients`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[str, Bot]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
已连接的 Bot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `register_adapter(name, adapter)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个协议适配器
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `name: str`: 适配器名称,用于在连接时进行识别
|
||||||
|
|
||||||
|
|
||||||
|
* `adapter: Type[Bot]`: 适配器 Class
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `type`
|
||||||
|
|
||||||
|
驱动类型名称
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `server_app`
|
||||||
|
|
||||||
|
驱动 APP 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `asgi`
|
||||||
|
|
||||||
|
驱动 ASGI 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `logger`
|
||||||
|
|
||||||
|
驱动专属 logger 日志记录器
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `bots`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[str, Bot]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
获取当前所有已连接的 Bot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `on_startup(func)`
|
||||||
|
|
||||||
|
注册一个在驱动启动时运行的函数
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `on_shutdown(func)`
|
||||||
|
|
||||||
|
注册一个在驱动停止时运行的函数
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `run(host=None, port=None, *args, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
启动驱动框架
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `host: Optional[str]`: 驱动绑定 IP
|
||||||
|
|
||||||
|
|
||||||
|
* `post: Optional[int]`: 驱动绑定端口
|
||||||
|
|
||||||
|
|
||||||
|
* `*args`
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `_handle_http()`
|
||||||
|
|
||||||
|
用于处理 HTTP 类型请求的函数
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `_handle_ws_reverse()`
|
||||||
|
|
||||||
|
用于处理 WebSocket 类型请求的函数
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `BaseWebSocket`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
WebSocket 连接封装,统一接口方便外部调用。
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract_ `__init__(websocket)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `websocket: Any`: WebSocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `websocket`
|
||||||
|
|
||||||
|
WebSocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract property_ `closed`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
连接是否已经关闭
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `accept()`
|
||||||
|
|
||||||
|
接受 WebSocket 连接请求
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `close(code)`
|
||||||
|
|
||||||
|
关闭 WebSocket 连接请求
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `receive()`
|
||||||
|
|
||||||
|
接收一条 WebSocket 信息
|
||||||
|
|
||||||
|
|
||||||
|
### _abstract async_ `send(data)`
|
||||||
|
|
||||||
|
发送一条 WebSocket 信息
|
125
docs/api/drivers/fastapi.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.drivers.fastapi 模块
|
||||||
|
|
||||||
|
## FastAPI 驱动适配
|
||||||
|
|
||||||
|
后端使用方法请参考: [FastAPI 文档](https://fastapi.tiangolo.com/)
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Driver`
|
||||||
|
|
||||||
|
基类:[`nonebot.drivers.BaseDriver`](#None)
|
||||||
|
|
||||||
|
FastAPI 驱动框架
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(env, config)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* `env: Env`: 包含环境信息的 Env 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `config: Config`: 包含配置信息的 Config 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `type`
|
||||||
|
|
||||||
|
驱动名称: `fastapi`
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `server_app`
|
||||||
|
|
||||||
|
`FastAPI APP` 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `asgi`
|
||||||
|
|
||||||
|
`FastAPI APP` 对象
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `logger`
|
||||||
|
|
||||||
|
fastapi 使用的 logger
|
||||||
|
|
||||||
|
|
||||||
|
### `on_startup(func)`
|
||||||
|
|
||||||
|
参考文档: [Events](https://fastapi.tiangolo.com/advanced/events/#startup-event)
|
||||||
|
|
||||||
|
|
||||||
|
### `on_shutdown(func)`
|
||||||
|
|
||||||
|
参考文档: [Events](https://fastapi.tiangolo.com/advanced/events/#startup-event)
|
||||||
|
|
||||||
|
|
||||||
|
### `run(host=None, port=None, *, app=None, **kwargs)`
|
||||||
|
|
||||||
|
使用 `uvicorn` 启动 FastAPI
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `_handle_http(adapter, data=Body(Ellipsis), x_self_id=Header(None), x_signature=Header(None), auth=Depends(get_auth_bearer))`
|
||||||
|
|
||||||
|
用于处理 HTTP 类型请求的函数
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `_handle_ws_reverse(adapter, websocket, x_self_id=Header(None), auth=Depends(get_auth_bearer))`
|
||||||
|
|
||||||
|
用于处理 WebSocket 类型请求的函数
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `WebSocket`
|
||||||
|
|
||||||
|
基类:[`nonebot.drivers.BaseWebSocket`](#None)
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(websocket)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* `websocket: Any`: WebSocket 连接对象
|
||||||
|
|
||||||
|
|
||||||
|
### _property_ `closed`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
连接是否已经关闭
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `accept()`
|
||||||
|
|
||||||
|
接受 WebSocket 连接请求
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `close(code=1000)`
|
||||||
|
|
||||||
|
关闭 WebSocket 连接请求
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `receive()`
|
||||||
|
|
||||||
|
接收一条 WebSocket 信息
|
||||||
|
|
||||||
|
|
||||||
|
### _async_ `send(data)`
|
||||||
|
|
||||||
|
发送一条 WebSocket 信息
|
497
docs/api/matcher.md
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.matcher 模块
|
||||||
|
|
||||||
|
## 事件响应器
|
||||||
|
|
||||||
|
该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行 对话 。
|
||||||
|
|
||||||
|
|
||||||
|
## `matchers`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[int, List[Type[Matcher]]]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
用于存储当前所有的事件响应器
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Matcher`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
事件响应器类
|
||||||
|
|
||||||
|
|
||||||
|
### `module`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Optional[str]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器所在模块名称
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `type`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`str`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器类型
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `rule`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Rule`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器匹配规则
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `permission`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Permission`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器触发权限
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `priority`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`int`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `block`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器是否阻止事件传播
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `temp`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`bool`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器是否为临时
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `expire_time`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Optional[datetime]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器过期时间点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `_default_state`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`dict`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器默认状态
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `_default_parser`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Optional[ArgsParser]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器默认参数解析函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__()`
|
||||||
|
|
||||||
|
实例化 Matcher 以便运行
|
||||||
|
|
||||||
|
|
||||||
|
### `handlers`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`List[Handler]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
事件响应器拥有的事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `new(type_='', rule=None, permission=None, handlers=None, temp=False, priority=1, block=False, *, module=None, default_state=None, expire_time=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
创建一个新的事件响应器,并存储至 [matchers](#matchers)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `type_: str`: 事件响应器类型,与 `event.type` 一致时触发,空字符串表示任意
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Rule]`: 匹配规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器,即触发一次后删除
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 响应优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级的响应器传播
|
||||||
|
|
||||||
|
|
||||||
|
* `module: Optional[str]`: 事件响应器所在模块名称
|
||||||
|
|
||||||
|
|
||||||
|
* `default_state: Optional[dict]`: 默认状态 `state`
|
||||||
|
|
||||||
|
|
||||||
|
* `expire_time: Optional[datetime]`: 事件响应器最终有效时间点,过时即被删除
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`: 新的事件响应器类
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `check_perm(bot, event)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查是否满足触发权限
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: 上报事件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `bool`: 是否满足权限
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `check_rule(bot, event, state)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
检查是否满足匹配规则
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `bot: Bot`: Bot 对象
|
||||||
|
|
||||||
|
|
||||||
|
* `event: Event`: 上报事件
|
||||||
|
|
||||||
|
|
||||||
|
* `state: dict`: 当前状态
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `bool`: 是否满足匹配规则
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `args_parser(func)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
装饰一个函数来更改当前事件响应器的默认参数解析函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `func: ArgsParser`: 参数解析函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `handle()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
装饰一个函数来向事件响应器直接添加一个处理函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* 无
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `receive()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
装饰一个函数来指示 NoneBot 在接收用户新的一条消息后继续运行该函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* 无
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _classmethod_ `got(key, prompt=None, args_parser=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
装饰一个函数来指示 NoneBot 当要获取的 `key` 不存在时接收用户新的一条消息并经过 `ArgsParser` 处理后再运行该函数,如果 `key` 已存在则直接继续运行
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `key: str`: 参数名
|
||||||
|
|
||||||
|
|
||||||
|
* `prompt: Optional[Union[str, Message, MessageSegment]]`: 在参数不存在时向用户发送的消息
|
||||||
|
|
||||||
|
|
||||||
|
* `args_parser: Optional[ArgsParser]`: 可选参数解析函数,空则使用默认解析函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `send(message, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
发送一条消息给当前交互用户
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, Message, MessageSegment]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `finish(message=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
发送一条消息给当前交互用户并结束当前事件响应器
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `message: Union[str, Message, MessageSegment]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `pause(prompt=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续下一个处理函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `prompt: Union[str, Message, MessageSegment]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### _async classmethod_ `reject(prompt=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后重新运行当前处理函数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `prompt: Union[str, Message, MessageSegment]`: 消息内容
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `MatcherGroup`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
事件响应器组合,统一管理。用法同 `Matcher`
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(type_='', rule=None, permission=None, handlers=None, temp=False, priority=1, block=False, *, module=None, default_state=None, expire_time=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
创建一个事件响应器组合,参数为默认值,与 `Matcher.new` 一致
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `matchers`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`List[Type[Matcher]]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
组内事件响应器列表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `new(type_='', rule=None, permission=None, handlers=None, temp=False, priority=1, block=False, *, module=None, default_state=None, expire_time=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
在组中创建一个新的事件响应器,参数留空则使用组合默认值
|
||||||
|
|
||||||
|
|
||||||
|
:::danger 警告
|
||||||
|
如果使用 handlers 参数覆盖组合默认值则该事件响应器不会随组合一起添加新的事件处理函数
|
||||||
|
:::
|
@@ -5,6 +5,55 @@ sidebarDepth: 0
|
|||||||
|
|
||||||
# NoneBot 模块
|
# NoneBot 模块
|
||||||
|
|
||||||
|
## 快捷导入
|
||||||
|
|
||||||
|
为方便使用,`nonebot` 模块从子模块导入了部分内容
|
||||||
|
|
||||||
|
|
||||||
|
* `on_message` => `nonebot.plugin.on_message`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_notice` => `nonebot.plugin.on_notice`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_request` => `nonebot.plugin.on_request`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_metaevent` => `nonebot.plugin.on_metaevent`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_startswith` => `nonebot.plugin.on_startswith`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_endswith` => `nonebot.plugin.on_endswith`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_command` => `nonebot.plugin.on_command`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_regex` => `nonebot.plugin.on_regex`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_regex` => `nonebot.plugin.on_regex`
|
||||||
|
|
||||||
|
|
||||||
|
* `on_regex` => `nonebot.plugin.on_regex`
|
||||||
|
|
||||||
|
|
||||||
|
* `CommandGroup` => `nonebot.plugin.CommandGroup`
|
||||||
|
|
||||||
|
|
||||||
|
* `load_plugin` => `nonebot.plugin.load_plugin`
|
||||||
|
|
||||||
|
|
||||||
|
* `load_plugins` => `nonebot.plugin.load_plugins`
|
||||||
|
|
||||||
|
|
||||||
|
* `load_builtin_plugins` => `nonebot.plugin.load_builtin_plugins`
|
||||||
|
|
||||||
|
|
||||||
|
* `get_loaded_plugins` => `nonebot.plugin.get_loaded_plugins`
|
||||||
|
|
||||||
|
|
||||||
## `get_driver()`
|
## `get_driver()`
|
||||||
|
|
||||||
|
629
docs/api/plugin.md
Normal file
@@ -0,0 +1,629 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# NoneBot.plugin 模块
|
||||||
|
|
||||||
|
## 插件
|
||||||
|
|
||||||
|
为 NoneBot 插件开发提供便携的定义函数。
|
||||||
|
|
||||||
|
|
||||||
|
## `plugins`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`Dict[str, Plugin]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
已加载的插件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `Plugin`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
存储插件信息
|
||||||
|
|
||||||
|
|
||||||
|
### `name`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `str`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 插件名称,使用 文件/文件夹 名称作为插件名
|
||||||
|
|
||||||
|
|
||||||
|
### `module`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `ModuleType`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 插件模块对象
|
||||||
|
|
||||||
|
|
||||||
|
### `matcher`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `Set[Type[Matcher]]`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 插件内定义的 `Matcher`
|
||||||
|
|
||||||
|
|
||||||
|
## `on(type='', rule=None, permission=None, *, handlers=None, temp=False, priority=1, block=False, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个基础事件响应器,可自定义类型。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `type: str`: 事件响应器类型
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_metaevent(rule=None, *, handlers=None, temp=False, priority=1, block=False, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个元事件响应器。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_message(rule=None, permission=None, *, handlers=None, temp=False, priority=1, block=True, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_notice(rule=None, *, handlers=None, temp=False, priority=1, block=False, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个通知事件响应器。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_request(rule=None, *, handlers=None, temp=False, priority=1, block=False, state=None)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个请求事件响应器。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_startswith(msg, rule=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息的\*\*文本部分\*\*以指定内容开头时响应。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `msg: str`: 指定消息开头内容
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_endswith(msg, rule=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息的\*\*文本部分\*\*以指定内容结尾时响应。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `msg: str`: 指定消息结尾内容
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_keyword(keywords, rule=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息纯文本部分包含关键词时响应。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `keywords: Set[str]`: 关键词列表
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_command(cmd, rule=None, aliases=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息以指定命令开头时响应。
|
||||||
|
|
||||||
|
命令匹配规则参考: [命令形式匹配](rule.html#command-command)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `cmd: Union[str, Tuple[str, ...]]`: 指定命令内容
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `aliases: Optional[Set[Union[str, Tuple[str, ...]]]]`: 命令别名
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `on_regex(pattern, flags=0, rule=None, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个消息事件响应器,并且当消息匹配正则表达式时响应。
|
||||||
|
|
||||||
|
命令匹配规则参考: [正则匹配](rule.html#regex-regex-flags-0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `pattern: str`: 正则表达式
|
||||||
|
|
||||||
|
|
||||||
|
* `flags: Union[int, re.RegexFlag]`: 正则匹配标志
|
||||||
|
|
||||||
|
|
||||||
|
* `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则
|
||||||
|
|
||||||
|
|
||||||
|
* `permission: Optional[Permission]`: 事件响应权限
|
||||||
|
|
||||||
|
|
||||||
|
* `handlers: Optional[List[Handler]]`: 事件处理函数列表
|
||||||
|
|
||||||
|
|
||||||
|
* `temp: bool`: 是否为临时事件响应器(仅执行一次)
|
||||||
|
|
||||||
|
|
||||||
|
* `priority: int`: 事件响应器优先级
|
||||||
|
|
||||||
|
|
||||||
|
* `block: bool`: 是否阻止事件向更低优先级传递
|
||||||
|
|
||||||
|
|
||||||
|
* `state: Optional[dict]`: 默认的 state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## _class_ `CommandGroup`
|
||||||
|
|
||||||
|
基类:`object`
|
||||||
|
|
||||||
|
命令组,用于声明一组有相同名称前缀的命令。
|
||||||
|
|
||||||
|
|
||||||
|
### `__init__(cmd, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `cmd: Union[str, Tuple[str, ...]]`: 命令前缀
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `on_command` 的参数默认值,参考 [on_command](#on-command-cmd-rule-none-aliases-none-kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `basecmd`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `Tuple[str, ...]`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 命令前缀
|
||||||
|
|
||||||
|
|
||||||
|
### `base_kwargs`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**: `Dict[str, Any]`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**: 其他传递给 `on_command` 的参数默认值
|
||||||
|
|
||||||
|
|
||||||
|
### `command(cmd, **kwargs)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
注册一个新的命令。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `cmd: Union[str, Tuple[str, ...]]`: 命令前缀
|
||||||
|
|
||||||
|
|
||||||
|
* `**kwargs`: 其他传递给 `on_command` 的参数,将会覆盖命令组默认值
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Type[Matcher]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `load_plugin(module_path)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
使用 `importlib` 加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `module_path: str`: 插件名称 `path.to.your.plugin`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Optional[Plugin]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `load_plugins(*plugin_dir)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
导入目录下多个插件,以 `_` 开头的插件不会被导入!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `*plugin_dir: str`: 插件路径
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Set[Plugin]`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `load_builtin_plugins()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
导入 NoneBot 内置插件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Plugin`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `get_loaded_plugins()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
获取当前已导入的插件。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `Set[Plugin]`
|
@@ -7,10 +7,10 @@ sidebarDepth: 0
|
|||||||
|
|
||||||
## 规则
|
## 规则
|
||||||
|
|
||||||
每个 `Matcher` 拥有一个 `Rule` ,其中是 **异步** `RuleChecker` 的集合,只有当所有 `RuleChecker` 检查结果为 `True` 时继续运行。
|
每个事件响应器 `Matcher` 拥有一个匹配规则 `Rule` ,其中是 **异步** `RuleChecker` 的集合,只有当所有 `RuleChecker` 检查结果为 `True` 时继续运行。
|
||||||
|
|
||||||
:::tip 提示
|
:::tip 提示
|
||||||
`RuleChecker` 既可以是 async function 也可以是 sync function
|
`RuleChecker` 既可以是 async function 也可以是 sync function,但在最终会被 `nonebot.utils.run_sync` 转换为 async function
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|
||||||
@@ -120,3 +120,91 @@ Rule(async_function, run_sync(sync_function))
|
|||||||
|
|
||||||
|
|
||||||
* `msg: str`: 消息结尾字符串
|
* `msg: str`: 消息结尾字符串
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `keyword(*keywords)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
匹配消息关键词
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `*keywords: str`: 关键词
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `command(*cmds)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
命令形式匹配,根据配置里提供的 `command_start`, `command_sep` 判断消息是否为命令。
|
||||||
|
|
||||||
|
可以通过 `state["_prefix"]["command"]` 获取匹配成功的命令(例:`("test",)`),通过 `state["_prefix"]["raw_command"]` 获取匹配成功的原始命令文本(例:`"/test"`)。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `*cmds: Union[str, Tuple[str, ...]]`: 命令内容
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **示例**
|
||||||
|
|
||||||
|
使用默认 `command_start`, `command_sep` 配置
|
||||||
|
|
||||||
|
命令 `("test",)` 可以匹配:`/test` 开头的消息
|
||||||
|
命令 `("test", "sub")` 可以匹配”`/test.sub` 开头的消息
|
||||||
|
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
命令内容与后续消息间无需空格!
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
## `regex(regex, flags=0)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
根据正则表达式进行匹配。
|
||||||
|
|
||||||
|
可以通过 `state["_matched"]` 获取正则表达式匹配成功的文本。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `regex: str`: 正则表达式
|
||||||
|
|
||||||
|
|
||||||
|
* `flags: Union[int, re.RegexFlag]`: 正则标志
|
||||||
|
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
正则表达式匹配使用 search 而非 match,如需从头匹配请使用 `r"^xxx"` 来确保匹配开头
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
## `to_me()`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
通过 `event.to_me` 判断消息是否是发送给机器人
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* 无
|
||||||
|
@@ -142,6 +142,22 @@ sidebarDepth: 0
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `MatcherGroup`
|
||||||
|
|
||||||
|
|
||||||
|
* **类型**
|
||||||
|
|
||||||
|
`MatcherGroup`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
MatcherGroup 为 Matcher 的集合。可以共享 Handler。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## `Rule`
|
## `Rule`
|
||||||
|
|
||||||
|
|
||||||
|
@@ -6,6 +6,29 @@ sidebarDepth: 0
|
|||||||
# NoneBot.utils 模块
|
# NoneBot.utils 模块
|
||||||
|
|
||||||
|
|
||||||
|
## `escape_tag(s)`
|
||||||
|
|
||||||
|
|
||||||
|
* **说明**
|
||||||
|
|
||||||
|
用于记录带颜色日志时转义 `<tag>` 类型特殊标签
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **参数**
|
||||||
|
|
||||||
|
|
||||||
|
* `s: str`: 需要转义的字符串
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* **返回**
|
||||||
|
|
||||||
|
|
||||||
|
* `str`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## `run_sync(func)`
|
## `run_sync(func)`
|
||||||
|
|
||||||
|
|
||||||
|
@@ -20,11 +20,9 @@ NoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人
|
|||||||
|
|
||||||
## 它如何工作?
|
## 它如何工作?
|
||||||
|
|
||||||
NoneBot 的运行离不开 酷 Q 和 CQHTTP 插件。酷 Q 扮演着「无头 QQ 客户端」的角色,它进行实际的消息、通知、请求的接收和发送,当 酷 Q 收到消息时,它将这个消息包装为一个事件(通知和请求同理),并通过它自己的插件机制将事件传送给 CQHTTP 插件,后者再根据其配置中的 `post_url` 或 `ws_reverse_url` 等项来将事件发送至 NoneBot。
|
<!-- TODO: how to work -->
|
||||||
|
|
||||||
在 NoneBot 收到事件前,它底层的 aiocqhttp 实际已经先看到了事件,aiocqhttp 根据事件的类型信息,通知到 NoneBot 的相应函数。特别地,对于消息类型的事件,还将消息内容转换成了 `aiocqhttp.message.Message` 类型,以便处理。
|
~~未填坑~~
|
||||||
|
|
||||||
NoneBot 的事件处理函数收到通知后,对于不同类型的事件,再做相应的预处理和解析,然后调用对应的插件,并向其提供适合此类事件的会话(Session)对象。NoneBot 插件的编写者要做的,就是利用 Session 对象中提供的数据,在插件的处理函数中实现所需的功能。
|
|
||||||
|
|
||||||
## 特色
|
## 特色
|
||||||
|
|
||||||
|
@@ -136,11 +136,11 @@ QQ 协议端举例:
|
|||||||
现在,尝试向你的 QQ 机器人账号发送如下内容:
|
现在,尝试向你的 QQ 机器人账号发送如下内容:
|
||||||
|
|
||||||
```default
|
```default
|
||||||
/say 你好,世界
|
/echo 你好,世界
|
||||||
```
|
```
|
||||||
|
|
||||||
到这里如果一切 OK,你应该会收到机器人给你回复了 `你好,世界`。这一历史性的对话标志着你已经成功地运行了一个 NoneBot 的最小实例,开始了编写更强大的 QQ 机器人的创意之旅!
|
到这里如果一切 OK,你应该会收到机器人给你回复了 `你好,世界`。这一历史性的对话标志着你已经成功地运行了一个 NoneBot 的最小实例,开始了编写更强大的 QQ 机器人的创意之旅!
|
||||||
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<Messenger :messages="[{ position: 'right', msg: '/say 你好,世界' }, { position: 'left', msg: '你好,世界' }]"/>
|
<Messenger :messages="[{ position: 'right', msg: '/echo 你好,世界' }, { position: 'left', msg: '你好,世界' }]"/>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
|
@@ -6,7 +6,10 @@
|
|||||||
请确保你的 Python 版本 >= 3.7。
|
请确保你的 Python 版本 >= 3.7。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
请在安装 nonebot2 之前卸载 nonebot 1.x
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
pip uninstall nonebot
|
||||||
pip install nonebot2
|
pip install nonebot2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -159,7 +159,7 @@ weather = on_command("天气", rule=to_me(), permission=Permission(), priority=5
|
|||||||
- `on_startswith(str)` ~ `on("message", startswith(str))`: 消息开头匹配处理器
|
- `on_startswith(str)` ~ `on("message", startswith(str))`: 消息开头匹配处理器
|
||||||
- `on_endswith(str)` ~ `on("message", endswith(str))`: 消息结尾匹配处理器
|
- `on_endswith(str)` ~ `on("message", endswith(str))`: 消息结尾匹配处理器
|
||||||
- `on_command(str|tuple)` ~ `on("message", command(str|tuple))`: 命令处理器
|
- `on_command(str|tuple)` ~ `on("message", command(str|tuple))`: 命令处理器
|
||||||
- `on_regax(pattern_str)` ~ `on("message", regax(pattern_str))`: 正则匹配处理器
|
- `on_regex(pattern_str)` ~ `on("message", regex(pattern_str))`: 正则匹配处理器
|
||||||
|
|
||||||
#### 匹配规则 rule
|
#### 匹配规则 rule
|
||||||
|
|
||||||
|
@@ -3,11 +3,17 @@ NoneBot Api Reference
|
|||||||
|
|
||||||
:模块索引:
|
:模块索引:
|
||||||
- `nonebot <nonebot.html>`_
|
- `nonebot <nonebot.html>`_
|
||||||
- `nonebot.typing <typing.html>`_
|
|
||||||
- `nonebot.config <config.html>`_
|
- `nonebot.config <config.html>`_
|
||||||
- `nonebot.sched <sched.html>`_
|
- `nonebot.plugin <plugin.html>`_
|
||||||
- `nonebot.log <log.html>`_
|
- `nonebot.matcher <matcher.html>`_
|
||||||
- `nonebot.rule <rule.html>`_
|
- `nonebot.rule <rule.html>`_
|
||||||
- `nonebot.permission <permission.html>`_
|
- `nonebot.permission <permission.html>`_
|
||||||
|
- `nonebot.sched <sched.html>`_
|
||||||
|
- `nonebot.log <log.html>`_
|
||||||
- `nonebot.utils <utils.html>`_
|
- `nonebot.utils <utils.html>`_
|
||||||
|
- `nonebot.typing <typing.html>`_
|
||||||
- `nonebot.exception <exception.html>`_
|
- `nonebot.exception <exception.html>`_
|
||||||
|
- `nonebot.drivers <drivers/>`_
|
||||||
|
- `nonebot.drivers.fastapi <drivers/fastapi.html>`_
|
||||||
|
- `nonebot.adapters <adapters/>`_
|
||||||
|
- `nonebot.adapters.cqhttp <adapters/cqhttp.html>`_
|
||||||
|
13
docs_build/adapters/README.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
NoneBot.adapters 模块
|
||||||
|
=====================
|
||||||
|
|
||||||
|
.. automodule:: nonebot.adapters
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
:special-members: __init__
|
||||||
|
:show-inheritance:
|
12
docs_build/adapters/cqhttp.rst
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
NoneBot.adapters.cqhttp 模块
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. automodule:: nonebot.adapters.cqhttp
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
:show-inheritance:
|
13
docs_build/drivers/README.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
NoneBot.drivers 模块
|
||||||
|
=====================
|
||||||
|
|
||||||
|
.. automodule:: nonebot.drivers
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
:special-members: __init__
|
||||||
|
:show-inheritance:
|
13
docs_build/drivers/fastapi.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
NoneBot.drivers.fastapi 模块
|
||||||
|
=====================
|
||||||
|
|
||||||
|
.. automodule:: nonebot.drivers.fastapi
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
:special-members: __init__
|
||||||
|
:show-inheritance:
|
13
docs_build/matcher.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
NoneBot.matcher 模块
|
||||||
|
====================
|
||||||
|
|
||||||
|
.. automodule:: nonebot.matcher
|
||||||
|
:members:
|
||||||
|
:private-members:
|
||||||
|
:special-members: __init__
|
||||||
|
:show-inheritance:
|
@@ -4,7 +4,7 @@ sidebarDepth: 0
|
|||||||
---
|
---
|
||||||
|
|
||||||
NoneBot.permission 模块
|
NoneBot.permission 模块
|
||||||
====================
|
=======================
|
||||||
|
|
||||||
.. automodule:: nonebot.permission
|
.. automodule:: nonebot.permission
|
||||||
:members:
|
:members:
|
||||||
|
12
docs_build/plugin.rst
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
contentSidebar: true
|
||||||
|
sidebarDepth: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
NoneBot.plugin 模块
|
||||||
|
====================
|
||||||
|
|
||||||
|
.. automodule:: nonebot.plugin
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
||||||
|
:special-members: __init__
|
@@ -7,6 +7,7 @@ NoneBot.utils 模块
|
|||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
||||||
|
.. autofunction:: nonebot.utils.escape_tag
|
||||||
.. autodecorator:: nonebot.utils.run_sync
|
.. autodecorator:: nonebot.utils.run_sync
|
||||||
.. autoclass:: nonebot.utils.DataclassEncoder
|
.. autoclass:: nonebot.utils.DataclassEncoder
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
@@ -1,5 +1,25 @@
|
|||||||
#!/usr/bin/env python3
|
"""
|
||||||
# -*- coding: utf-8 -*-
|
快捷导入
|
||||||
|
========
|
||||||
|
|
||||||
|
为方便使用,``nonebot`` 模块从子模块导入了部分内容
|
||||||
|
|
||||||
|
- ``on_message`` => ``nonebot.plugin.on_message``
|
||||||
|
- ``on_notice`` => ``nonebot.plugin.on_notice``
|
||||||
|
- ``on_request`` => ``nonebot.plugin.on_request``
|
||||||
|
- ``on_metaevent`` => ``nonebot.plugin.on_metaevent``
|
||||||
|
- ``on_startswith`` => ``nonebot.plugin.on_startswith``
|
||||||
|
- ``on_endswith`` => ``nonebot.plugin.on_endswith``
|
||||||
|
- ``on_command`` => ``nonebot.plugin.on_command``
|
||||||
|
- ``on_regex`` => ``nonebot.plugin.on_regex``
|
||||||
|
- ``on_regex`` => ``nonebot.plugin.on_regex``
|
||||||
|
- ``on_regex`` => ``nonebot.plugin.on_regex``
|
||||||
|
- ``CommandGroup`` => ``nonebot.plugin.CommandGroup``
|
||||||
|
- ``load_plugin`` => ``nonebot.plugin.load_plugin``
|
||||||
|
- ``load_plugins`` => ``nonebot.plugin.load_plugins``
|
||||||
|
- ``load_builtin_plugins`` => ``nonebot.plugin.load_builtin_plugins``
|
||||||
|
- ``get_loaded_plugins`` => ``nonebot.plugin.get_loaded_plugins``
|
||||||
|
"""
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
from nonebot.typing import Bot, Dict, Type, Union, Driver, Optional, NoReturn
|
from nonebot.typing import Bot, Dict, Type, Union, Driver, Optional, NoReturn
|
||||||
@@ -109,6 +129,7 @@ def get_bots() -> Union[NoReturn, Dict[str, Bot]]:
|
|||||||
|
|
||||||
|
|
||||||
from nonebot.sched import scheduler
|
from nonebot.sched import scheduler
|
||||||
|
from nonebot.utils import escape_tag
|
||||||
from nonebot.config import Env, Config
|
from nonebot.config import Env, Config
|
||||||
from nonebot.log import logger, default_filter
|
from nonebot.log import logger, default_filter
|
||||||
from nonebot.adapters.cqhttp import Bot as CQBot
|
from nonebot.adapters.cqhttp import Bot as CQBot
|
||||||
@@ -155,8 +176,8 @@ def init(*, _env_file: Optional[str] = None, **kwargs):
|
|||||||
_env_file=_env_file or f".env.{env.environment}")
|
_env_file=_env_file or f".env.{env.environment}")
|
||||||
|
|
||||||
default_filter.level = "DEBUG" if config.debug else "INFO"
|
default_filter.level = "DEBUG" if config.debug else "INFO"
|
||||||
logger.opt(
|
logger.opt(colors=True).debug(
|
||||||
colors=True).debug(f"Loaded <y><b>Config</b></y>: {config.dict()}")
|
f"Loaded <y><b>Config</b></y>: {escape_tag(str(config.dict()))}")
|
||||||
|
|
||||||
DriverClass: Type[Driver] = getattr(
|
DriverClass: Type[Driver] = getattr(
|
||||||
importlib.import_module(config.driver), "Driver")
|
importlib.import_module(config.driver), "Driver")
|
||||||
@@ -213,5 +234,5 @@ async def _start_scheduler():
|
|||||||
|
|
||||||
|
|
||||||
from nonebot.plugin import on_message, on_notice, on_request, on_metaevent
|
from nonebot.plugin import on_message, on_notice, on_request, on_metaevent
|
||||||
from nonebot.plugin import on_startswith, on_endswith, on_command, on_regex
|
from nonebot.plugin import on_startswith, on_endswith, on_command, on_regex, CommandGroup
|
||||||
from nonebot.plugin import load_plugin, load_plugins, load_builtin_plugins, get_loaded_plugins
|
from nonebot.plugin import load_plugin, load_plugins, load_builtin_plugins, get_loaded_plugins
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
"""
|
||||||
# -*- coding: utf-8 -*-
|
协议适配基类
|
||||||
|
============
|
||||||
|
|
||||||
|
各协议请继承以下基类,并使用 ``driver.register_adapter`` 注册适配器
|
||||||
|
"""
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
from functools import reduce, partial
|
from functools import reduce, partial
|
||||||
@@ -11,6 +15,9 @@ from nonebot.typing import Any, Dict, Union, Optional, Callable, Iterable, Await
|
|||||||
|
|
||||||
|
|
||||||
class BaseBot(abc.ABC):
|
class BaseBot(abc.ABC):
|
||||||
|
"""
|
||||||
|
Bot 基类。用于处理上报消息,并提供 API 调用接口。
|
||||||
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@@ -19,12 +26,25 @@ class BaseBot(abc.ABC):
|
|||||||
config: Config,
|
config: Config,
|
||||||
self_id: str,
|
self_id: str,
|
||||||
*,
|
*,
|
||||||
websocket: WebSocket = None):
|
websocket: Optional[WebSocket] = None):
|
||||||
|
"""
|
||||||
|
:参数:
|
||||||
|
* ``driver: Driver``: Driver 对象
|
||||||
|
* ``connection_type: str``: http 或者 websocket
|
||||||
|
* ``config: Config``: Config 对象
|
||||||
|
* ``self_id: str``: 机器人 ID
|
||||||
|
* ``websocket: Optional[WebSocket]``: Websocket 连接对象
|
||||||
|
"""
|
||||||
self.driver = driver
|
self.driver = driver
|
||||||
|
"""Driver 对象"""
|
||||||
self.connection_type = connection_type
|
self.connection_type = connection_type
|
||||||
|
"""连接类型"""
|
||||||
self.config = config
|
self.config = config
|
||||||
|
"""Config 配置对象"""
|
||||||
self.self_id = self_id
|
self.self_id = self_id
|
||||||
|
"""机器人 ID"""
|
||||||
self.websocket = websocket
|
self.websocket = websocket
|
||||||
|
"""Websocket 连接对象"""
|
||||||
|
|
||||||
def __getattr__(self, name: str) -> Callable[..., Awaitable[Any]]:
|
def __getattr__(self, name: str) -> Callable[..., Awaitable[Any]]:
|
||||||
return partial(self.call_api, name)
|
return partial(self.call_api, name)
|
||||||
@@ -32,25 +52,61 @@ class BaseBot(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
|
"""Adapter 类型"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def handle_message(self, message: dict):
|
async def handle_message(self, message: dict):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
处理上报消息的函数,转换为 ``Event`` 事件后调用 ``nonebot.message.handle_event`` 进一步处理事件。
|
||||||
|
:参数:
|
||||||
|
* ``message: dict``: 收到的上报消息
|
||||||
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def call_api(self, api: str, data: dict):
|
async def call_api(self, api: str, **data):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
调用机器人 API 接口,可以通过该函数或直接通过 bot 属性进行调用
|
||||||
|
:参数:
|
||||||
|
* ``api: str``: API 名称
|
||||||
|
* ``**data``: API 数据
|
||||||
|
:示例:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
await bot.call_api("send_msg", data={"message": "hello world"})
|
||||||
|
await bot.send_msg(message="hello world")
|
||||||
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def send(self, *args, **kwargs):
|
async def send(self, event: "BaseEvent",
|
||||||
|
message: Union[str, "BaseMessage",
|
||||||
|
"BaseMessageSegment"], **kwargs):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
调用机器人基础发送消息接口
|
||||||
|
:参数:
|
||||||
|
* ``event: Event``: 上报事件
|
||||||
|
* ``message: Union[str, Message, MessageSegment]``: 要发送的消息
|
||||||
|
* ``**kwargs``
|
||||||
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
# TODO: improve event
|
|
||||||
class BaseEvent(abc.ABC):
|
class BaseEvent(abc.ABC):
|
||||||
|
"""
|
||||||
|
Event 基类。提供上报信息的关键信息,其余信息可从原始上报消息获取。
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, raw_event: dict):
|
def __init__(self, raw_event: dict):
|
||||||
|
"""
|
||||||
|
:参数:
|
||||||
|
* ``raw_event: dict``: 原始上报消息
|
||||||
|
"""
|
||||||
self._raw_event = raw_event
|
self._raw_event = raw_event
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
@@ -58,31 +114,37 @@ class BaseEvent(abc.ABC):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def raw_event(self) -> dict:
|
def raw_event(self) -> dict:
|
||||||
|
"""原始上报消息"""
|
||||||
return self._raw_event
|
return self._raw_event
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def id(self) -> int:
|
def id(self) -> int:
|
||||||
|
"""事件 ID"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
|
"""事件名称"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def self_id(self) -> str:
|
def self_id(self) -> str:
|
||||||
|
"""机器人 ID"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def time(self) -> int:
|
def time(self) -> int:
|
||||||
|
"""事件发生时间"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
|
"""事件主类型"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@type.setter
|
@type.setter
|
||||||
@@ -93,6 +155,7 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def detail_type(self) -> str:
|
def detail_type(self) -> str:
|
||||||
|
"""事件详细类型"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@detail_type.setter
|
@detail_type.setter
|
||||||
@@ -103,6 +166,7 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def sub_type(self) -> Optional[str]:
|
def sub_type(self) -> Optional[str]:
|
||||||
|
"""事件子类型"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@sub_type.setter
|
@sub_type.setter
|
||||||
@@ -113,6 +177,7 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def user_id(self) -> Optional[int]:
|
def user_id(self) -> Optional[int]:
|
||||||
|
"""触发事件的主体 ID"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@user_id.setter
|
@user_id.setter
|
||||||
@@ -123,6 +188,7 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def group_id(self) -> Optional[int]:
|
def group_id(self) -> Optional[int]:
|
||||||
|
"""触发事件的主体群 ID"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@group_id.setter
|
@group_id.setter
|
||||||
@@ -133,6 +199,7 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def to_me(self) -> Optional[bool]:
|
def to_me(self) -> Optional[bool]:
|
||||||
|
"""事件是否为发送给机器人的消息"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@to_me.setter
|
@to_me.setter
|
||||||
@@ -143,6 +210,7 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def message(self) -> Optional[Message]:
|
def message(self) -> Optional[Message]:
|
||||||
|
"""消息内容"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@message.setter
|
@message.setter
|
||||||
@@ -153,6 +221,7 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def reply(self) -> Optional[dict]:
|
def reply(self) -> Optional[dict]:
|
||||||
|
"""回复的消息"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@reply.setter
|
@reply.setter
|
||||||
@@ -163,6 +232,7 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def raw_message(self) -> Optional[str]:
|
def raw_message(self) -> Optional[str]:
|
||||||
|
"""原始消息"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@raw_message.setter
|
@raw_message.setter
|
||||||
@@ -173,11 +243,13 @@ class BaseEvent(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def plain_text(self) -> Optional[str]:
|
def plain_text(self) -> Optional[str]:
|
||||||
|
"""纯文本消息"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def sender(self) -> Optional[dict]:
|
def sender(self) -> Optional[dict]:
|
||||||
|
"""消息发送者信息"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@sender.setter
|
@sender.setter
|
||||||
@@ -188,8 +260,17 @@ class BaseEvent(abc.ABC):
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class BaseMessageSegment(abc.ABC):
|
class BaseMessageSegment(abc.ABC):
|
||||||
|
"""消息段基类"""
|
||||||
type: str
|
type: str
|
||||||
data: Dict[str, Union[str, list]] = field(default_factory=lambda: {})
|
"""
|
||||||
|
- 类型: ``str``
|
||||||
|
- 说明: 消息段类型
|
||||||
|
"""
|
||||||
|
data: Dict[str, Any] = field(default_factory=lambda: {})
|
||||||
|
"""
|
||||||
|
- 类型: ``Dict[str, Union[str, list]]``
|
||||||
|
- 说明: 消息段数据
|
||||||
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@@ -199,14 +280,33 @@ class BaseMessageSegment(abc.ABC):
|
|||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return getattr(self, key)
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
return setattr(self, key, value)
|
||||||
|
|
||||||
|
def get(self, key, default=None):
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@abc.abstractmethod
|
||||||
|
def text(cls, text: str) -> "BaseMessageSegment":
|
||||||
|
return cls("text", {"text": text})
|
||||||
|
|
||||||
|
|
||||||
class BaseMessage(list, abc.ABC):
|
class BaseMessage(list, abc.ABC):
|
||||||
|
"""消息数组"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
message: Union[str, dict, list, BaseMessageSegment,
|
message: Union[str, dict, list, BaseMessageSegment,
|
||||||
"BaseMessage"] = None,
|
"BaseMessage"] = None,
|
||||||
*args,
|
*args,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
"""
|
||||||
|
:参数:
|
||||||
|
* ``message: Union[str, dict, list, MessageSegment, Message]``: 消息内容
|
||||||
|
"""
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
if isinstance(message, (str, dict, list)):
|
if isinstance(message, (str, dict, list)):
|
||||||
self.extend(self._construct(message))
|
self.extend(self._construct(message))
|
||||||
@@ -240,6 +340,12 @@ class BaseMessage(list, abc.ABC):
|
|||||||
return result.__add__(self)
|
return result.__add__(self)
|
||||||
|
|
||||||
def append(self, obj: Union[str, BaseMessageSegment]) -> "BaseMessage":
|
def append(self, obj: Union[str, BaseMessageSegment]) -> "BaseMessage":
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
添加一个消息段到消息数组末尾
|
||||||
|
:参数:
|
||||||
|
* ``obj: Union[str, MessageSegment]``: 要添加的消息段
|
||||||
|
"""
|
||||||
if isinstance(obj, BaseMessageSegment):
|
if isinstance(obj, BaseMessageSegment):
|
||||||
if obj.type == "text" and self and self[-1].type == "text":
|
if obj.type == "text" and self and self[-1].type == "text":
|
||||||
self[-1].data["text"] += obj.data["text"]
|
self[-1].data["text"] += obj.data["text"]
|
||||||
@@ -254,11 +360,21 @@ class BaseMessage(list, abc.ABC):
|
|||||||
def extend(
|
def extend(
|
||||||
self, obj: Union["BaseMessage",
|
self, obj: Union["BaseMessage",
|
||||||
Iterable[BaseMessageSegment]]) -> "BaseMessage":
|
Iterable[BaseMessageSegment]]) -> "BaseMessage":
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
拼接一个消息数组或多个消息段到消息数组末尾
|
||||||
|
:参数:
|
||||||
|
* ``obj: Union[Message, Iterable[MessageSegment]]``: 要添加的消息数组
|
||||||
|
"""
|
||||||
for segment in obj:
|
for segment in obj:
|
||||||
self.append(segment)
|
self.append(segment)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def reduce(self) -> None:
|
def reduce(self) -> None:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
缩减消息数组,即拼接相邻纯文本消息段
|
||||||
|
"""
|
||||||
index = 0
|
index = 0
|
||||||
while index < len(self):
|
while index < len(self):
|
||||||
if index > 0 and self[
|
if index > 0 and self[
|
||||||
@@ -269,8 +385,13 @@ class BaseMessage(list, abc.ABC):
|
|||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
def extract_plain_text(self) -> str:
|
def extract_plain_text(self) -> str:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
提取消息内纯文本消息
|
||||||
|
"""
|
||||||
|
|
||||||
def _concat(x: str, y: BaseMessageSegment) -> str:
|
def _concat(x: str, y: BaseMessageSegment) -> str:
|
||||||
return f"{x} {y.data['text']}" if y.type == "text" else x
|
return f"{x} {y.data['text']}" if y.type == "text" else x
|
||||||
|
|
||||||
return reduce(_concat, self, "")
|
plain_text = reduce(_concat, self, "")
|
||||||
|
return plain_text[1:] if plain_text else plain_text
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
CQHTTP (OneBot) v11 协议适配
|
CQHTTP (OneBot) v11 协议适配
|
||||||
============================
|
============================
|
||||||
@@ -28,14 +26,29 @@ from nonebot.adapters import BaseBot, BaseEvent, BaseMessage, BaseMessageSegment
|
|||||||
|
|
||||||
|
|
||||||
def log(level: str, message: str):
|
def log(level: str, message: str):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
用于打印 CQHTTP 日志。
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``level: str``: 日志等级
|
||||||
|
* ``message: str``: 日志信息
|
||||||
|
"""
|
||||||
return logger.opt(colors=True).log(level, "<m>CQHTTP</m> | " + message)
|
return logger.opt(colors=True).log(level, "<m>CQHTTP</m> | " + message)
|
||||||
|
|
||||||
|
|
||||||
def escape(s: str, *, escape_comma: bool = True) -> str:
|
def escape(s: str, *, escape_comma: bool = True) -> str:
|
||||||
"""
|
"""
|
||||||
对字符串进行 CQ 码转义。
|
:说明:
|
||||||
|
|
||||||
``escape_comma`` 参数控制是否转义逗号(``,``)。
|
对字符串进行 CQ 码转义。
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``s: str``: 需要转义的字符串
|
||||||
|
* ``escape_comma: bool``: 是否转义逗号(``,``)。
|
||||||
"""
|
"""
|
||||||
s = s.replace("&", "&") \
|
s = s.replace("&", "&") \
|
||||||
.replace("[", "[") \
|
.replace("[", "[") \
|
||||||
@@ -46,7 +59,15 @@ def escape(s: str, *, escape_comma: bool = True) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def unescape(s: str) -> str:
|
def unescape(s: str) -> str:
|
||||||
"""对字符串进行 CQ 码去转义。"""
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
对字符串进行 CQ 码去转义。
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``s: str``: 需要转义的字符串
|
||||||
|
"""
|
||||||
return s.replace(",", ",") \
|
return s.replace(",", ",") \
|
||||||
.replace("[", "[") \
|
.replace("[", "[") \
|
||||||
.replace("]", "]") \
|
.replace("]", "]") \
|
||||||
@@ -54,10 +75,21 @@ def unescape(s: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _b2s(b: Optional[bool]) -> Optional[str]:
|
def _b2s(b: Optional[bool]) -> Optional[str]:
|
||||||
|
"""转换布尔值为字符串。"""
|
||||||
return b if b is None else str(b).lower()
|
return b if b is None else str(b).lower()
|
||||||
|
|
||||||
|
|
||||||
async def _check_reply(bot: "Bot", event: "Event"):
|
async def _check_reply(bot: "Bot", event: "Event"):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
检查消息中存在的回复,去除并赋值 ``event.reply``, ``event.to_me``
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``bot: Bot``: Bot 对象
|
||||||
|
* ``event: Event``: Event 对象
|
||||||
|
"""
|
||||||
if event.type != "message":
|
if event.type != "message":
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -74,6 +106,16 @@ async def _check_reply(bot: "Bot", event: "Event"):
|
|||||||
|
|
||||||
|
|
||||||
def _check_at_me(bot: "Bot", event: "Event"):
|
def _check_at_me(bot: "Bot", event: "Event"):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
检查消息开头或结尾是否存在 @机器人,去除并赋值 ``event.to_me``
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``bot: Bot``: Bot 对象
|
||||||
|
* ``event: Event``: Event 对象
|
||||||
|
"""
|
||||||
if event.type != "message":
|
if event.type != "message":
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -119,6 +161,16 @@ def _check_at_me(bot: "Bot", event: "Event"):
|
|||||||
|
|
||||||
|
|
||||||
def _check_nickname(bot: "Bot", event: "Event"):
|
def _check_nickname(bot: "Bot", event: "Event"):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
检查消息开头是否存在,去除并赋值 ``event.to_me``
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``bot: Bot``: Bot 对象
|
||||||
|
* ``event: Event``: Event 对象
|
||||||
|
"""
|
||||||
if event.type != "message":
|
if event.type != "message":
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -128,13 +180,13 @@ def _check_nickname(bot: "Bot", event: "Event"):
|
|||||||
|
|
||||||
first_text = first_msg_seg.data["text"]
|
first_text = first_msg_seg.data["text"]
|
||||||
|
|
||||||
if bot.config.NICKNAME:
|
if bot.config.nickname:
|
||||||
# check if the user is calling me with my nickname
|
# check if the user is calling me with my nickname
|
||||||
if isinstance(bot.config.NICKNAME, str) or \
|
if isinstance(bot.config.nickname, str) or \
|
||||||
not isinstance(bot.config.NICKNAME, Iterable):
|
not isinstance(bot.config.nickname, Iterable):
|
||||||
nicknames = (bot.config.NICKNAME,)
|
nicknames = (bot.config.nickname,)
|
||||||
else:
|
else:
|
||||||
nicknames = filter(lambda n: n, bot.config.NICKNAME)
|
nicknames = filter(lambda n: n, bot.config.nickname)
|
||||||
nickname_regex = "|".join(nicknames)
|
nickname_regex = "|".join(nicknames)
|
||||||
m = re.search(rf"^({nickname_regex})([\s,,]*|$)", first_text,
|
m = re.search(rf"^({nickname_regex})([\s,,]*|$)", first_text,
|
||||||
re.IGNORECASE)
|
re.IGNORECASE)
|
||||||
@@ -145,7 +197,25 @@ def _check_nickname(bot: "Bot", event: "Event"):
|
|||||||
first_msg_seg.data["text"] = first_text[m.end():]
|
first_msg_seg.data["text"] = first_text[m.end():]
|
||||||
|
|
||||||
|
|
||||||
def _handle_api_result(result: Optional[Dict[str, Any]]) -> Any:
|
def _handle_api_result(
|
||||||
|
result: Optional[Dict[str, Any]]) -> Union[Any, NoReturn]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
处理 API 请求返回值。
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``result: Optional[Dict[str, Any]]``: API 返回数据
|
||||||
|
|
||||||
|
:返回:
|
||||||
|
|
||||||
|
- ``Any``: API 调用返回数据
|
||||||
|
|
||||||
|
:异常:
|
||||||
|
|
||||||
|
- ``ActionFailed``: API 调用失败
|
||||||
|
"""
|
||||||
if isinstance(result, dict):
|
if isinstance(result, dict):
|
||||||
if result.get("status") == "failed":
|
if result.get("status") == "failed":
|
||||||
raise ActionFailed(retcode=result.get("retcode"))
|
raise ActionFailed(retcode=result.get("retcode"))
|
||||||
@@ -183,6 +253,9 @@ class ResultStore:
|
|||||||
|
|
||||||
|
|
||||||
class Bot(BaseBot):
|
class Bot(BaseBot):
|
||||||
|
"""
|
||||||
|
CQHTTP 协议 Bot 适配。继承属性参考 `BaseBot <./#class-basebot>`_ 。
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
driver: Driver,
|
driver: Driver,
|
||||||
@@ -190,7 +263,7 @@ class Bot(BaseBot):
|
|||||||
config: Config,
|
config: Config,
|
||||||
self_id: str,
|
self_id: str,
|
||||||
*,
|
*,
|
||||||
websocket: WebSocket = None):
|
websocket: Optional[WebSocket] = None):
|
||||||
if connection_type not in ["http", "websocket"]:
|
if connection_type not in ["http", "websocket"]:
|
||||||
raise ValueError("Unsupported connection type")
|
raise ValueError("Unsupported connection type")
|
||||||
|
|
||||||
@@ -203,10 +276,18 @@ class Bot(BaseBot):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseBot)
|
@overrides(BaseBot)
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
|
"""
|
||||||
|
- 返回: ``"cqhttp"``
|
||||||
|
"""
|
||||||
return "cqhttp"
|
return "cqhttp"
|
||||||
|
|
||||||
@overrides(BaseBot)
|
@overrides(BaseBot)
|
||||||
async def handle_message(self, message: dict):
|
async def handle_message(self, message: dict):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
调用 `_check_reply <#async-check-reply-bot-event>`_, `_check_at_me <#check-at-me-bot-event>`_, `_check_nickname <#check-nickname-bot-event>`_ 处理事件并转换为 `Event <#class-event>`_
|
||||||
|
"""
|
||||||
if not message:
|
if not message:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -230,6 +311,25 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
@overrides(BaseBot)
|
@overrides(BaseBot)
|
||||||
async def call_api(self, api: str, **data) -> Union[Any, NoReturn]:
|
async def call_api(self, api: str, **data) -> Union[Any, NoReturn]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
调用 CQHTTP 协议 API
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``api: str``: API 名称
|
||||||
|
* ``**data: Any``: API 参数
|
||||||
|
|
||||||
|
:返回:
|
||||||
|
|
||||||
|
- ``Any``: API 调用返回数据
|
||||||
|
|
||||||
|
:异常:
|
||||||
|
|
||||||
|
- ``NetworkError``: 网络错误
|
||||||
|
- ``ActionFailed``: API 调用失败
|
||||||
|
"""
|
||||||
if "self_id" in data:
|
if "self_id" in data:
|
||||||
self_id = data.pop("self_id")
|
self_id = data.pop("self_id")
|
||||||
if self_id:
|
if self_id:
|
||||||
@@ -278,12 +378,36 @@ class Bot(BaseBot):
|
|||||||
raise NetworkError("HTTP request failed")
|
raise NetworkError("HTTP request failed")
|
||||||
|
|
||||||
@overrides(BaseBot)
|
@overrides(BaseBot)
|
||||||
async def send(self, event: "Event", message: Union[str, "Message",
|
async def send(self,
|
||||||
"MessageSegment"],
|
event: "Event",
|
||||||
|
message: Union[str, "Message", "MessageSegment"],
|
||||||
|
at_sender: bool = False,
|
||||||
**kwargs) -> Union[Any, NoReturn]:
|
**kwargs) -> Union[Any, NoReturn]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
根据 ``event`` 向触发事件的主体发送消息。
|
||||||
|
|
||||||
|
:参数:
|
||||||
|
|
||||||
|
* ``event: Event``: Event 对象
|
||||||
|
* ``message: Union[str, Message, MessageSegment]``: 要发送的消息
|
||||||
|
* ``at_sender: bool``: 是否 @ 事件主体
|
||||||
|
* ``**kwargs``: 覆盖默认参数
|
||||||
|
|
||||||
|
:返回:
|
||||||
|
|
||||||
|
- ``Any``: API 调用返回数据
|
||||||
|
|
||||||
|
:异常:
|
||||||
|
|
||||||
|
- ``ValueError``: 缺少 ``user_id``, ``group_id``
|
||||||
|
- ``NetworkError``: 网络错误
|
||||||
|
- ``ActionFailed``: API 调用失败
|
||||||
|
"""
|
||||||
msg = message if isinstance(message, Message) else Message(message)
|
msg = message if isinstance(message, Message) else Message(message)
|
||||||
|
|
||||||
at_sender = kwargs.pop("at_sender", False) and bool(event.user_id)
|
at_sender = at_sender and bool(event.user_id)
|
||||||
|
|
||||||
params = {}
|
params = {}
|
||||||
if event.user_id:
|
if event.user_id:
|
||||||
@@ -309,6 +433,9 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
|
|
||||||
class Event(BaseEvent):
|
class Event(BaseEvent):
|
||||||
|
"""
|
||||||
|
CQHTTP 协议 Event 适配。继承属性参考 `BaseEvent <./#class-baseevent>`_ 。
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, raw_event: dict):
|
def __init__(self, raw_event: dict):
|
||||||
if "message" in raw_event:
|
if "message" in raw_event:
|
||||||
@@ -319,11 +446,19 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def id(self) -> Optional[int]:
|
def id(self) -> Optional[int]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[int]``
|
||||||
|
- 说明: 事件/消息 ID
|
||||||
|
"""
|
||||||
return self._raw_event.get("message_id") or self._raw_event.get("flag")
|
return self._raw_event.get("message_id") or self._raw_event.get("flag")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
|
"""
|
||||||
|
- 类型: ``str``
|
||||||
|
- 说明: 事件名称,由类型与 ``.`` 组合而成
|
||||||
|
"""
|
||||||
n = self.type + "." + self.detail_type
|
n = self.type + "." + self.detail_type
|
||||||
if self.sub_type:
|
if self.sub_type:
|
||||||
n += "." + self.sub_type
|
n += "." + self.sub_type
|
||||||
@@ -332,16 +467,28 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def self_id(self) -> str:
|
def self_id(self) -> str:
|
||||||
|
"""
|
||||||
|
- 类型: ``str``
|
||||||
|
- 说明: 机器人自身 ID
|
||||||
|
"""
|
||||||
return str(self._raw_event["self_id"])
|
return str(self._raw_event["self_id"])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def time(self) -> int:
|
def time(self) -> int:
|
||||||
|
"""
|
||||||
|
- 类型: ``int``
|
||||||
|
- 说明: 事件发生时间
|
||||||
|
"""
|
||||||
return self._raw_event["time"]
|
return self._raw_event["time"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
|
"""
|
||||||
|
- 类型: ``str``
|
||||||
|
- 说明: 事件类型
|
||||||
|
"""
|
||||||
return self._raw_event["post_type"]
|
return self._raw_event["post_type"]
|
||||||
|
|
||||||
@type.setter
|
@type.setter
|
||||||
@@ -352,6 +499,10 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def detail_type(self) -> str:
|
def detail_type(self) -> str:
|
||||||
|
"""
|
||||||
|
- 类型: ``str``
|
||||||
|
- 说明: 事件详细类型
|
||||||
|
"""
|
||||||
return self._raw_event[f"{self.type}_type"]
|
return self._raw_event[f"{self.type}_type"]
|
||||||
|
|
||||||
@detail_type.setter
|
@detail_type.setter
|
||||||
@@ -362,9 +513,13 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def sub_type(self) -> Optional[str]:
|
def sub_type(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[str]``
|
||||||
|
- 说明: 事件子类型
|
||||||
|
"""
|
||||||
return self._raw_event.get("sub_type")
|
return self._raw_event.get("sub_type")
|
||||||
|
|
||||||
@type.setter
|
@sub_type.setter
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def sub_type(self, value) -> None:
|
def sub_type(self, value) -> None:
|
||||||
self._raw_event["sub_type"] = value
|
self._raw_event["sub_type"] = value
|
||||||
@@ -372,6 +527,10 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def user_id(self) -> Optional[int]:
|
def user_id(self) -> Optional[int]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[int]``
|
||||||
|
- 说明: 事件主体 ID
|
||||||
|
"""
|
||||||
return self._raw_event.get("user_id")
|
return self._raw_event.get("user_id")
|
||||||
|
|
||||||
@user_id.setter
|
@user_id.setter
|
||||||
@@ -382,6 +541,10 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def group_id(self) -> Optional[int]:
|
def group_id(self) -> Optional[int]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[int]``
|
||||||
|
- 说明: 事件主体群 ID
|
||||||
|
"""
|
||||||
return self._raw_event.get("group_id")
|
return self._raw_event.get("group_id")
|
||||||
|
|
||||||
@group_id.setter
|
@group_id.setter
|
||||||
@@ -392,6 +555,10 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def to_me(self) -> Optional[bool]:
|
def to_me(self) -> Optional[bool]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[bool]``
|
||||||
|
- 说明: 消息是否与机器人相关
|
||||||
|
"""
|
||||||
return self._raw_event.get("to_me")
|
return self._raw_event.get("to_me")
|
||||||
|
|
||||||
@to_me.setter
|
@to_me.setter
|
||||||
@@ -402,6 +569,10 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def message(self) -> Optional["Message"]:
|
def message(self) -> Optional["Message"]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[Message]``
|
||||||
|
- 说明: 消息内容
|
||||||
|
"""
|
||||||
return self._raw_event.get("message")
|
return self._raw_event.get("message")
|
||||||
|
|
||||||
@message.setter
|
@message.setter
|
||||||
@@ -412,6 +583,10 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def reply(self) -> Optional[dict]:
|
def reply(self) -> Optional[dict]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[dict]``
|
||||||
|
- 说明: 回复消息详情
|
||||||
|
"""
|
||||||
return self._raw_event.get("reply")
|
return self._raw_event.get("reply")
|
||||||
|
|
||||||
@reply.setter
|
@reply.setter
|
||||||
@@ -422,6 +597,10 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def raw_message(self) -> Optional[str]:
|
def raw_message(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[str]``
|
||||||
|
- 说明: 原始消息
|
||||||
|
"""
|
||||||
return self._raw_event.get("raw_message")
|
return self._raw_event.get("raw_message")
|
||||||
|
|
||||||
@raw_message.setter
|
@raw_message.setter
|
||||||
@@ -432,11 +611,19 @@ class Event(BaseEvent):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def plain_text(self) -> Optional[str]:
|
def plain_text(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[str]``
|
||||||
|
- 说明: 纯文本消息内容
|
||||||
|
"""
|
||||||
return self.message and self.message.extract_plain_text()
|
return self.message and self.message.extract_plain_text()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(BaseEvent)
|
@overrides(BaseEvent)
|
||||||
def sender(self) -> Optional[dict]:
|
def sender(self) -> Optional[dict]:
|
||||||
|
"""
|
||||||
|
- 类型: ``Optional[dict]``
|
||||||
|
- 说明: 消息发送者信息
|
||||||
|
"""
|
||||||
return self._raw_event.get("sender")
|
return self._raw_event.get("sender")
|
||||||
|
|
||||||
@sender.setter
|
@sender.setter
|
||||||
@@ -446,11 +633,14 @@ class Event(BaseEvent):
|
|||||||
|
|
||||||
|
|
||||||
class MessageSegment(BaseMessageSegment):
|
class MessageSegment(BaseMessageSegment):
|
||||||
|
"""
|
||||||
|
CQHTTP 协议 MessageSegment 适配。具体方法参考协议消息段类型或源码。
|
||||||
|
"""
|
||||||
|
|
||||||
@overrides(BaseMessageSegment)
|
@overrides(BaseMessageSegment)
|
||||||
def __init__(self, type: str, data: Dict[str, Union[str, list]]) -> None:
|
def __init__(self, type: str, data: Dict[str, Any]) -> None:
|
||||||
if type == "text":
|
if type == "text":
|
||||||
data["text"] = unescape(data["text"]) # type: ignore
|
data["text"] = unescape(data["text"])
|
||||||
super().__init__(type=type, data=data)
|
super().__init__(type=type, data=data)
|
||||||
|
|
||||||
@overrides(BaseMessageSegment)
|
@overrides(BaseMessageSegment)
|
||||||
@@ -624,6 +814,9 @@ class MessageSegment(BaseMessageSegment):
|
|||||||
|
|
||||||
|
|
||||||
class Message(BaseMessage):
|
class Message(BaseMessage):
|
||||||
|
"""
|
||||||
|
CQHTTP 协议 Message 适配。
|
||||||
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@overrides(BaseMessage)
|
@overrides(BaseMessage)
|
||||||
|
@@ -1,15 +1,91 @@
|
|||||||
from nonebot.adapters import BaseBot
|
import asyncio
|
||||||
from nonebot.typing import Any, Dict, List, Union, Message, Optional
|
|
||||||
|
from nonebot.config import Config
|
||||||
|
from nonebot.adapters import BaseBot, BaseEvent, BaseMessage, BaseMessageSegment
|
||||||
|
from nonebot.typing import Any, Dict, List, Union, Driver, Optional, NoReturn, WebSocket, Iterable
|
||||||
|
|
||||||
|
|
||||||
|
def log(level: str, message: str):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def escape(s: str, *, escape_comma: bool = ...) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def unescape(s: str) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def _b2s(b: Optional[bool]) -> Optional[str]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
async def _check_reply(bot: "Bot", event: "Event"):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def _check_at_me(bot: "Bot", event: "Event"):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def _check_nickname(bot: "Bot", event: "Event"):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_api_result(
|
||||||
|
result: Optional[Dict[str, Any]]) -> Union[Any, NoReturn]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class ResultStore:
|
||||||
|
_seq: int = ...
|
||||||
|
_futures: Dict[int, asyncio.Future] = ...
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_seq(cls) -> int:
|
||||||
|
...
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_result(cls, result: Dict[str, Any]):
|
||||||
|
...
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def fetch(cls, seq: int, timeout: Optional[float]) -> Dict[str, Any]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
class Bot(BaseBot):
|
class Bot(BaseBot):
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
driver: Driver,
|
||||||
|
connection_type: str,
|
||||||
|
config: Config,
|
||||||
|
self_id: str,
|
||||||
|
*,
|
||||||
|
websocket: WebSocket = None):
|
||||||
|
...
|
||||||
|
|
||||||
|
def type(self) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
async def handle_message(self, message: dict):
|
||||||
|
...
|
||||||
|
|
||||||
|
async def call_api(self, api: str, **data) -> Union[Any, NoReturn]:
|
||||||
|
...
|
||||||
|
|
||||||
|
async def send(self, event: "Event", message: Union[str, "Message",
|
||||||
|
"MessageSegment"],
|
||||||
|
**kwargs) -> Union[Any, NoReturn]:
|
||||||
|
...
|
||||||
|
|
||||||
async def send_private_msg(self,
|
async def send_private_msg(self,
|
||||||
*,
|
*,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
message: Union[str, Message],
|
message: Union[str, Message],
|
||||||
auto_escape: bool = False,
|
auto_escape: bool = ...,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -28,8 +104,8 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
message: Union[str, Message],
|
message: Union[str, Message],
|
||||||
auto_escape: bool = False,
|
auto_escape: bool = ...,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -46,12 +122,12 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def send_msg(self,
|
async def send_msg(self,
|
||||||
*,
|
*,
|
||||||
message_type: Optional[str] = None,
|
message_type: Optional[str] = ...,
|
||||||
user_id: Optional[int] = None,
|
user_id: Optional[int] = ...,
|
||||||
group_id: Optional[int] = None,
|
group_id: Optional[int] = ...,
|
||||||
message: Union[str, Message],
|
message: Union[str, Message],
|
||||||
auto_escape: bool = False,
|
auto_escape: bool = ...,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -71,7 +147,7 @@ class Bot(BaseBot):
|
|||||||
async def delete_msg(self,
|
async def delete_msg(self,
|
||||||
*,
|
*,
|
||||||
message_id: int,
|
message_id: int,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -87,7 +163,7 @@ class Bot(BaseBot):
|
|||||||
async def get_msg(self,
|
async def get_msg(self,
|
||||||
*,
|
*,
|
||||||
message_id: int,
|
message_id: int,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -103,7 +179,7 @@ class Bot(BaseBot):
|
|||||||
async def get_forward_msg(self,
|
async def get_forward_msg(self,
|
||||||
*,
|
*,
|
||||||
id: int,
|
id: int,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -119,8 +195,8 @@ class Bot(BaseBot):
|
|||||||
async def send_like(self,
|
async def send_like(self,
|
||||||
*,
|
*,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
times: int = 1,
|
times: int = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -138,8 +214,8 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
reject_add_request: bool = False,
|
reject_add_request: bool = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -158,8 +234,8 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
duration: int = 30 * 60,
|
duration: int = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -177,11 +253,10 @@ class Bot(BaseBot):
|
|||||||
async def set_group_anonymous_ban(self,
|
async def set_group_anonymous_ban(self,
|
||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
anonymous: Optional[Dict[str,
|
anonymous: Optional[Dict[str, Any]] = ...,
|
||||||
Any]] = None,
|
anonymous_flag: Optional[str] = ...,
|
||||||
anonymous_flag: Optional[str] = None,
|
duration: int = ...,
|
||||||
duration: int = 30 * 60,
|
self_id: Optional[int] = ...) -> None:
|
||||||
self_id: Optional[int] = None) -> None:
|
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -200,8 +275,8 @@ class Bot(BaseBot):
|
|||||||
async def set_group_whole_ban(self,
|
async def set_group_whole_ban(self,
|
||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
enable: bool = True,
|
enable: bool = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -219,8 +294,8 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
enable: bool = True,
|
enable: bool = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -238,8 +313,8 @@ class Bot(BaseBot):
|
|||||||
async def set_group_anonymous(self,
|
async def set_group_anonymous(self,
|
||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
enable: bool = True,
|
enable: bool = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -257,8 +332,8 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
card: str = "",
|
card: str = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -277,7 +352,7 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
group_name: str,
|
group_name: str,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -294,8 +369,8 @@ class Bot(BaseBot):
|
|||||||
async def set_group_leave(self,
|
async def set_group_leave(self,
|
||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
is_dismiss: bool = False,
|
is_dismiss: bool = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -313,9 +388,9 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
special_title: str = "",
|
special_title: str = ...,
|
||||||
duration: int = -1,
|
duration: int = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -334,9 +409,9 @@ class Bot(BaseBot):
|
|||||||
async def set_friend_add_request(self,
|
async def set_friend_add_request(self,
|
||||||
*,
|
*,
|
||||||
flag: str,
|
flag: str,
|
||||||
approve: bool = True,
|
approve: bool = ...,
|
||||||
remark: str = "",
|
remark: str = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -355,9 +430,9 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
flag: str,
|
flag: str,
|
||||||
sub_type: str,
|
sub_type: str,
|
||||||
approve: bool = True,
|
approve: bool = ...,
|
||||||
reason: str = "",
|
reason: str = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -375,7 +450,7 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def get_login_info(self,
|
async def get_login_info(self,
|
||||||
*,
|
*,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -387,12 +462,11 @@ class Bot(BaseBot):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
async def get_stranger_info(
|
async def get_stranger_info(self,
|
||||||
self,
|
*,
|
||||||
*,
|
user_id: int,
|
||||||
user_id: int,
|
no_cache: bool = ...,
|
||||||
no_cache: bool = False,
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -408,7 +482,7 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def get_friend_list(self,
|
async def get_friend_list(self,
|
||||||
*,
|
*,
|
||||||
self_id: Optional[int] = None
|
self_id: Optional[int] = ...
|
||||||
) -> List[Dict[str, Any]]:
|
) -> List[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@@ -424,8 +498,8 @@ class Bot(BaseBot):
|
|||||||
async def get_group_info(self,
|
async def get_group_info(self,
|
||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
no_cache: bool = False,
|
no_cache: bool = ...,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -441,7 +515,7 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def get_group_list(self,
|
async def get_group_list(self,
|
||||||
*,
|
*,
|
||||||
self_id: Optional[int] = None
|
self_id: Optional[int] = ...
|
||||||
) -> List[Dict[str, Any]]:
|
) -> List[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
@@ -459,8 +533,8 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
no_cache: bool = False,
|
no_cache: bool = ...,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -479,7 +553,7 @@ class Bot(BaseBot):
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
group_id: int,
|
group_id: int,
|
||||||
self_id: Optional[int] = None) -> List[Dict[str, Any]]:
|
self_id: Optional[int] = ...) -> List[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -492,12 +566,12 @@ class Bot(BaseBot):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
async def get_group_honor_info(
|
async def get_group_honor_info(self,
|
||||||
self,
|
*,
|
||||||
*,
|
group_id: int,
|
||||||
group_id: int,
|
type: str = ...,
|
||||||
type: str = "all",
|
self_id: Optional[int] = ...
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -513,8 +587,8 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def get_cookies(self,
|
async def get_cookies(self,
|
||||||
*,
|
*,
|
||||||
domain: str = "",
|
domain: str = ...,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -529,7 +603,7 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def get_csrf_token(self,
|
async def get_csrf_token(self,
|
||||||
*,
|
*,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -543,8 +617,8 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def get_credentials(self,
|
async def get_credentials(self,
|
||||||
*,
|
*,
|
||||||
domain: str = "",
|
domain: str = ...,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -561,7 +635,7 @@ class Bot(BaseBot):
|
|||||||
*,
|
*,
|
||||||
file: str,
|
file: str,
|
||||||
out_format: str,
|
out_format: str,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -578,7 +652,7 @@ class Bot(BaseBot):
|
|||||||
async def get_image(self,
|
async def get_image(self,
|
||||||
*,
|
*,
|
||||||
file: str,
|
file: str,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -593,7 +667,7 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def can_send_image(self,
|
async def can_send_image(self,
|
||||||
*,
|
*,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -607,7 +681,7 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def can_send_record(self,
|
async def can_send_record(self,
|
||||||
*,
|
*,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -621,7 +695,7 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def get_status(self,
|
async def get_status(self,
|
||||||
*,
|
*,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -635,7 +709,7 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def get_version_info(self,
|
async def get_version_info(self,
|
||||||
*,
|
*,
|
||||||
self_id: Optional[int] = None) -> Dict[str, Any]:
|
self_id: Optional[int] = ...) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -649,8 +723,8 @@ class Bot(BaseBot):
|
|||||||
|
|
||||||
async def set_restart(self,
|
async def set_restart(self,
|
||||||
*,
|
*,
|
||||||
delay: int = 0,
|
delay: int = ...,
|
||||||
self_id: Optional[int] = None) -> None:
|
self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -663,7 +737,7 @@ class Bot(BaseBot):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
async def clean_cache(self, *, self_id: Optional[int] = None) -> None:
|
async def clean_cache(self, *, self_id: Optional[int] = ...) -> None:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
|
||||||
@@ -674,3 +748,242 @@ class Bot(BaseBot):
|
|||||||
* ``self_id``: 机器人 QQ 号
|
* ``self_id``: 机器人 QQ 号
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class Event(BaseEvent):
|
||||||
|
|
||||||
|
def __init__(self, raw_event: dict):
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self) -> Optional[int]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def self_id(self) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def time(self) -> int:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
@type.setter
|
||||||
|
def type(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def detail_type(self) -> str:
|
||||||
|
...
|
||||||
|
|
||||||
|
@detail_type.setter
|
||||||
|
def detail_type(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sub_type(self) -> Optional[str]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@sub_type.setter
|
||||||
|
def sub_type(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user_id(self) -> Optional[int]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@user_id.setter
|
||||||
|
def user_id(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def group_id(self) -> Optional[int]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@group_id.setter
|
||||||
|
def group_id(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def to_me(self) -> Optional[bool]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@to_me.setter
|
||||||
|
def to_me(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def message(self) -> Optional["Message"]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@message.setter
|
||||||
|
def message(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def reply(self) -> Optional[dict]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@reply.setter
|
||||||
|
def reply(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def raw_message(self) -> Optional[str]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@raw_message.setter
|
||||||
|
def raw_message(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def plain_text(self) -> Optional[str]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sender(self) -> Optional[dict]:
|
||||||
|
...
|
||||||
|
|
||||||
|
@sender.setter
|
||||||
|
def sender(self, value) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class MessageSegment(BaseMessageSegment):
|
||||||
|
|
||||||
|
def __init__(self, type: str, data: Dict[str, Any]) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
...
|
||||||
|
|
||||||
|
def __add__(self, other) -> "Message":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def anonymous(ignore_failure: Optional[bool] = ...) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def at(user_id: Union[int, str]) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def contact_group(group_id: int) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def contact_user(user_id: int) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dice() -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def face(id_: int) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def forward(id_: str) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def image(file: str,
|
||||||
|
type_: Optional[str] = ...,
|
||||||
|
cache: bool = ...,
|
||||||
|
proxy: bool = ...,
|
||||||
|
timeout: Optional[int] = ...) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def json(data: str) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def location(latitude: float,
|
||||||
|
longitude: float,
|
||||||
|
title: Optional[str] = ...,
|
||||||
|
content: Optional[str] = ...) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def music(type_: str, id_: int) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def music_custom(url: str,
|
||||||
|
audio: str,
|
||||||
|
title: str,
|
||||||
|
content: Optional[str] = ...,
|
||||||
|
img_url: Optional[str] = ...) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def node(id_: int) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def node_custom(user_id: int, nickname: str,
|
||||||
|
content: Union[str, "Message"]) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def poke(type_: str, id_: str) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def record(file: str,
|
||||||
|
magic: Optional[bool] = ...,
|
||||||
|
cache: Optional[bool] = ...,
|
||||||
|
proxy: Optional[bool] = ...,
|
||||||
|
timeout: Optional[int] = ...) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def reply(id_: int) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def rps() -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def shake() -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def share(url: str = ...,
|
||||||
|
title: str = ...,
|
||||||
|
content: Optional[str] = ...,
|
||||||
|
img_url: Optional[str] = ...) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def text(text: str) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def video(file: str,
|
||||||
|
cache: Optional[bool] = ...,
|
||||||
|
proxy: Optional[bool] = ...,
|
||||||
|
timeout: Optional[int] = ...) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def xml(data: str) -> "MessageSegment":
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class Message(BaseMessage):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _construct(msg: Union[str, dict, list]) -> Iterable[MessageSegment]:
|
||||||
|
...
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
配置
|
配置
|
||||||
====
|
====
|
||||||
@@ -211,10 +209,10 @@ class Config(BaseConfig):
|
|||||||
|
|
||||||
SUPER_USERS=[12345789]
|
SUPER_USERS=[12345789]
|
||||||
"""
|
"""
|
||||||
nickname: Union[str, Set[str]] = ""
|
nickname: Set[str] = set()
|
||||||
"""
|
"""
|
||||||
- 类型: ``Union[str, Set[str]]``
|
- 类型: ``Set[str]``
|
||||||
- 默认值: ``""``
|
- 默认值: ``set()``
|
||||||
- 说明:
|
- 说明:
|
||||||
机器人昵称。
|
机器人昵称。
|
||||||
"""
|
"""
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
"""
|
||||||
# -*- coding: utf-8 -*-
|
后端驱动适配基类
|
||||||
|
===============
|
||||||
|
|
||||||
|
各驱动请继承以下基类
|
||||||
|
"""
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
@@ -9,16 +13,48 @@ from nonebot.typing import Bot, Dict, Type, Union, Optional, Callable
|
|||||||
|
|
||||||
|
|
||||||
class BaseDriver(abc.ABC):
|
class BaseDriver(abc.ABC):
|
||||||
|
"""
|
||||||
|
Driver 基类。将后端框架封装,以满足适配器使用。
|
||||||
|
"""
|
||||||
|
|
||||||
_adapters: Dict[str, Type[Bot]] = {}
|
_adapters: Dict[str, Type[Bot]] = {}
|
||||||
|
"""
|
||||||
|
:类型: ``Dict[str, Type[Bot]]``
|
||||||
|
:说明: 已注册的适配器列表
|
||||||
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def __init__(self, env: Env, config: Config):
|
def __init__(self, env: Env, config: Config):
|
||||||
|
"""
|
||||||
|
:参数:
|
||||||
|
* ``env: Env``: 包含环境信息的 Env 对象
|
||||||
|
* ``config: Config``: 包含配置信息的 Config 对象
|
||||||
|
"""
|
||||||
self.env = env.environment
|
self.env = env.environment
|
||||||
|
"""
|
||||||
|
:类型: ``str``
|
||||||
|
:说明: 环境名称
|
||||||
|
"""
|
||||||
self.config = config
|
self.config = config
|
||||||
|
"""
|
||||||
|
:类型: ``Config``
|
||||||
|
:说明: 配置对象
|
||||||
|
"""
|
||||||
self._clients: Dict[str, Bot] = {}
|
self._clients: Dict[str, Bot] = {}
|
||||||
|
"""
|
||||||
|
:类型: ``Dict[str, Bot]``
|
||||||
|
:说明: 已连接的 Bot
|
||||||
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def register_adapter(cls, name: str, adapter: Type[Bot]):
|
def register_adapter(cls, name: str, adapter: Type[Bot]):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
注册一个协议适配器
|
||||||
|
:参数:
|
||||||
|
* ``name: str``: 适配器名称,用于在连接时进行识别
|
||||||
|
* ``adapter: Type[Bot]``: 适配器 Class
|
||||||
|
"""
|
||||||
cls._adapters[name] = adapter
|
cls._adapters[name] = adapter
|
||||||
logger.opt(
|
logger.opt(
|
||||||
colors=True).debug(f'Succeeded to load adapter "<y>{name}</y>"')
|
colors=True).debug(f'Succeeded to load adapter "<y>{name}</y>"')
|
||||||
@@ -26,33 +62,43 @@ class BaseDriver(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def type(self):
|
def type(self):
|
||||||
|
"""驱动类型名称"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def server_app(self):
|
def server_app(self):
|
||||||
|
"""驱动 APP 对象"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def asgi(self):
|
def asgi(self):
|
||||||
|
"""驱动 ASGI 对象"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def logger(self):
|
def logger(self):
|
||||||
|
"""驱动专属 logger 日志记录器"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bots(self) -> Dict[str, Bot]:
|
def bots(self) -> Dict[str, Bot]:
|
||||||
|
"""
|
||||||
|
:类型: ``Dict[str, Bot]``
|
||||||
|
:说明: 获取当前所有已连接的 Bot
|
||||||
|
"""
|
||||||
return self._clients
|
return self._clients
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def on_startup(self, func: Callable) -> Callable:
|
def on_startup(self, func: Callable) -> Callable:
|
||||||
|
"""注册一个在驱动启动时运行的函数"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def on_shutdown(self, func: Callable) -> Callable:
|
def on_shutdown(self, func: Callable) -> Callable:
|
||||||
|
"""注册一个在驱动停止时运行的函数"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
@@ -61,44 +107,69 @@ class BaseDriver(abc.ABC):
|
|||||||
port: Optional[int] = None,
|
port: Optional[int] = None,
|
||||||
*args,
|
*args,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
启动驱动框架
|
||||||
|
:参数:
|
||||||
|
* ``host: Optional[str]``: 驱动绑定 IP
|
||||||
|
* ``post: Optional[int]``: 驱动绑定端口
|
||||||
|
* ``*args``
|
||||||
|
* ``**kwargs``
|
||||||
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def _handle_http(self):
|
async def _handle_http(self):
|
||||||
|
"""用于处理 HTTP 类型请求的函数"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def _handle_ws_reverse(self):
|
async def _handle_ws_reverse(self):
|
||||||
|
"""用于处理 WebSocket 类型请求的函数"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class BaseWebSocket(object):
|
class BaseWebSocket(object):
|
||||||
|
"""WebSocket 连接封装,统一接口方便外部调用。"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def __init__(self, websocket):
|
def __init__(self, websocket):
|
||||||
|
"""
|
||||||
|
:参数:
|
||||||
|
* ``websocket: Any``: WebSocket 连接对象
|
||||||
|
"""
|
||||||
self._websocket = websocket
|
self._websocket = websocket
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def websocket(self):
|
def websocket(self):
|
||||||
|
"""WebSocket 连接对象"""
|
||||||
return self._websocket
|
return self._websocket
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def closed(self):
|
def closed(self):
|
||||||
|
"""
|
||||||
|
:类型: ``bool``
|
||||||
|
:说明: 连接是否已经关闭
|
||||||
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def accept(self):
|
async def accept(self):
|
||||||
|
"""接受 WebSocket 连接请求"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def close(self, code: int):
|
async def close(self, code: int):
|
||||||
|
"""关闭 WebSocket 连接请求"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def receive(self) -> dict:
|
async def receive(self) -> dict:
|
||||||
|
"""接收一条 WebSocket 信息"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def send(self, data: dict):
|
async def send(self, data: dict):
|
||||||
|
"""发送一条 WebSocket 信息"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@@ -1,5 +1,12 @@
|
|||||||
#!/usr/bin/env python3
|
"""
|
||||||
# -*- coding: utf-8 -*-
|
FastAPI 驱动适配
|
||||||
|
================
|
||||||
|
|
||||||
|
后端使用方法请参考: `FastAPI 文档`_
|
||||||
|
|
||||||
|
.. _FastAPI 文档:
|
||||||
|
https://fastapi.tiangolo.com/
|
||||||
|
"""
|
||||||
|
|
||||||
import hmac
|
import hmac
|
||||||
import json
|
import json
|
||||||
@@ -23,7 +30,7 @@ def get_auth_bearer(access_token: Optional[str] = Header(
|
|||||||
if not access_token:
|
if not access_token:
|
||||||
return None
|
return None
|
||||||
scheme, _, param = access_token.partition(" ")
|
scheme, _, param = access_token.partition(" ")
|
||||||
if scheme.lower() != "bearer":
|
if scheme.lower() not in ["bearer", "token"]:
|
||||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
detail="Not authenticated",
|
detail="Not authenticated",
|
||||||
headers={"WWW-Authenticate": "Bearer"})
|
headers={"WWW-Authenticate": "Bearer"})
|
||||||
@@ -31,6 +38,7 @@ def get_auth_bearer(access_token: Optional[str] = Header(
|
|||||||
|
|
||||||
|
|
||||||
class Driver(BaseDriver):
|
class Driver(BaseDriver):
|
||||||
|
"""FastAPI 驱动框架"""
|
||||||
|
|
||||||
def __init__(self, env: Env, config: Config):
|
def __init__(self, env: Env, config: Config):
|
||||||
super().__init__(env, config)
|
super().__init__(env, config)
|
||||||
@@ -50,29 +58,35 @@ class Driver(BaseDriver):
|
|||||||
@property
|
@property
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
def type(self) -> str:
|
def type(self) -> str:
|
||||||
|
"""驱动名称: ``fastapi``"""
|
||||||
return "fastapi"
|
return "fastapi"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
def server_app(self) -> FastAPI:
|
def server_app(self) -> FastAPI:
|
||||||
|
"""``FastAPI APP`` 对象"""
|
||||||
return self._server_app
|
return self._server_app
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
def asgi(self):
|
def asgi(self):
|
||||||
|
"""``FastAPI APP`` 对象"""
|
||||||
return self._server_app
|
return self._server_app
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
def logger(self) -> logging.Logger:
|
def logger(self) -> logging.Logger:
|
||||||
|
"""fastapi 使用的 logger"""
|
||||||
return logging.getLogger("fastapi")
|
return logging.getLogger("fastapi")
|
||||||
|
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
def on_startup(self, func: Callable) -> Callable:
|
def on_startup(self, func: Callable) -> Callable:
|
||||||
|
"""参考文档: `Events <https://fastapi.tiangolo.com/advanced/events/#startup-event>`_"""
|
||||||
return self.server_app.on_event("startup")(func)
|
return self.server_app.on_event("startup")(func)
|
||||||
|
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
def on_shutdown(self, func: Callable) -> Callable:
|
def on_shutdown(self, func: Callable) -> Callable:
|
||||||
|
"""参考文档: `Events <https://fastapi.tiangolo.com/advanced/events/#startup-event>`_"""
|
||||||
return self.server_app.on_event("shutdown")(func)
|
return self.server_app.on_event("shutdown")(func)
|
||||||
|
|
||||||
@overrides(BaseDriver)
|
@overrides(BaseDriver)
|
||||||
@@ -82,6 +96,7 @@ class Driver(BaseDriver):
|
|||||||
*,
|
*,
|
||||||
app: Optional[str] = None,
|
app: Optional[str] = None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
"""使用 ``uvicorn`` 启动 FastAPI"""
|
||||||
LOGGING_CONFIG = {
|
LOGGING_CONFIG = {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"disable_existing_loggers": False,
|
"disable_existing_loggers": False,
|
||||||
@@ -200,8 +215,8 @@ class Driver(BaseDriver):
|
|||||||
websocket=ws)
|
websocket=ws)
|
||||||
else:
|
else:
|
||||||
logger.warning("Unknown adapter")
|
logger.warning("Unknown adapter")
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
|
await ws.close(code=status.WS_1008_POLICY_VIOLATION)
|
||||||
detail="adapter not found")
|
return
|
||||||
|
|
||||||
await ws.accept()
|
await ws.accept()
|
||||||
self._clients[x_self_id] = bot
|
self._clients[x_self_id] = bot
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
异常
|
异常
|
||||||
====
|
====
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
日志
|
日志
|
||||||
====
|
====
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
"""
|
||||||
# -*- coding: utf-8 -*-
|
事件响应器
|
||||||
|
==========
|
||||||
|
|
||||||
|
该模块实现事件响应器的创建与运行,并提供一些快捷方法来帮助用户更好的与机器人进行 对话 。
|
||||||
|
"""
|
||||||
|
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
import typing
|
import typing
|
||||||
@@ -16,6 +20,10 @@ from nonebot.typing import Bot, Event, Handler, Message, ArgsParser, MessageSegm
|
|||||||
from nonebot.exception import PausedException, RejectedException, FinishedException
|
from nonebot.exception import PausedException, RejectedException, FinishedException
|
||||||
|
|
||||||
matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list)
|
matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list)
|
||||||
|
"""
|
||||||
|
:类型: ``Dict[int, List[Type[Matcher]]]``
|
||||||
|
:说明: 用于存储当前所有的事件响应器
|
||||||
|
"""
|
||||||
current_bot: ContextVar = ContextVar("current_bot")
|
current_bot: ContextVar = ContextVar("current_bot")
|
||||||
current_event: ContextVar = ContextVar("current_event")
|
current_event: ContextVar = ContextVar("current_event")
|
||||||
|
|
||||||
@@ -32,22 +40,65 @@ class MatcherMeta(type):
|
|||||||
|
|
||||||
|
|
||||||
class Matcher(metaclass=MatcherMeta):
|
class Matcher(metaclass=MatcherMeta):
|
||||||
"""`Matcher`类
|
"""事件响应器类"""
|
||||||
"""
|
|
||||||
module: Optional[str] = None
|
module: Optional[str] = None
|
||||||
|
"""
|
||||||
|
:类型: ``Optional[str]``
|
||||||
|
:说明: 事件响应器所在模块名称
|
||||||
|
"""
|
||||||
|
|
||||||
type: str = ""
|
type: str = ""
|
||||||
|
"""
|
||||||
|
:类型: ``str``
|
||||||
|
:说明: 事件响应器类型
|
||||||
|
"""
|
||||||
rule: Rule = Rule()
|
rule: Rule = Rule()
|
||||||
|
"""
|
||||||
|
:类型: ``Rule``
|
||||||
|
:说明: 事件响应器匹配规则
|
||||||
|
"""
|
||||||
permission: Permission = Permission()
|
permission: Permission = Permission()
|
||||||
|
"""
|
||||||
|
:类型: ``Permission``
|
||||||
|
:说明: 事件响应器触发权限
|
||||||
|
"""
|
||||||
handlers: List[Handler] = []
|
handlers: List[Handler] = []
|
||||||
temp: bool = False
|
"""
|
||||||
expire_time: Optional[datetime] = None
|
:类型: ``List[Handler]``
|
||||||
|
:说明: 事件响应器拥有的事件处理函数列表
|
||||||
|
"""
|
||||||
priority: int = 1
|
priority: int = 1
|
||||||
|
"""
|
||||||
|
:类型: ``int``
|
||||||
|
:说明: 事件响应器优先级
|
||||||
|
"""
|
||||||
block: bool = False
|
block: bool = False
|
||||||
|
"""
|
||||||
|
:类型: ``bool``
|
||||||
|
:说明: 事件响应器是否阻止事件传播
|
||||||
|
"""
|
||||||
|
temp: bool = False
|
||||||
|
"""
|
||||||
|
:类型: ``bool``
|
||||||
|
:说明: 事件响应器是否为临时
|
||||||
|
"""
|
||||||
|
expire_time: Optional[datetime] = None
|
||||||
|
"""
|
||||||
|
:类型: ``Optional[datetime]``
|
||||||
|
:说明: 事件响应器过期时间点
|
||||||
|
"""
|
||||||
|
|
||||||
_default_state: dict = {}
|
_default_state: dict = {}
|
||||||
|
"""
|
||||||
|
:类型: ``dict``
|
||||||
|
:说明: 事件响应器默认状态
|
||||||
|
"""
|
||||||
|
|
||||||
_default_parser: Optional[ArgsParser] = None
|
_default_parser: Optional[ArgsParser] = None
|
||||||
|
"""
|
||||||
|
:类型: ``Optional[ArgsParser]``
|
||||||
|
:说明: 事件响应器默认参数解析函数
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""实例化 Matcher 以便运行
|
"""实例化 Matcher 以便运行
|
||||||
@@ -65,9 +116,9 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def new(cls,
|
def new(cls,
|
||||||
type_: str = "",
|
type_: str = "",
|
||||||
rule: Rule = Rule(),
|
rule: Optional[Rule] = None,
|
||||||
permission: Permission = Permission(),
|
permission: Optional[Permission] = None,
|
||||||
handlers: Optional[list] = None,
|
handlers: Optional[List[Handler]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
@@ -75,18 +126,30 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
module: Optional[str] = None,
|
module: Optional[str] = None,
|
||||||
default_state: Optional[dict] = None,
|
default_state: Optional[dict] = None,
|
||||||
expire_time: Optional[datetime] = None) -> Type["Matcher"]:
|
expire_time: Optional[datetime] = None) -> Type["Matcher"]:
|
||||||
"""创建新的 Matcher
|
"""
|
||||||
|
:说明:
|
||||||
Returns:
|
创建一个新的事件响应器,并存储至 `matchers <#matchers>`_
|
||||||
Type["Matcher"]: 新的 Matcher 类
|
:参数:
|
||||||
|
* ``type_: str``: 事件响应器类型,与 ``event.type`` 一致时触发,空字符串表示任意
|
||||||
|
* ``rule: Optional[Rule]``: 匹配规则
|
||||||
|
* ``permission: Optional[Permission]``: 权限
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器,即触发一次后删除
|
||||||
|
* ``priority: int``: 响应优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级的响应器传播
|
||||||
|
* ``module: Optional[str]``: 事件响应器所在模块名称
|
||||||
|
* ``default_state: Optional[dict]``: 默认状态 ``state``
|
||||||
|
* ``expire_time: Optional[datetime]``: 事件响应器最终有效时间点,过时即被删除
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``: 新的事件响应器类
|
||||||
"""
|
"""
|
||||||
|
|
||||||
NewMatcher = type(
|
NewMatcher = type(
|
||||||
"Matcher", (Matcher,), {
|
"Matcher", (Matcher,), {
|
||||||
"module": module,
|
"module": module,
|
||||||
"type": type_,
|
"type": type_,
|
||||||
"rule": rule,
|
"rule": rule or Rule(),
|
||||||
"permission": permission,
|
"permission": permission or Permission(),
|
||||||
"handlers": handlers or [],
|
"handlers": handlers or [],
|
||||||
"temp": temp,
|
"temp": temp,
|
||||||
"expire_time": expire_time,
|
"expire_time": expire_time,
|
||||||
@@ -101,29 +164,51 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def check_perm(cls, bot: Bot, event: Event) -> bool:
|
async def check_perm(cls, bot: Bot, event: Event) -> bool:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
检查是否满足触发权限
|
||||||
|
:参数:
|
||||||
|
* ``bot: Bot``: Bot 对象
|
||||||
|
* ``event: Event``: 上报事件
|
||||||
|
:返回:
|
||||||
|
- ``bool``: 是否满足权限
|
||||||
|
"""
|
||||||
return await cls.permission(bot, event)
|
return await cls.permission(bot, event)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def check_rule(cls, bot: Bot, event: Event, state: dict) -> bool:
|
async def check_rule(cls, bot: Bot, event: Event, state: dict) -> bool:
|
||||||
"""检查 Matcher 的 Rule 是否成立
|
"""
|
||||||
|
:说明:
|
||||||
Args:
|
检查是否满足匹配规则
|
||||||
event (Event): 消息事件
|
:参数:
|
||||||
|
* ``bot: Bot``: Bot 对象
|
||||||
Returns:
|
* ``event: Event``: 上报事件
|
||||||
bool: 条件成立与否
|
* ``state: dict``: 当前状态
|
||||||
|
:返回:
|
||||||
|
- ``bool``: 是否满足匹配规则
|
||||||
"""
|
"""
|
||||||
return (event.type == (cls.type or event.type) and
|
return (event.type == (cls.type or event.type) and
|
||||||
await cls.rule(bot, event, state))
|
await cls.rule(bot, event, state))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def args_parser(cls, func: ArgsParser) -> ArgsParser:
|
def args_parser(cls, func: ArgsParser) -> ArgsParser:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
装饰一个函数来更改当前事件响应器的默认参数解析函数
|
||||||
|
:参数:
|
||||||
|
* ``func: ArgsParser``: 参数解析函数
|
||||||
|
"""
|
||||||
cls._default_parser = func
|
cls._default_parser = func
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def handle(cls) -> Callable[[Handler], Handler]:
|
def handle(cls) -> Callable[[Handler], Handler]:
|
||||||
"""直接处理消息事件"""
|
"""
|
||||||
|
:说明:
|
||||||
|
装饰一个函数来向事件响应器直接添加一个处理函数
|
||||||
|
:参数:
|
||||||
|
* 无
|
||||||
|
"""
|
||||||
|
|
||||||
def _decorator(func: Handler) -> Handler:
|
def _decorator(func: Handler) -> Handler:
|
||||||
cls.handlers.append(func)
|
cls.handlers.append(func)
|
||||||
@@ -133,7 +218,12 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def receive(cls) -> Callable[[Handler], Handler]:
|
def receive(cls) -> Callable[[Handler], Handler]:
|
||||||
"""接收一条新消息并处理"""
|
"""
|
||||||
|
:说明:
|
||||||
|
装饰一个函数来指示 NoneBot 在接收用户新的一条消息后继续运行该函数
|
||||||
|
:参数:
|
||||||
|
* 无
|
||||||
|
"""
|
||||||
|
|
||||||
async def _receive(bot: Bot, event: Event, state: dict) -> NoReturn:
|
async def _receive(bot: Bot, event: Event, state: dict) -> NoReturn:
|
||||||
raise PausedException
|
raise PausedException
|
||||||
@@ -154,20 +244,31 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
def got(
|
def got(
|
||||||
cls,
|
cls,
|
||||||
key: str,
|
key: str,
|
||||||
prompt: Optional[str] = None,
|
prompt: Optional[Union[str, Message, MessageSegment]] = None,
|
||||||
args_parser: Optional[ArgsParser] = None
|
args_parser: Optional[ArgsParser] = None
|
||||||
) -> Callable[[Handler], Handler]:
|
) -> Callable[[Handler], Handler]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
装饰一个函数来指示 NoneBot 当要获取的 ``key`` 不存在时接收用户新的一条消息并经过 ``ArgsParser`` 处理后再运行该函数,如果 ``key`` 已存在则直接继续运行
|
||||||
|
:参数:
|
||||||
|
* ``key: str``: 参数名
|
||||||
|
* ``prompt: Optional[Union[str, Message, MessageSegment]]``: 在参数不存在时向用户发送的消息
|
||||||
|
* ``args_parser: Optional[ArgsParser]``: 可选参数解析函数,空则使用默认解析函数
|
||||||
|
"""
|
||||||
|
|
||||||
async def _key_getter(bot: Bot, event: Event, state: dict):
|
async def _key_getter(bot: Bot, event: Event, state: dict):
|
||||||
|
state["_current_key"] = key
|
||||||
if key not in state:
|
if key not in state:
|
||||||
state["_current_key"] = key
|
|
||||||
if prompt:
|
if prompt:
|
||||||
await bot.send(event=event, message=prompt)
|
await bot.send(event=event, message=prompt)
|
||||||
raise PausedException
|
raise PausedException
|
||||||
|
else:
|
||||||
|
state["_skip_key"] = True
|
||||||
|
|
||||||
async def _key_parser(bot: Bot, event: Event, state: dict):
|
async def _key_parser(bot: Bot, event: Event, state: dict):
|
||||||
# if key in state:
|
if key in state and state.get("_skip_key"):
|
||||||
# return
|
del state["_skip_key"]
|
||||||
|
return
|
||||||
parser = args_parser or cls._default_parser
|
parser = args_parser or cls._default_parser
|
||||||
if parser:
|
if parser:
|
||||||
await parser(bot, event, state)
|
await parser(bot, event, state)
|
||||||
@@ -185,6 +286,8 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
async def wrapper(bot: Bot, event: Event, state: dict):
|
async def wrapper(bot: Bot, event: Event, state: dict):
|
||||||
await parser(bot, event, state)
|
await parser(bot, event, state)
|
||||||
await func(bot, event, state)
|
await func(bot, event, state)
|
||||||
|
if "_current_key" in state:
|
||||||
|
del state["_current_key"]
|
||||||
|
|
||||||
cls.handlers.append(wrapper)
|
cls.handlers.append(wrapper)
|
||||||
|
|
||||||
@@ -193,36 +296,70 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
return _decorator
|
return _decorator
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def finish(
|
async def send(cls, message: Union[str, Message, MessageSegment], **kwargs):
|
||||||
cls,
|
"""
|
||||||
prompt: Optional[Union[str, Message,
|
:说明:
|
||||||
MessageSegment]] = None) -> NoReturn:
|
发送一条消息给当前交互用户
|
||||||
bot: Bot = current_bot.get()
|
:参数:
|
||||||
event: Event = current_event.get()
|
* ``message: Union[str, Message, MessageSegment]``: 消息内容
|
||||||
if prompt:
|
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
await bot.send(event=event, message=prompt)
|
"""
|
||||||
|
bot = current_bot.get()
|
||||||
|
event = current_event.get()
|
||||||
|
await bot.send(event=event, message=message, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def finish(cls,
|
||||||
|
message: Optional[Union[str, Message,
|
||||||
|
MessageSegment]] = None,
|
||||||
|
**kwargs) -> NoReturn:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
发送一条消息给当前交互用户并结束当前事件响应器
|
||||||
|
:参数:
|
||||||
|
* ``message: Union[str, Message, MessageSegment]``: 消息内容
|
||||||
|
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
"""
|
||||||
|
bot = current_bot.get()
|
||||||
|
event = current_event.get()
|
||||||
|
if message:
|
||||||
|
await bot.send(event=event, message=message, **kwargs)
|
||||||
raise FinishedException
|
raise FinishedException
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def pause(
|
async def pause(cls,
|
||||||
cls,
|
prompt: Optional[Union[str, Message,
|
||||||
prompt: Optional[Union[str, Message,
|
MessageSegment]] = None,
|
||||||
MessageSegment]] = None) -> NoReturn:
|
**kwargs) -> NoReturn:
|
||||||
bot: Bot = current_bot.get()
|
"""
|
||||||
event: Event = current_event.get()
|
:说明:
|
||||||
|
发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后继续下一个处理函数
|
||||||
|
:参数:
|
||||||
|
* ``prompt: Union[str, Message, MessageSegment]``: 消息内容
|
||||||
|
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
"""
|
||||||
|
bot = current_bot.get()
|
||||||
|
event = current_event.get()
|
||||||
if prompt:
|
if prompt:
|
||||||
await bot.send(event=event, message=prompt)
|
await bot.send(event=event, message=prompt, **kwargs)
|
||||||
raise PausedException
|
raise PausedException
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def reject(
|
async def reject(cls,
|
||||||
cls,
|
prompt: Optional[Union[str, Message,
|
||||||
prompt: Optional[Union[str, Message,
|
MessageSegment]] = None,
|
||||||
MessageSegment]] = None) -> NoReturn:
|
**kwargs) -> NoReturn:
|
||||||
bot: Bot = current_bot.get()
|
"""
|
||||||
event: Event = current_event.get()
|
:说明:
|
||||||
|
发送一条消息给当前交互用户并暂停事件响应器,在接收用户新的一条消息后重新运行当前处理函数
|
||||||
|
:参数:
|
||||||
|
* ``prompt: Union[str, Message, MessageSegment]``: 消息内容
|
||||||
|
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||||
|
"""
|
||||||
|
bot = current_bot.get()
|
||||||
|
event = current_event.get()
|
||||||
if prompt:
|
if prompt:
|
||||||
await bot.send(event=event, message=prompt)
|
await bot.send(event=event, message=prompt, **kwargs)
|
||||||
raise RejectedException
|
raise RejectedException
|
||||||
|
|
||||||
# 运行handlers
|
# 运行handlers
|
||||||
@@ -273,3 +410,198 @@ class Matcher(metaclass=MatcherMeta):
|
|||||||
logger.info(f"Matcher {self} running complete")
|
logger.info(f"Matcher {self} running complete")
|
||||||
current_bot.reset(b_t)
|
current_bot.reset(b_t)
|
||||||
current_event.reset(e_t)
|
current_event.reset(e_t)
|
||||||
|
|
||||||
|
|
||||||
|
class MatcherGroup:
|
||||||
|
"""事件响应器组合,统一管理。用法同 ``Matcher``"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
type_: str = "",
|
||||||
|
rule: Optional[Rule] = None,
|
||||||
|
permission: Optional[Permission] = None,
|
||||||
|
handlers: Optional[list] = None,
|
||||||
|
temp: bool = False,
|
||||||
|
priority: int = 1,
|
||||||
|
block: bool = False,
|
||||||
|
*,
|
||||||
|
module: Optional[str] = None,
|
||||||
|
default_state: Optional[dict] = None,
|
||||||
|
expire_time: Optional[datetime] = None):
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
创建一个事件响应器组合,参数为默认值,与 ``Matcher.new`` 一致
|
||||||
|
"""
|
||||||
|
self.matchers: List[Type[Matcher]] = []
|
||||||
|
"""
|
||||||
|
:类型: ``List[Type[Matcher]]``
|
||||||
|
:说明: 组内事件响应器列表
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.type = type_
|
||||||
|
self.rule = rule or Rule()
|
||||||
|
self.permission = permission or Permission()
|
||||||
|
self.handlers = handlers
|
||||||
|
self.temp = temp
|
||||||
|
self.priority = priority
|
||||||
|
self.block = block
|
||||||
|
self.module = module
|
||||||
|
self.expire_time = expire_time
|
||||||
|
|
||||||
|
self._default_state = default_state
|
||||||
|
|
||||||
|
self._default_parser: Optional[ArgsParser] = None
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return (
|
||||||
|
f"<MatcherGroup from {self.module or 'unknow'}, type={self.type}, "
|
||||||
|
f"priority={self.priority}, temp={self.temp}>")
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.__repr__()
|
||||||
|
|
||||||
|
def new(self,
|
||||||
|
type_: str = "",
|
||||||
|
rule: Optional[Rule] = None,
|
||||||
|
permission: Optional[Permission] = None,
|
||||||
|
handlers: Optional[list] = None,
|
||||||
|
temp: bool = False,
|
||||||
|
priority: int = 1,
|
||||||
|
block: bool = False,
|
||||||
|
*,
|
||||||
|
module: Optional[str] = None,
|
||||||
|
default_state: Optional[dict] = None,
|
||||||
|
expire_time: Optional[datetime] = None) -> Type[Matcher]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
在组中创建一个新的事件响应器,参数留空则使用组合默认值
|
||||||
|
|
||||||
|
\:\:\:danger 警告
|
||||||
|
如果使用 handlers 参数覆盖组合默认值则该事件响应器不会随组合一起添加新的事件处理函数
|
||||||
|
\:\:\:
|
||||||
|
"""
|
||||||
|
matcher = Matcher.new(type_=type_ or self.type,
|
||||||
|
rule=self.rule & rule,
|
||||||
|
permission=permission or self.permission,
|
||||||
|
handlers=handlers or self.handlers,
|
||||||
|
temp=temp or self.temp,
|
||||||
|
priority=priority or self.priority,
|
||||||
|
block=block or self.block,
|
||||||
|
module=module or self.module,
|
||||||
|
default_state=default_state or
|
||||||
|
self._default_state,
|
||||||
|
expire_time=expire_time or self.expire_time)
|
||||||
|
self.matchers.append(matcher)
|
||||||
|
return matcher
|
||||||
|
|
||||||
|
def args_parser(self, func: ArgsParser) -> ArgsParser:
|
||||||
|
self._default_parser = func
|
||||||
|
for matcher in self.matchers:
|
||||||
|
matcher.args_parser(func)
|
||||||
|
return func
|
||||||
|
|
||||||
|
def handle(self) -> Callable[[Handler], Handler]:
|
||||||
|
|
||||||
|
def _decorator(func: Handler) -> Handler:
|
||||||
|
self.handlers.append(func)
|
||||||
|
return func
|
||||||
|
|
||||||
|
return _decorator
|
||||||
|
|
||||||
|
def receive(self) -> Callable[[Handler], Handler]:
|
||||||
|
|
||||||
|
async def _receive(bot: Bot, event: Event, state: dict) -> NoReturn:
|
||||||
|
raise PausedException
|
||||||
|
|
||||||
|
if self.handlers:
|
||||||
|
# 已有前置handlers则接受一条新的消息,否则视为接收初始消息
|
||||||
|
self.handlers.append(_receive)
|
||||||
|
|
||||||
|
def _decorator(func: Handler) -> Handler:
|
||||||
|
if not self.handlers or self.handlers[-1] is not func:
|
||||||
|
self.handlers.append(func)
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
||||||
|
return _decorator
|
||||||
|
|
||||||
|
def got(
|
||||||
|
self,
|
||||||
|
key: str,
|
||||||
|
prompt: Optional[str] = None,
|
||||||
|
args_parser: Optional[ArgsParser] = None
|
||||||
|
) -> Callable[[Handler], Handler]:
|
||||||
|
|
||||||
|
async def _key_getter(bot: Bot, event: Event, state: dict):
|
||||||
|
state["_current_key"] = key
|
||||||
|
if key not in state:
|
||||||
|
if prompt:
|
||||||
|
await bot.send(event=event, message=prompt)
|
||||||
|
raise PausedException
|
||||||
|
else:
|
||||||
|
state["_skip_key"] = True
|
||||||
|
|
||||||
|
async def _key_parser(bot: Bot, event: Event, state: dict):
|
||||||
|
if key in state and state.get("_skip_key"):
|
||||||
|
del state["_skip_key"]
|
||||||
|
return
|
||||||
|
parser = args_parser or self._default_parser
|
||||||
|
if parser:
|
||||||
|
await parser(bot, event, state)
|
||||||
|
else:
|
||||||
|
state[state["_current_key"]] = str(event.message)
|
||||||
|
|
||||||
|
self.handlers.append(_key_getter)
|
||||||
|
self.handlers.append(_key_parser)
|
||||||
|
|
||||||
|
def _decorator(func: Handler) -> Handler:
|
||||||
|
if not hasattr(self.handlers[-1], "__wrapped__"):
|
||||||
|
parser = self.handlers.pop()
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
async def wrapper(bot: Bot, event: Event, state: dict):
|
||||||
|
await parser(bot, event, state)
|
||||||
|
await func(bot, event, state)
|
||||||
|
if "_current_key" in state:
|
||||||
|
del state["_current_key"]
|
||||||
|
|
||||||
|
self.handlers.append(wrapper)
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
||||||
|
return _decorator
|
||||||
|
|
||||||
|
async def send(self, message: Union[str, Message, MessageSegment],
|
||||||
|
**kwargs):
|
||||||
|
bot = current_bot.get()
|
||||||
|
event = current_event.get()
|
||||||
|
await bot.send(event=event, message=message, **kwargs)
|
||||||
|
|
||||||
|
async def finish(self,
|
||||||
|
message: Optional[Union[str, Message,
|
||||||
|
MessageSegment]] = None,
|
||||||
|
**kwargs) -> NoReturn:
|
||||||
|
bot = current_bot.get()
|
||||||
|
event = current_event.get()
|
||||||
|
if message:
|
||||||
|
await bot.send(event=event, message=message, **kwargs)
|
||||||
|
raise FinishedException
|
||||||
|
|
||||||
|
async def pause(self,
|
||||||
|
prompt: Optional[Union[str, Message,
|
||||||
|
MessageSegment]] = None,
|
||||||
|
**kwargs) -> NoReturn:
|
||||||
|
bot = current_bot.get()
|
||||||
|
event = current_event.get()
|
||||||
|
if prompt:
|
||||||
|
await bot.send(event=event, message=prompt, **kwargs)
|
||||||
|
raise PausedException
|
||||||
|
|
||||||
|
async def reject(self,
|
||||||
|
prompt: Optional[Union[str, Message,
|
||||||
|
MessageSegment]] = None,
|
||||||
|
**kwargs) -> NoReturn:
|
||||||
|
bot = current_bot.get()
|
||||||
|
event = current_event.get()
|
||||||
|
if prompt:
|
||||||
|
await bot.send(event=event, message=prompt, **kwargs)
|
||||||
|
raise RejectedException
|
||||||
|
@@ -1,11 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from nonebot.rule import TrieRule
|
from nonebot.rule import TrieRule
|
||||||
|
from nonebot.utils import escape_tag
|
||||||
from nonebot.matcher import matchers
|
from nonebot.matcher import matchers
|
||||||
from nonebot.typing import Set, Type, Union, NoReturn
|
from nonebot.typing import Set, Type, Union, NoReturn
|
||||||
from nonebot.typing import Bot, Event, Matcher, PreProcessor
|
from nonebot.typing import Bot, Event, Matcher, PreProcessor
|
||||||
@@ -56,6 +54,7 @@ async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event,
|
|||||||
|
|
||||||
|
|
||||||
async def handle_event(bot: Bot, event: Event):
|
async def handle_event(bot: Bot, event: Event):
|
||||||
|
show_log = True
|
||||||
log_msg = f"<m>{bot.type.upper()} </m>| {event.self_id} [{event.name}]: "
|
log_msg = f"<m>{bot.type.upper()} </m>| {event.self_id} [{event.name}]: "
|
||||||
if event.type == "message":
|
if event.type == "message":
|
||||||
log_msg += f"Message {event.id} from "
|
log_msg += f"Message {event.id} from "
|
||||||
@@ -64,15 +63,19 @@ async def handle_event(bot: Bot, event: Event):
|
|||||||
log_msg += f"@[群:{event.group_id}]:"
|
log_msg += f"@[群:{event.group_id}]:"
|
||||||
|
|
||||||
log_msg += ' "' + "".join(
|
log_msg += ' "' + "".join(
|
||||||
map(lambda x: str(x) if x.type == "text" else f"<le>{x!s}</le>",
|
map(
|
||||||
|
lambda x: escape_tag(str(x))
|
||||||
|
if x.type == "text" else f"<le>{escape_tag(str(x))}</le>",
|
||||||
event.message)) + '"' # type: ignore
|
event.message)) + '"' # type: ignore
|
||||||
elif event.type == "notice":
|
elif event.type == "notice":
|
||||||
log_msg += f"Notice {event.raw_event}"
|
log_msg += f"Notice {event.raw_event}"
|
||||||
elif event.type == "request":
|
elif event.type == "request":
|
||||||
log_msg += f"Request {event.raw_event}"
|
log_msg += f"Request {event.raw_event}"
|
||||||
elif event.type == "meta_event":
|
elif event.type == "meta_event":
|
||||||
log_msg += f"MetaEvent {event.raw_event}"
|
# log_msg += f"MetaEvent {event.detail_type}"
|
||||||
logger.opt(colors=True).info(log_msg)
|
show_log = False
|
||||||
|
if show_log:
|
||||||
|
logger.opt(colors=True).info(log_msg)
|
||||||
|
|
||||||
coros = []
|
coros = []
|
||||||
state = {}
|
state = {}
|
||||||
@@ -100,7 +103,8 @@ async def handle_event(bot: Bot, event: Event):
|
|||||||
for matcher in matchers[priority]
|
for matcher in matchers[priority]
|
||||||
]
|
]
|
||||||
|
|
||||||
logger.debug(f"Checking for matchers in priority {priority}...")
|
if show_log:
|
||||||
|
logger.debug(f"Checking for matchers in priority {priority}...")
|
||||||
results = await asyncio.gather(*pending_tasks, return_exceptions=True)
|
results = await asyncio.gather(*pending_tasks, return_exceptions=True)
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
权限
|
权限
|
||||||
====
|
====
|
||||||
@@ -14,7 +12,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from nonebot.utils import run_sync
|
from nonebot.utils import run_sync
|
||||||
from nonebot.typing import Bot, Event, Union, NoReturn, Callable, Awaitable, PermissionChecker
|
from nonebot.typing import Bot, Event, Union, NoReturn, Optional, Callable, Awaitable, PermissionChecker
|
||||||
|
|
||||||
|
|
||||||
class Permission:
|
class Permission:
|
||||||
@@ -53,10 +51,13 @@ class Permission:
|
|||||||
def __and__(self, other) -> NoReturn:
|
def __and__(self, other) -> NoReturn:
|
||||||
raise RuntimeError("And operation between Permissions is not allowed.")
|
raise RuntimeError("And operation between Permissions is not allowed.")
|
||||||
|
|
||||||
def __or__(self, other: Union["Permission",
|
def __or__(
|
||||||
PermissionChecker]) -> "Permission":
|
self, other: Optional[Union["Permission",
|
||||||
|
PermissionChecker]]) -> "Permission":
|
||||||
checkers = self.checkers.copy()
|
checkers = self.checkers.copy()
|
||||||
if isinstance(other, Permission):
|
if other is None:
|
||||||
|
return self
|
||||||
|
elif isinstance(other, Permission):
|
||||||
checkers |= other.checkers
|
checkers |= other.checkers
|
||||||
elif asyncio.iscoroutinefunction(other):
|
elif asyncio.iscoroutinefunction(other):
|
||||||
checkers.add(other) # type: ignore
|
checkers.add(other) # type: ignore
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
"""
|
||||||
# -*- coding: utf-8 -*-
|
插件
|
||||||
|
====
|
||||||
|
|
||||||
|
为 NoneBot 插件开发提供便携的定义函数。
|
||||||
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
@@ -12,32 +16,65 @@ from nonebot.log import logger
|
|||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
from nonebot.permission import Permission
|
from nonebot.permission import Permission
|
||||||
from nonebot.typing import Handler, RuleChecker
|
from nonebot.typing import Handler, RuleChecker
|
||||||
from nonebot.rule import Rule, startswith, endswith, command, regex
|
from nonebot.rule import Rule, startswith, endswith, keyword, command, regex
|
||||||
from nonebot.typing import Set, List, Dict, Type, Tuple, Union, Optional, ModuleType
|
from nonebot.typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, ModuleType
|
||||||
|
|
||||||
plugins: Dict[str, "Plugin"] = {}
|
plugins: Dict[str, "Plugin"] = {}
|
||||||
|
"""
|
||||||
|
:类型: ``Dict[str, Plugin]``
|
||||||
|
:说明: 已加载的插件
|
||||||
|
"""
|
||||||
|
|
||||||
_tmp_matchers: Set[Type[Matcher]] = set()
|
_tmp_matchers: Set[Type[Matcher]] = set()
|
||||||
|
|
||||||
|
|
||||||
@dataclass(eq=False)
|
@dataclass(eq=False)
|
||||||
class Plugin(object):
|
class Plugin(object):
|
||||||
|
"""存储插件信息"""
|
||||||
name: str
|
name: str
|
||||||
|
"""
|
||||||
|
- **类型**: ``str``
|
||||||
|
- **说明**: 插件名称,使用 文件/文件夹 名称作为插件名
|
||||||
|
"""
|
||||||
module: ModuleType
|
module: ModuleType
|
||||||
|
"""
|
||||||
|
- **类型**: ``ModuleType``
|
||||||
|
- **说明**: 插件模块对象
|
||||||
|
"""
|
||||||
matcher: Set[Type[Matcher]]
|
matcher: Set[Type[Matcher]]
|
||||||
|
"""
|
||||||
|
- **类型**: ``Set[Type[Matcher]]``
|
||||||
|
- **说明**: 插件内定义的 ``Matcher``
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def on(rule: Union[Rule, RuleChecker] = Rule(),
|
def on(type: str = "",
|
||||||
permission: Permission = Permission(),
|
rule: Optional[Union[Rule, RuleChecker]] = None,
|
||||||
|
permission: Optional[Permission] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Handler]] = None,
|
handlers: Optional[List[Handler]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
state: Optional[dict] = None) -> Type[Matcher]:
|
state: Optional[dict] = None) -> Type[Matcher]:
|
||||||
matcher = Matcher.new("",
|
"""
|
||||||
|
:说明:
|
||||||
|
注册一个基础事件响应器,可自定义类型。
|
||||||
|
:参数:
|
||||||
|
* ``type: str``: 事件响应器类型
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``permission: Optional[Permission]``: 事件响应权限
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
|
matcher = Matcher.new(type,
|
||||||
Rule() & rule,
|
Rule() & rule,
|
||||||
permission,
|
permission or Permission(),
|
||||||
temp=temp,
|
temp=temp,
|
||||||
priority=priority,
|
priority=priority,
|
||||||
block=block,
|
block=block,
|
||||||
@@ -47,13 +84,26 @@ def on(rule: Union[Rule, RuleChecker] = Rule(),
|
|||||||
return matcher
|
return matcher
|
||||||
|
|
||||||
|
|
||||||
def on_metaevent(rule: Union[Rule, RuleChecker] = Rule(),
|
def on_metaevent(rule: Optional[Union[Rule, RuleChecker]] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Handler]] = None,
|
handlers: Optional[List[Handler]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
state: Optional[dict] = None) -> Type[Matcher]:
|
state: Optional[dict] = None) -> Type[Matcher]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
注册一个元事件响应器。
|
||||||
|
:参数:
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
matcher = Matcher.new("meta_event",
|
matcher = Matcher.new("meta_event",
|
||||||
Rule() & rule,
|
Rule() & rule,
|
||||||
Permission(),
|
Permission(),
|
||||||
@@ -66,17 +116,31 @@ def on_metaevent(rule: Union[Rule, RuleChecker] = Rule(),
|
|||||||
return matcher
|
return matcher
|
||||||
|
|
||||||
|
|
||||||
def on_message(rule: Union[Rule, RuleChecker] = Rule(),
|
def on_message(rule: Optional[Union[Rule, RuleChecker]] = None,
|
||||||
permission: Permission = Permission(),
|
permission: Optional[Permission] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Handler]] = None,
|
handlers: Optional[List[Handler]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = True,
|
block: bool = True,
|
||||||
state: Optional[dict] = None) -> Type[Matcher]:
|
state: Optional[dict] = None) -> Type[Matcher]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
注册一个消息事件响应器。
|
||||||
|
:参数:
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``permission: Optional[Permission]``: 事件响应权限
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
matcher = Matcher.new("message",
|
matcher = Matcher.new("message",
|
||||||
Rule() & rule,
|
Rule() & rule,
|
||||||
permission,
|
permission or Permission(),
|
||||||
temp=temp,
|
temp=temp,
|
||||||
priority=priority,
|
priority=priority,
|
||||||
block=block,
|
block=block,
|
||||||
@@ -86,13 +150,26 @@ def on_message(rule: Union[Rule, RuleChecker] = Rule(),
|
|||||||
return matcher
|
return matcher
|
||||||
|
|
||||||
|
|
||||||
def on_notice(rule: Union[Rule, RuleChecker] = Rule(),
|
def on_notice(rule: Optional[Union[Rule, RuleChecker]] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Handler]] = None,
|
handlers: Optional[List[Handler]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
state: Optional[dict] = None) -> Type[Matcher]:
|
state: Optional[dict] = None) -> Type[Matcher]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
注册一个通知事件响应器。
|
||||||
|
:参数:
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
matcher = Matcher.new("notice",
|
matcher = Matcher.new("notice",
|
||||||
Rule() & rule,
|
Rule() & rule,
|
||||||
Permission(),
|
Permission(),
|
||||||
@@ -105,13 +182,26 @@ def on_notice(rule: Union[Rule, RuleChecker] = Rule(),
|
|||||||
return matcher
|
return matcher
|
||||||
|
|
||||||
|
|
||||||
def on_request(rule: Union[Rule, RuleChecker] = Rule(),
|
def on_request(rule: Optional[Union[Rule, RuleChecker]] = None,
|
||||||
*,
|
*,
|
||||||
handlers: Optional[List[Handler]] = None,
|
handlers: Optional[List[Handler]] = None,
|
||||||
temp: bool = False,
|
temp: bool = False,
|
||||||
priority: int = 1,
|
priority: int = 1,
|
||||||
block: bool = False,
|
block: bool = False,
|
||||||
state: Optional[dict] = None) -> Type[Matcher]:
|
state: Optional[dict] = None) -> Type[Matcher]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
注册一个请求事件响应器。
|
||||||
|
:参数:
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
matcher = Matcher.new("request",
|
matcher = Matcher.new("request",
|
||||||
Rule() & rule,
|
Rule() & rule,
|
||||||
Permission(),
|
Permission(),
|
||||||
@@ -125,29 +215,90 @@ def on_request(rule: Union[Rule, RuleChecker] = Rule(),
|
|||||||
|
|
||||||
|
|
||||||
def on_startswith(msg: str,
|
def on_startswith(msg: str,
|
||||||
rule: Optional[Union[Rule, RuleChecker]] = None,
|
rule: Optional[Optional[Union[Rule, RuleChecker]]] = None,
|
||||||
permission: Permission = Permission(),
|
|
||||||
**kwargs) -> Type[Matcher]:
|
**kwargs) -> Type[Matcher]:
|
||||||
return on_message(startswith(msg) &
|
"""
|
||||||
rule, permission, **kwargs) if rule else on_message(
|
:说明:
|
||||||
startswith(msg), permission, **kwargs)
|
注册一个消息事件响应器,并且当消息的**文本部分**以指定内容开头时响应。
|
||||||
|
:参数:
|
||||||
|
* ``msg: str``: 指定消息开头内容
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``permission: Optional[Permission]``: 事件响应权限
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
|
return on_message(startswith(msg) & rule, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def on_endswith(msg: str,
|
def on_endswith(msg: str,
|
||||||
rule: Optional[Union[Rule, RuleChecker]] = None,
|
rule: Optional[Optional[Union[Rule, RuleChecker]]] = None,
|
||||||
permission: Permission = Permission(),
|
|
||||||
**kwargs) -> Type[Matcher]:
|
**kwargs) -> Type[Matcher]:
|
||||||
return on_message(endswith(msg) &
|
"""
|
||||||
rule, permission, **kwargs) if rule else on_message(
|
:说明:
|
||||||
startswith(msg), permission, **kwargs)
|
注册一个消息事件响应器,并且当消息的**文本部分**以指定内容结尾时响应。
|
||||||
|
:参数:
|
||||||
|
* ``msg: str``: 指定消息结尾内容
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``permission: Optional[Permission]``: 事件响应权限
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
|
return on_message(endswith(msg) & rule, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def on_keyword(keywords: Set[str],
|
||||||
|
rule: Optional[Union[Rule, RuleChecker]] = None,
|
||||||
|
**kwargs) -> Type[Matcher]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
注册一个消息事件响应器,并且当消息纯文本部分包含关键词时响应。
|
||||||
|
:参数:
|
||||||
|
* ``keywords: Set[str]``: 关键词列表
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``permission: Optional[Permission]``: 事件响应权限
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
|
return on_message(keyword(*keywords) & rule, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def on_command(cmd: Union[str, Tuple[str, ...]],
|
def on_command(cmd: Union[str, Tuple[str, ...]],
|
||||||
rule: Optional[Union[Rule, RuleChecker]] = None,
|
rule: Optional[Union[Rule, RuleChecker]] = None,
|
||||||
permission: Permission = Permission(),
|
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None,
|
||||||
**kwargs) -> Type[Matcher]:
|
**kwargs) -> Type[Matcher]:
|
||||||
if isinstance(cmd, str):
|
"""
|
||||||
cmd = (cmd,)
|
:说明:
|
||||||
|
注册一个消息事件响应器,并且当消息以指定命令开头时响应。
|
||||||
|
|
||||||
|
命令匹配规则参考: `命令形式匹配 <rule.html#command-command>`_
|
||||||
|
:参数:
|
||||||
|
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
|
||||||
|
* ``permission: Optional[Permission]``: 事件响应权限
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
|
|
||||||
async def _strip_cmd(bot, event, state: dict):
|
async def _strip_cmd(bot, event, state: dict):
|
||||||
message = event.message
|
message = event.message
|
||||||
@@ -157,23 +308,85 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
|
|||||||
handlers = kwargs.pop("handlers", [])
|
handlers = kwargs.pop("handlers", [])
|
||||||
handlers.insert(0, _strip_cmd)
|
handlers.insert(0, _strip_cmd)
|
||||||
|
|
||||||
return on_message(
|
commands = set([cmd]) | (aliases or set())
|
||||||
command(cmd) &
|
return on_message(command(*commands) & rule, handlers=handlers, **kwargs)
|
||||||
rule, permission, handlers=handlers, **kwargs) if rule else on_message(
|
|
||||||
command(cmd), permission, handlers=handlers, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def on_regex(pattern: str,
|
def on_regex(pattern: str,
|
||||||
flags: Union[int, re.RegexFlag] = 0,
|
flags: Union[int, re.RegexFlag] = 0,
|
||||||
rule: Optional[Rule] = None,
|
rule: Optional[Rule] = None,
|
||||||
permission: Permission = Permission(),
|
|
||||||
**kwargs) -> Type[Matcher]:
|
**kwargs) -> Type[Matcher]:
|
||||||
return on_message(regex(pattern, flags) &
|
"""
|
||||||
rule, permission, **kwargs) if rule else on_message(
|
:说明:
|
||||||
regex(pattern, flags), permission, **kwargs)
|
注册一个消息事件响应器,并且当消息匹配正则表达式时响应。
|
||||||
|
|
||||||
|
命令匹配规则参考: `正则匹配 <rule.html#regex-regex-flags-0>`_
|
||||||
|
:参数:
|
||||||
|
* ``pattern: str``: 正则表达式
|
||||||
|
* ``flags: Union[int, re.RegexFlag]``: 正则匹配标志
|
||||||
|
* ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
|
||||||
|
* ``permission: Optional[Permission]``: 事件响应权限
|
||||||
|
* ``handlers: Optional[List[Handler]]``: 事件处理函数列表
|
||||||
|
* ``temp: bool``: 是否为临时事件响应器(仅执行一次)
|
||||||
|
* ``priority: int``: 事件响应器优先级
|
||||||
|
* ``block: bool``: 是否阻止事件向更低优先级传递
|
||||||
|
* ``state: Optional[dict]``: 默认的 state
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
|
return on_message(regex(pattern, flags) & rule, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class CommandGroup:
|
||||||
|
"""命令组,用于声明一组有相同名称前缀的命令。"""
|
||||||
|
|
||||||
|
def __init__(self, cmd: Union[str, Tuple[str, ...]], **kwargs):
|
||||||
|
"""
|
||||||
|
:参数:
|
||||||
|
* ``cmd: Union[str, Tuple[str, ...]]``: 命令前缀
|
||||||
|
* ``**kwargs``: 其他传递给 ``on_command`` 的参数默认值,参考 `on_command <#on-command-cmd-rule-none-aliases-none-kwargs>`_
|
||||||
|
"""
|
||||||
|
self.basecmd: Tuple[str, ...] = (cmd,) if isinstance(cmd, str) else cmd
|
||||||
|
"""
|
||||||
|
- **类型**: ``Tuple[str, ...]``
|
||||||
|
- **说明**: 命令前缀
|
||||||
|
"""
|
||||||
|
if "aliases" in kwargs:
|
||||||
|
del kwargs["aliases"]
|
||||||
|
self.base_kwargs: Dict[str, Any] = kwargs
|
||||||
|
"""
|
||||||
|
- **类型**: ``Dict[str, Any]``
|
||||||
|
- **说明**: 其他传递给 ``on_command`` 的参数默认值
|
||||||
|
"""
|
||||||
|
|
||||||
|
def command(self, cmd: Union[str, Tuple[str, ...]],
|
||||||
|
**kwargs) -> Type[Matcher]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
注册一个新的命令。
|
||||||
|
:参数:
|
||||||
|
* ``cmd: Union[str, Tuple[str, ...]]``: 命令前缀
|
||||||
|
* ``**kwargs``: 其他传递给 ``on_command`` 的参数,将会覆盖命令组默认值
|
||||||
|
:返回:
|
||||||
|
- ``Type[Matcher]``
|
||||||
|
"""
|
||||||
|
sub_cmd = (cmd,) if isinstance(cmd, str) else cmd
|
||||||
|
cmd = self.basecmd + sub_cmd
|
||||||
|
|
||||||
|
final_kwargs = self.base_kwargs.copy()
|
||||||
|
final_kwargs.update(kwargs)
|
||||||
|
return on_command(cmd, **final_kwargs)
|
||||||
|
|
||||||
|
|
||||||
def load_plugin(module_path: str) -> Optional[Plugin]:
|
def load_plugin(module_path: str) -> Optional[Plugin]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
使用 ``importlib`` 加载单个插件,可以是本地插件或是通过 ``pip`` 安装的插件。
|
||||||
|
:参数:
|
||||||
|
* ``module_path: str``: 插件名称 ``path.to.your.plugin``
|
||||||
|
:返回:
|
||||||
|
- ``Optional[Plugin]``
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
_tmp_matchers.clear()
|
_tmp_matchers.clear()
|
||||||
if module_path in plugins:
|
if module_path in plugins:
|
||||||
@@ -198,6 +411,14 @@ def load_plugin(module_path: str) -> Optional[Plugin]:
|
|||||||
|
|
||||||
|
|
||||||
def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
导入目录下多个插件,以 ``_`` 开头的插件不会被导入!
|
||||||
|
:参数:
|
||||||
|
- ``*plugin_dir: str``: 插件路径
|
||||||
|
:返回:
|
||||||
|
- ``Set[Plugin]``
|
||||||
|
"""
|
||||||
loaded_plugins = set()
|
loaded_plugins = set()
|
||||||
for module_info in pkgutil.iter_modules(plugin_dir):
|
for module_info in pkgutil.iter_modules(plugin_dir):
|
||||||
_tmp_matchers.clear()
|
_tmp_matchers.clear()
|
||||||
@@ -205,7 +426,7 @@ def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
|||||||
if name.startswith("_"):
|
if name.startswith("_"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
spec = module_info.module_finder.find_spec(name)
|
spec = module_info.module_finder.find_spec(name, None)
|
||||||
if spec.name in plugins:
|
if spec.name in plugins:
|
||||||
continue
|
continue
|
||||||
elif spec.name in sys.modules:
|
elif spec.name in sys.modules:
|
||||||
@@ -228,9 +449,21 @@ def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
|||||||
return loaded_plugins
|
return loaded_plugins
|
||||||
|
|
||||||
|
|
||||||
def load_builtin_plugins():
|
def load_builtin_plugins() -> Optional[Plugin]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
导入 NoneBot 内置插件
|
||||||
|
:返回:
|
||||||
|
- ``Plugin``
|
||||||
|
"""
|
||||||
return load_plugin("nonebot.plugins.base")
|
return load_plugin("nonebot.plugins.base")
|
||||||
|
|
||||||
|
|
||||||
def get_loaded_plugins() -> Set[Plugin]:
|
def get_loaded_plugins() -> Set[Plugin]:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
获取当前已导入的插件。
|
||||||
|
:返回:
|
||||||
|
- ``Set[Plugin]``
|
||||||
|
"""
|
||||||
return set(plugins.values())
|
return set(plugins.values())
|
||||||
|
173
nonebot/plugin.pyi
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
from nonebot.typing import Rule, Matcher, Handler, Permission, RuleChecker
|
||||||
|
from nonebot.typing import Set, List, Dict, Type, Tuple, Union, Optional, ModuleType
|
||||||
|
|
||||||
|
plugins: Dict[str, "Plugin"] = ...
|
||||||
|
|
||||||
|
_tmp_matchers: Set[Type[Matcher]] = ...
|
||||||
|
|
||||||
|
|
||||||
|
class Plugin(object):
|
||||||
|
name: str
|
||||||
|
module: ModuleType
|
||||||
|
matcher: Set[Type[Matcher]]
|
||||||
|
|
||||||
|
|
||||||
|
def on(type: str = ...,
|
||||||
|
rule: Optional[Union[Rule, RuleChecker]] = ...,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
*,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_metaevent(rule: Optional[Union[Rule, RuleChecker]] = ...,
|
||||||
|
*,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_message(rule: Optional[Union[Rule, RuleChecker]] = ...,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
*,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_notice(rule: Optional[Union[Rule, RuleChecker]] = ...,
|
||||||
|
*,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_request(rule: Optional[Union[Rule, RuleChecker]] = ...,
|
||||||
|
*,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_startswith(msg: str,
|
||||||
|
rule: Optional[Optional[Union[Rule, RuleChecker]]] = ...,
|
||||||
|
*,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_endswith(msg: str,
|
||||||
|
rule: Optional[Optional[Union[Rule, RuleChecker]]] = ...,
|
||||||
|
*,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_keyword(keywords: Set[str],
|
||||||
|
rule: Optional[Optional[Union[Rule, RuleChecker]]] = ...,
|
||||||
|
*,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_command(cmd: Union[str, Tuple[str, ...]],
|
||||||
|
rule: Optional[Union[Rule, RuleChecker]] = ...,
|
||||||
|
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
|
||||||
|
*,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def on_regex(pattern: str,
|
||||||
|
flags: Union[int, re.RegexFlag] = 0,
|
||||||
|
rule: Optional[Rule] = ...,
|
||||||
|
*,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def load_plugin(module_path: str) -> Optional[Plugin]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def load_plugins(*plugin_dir: str) -> Set[Plugin]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def load_builtin_plugins():
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def get_loaded_plugins() -> Set[Plugin]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class CommandGroup:
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
cmd: Union[str, Tuple[str, ...]],
|
||||||
|
rule: Optional[Union[Rule, RuleChecker]] = ...,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
*,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...):
|
||||||
|
...
|
||||||
|
|
||||||
|
def command(self,
|
||||||
|
cmd: Union[str, Tuple[str, ...]],
|
||||||
|
rule: Optional[Union[Rule, RuleChecker]] = ...,
|
||||||
|
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
|
||||||
|
permission: Optional[Permission] = ...,
|
||||||
|
*,
|
||||||
|
handlers: Optional[List[Handler]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[dict] = ...) -> Type[Matcher]:
|
||||||
|
...
|
@@ -1,10 +1,34 @@
|
|||||||
|
from functools import reduce
|
||||||
|
|
||||||
from nonebot.rule import to_me
|
from nonebot.rule import to_me
|
||||||
from nonebot.plugin import on_command
|
from nonebot.plugin import on_command
|
||||||
from nonebot.typing import Bot, Event
|
from nonebot.permission import SUPERUSER
|
||||||
|
from nonebot.typing import Bot, Event, MessageSegment
|
||||||
|
|
||||||
say = on_command("say", to_me())
|
say = on_command("say", to_me(), permission=SUPERUSER)
|
||||||
|
|
||||||
|
|
||||||
@say.handle()
|
@say.handle()
|
||||||
async def repeat(bot: Bot, event: Event, state: dict):
|
async def say_unescape(bot: Bot, event: Event, state: dict):
|
||||||
await bot.send(message=event.message, event=event)
|
Message = event.message.__class__
|
||||||
|
|
||||||
|
def _unescape(message: Message, segment: MessageSegment):
|
||||||
|
if segment.type == "text":
|
||||||
|
return message.append(segment.data["text"])
|
||||||
|
return message.append(segment)
|
||||||
|
|
||||||
|
message = reduce(_unescape, event.message, Message()) # type: ignore
|
||||||
|
await bot.send(message=message, event=event)
|
||||||
|
|
||||||
|
|
||||||
|
echo = on_command("echo", to_me())
|
||||||
|
|
||||||
|
|
||||||
|
@echo.handle()
|
||||||
|
async def echo_escape(bot: Bot, event: Event, state: dict):
|
||||||
|
Message = event.message.__class__
|
||||||
|
MessageSegment = event.message[0].__class__
|
||||||
|
|
||||||
|
message = Message().append( # type: ignore
|
||||||
|
MessageSegment.text(str(event.message)))
|
||||||
|
await bot.send(message=message, event=event)
|
||||||
|
@@ -1,13 +1,11 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
规则
|
规则
|
||||||
====
|
====
|
||||||
|
|
||||||
每个 ``Matcher`` 拥有一个 ``Rule`` ,其中是 **异步** ``RuleChecker`` 的集合,只有当所有 ``RuleChecker`` 检查结果为 ``True`` 时继续运行。
|
每个事件响应器 ``Matcher`` 拥有一个匹配规则 ``Rule`` ,其中是 **异步** ``RuleChecker`` 的集合,只有当所有 ``RuleChecker`` 检查结果为 ``True`` 时继续运行。
|
||||||
|
|
||||||
\:\:\:tip 提示
|
\:\:\:tip 提示
|
||||||
``RuleChecker`` 既可以是 async function 也可以是 sync function
|
``RuleChecker`` 既可以是 async function 也可以是 sync function,但在最终会被 ``nonebot.utils.run_sync`` 转换为 async function
|
||||||
\:\:\:
|
\:\:\:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -20,7 +18,7 @@ from pygtrie import CharTrie
|
|||||||
from nonebot import get_driver
|
from nonebot import get_driver
|
||||||
from nonebot.log import logger
|
from nonebot.log import logger
|
||||||
from nonebot.utils import run_sync
|
from nonebot.utils import run_sync
|
||||||
from nonebot.typing import Bot, Any, Dict, Event, Union, Tuple, NoReturn, Callable, Awaitable, RuleChecker
|
from nonebot.typing import Bot, Any, Dict, Event, Union, Tuple, NoReturn, Optional, Callable, Awaitable, RuleChecker
|
||||||
|
|
||||||
|
|
||||||
class Rule:
|
class Rule:
|
||||||
@@ -68,9 +66,11 @@ class Rule:
|
|||||||
*map(lambda c: c(bot, event, state), self.checkers))
|
*map(lambda c: c(bot, event, state), self.checkers))
|
||||||
return all(results)
|
return all(results)
|
||||||
|
|
||||||
def __and__(self, other: Union["Rule", RuleChecker]) -> "Rule":
|
def __and__(self, other: Optional[Union["Rule", RuleChecker]]) -> "Rule":
|
||||||
checkers = self.checkers.copy()
|
checkers = self.checkers.copy()
|
||||||
if isinstance(other, Rule):
|
if other is None:
|
||||||
|
return self
|
||||||
|
elif isinstance(other, Rule):
|
||||||
checkers |= other.checkers
|
checkers |= other.checkers
|
||||||
elif asyncio.iscoroutinefunction(other):
|
elif asyncio.iscoroutinefunction(other):
|
||||||
checkers.add(other) # type: ignore
|
checkers.add(other) # type: ignore
|
||||||
@@ -182,41 +182,97 @@ def endswith(msg: str) -> Rule:
|
|||||||
return Rule(_endswith)
|
return Rule(_endswith)
|
||||||
|
|
||||||
|
|
||||||
def keyword(msg: str) -> Rule:
|
def keyword(*keywords: str) -> Rule:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
匹配消息关键词
|
||||||
|
:参数:
|
||||||
|
* ``*keywords: str``: 关键词
|
||||||
|
"""
|
||||||
|
|
||||||
async def _keyword(bot: Bot, event: Event, state: dict) -> bool:
|
async def _keyword(bot: Bot, event: Event, state: dict) -> bool:
|
||||||
return bool(event.plain_text and msg in event.plain_text)
|
return bool(event.plain_text and
|
||||||
|
any(keyword in event.plain_text for keyword in keywords))
|
||||||
|
|
||||||
return Rule(_keyword)
|
return Rule(_keyword)
|
||||||
|
|
||||||
|
|
||||||
def command(command: Tuple[str, ...]) -> Rule:
|
def command(*cmds: Union[str, Tuple[str, ...]]) -> Rule:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
命令形式匹配,根据配置里提供的 ``command_start``, ``command_sep`` 判断消息是否为命令。
|
||||||
|
|
||||||
|
可以通过 ``state["_prefix"]["command"]`` 获取匹配成功的命令(例:``("test",)``),通过 ``state["_prefix"]["raw_command"]`` 获取匹配成功的原始命令文本(例:``"/test"``)。
|
||||||
|
:参数:
|
||||||
|
* ``*cmds: Union[str, Tuple[str, ...]]``: 命令内容
|
||||||
|
:示例:
|
||||||
|
使用默认 ``command_start``, ``command_sep`` 配置
|
||||||
|
|
||||||
|
命令 ``("test",)`` 可以匹配:``/test`` 开头的消息
|
||||||
|
命令 ``("test", "sub")`` 可以匹配”``/test.sub`` 开头的消息
|
||||||
|
|
||||||
|
\:\:\:tip 提示
|
||||||
|
命令内容与后续消息间无需空格!
|
||||||
|
\:\:\:
|
||||||
|
"""
|
||||||
|
|
||||||
config = get_driver().config
|
config = get_driver().config
|
||||||
command_start = config.command_start
|
command_start = config.command_start
|
||||||
command_sep = config.command_sep
|
command_sep = config.command_sep
|
||||||
if len(command) == 1:
|
commands = list(cmds)
|
||||||
for start in command_start:
|
for index, command in enumerate(commands):
|
||||||
TrieRule.add_prefix(f"{start}{command[0]}", command)
|
if isinstance(command, str):
|
||||||
else:
|
commands[index] = command = (command,)
|
||||||
for start, sep in product(command_start, command_sep):
|
|
||||||
TrieRule.add_prefix(f"{start}{sep.join(command)}", command)
|
if len(command) == 1:
|
||||||
|
for start in command_start:
|
||||||
|
TrieRule.add_prefix(f"{start}{command[0]}", command)
|
||||||
|
else:
|
||||||
|
for start, sep in product(command_start, command_sep):
|
||||||
|
TrieRule.add_prefix(f"{start}{sep.join(command)}", command)
|
||||||
|
|
||||||
async def _command(bot: Bot, event: Event, state: dict) -> bool:
|
async def _command(bot: Bot, event: Event, state: dict) -> bool:
|
||||||
return command == state["_prefix"]["command"]
|
return state["_prefix"]["command"] in commands
|
||||||
|
|
||||||
return Rule(_command)
|
return Rule(_command)
|
||||||
|
|
||||||
|
|
||||||
def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule:
|
def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
根据正则表达式进行匹配。
|
||||||
|
|
||||||
|
可以通过 ``state["_matched"]`` 获取正则表达式匹配成功的文本。
|
||||||
|
:参数:
|
||||||
|
* ``regex: str``: 正则表达式
|
||||||
|
* ``flags: Union[int, re.RegexFlag]``: 正则标志
|
||||||
|
|
||||||
|
\:\:\:tip 提示
|
||||||
|
正则表达式匹配使用 search 而非 match,如需从头匹配请使用 ``r"^xxx"`` 来确保匹配开头
|
||||||
|
\:\:\:
|
||||||
|
"""
|
||||||
|
|
||||||
pattern = re.compile(regex, flags)
|
pattern = re.compile(regex, flags)
|
||||||
|
|
||||||
async def _regex(bot: Bot, event: Event, state: dict) -> bool:
|
async def _regex(bot: Bot, event: Event, state: dict) -> bool:
|
||||||
return bool(pattern.search(str(event.message)))
|
matched = pattern.search(str(event.message))
|
||||||
|
if matched:
|
||||||
|
state["_matched"] = matched.group()
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
state["_matched"] = None
|
||||||
|
return False
|
||||||
|
|
||||||
return Rule(_regex)
|
return Rule(_regex)
|
||||||
|
|
||||||
|
|
||||||
def to_me() -> Rule:
|
def to_me() -> Rule:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
通过 ``event.to_me`` 判断消息是否是发送给机器人
|
||||||
|
:参数:
|
||||||
|
* 无
|
||||||
|
"""
|
||||||
|
|
||||||
async def _to_me(bot: Bot, event: Event, state: dict) -> bool:
|
async def _to_me(bot: Bot, event: Event, state: dict) -> bool:
|
||||||
return bool(event.to_me)
|
return bool(event.to_me)
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
计划任务
|
计划任务
|
||||||
========
|
========
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
"""
|
||||||
类型
|
类型
|
||||||
====
|
====
|
||||||
@@ -28,10 +26,10 @@ from typing import Union, TypeVar, Optional, Iterable, Callable, Awaitable
|
|||||||
# import some modules needed when checking types
|
# import some modules needed when checking types
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from nonebot.rule import Rule as RuleClass
|
from nonebot.rule import Rule as RuleClass
|
||||||
from nonebot.matcher import Matcher as MatcherClass
|
|
||||||
from nonebot.drivers import BaseDriver, BaseWebSocket
|
from nonebot.drivers import BaseDriver, BaseWebSocket
|
||||||
from nonebot.permission import Permission as PermissionClass
|
from nonebot.permission import Permission as PermissionClass
|
||||||
from nonebot.adapters import BaseBot, BaseEvent, BaseMessage, BaseMessageSegment
|
from nonebot.adapters import BaseBot, BaseEvent, BaseMessage, BaseMessageSegment
|
||||||
|
from nonebot.matcher import Matcher as MatcherClass, MatcherGroup as MatcherGroupClass
|
||||||
|
|
||||||
|
|
||||||
def overrides(InterfaceClass: object):
|
def overrides(InterfaceClass: object):
|
||||||
@@ -112,6 +110,14 @@ Matcher = TypeVar("Matcher", bound="MatcherClass")
|
|||||||
|
|
||||||
Matcher 即响应事件的处理类。通过 Rule 判断是否响应事件,运行 Handler。
|
Matcher 即响应事件的处理类。通过 Rule 判断是否响应事件,运行 Handler。
|
||||||
"""
|
"""
|
||||||
|
MatcherGroup = TypeVar("MatcherGroup", bound="MatcherGroupClass")
|
||||||
|
"""
|
||||||
|
:类型: ``MatcherGroup``
|
||||||
|
|
||||||
|
:说明:
|
||||||
|
|
||||||
|
MatcherGroup 为 Matcher 的集合。可以共享 Handler。
|
||||||
|
"""
|
||||||
Rule = TypeVar("Rule", bound="RuleClass")
|
Rule = TypeVar("Rule", bound="RuleClass")
|
||||||
"""
|
"""
|
||||||
:类型: ``Rule``
|
:类型: ``Rule``
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
#!/usr/bin/env python3
|
import re
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import asyncio
|
import asyncio
|
||||||
import dataclasses
|
import dataclasses
|
||||||
@@ -9,6 +7,18 @@ from functools import wraps, partial
|
|||||||
from nonebot.typing import Any, Callable, Awaitable, overrides
|
from nonebot.typing import Any, Callable, Awaitable, overrides
|
||||||
|
|
||||||
|
|
||||||
|
def escape_tag(s: str) -> str:
|
||||||
|
"""
|
||||||
|
:说明:
|
||||||
|
用于记录带颜色日志时转义 ``<tag>`` 类型特殊标签
|
||||||
|
:参数:
|
||||||
|
* ``s: str``: 需要转义的字符串
|
||||||
|
:返回:
|
||||||
|
- ``str``
|
||||||
|
"""
|
||||||
|
return re.sub(r"</?((?:[fb]g\s)?[^<>\s]*)>", r"\\\g<0>", s)
|
||||||
|
|
||||||
|
|
||||||
def run_sync(func: Callable[..., Any]) -> Callable[..., Awaitable[Any]]:
|
def run_sync(func: Callable[..., Any]) -> Callable[..., Awaitable[Any]]:
|
||||||
"""
|
"""
|
||||||
:说明:
|
:说明:
|
||||||
|
1695
package-lock.json
generated
14
package.json
@@ -20,14 +20,16 @@
|
|||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vuepress/plugin-back-to-top": "^1.5.4",
|
"@vuepress/plugin-back-to-top": "^1.7.1",
|
||||||
"@vuepress/plugin-medium-zoom": "^1.5.4",
|
"@vuepress/plugin-medium-zoom": "^1.7.1",
|
||||||
"vuepress": "^1.5.4",
|
"@vuepress/plugin-pwa": "^1.7.1",
|
||||||
"vuepress-plugin-versioning": "^4.5.0",
|
"vuepress": "^1.7.1",
|
||||||
"vuepress-theme-titanium": "^4.5.1"
|
"vuepress-plugin-versioning": "git+https://github.com/nonebot/vuepress-plugin-versioning.git",
|
||||||
|
"vuepress-theme-nonebot": "git+https://github.com/nonebot/vuepress-theme-nonebot.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vuetify": "^2.3.10",
|
"copy-to-clipboard": "^3.3.1",
|
||||||
|
"vuetify": "^2.3.16",
|
||||||
"wowjs": "^1.1.3"
|
"wowjs": "^1.1.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
pages/plugin-store.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
# 插件广场
|
||||||
|
|
||||||
|
<Plugins></Plugins>
|
1665
poetry.lock
generated
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "nonebot2"
|
name = "nonebot2"
|
||||||
version = "2.0.0a1"
|
version = "2.0.0a4"
|
||||||
description = "An asynchronous python bot framework."
|
description = "An asynchronous python bot framework."
|
||||||
authors = ["yanyongyu <yanyongyu_1@126.com>"]
|
authors = ["yanyongyu <yanyongyu_1@126.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@@ -24,15 +24,15 @@ include = ["nonebot/py.typed"]
|
|||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.7"
|
python = "^3.7"
|
||||||
httpx = "^0.13.3"
|
httpx = "^0.16.1"
|
||||||
loguru = "^0.5.1"
|
loguru = "^0.5.1"
|
||||||
pygtrie = "^2.3.3"
|
pygtrie = "^2.3.3"
|
||||||
fastapi = "^0.58.1"
|
fastapi = "^0.58.1"
|
||||||
uvicorn = "^0.11.5"
|
uvicorn = "^0.11.5"
|
||||||
pydantic = { extras = ["dotenv"], version = "^1.6.1" }
|
pydantic = { extras = ["dotenv"], version = "^1.6.1" }
|
||||||
apscheduler = { version = "^3.6.3", optional = true }
|
apscheduler = { version = "^3.6.3", optional = true }
|
||||||
# nonebot-test = { version = "^0.1.0", optional = true }
|
nonebot-test = { version = "^0.1.0", optional = true }
|
||||||
# nb-cli = { version="^0.1.0", optional = true }
|
nb-cli = { version="^0.2.0", optional = true }
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
yapf = "^0.30.0"
|
yapf = "^0.30.0"
|
||||||
@@ -40,8 +40,8 @@ sphinx = "^3.1.1"
|
|||||||
sphinx-markdown-builder = { git = "https://github.com/nonebot/sphinx-markdown-builder.git" }
|
sphinx-markdown-builder = { git = "https://github.com/nonebot/sphinx-markdown-builder.git" }
|
||||||
|
|
||||||
[tool.poetry.extras]
|
[tool.poetry.extras]
|
||||||
# cli = ["nb-cli"]
|
cli = ["nb-cli"]
|
||||||
# test = ["nonebot-test"]
|
test = ["nonebot-test"]
|
||||||
scheduler = ["apscheduler"]
|
scheduler = ["apscheduler"]
|
||||||
full = ["nb-cli", "nonebot-test", "scheduler"]
|
full = ["nb-cli", "nonebot-test", "scheduler"]
|
||||||
|
|
||||||
|
@@ -3,6 +3,9 @@ HOST=0.0.0.0
|
|||||||
PORT=2333
|
PORT=2333
|
||||||
DEBUG=true
|
DEBUG=true
|
||||||
|
|
||||||
|
SUPERUSERS=[123123123]
|
||||||
|
NICKNAME=["bot"]
|
||||||
|
|
||||||
COMMAND_START=["", "/", "#"]
|
COMMAND_START=["", "/", "#"]
|
||||||
COMMAND_SEP=["/", "."]
|
COMMAND_SEP=["/", "."]
|
||||||
|
|
||||||
|
@@ -1,6 +1,3 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
6
tests/test_plugins/test_group/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from nonebot.rule import to_me
|
||||||
|
from nonebot import CommandGroup
|
||||||
|
|
||||||
|
test = CommandGroup("test", rule=to_me())
|
||||||
|
|
||||||
|
from . import commands
|
11
tests/test_plugins/test_group/commands.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from nonebot.typing import Bot, Event
|
||||||
|
from nonebot.permission import GROUP_OWNER
|
||||||
|
|
||||||
|
from . import test
|
||||||
|
|
||||||
|
test_1 = test.command("1", aliases={"test"}, permission=GROUP_OWNER)
|
||||||
|
|
||||||
|
|
||||||
|
@test_1.handle()
|
||||||
|
async def test1(bot: Bot, event: Event, state: dict):
|
||||||
|
await test_1.finish(event.raw_message)
|
@@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from nonebot.rule import to_me
|
|
||||||
from nonebot.typing import Event
|
|
||||||
from nonebot.plugin import on_message
|
|
||||||
from nonebot.adapters.cqhttp import Bot
|
|
||||||
|
|
||||||
test_message = on_message(to_me(), state={"default": 1})
|
|
||||||
|
|
||||||
|
|
||||||
@test_message.handle()
|
|
||||||
async def test_handler(bot: Bot, event: Event, state: dict):
|
|
||||||
print("[*] Test Matcher Received:", event)
|
|
||||||
state["event"] = event
|
|
||||||
await bot.send(message="Received", event=event)
|
|
||||||
|
|
||||||
|
|
||||||
@test_message.receive()
|
|
||||||
async def test_receive(bot: Bot, event: Event, state: dict):
|
|
||||||
print("[*] Test Matcher Received next time:", event)
|
|
||||||
print("[*] Current State:", state)
|
|