From 389e83b4f7ae55e76f37260966de5add348731e1 Mon Sep 17 00:00:00 2001 From: Richard Chien Date: Fri, 31 Jan 2020 13:08:17 +0800 Subject: [PATCH] Update docs --- docs/.vuepress/config.js | 2 +- docs/advanced/scheduler.md | 81 +++++++------------ docs/advanced/server-app.md | 36 ++++++--- docs/guide/command.md | 4 - .../{calling-cqhttp-api.md => cqhttp.md} | 16 +++- 5 files changed, 67 insertions(+), 72 deletions(-) rename docs/guide/{calling-cqhttp-api.md => cqhttp.md} (69%) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index d20fd38b..cc2868a0 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -46,7 +46,7 @@ module.exports = { 'nl-processor', 'tuling', 'notice-and-request', - 'calling-cqhttp-api', + 'cqhttp', 'scheduler', 'usage', 'whats-next', diff --git a/docs/advanced/scheduler.md b/docs/advanced/scheduler.md index da20cc4e..e17950a8 100644 --- a/docs/advanced/scheduler.md +++ b/docs/advanced/scheduler.md @@ -1,44 +1,31 @@ # 计划任务 -nonebot 内置了 apscheduler, -通过`from nonebot import scheduler`获取, -这是一个`AsyncIOScheduler`的实例, -详细用法可见[官方文档](https://apscheduler.readthedocs.io/)。 - -这里列出一些常见的用法。 +NoneBot 可选地内置了计划任务功能,在指南的 [添加计划任务](../guide/scheduler.md) 已经进行了简单的介绍。这里列出更多常见的用法。 ## 固定的计划任务 -利用固定的*触发器*(trigger)来触发某些任务 +可以利用固定的*触发器*(trigger)来触发某些任务。 ### 一次性任务 -`date`触发器 -[完整文档](https://apscheduler.readthedocs.io/en/stable/modules/triggers/date.html#module-apscheduler.triggers.date) - -固定时间触发,仅触发一次 +[`date` 触发器](https://apscheduler.readthedocs.io/en/stable/modules/triggers/date.html#module-apscheduler.triggers.date) 固定时间触发,仅触发一次: ```python from datetime import datetime @nonebot.scheduler.scheduled_job( - 'cron', + 'date', run_date=datetime(2021, 1, 1, 0, 0), # timezone=None, - ) +) async def _(): - await bot.send_group_msg(group_id=672076603, + await bot.send_group_msg(group_id=123456, message="2021,新年快乐!") ``` ### 定期任务 -`cron`触发器 -[完整文档](https://apscheduler.readthedocs.io/en/stable/modules/triggers/cron.html#module-apscheduler.triggers.cron) - -从`start_date`开始,每一个固定时间触发,到`end_date`结束 - -比如每小时、每个工作日早上8点 +[`cron` 触发器](https://apscheduler.readthedocs.io/en/stable/modules/triggers/cron.html#module-apscheduler.triggers.cron) 从 `start_date` 开始到 `end_date` 结束,根据类似 [Cron](https://wiki.archlinux.org/index.php/Cron_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)) 的规则触发任务: ```python @nonebot.scheduler.scheduled_job( @@ -54,18 +41,15 @@ async def _(): # start_date=None, # end_date=None, # timezone=None, - ) +) async def _(): - await bot.send_group_msg(group_id=672076603, + await bot.send_group_msg(group_id=123456, message="起床啦!") ``` ### 间隔任务 -`interval`触发器 -[完整文档](https://apscheduler.readthedocs.io/en/stable/modules/triggers/interval.html#module-apscheduler.triggers.interval) - -从`start_date`开始,每间隔一段时间触发,到`end_date`结束 +[`interval` 触发器](https://apscheduler.readthedocs.io/en/stable/modules/triggers/interval.html#module-apscheduler.triggers.interval) 从 `start_date` 开始,每间隔一段时间触发,到 `end_date` 结束: ```python @nonebot.scheduler.scheduled_job( @@ -77,20 +61,17 @@ async def _(): # seconds=0, # start_date=time.now(), # end_date=None, - ) +) async def _(): has_new_item = check_new_item() if has_new_item: - await bot.send_group_msg(group_id=672076603, - message="RC更新啦!") + await bot.send_group_msg(group_id=123456, + message="XX有更新啦!") ``` ## 动态的计划任务 -有时,我们需要机器人在运行的过程中,添加一些计划任务, -那么我们就需要 `scheduler.add_job` 来帮忙 - -这里,我们以*一次性任务*为例,其他类型的任务可以用相同的方法 +有时,我们需要机器人在运行的过程中,添加或删除计划任务,那么我们就需要 `scheduler.add_job` 来帮忙。这里,我们以*一次性任务*为例,其他类型的任务可以用相同的方法: ```python import datetime @@ -112,27 +93,22 @@ async def _(session: CommandSession): # 添加任务 scheduler.add_job( - func=session.send, # 要添加任务的函数,不要带参数 - trigger=trigger, # 触发器 - args=('不要再赖床啦!',), # 函数的参数列表,注意:只有一个值时,不能省略末尾的逗号 + func=session.send, # 要添加任务的函数,不要带参数 + trigger=trigger, # 触发器 + args=('不要再赖床啦!',), # 函数的参数列表,注意:只有一个值时,不能省略末尾的逗号 # kwargs=None, - misfire_grace_time=60, # 允许的误差时间,建议不要省略 - # jobstore='default', # 任务储存库,在下一小节中说明 + misfire_grace_time=60, # 允许的误差时间,建议不要省略 + # jobstore='default', # 任务储存库,在下一小节中说明 ) ``` -## 储存任务 + diff --git a/docs/advanced/server-app.md b/docs/advanced/server-app.md index 85f00152..07a8e4c9 100644 --- a/docs/advanced/server-app.md +++ b/docs/advanced/server-app.md @@ -2,22 +2,38 @@ 如果需要对 web 框架进行更详细的控制,可以通过 `bot.server_app` 访问到内部的 Quart 对象,之后可以像使用 Quart 的 app 对象一样添加路由、设置生命周期处理函数等。 +::: tip 提示 +Quart 是一个与 Flask 具有相同 API 的异步 web 框架,其用法可以参考 [官方文档](https://pgjones.gitlab.io/quart/)。 +::: + ## 自定义路由 -### 简单的主页 +这里以一个简单的管理页面为例: ```python -from nonebot import get_bot -bot = get_bot() +import nonebot -@bot.server_app.route('/') -async def hello_world(): - await bot.send_private_msg(1002647525, '你的主页被访问了') - return '欢迎来到我的主页' +bot = nonebot.get_bot() # 在此之前必须已经 init + +@bot.server_app.route('/admin') +async def admin(): + await bot.send_private_msg(12345678, '你的主页被访问了') + return '欢迎来到管理页面' ``` -启动 nonebot 后访问 ,你会看见主页的欢迎词,并收到机器人的提醒。 +启动 NoneBot 后访问 ,你会看见管理页面的欢迎词,并收到机器人的提醒。 -### 更多应用 +## 处理生命周期事件 -Quart 是一个与 Flask 具有相同 API 的异步 web 框架,其用法可以参考[Flask官方文档](https://flask.palletsprojects.com/)或它的[简中翻译版本](http://docs.jinkan.org/docs/flask/),关于 Quart 可以参考[Quart官方文档](https://pgjones.gitlab.io/quart/) +有时可能需要在 NoneBot 启动时初始化数据库连接池,例如: + +```python +import nonebot + +bot = nonebot.get_bot() # 在此之前必须已经 init + +@bot.server_app.before_serving +async def init_db(): + # 这会在 NoneBot 启动后立即运行 + pass +``` diff --git a/docs/guide/command.md b/docs/guide/command.md index 1da92f31..e8080985 100644 --- a/docs/guide/command.md +++ b/docs/guide/command.md @@ -201,7 +201,3 @@ async def _(session: CommandSession): ``` 观察看看有什么不同,以及它的回复是否符合我们对代码的理解。如果成功的话,此时你已经完成了一个**可交互的**天气查询命令的雏形,只需要再接入天气 API 就可以真正投入使用了! - -## 获取对话细节 - -如果我们需要获取对话中更多的细节,如发送者的群名片、群专属头衔、性别等参数,可以通过 `session.ctx` 获取原始的数据。数据格式详见[CQHTTP文档](https://cqhttp.cc/docs/#/Post?id=%E4%BA%8B%E4%BB%B6%E5%88%97%E8%A1%A8)。 diff --git a/docs/guide/calling-cqhttp-api.md b/docs/guide/cqhttp.md similarity index 69% rename from docs/guide/calling-cqhttp-api.md rename to docs/guide/cqhttp.md index 2d8d28dd..d2197f49 100644 --- a/docs/guide/calling-cqhttp-api.md +++ b/docs/guide/cqhttp.md @@ -1,10 +1,18 @@ -# 主动调用 CQHTTP 接口 +# CQHTTP 事件和 API -到目前为止,我们都在调用 `CommandSession` 类的 `send()` 方法,而这个方法只能回复给消息的发送方,不能手动指定发送者,因此当我们需要实现将收到的消息经过处理后转发给另一个接收方这样的功能时,这个方法就用不了了。 +到目前为止,我们都在使用 NoneBot 显式提供的接口,但实际上 CQHTTP 插件还提供了更多的事件数据和 API,可能利用这些它们实现更加自由的逻辑。 -幸运的是,`NoneBot` 类是继承自 [python-aiocqhttp] 的 `CQHttp` 类的,而这个类实现了一个 `__getattr__()` 方法,由此提供了直接通过 bot 对象调用 CQHTTP 的 API 的能力。 +## 事件数据 -[python-aiocqhttp]: https://github.com/richardchien/python-aiocqhttp +在 [发生了什么?](./whats-happened.md) 中我们提到,收到 酷Q 事件后,CQHTTP 通过反向 WebSocket 给 NoneBot 发送事件数据。这些数据被 NoneBot 放在了 `session.ctx` 中,是一个字典,你可以通过断点调试或打印等方式查看它的内容,其中的字段名和含义见 CQHTTP 的 [事件列表](https://cqhttp.cc/docs/#/Post?id=事件列表) 中的「上报数据」。 + +## API 调用 + +前面我们已经多次调用 `CommandSession` 类的 `send()` 方法,而这个方法只能回复给消息的发送方,不能手动指定发送者,因此当我们需要实现将收到的消息经过处理后转发给另一个接收方这样的功能时,这个方法就用不了了。 + +幸运的是,`NoneBot` 类是继承自 [python-aiocqhttp] 的 `CQHttp` 类的,而这个类实现了 `__getattr__()` 魔术方法,由此提供了直接通过 bot 对象调用 CQHTTP 的 API 的能力。 + +[python-aiocqhttp]: https://github.com/cqmoe/python-aiocqhttp ::: tip 提示 如果你在使用 HTTP 通信,要调用 CQHTTP API 要在 `config.py` 中添加: