mirror of
https://github.com/snowy-yang/qqbotsdk.git
synced 2026-10-21 12:24:49 +00:00
GUIDE/API 拆为 docs/guide/ 五页与 docs/api/ 七页,侧边栏分组折叠, 旧链接 alias 映射;安装改为 pip install qqbotsdk-py,README 加徽章; 删除 docs 分支同步工作流,pages.yml 直部署(自定义域名 CNAME 随产物带上)。
75 lines
3.4 KiB
Markdown
75 lines
3.4 KiB
Markdown
# 事件处理
|
||
|
||
handler 的注册、参数注入约定与后台并发。注入约定表只在本文。
|
||
|
||
## 注册
|
||
|
||
用装饰器把 handler 注册到 `Bot`,事件名即线上 payload 的 `t` 名(如 `GROUP_AT_MESSAGE_CREATE`)。参数按类型标注注入,可任意混用:
|
||
|
||
```python
|
||
from qqbotsdk import Bot
|
||
from qqbotsdk.api import BotApi
|
||
from qqbotsdk.events import Event
|
||
from qqbotsdk.payloads import GroupAtMessage, Interaction
|
||
|
||
bot = Bot()
|
||
|
||
|
||
# 标注 payload dataclass,拿到解析后的对象
|
||
@bot.on("GROUP_AT_MESSAGE_CREATE")
|
||
async def typed(msg: GroupAtMessage):
|
||
print(msg.group_openid, msg.user_openid, msg.content)
|
||
|
||
|
||
# payload 与组件任意组合;Event 拿完整信封(如按钮回调要 event_id)
|
||
@bot.on("INTERACTION_CREATE")
|
||
async def full(inter: Interaction, event: Event, api: BotApi):
|
||
...
|
||
```
|
||
|
||
handler 参数按标注解析的完整规则:
|
||
|
||
| 参数标注 | 得到 |
|
||
|---|---|
|
||
| payload dataclass(如 `GroupAtMessage`,全部类型见[事件 payload](/docs/api/events.md)) | 解析后的 dataclass 对象 |
|
||
| `Event` | 事件封装对象,只含信封语义(`.raw`/`.data`/`.typed`/`.type`/`.event_id`);事件体字段请标注 payload dataclass 获取 |
|
||
| 组件类型(`BotApi`/`Bot`/`Session`/`Config` 等已登记进 `bot.services` 的类型) | 按类型登记的实例 |
|
||
|
||
无标注或标注以上三者皆非的形参会在分发时抛 `ValueError`(记日志、按 handler 隔离)——SDK 不注入原始数据:要事件体字段就标注 payload dataclass,要完整信封就标注 `Event`。
|
||
|
||
## 注册与分发语义
|
||
|
||
- 只有**业务事件(op=0)**会分发给你的 handler;协议帧(HELLO/READY/INVALID_SESSION/op=13)由 SDK 的协议处理器就地处理,不触达 handler(`Ready` 是例外,它既是握手结果也是可监听的业务事件)。
|
||
- 同一函数对同一事件重复注册只生效一次;handler 按注册顺序串行执行(`background=True` 的除外)。
|
||
- 业务事件处理器的**返回值不会回流**,回复消息请在 handler 里显式调 API。
|
||
- 单个 handler 抛异常只记录日志,不影响同事件其他 handler 和主循环。
|
||
- 所在分组未订阅(intents.toml 中为 `false`)的事件不会到达 handler(见[配置与订阅](/docs/guide/config.md))。
|
||
|
||
## 后台并发 handler
|
||
|
||
默认同一事件的所有 handler 串行执行,某个慢 handler 会延迟后续事件。调用密集、不关心先后顺序的 handler 可加 `background=True` 丢进后台任务,事件流不再等它:
|
||
|
||
```python
|
||
@bot.on("GROUP_AT_MESSAGE_CREATE", background=True)
|
||
async def slow_work(msg: GroupAtMessage, api: BotApi):
|
||
... # 耗时处理,不阻塞其他事件的分发
|
||
```
|
||
|
||
代价是同一事件内 handler 间失去先后保证,因此仅用于业务 handler。`bot.run()` 退出时统一取消在飞的后台任务。
|
||
|
||
## 自定义组件注入
|
||
|
||
`bot.services` 是 `dict[type, Any]` 组件登记表:SDK 启动时登记内置组件(`Bot`/`EventEmitter`/`EventQueue`/`Config`/`Session`/`ClientSession`/`AccessToken`/`BotApi`),你也可以登记自定义类型:
|
||
|
||
```python
|
||
bot = Bot()
|
||
bot.services[MyService] = MyService(...) # 任意时机登记(启动前后皆可)
|
||
|
||
|
||
@bot.on("GROUP_AT_MESSAGE_CREATE")
|
||
async def with_service(msg: GroupAtMessage, svc: MyService):
|
||
... # 形参标注 MyService 即拿到实例
|
||
```
|
||
|
||
services 命中在每条事件分发时实时判定,"先注册 handler、后登记组件"的顺序可用。
|