docs: README/CHANGELOG 同步——方式三改写、CI 与文档站部署说明

README 方式三示例从 event.user_id/group_id/content/message_id 改为
typed payload + 组件注入组合;开发节补 CI 与 Cloudflare Pages 部署
说明;CHANGELOG Unreleased 记录 Event 兼容属性移除(破坏性)、
Gitea Actions CI 与文档站部署三项。
This commit is contained in:
snowy-yang committed 2026-09-24 20:18:46 +08:00
1 parent 35e501aabb
commit f45299f92c
2 files changed
+14 -6

No files matched your search

+3
View File
@@ -21,6 +21,8 @@
- 群消息全量模式:新增 `GROUP_MESSAGE_CREATE` 事件接收,与 `GROUP_AT_MESSAGE_CREATE` 共用 `GroupAtMessage`(需在开放平台开通"接收所有消息"权限,不限 @机器人);`GroupAtMessage` 补齐官方新增的 `message_type`/`message_scene`/`attachments`/`mentions`/`ark_data`/`msg_elements` 字段 - 群消息全量模式:新增 `GROUP_MESSAGE_CREATE` 事件接收,与 `GROUP_AT_MESSAGE_CREATE` 共用 `GroupAtMessage`(需在开放平台开通"接收所有消息"权限,不限 @机器人);`GroupAtMessage` 补齐官方新增的 `message_type`/`message_scene`/`attachments`/`mentions`/`ark_data`/`msg_elements` 字段
- **连接寿命主动重连**:服务端约 1 小时后会无预警断开连接(实测),故连接存活到 `_SERVER_LIFETIME - _RECONNECT_MARGIN`(默认 60min − 10min = 50min)时由 SDK 主动收尾重连——走正常 RESUME 续传、期间消息由网关补发,而不是被服务端掐断后由看门狗判成异常断开;收帧超时在"静默阈值"与"寿命余量"两个截止里取先到者,静默仍归看门狗处理 - **连接寿命主动重连**:服务端约 1 小时后会无预警断开连接(实测),故连接存活到 `_SERVER_LIFETIME - _RECONNECT_MARGIN`(默认 60min − 10min = 50min)时由 SDK 主动收尾重连——走正常 RESUME 续传、期间消息由网关补发,而不是被服务端掐断后由看门狗判成异常断开;收帧超时在"静默阈值"与"寿命余量"两个截止里取先到者,静默仍归看门狗处理
- 文档站点:基于 docsify(侧边栏、全文搜索、代码复制、mermaid 图渲染、分页),`npx docsify-cli serve` 本地预览;新增 `examples/README.md` 示例索引 - 文档站点:基于 docsify(侧边栏、全文搜索、代码复制、mermaid 图渲染、分页),`npx docsify-cli serve` 本地预览;新增 `examples/README.md` 示例索引
- Gitea Actions CI:push(main)/Pull Request/手动触发时自动执行 `ruff check` 与 `pyright`(`.gitea/workflows/ci.yml`,uv 同步依赖后运行与本地开发一致的检查命令)
- 文档站线上部署:`scripts/deploy_docs.sh` 组装纯文档目录(不携带源码)并经 wrangler 上传 Cloudflare Pages(Direct Upload,零构建);`.gitea/workflows/deploy-docs.yml` 在 main 的文档文件变更时自动部署
### 变更 ### 变更
@@ -45,6 +47,7 @@
### 移除 ### 移除
- **`Event` 的字段名映射属性 `user_id`/`group_id`/`content`/`message_id`**(含旧版群消息 payload 顶层 `from_user_id` 字段的回退):`Event` 收敛为推送信封封装,只保留 `.raw`/`.data`/`.typed`/`.type`/`.event_id`;事件体字段一律标注 payload dataclass(如 `msg: GroupAtMessage`)获取解析结果,或经 `.data`/`.raw` 自取。破坏性变更:原 `event.group_id` 改为 typed payload 的 `msg.group_openid`,`event.message_id` 改为 `msg.id`,以此类推
- `EventEmitter.register_protocol()`、`EventEmitter.handle()` 与 `emitter` 持有协议层的机制(协议处理器改为由 connecter 持有并逐帧调用,见上文"变更") - `EventEmitter.register_protocol()`、`EventEmitter.handle()` 与 `emitter` 持有协议层的机制(协议处理器改为由 connecter 持有并逐帧调用,见上文"变更")
- apscheduler 依赖(心跳迁入 connecter 后不再需要调度器) - apscheduler 依赖(心跳迁入 connecter 后不再需要调度器)
- 音乐插件示例(`plugins/`、根目录 `main.py`)已拆分为独立的点歌 bot 项目(含 Markdown 卡片、按钮回调与内置短网址多线程下载代理),不再随 SDK 仓库分发 - 音乐插件示例(`plugins/`、根目录 `main.py`)已拆分为独立的点歌 bot 项目(含 Markdown 卡片、按钮回调与内置短网址多线程下载代理),不再随 SDK 仓库分发
+11 -6
View File
@@ -86,19 +86,20 @@ from qqbotsdk.payloads import GroupAtMessage
async def on_group_message(msg: GroupAtMessage): async def on_group_message(msg: GroupAtMessage):
print(msg.group_openid, msg.user_openid, msg.content) print(msg.group_openid, msg.user_openid, msg.content)
# 方式三:参数注入(按形参标注解析,`BotApi` 等组件由 SDK 装配) # 方式三:参数注入(按形参标注装配,payload 与 `BotApi` 等组件可任意组合)
from qqbotsdk.api import BotApi from qqbotsdk.api import BotApi
from qqbotsdk.events import Event from qqbotsdk.events import Event
from qqbotsdk.payloads import GroupAtMessage
@ee.on("GROUP_AT_MESSAGE_CREATE") @ee.on("GROUP_AT_MESSAGE_CREATE")
async def handle(event: Event, api: BotApi): async def handle(msg: GroupAtMessage, event: Event, api: BotApi):
print(event.user_id, event.group_id, event.content) print(event.event_id) # 信封信息(op/t/d/id)经 Event 取用,事件字段走 payload
# 被动回复:带 msg_id(群聊 5 分钟/单聊 60 分钟内有效,最多分别回复 5/4 次); # 被动回复:带 msg_id(群聊 5 分钟/单聊 60 分钟内有效,最多分别回复 5/4 次);
# 同一条消息多次回复递增 msg_seq # 同一条消息多次回复递增 msg_seq
await api.post_group_message( await api.post_group_message(
event.group_id, msg.group_openid,
content=f"你说:{event.content}", content=f"你说:{msg.content}",
msg_id=event.message_id, msg_id=msg.id,
) # 失败抛 ApiError;富媒体先 upload_group_file 拿 file_info ) # 失败抛 ApiError;富媒体先 upload_group_file 拿 file_info
# 业务事件(op=0)才进分发,返回值不回流,回复请显式调 BotApi; # 业务事件(op=0)才进分发,返回值不回流,回复请显式调 BotApi;
@@ -128,12 +129,16 @@ uv run pytest # 单元测试
uv run ruff check src tests examples && uv run pyright uv run ruff check src tests examples && uv run pyright
``` ```
推送到 main 与 Pull Request 会由 Gitea Actions 自动执行同样的 ruff + pyright 检查([.gitea/workflows/ci.yml](.gitea/workflows/ci.yml))。
文档站点基于 [docsify](https://docsify.js.org/)(无需构建,仓库根 `index.html` + Markdown),本地预览: 文档站点基于 [docsify](https://docsify.js.org/)(无需构建,仓库根 `index.html` + Markdown),本地预览:
```bash ```bash
npx docsify-cli serve # 打开 http://localhost:3000 npx docsify-cli serve # 打开 http://localhost:3000
``` ```
线上部署在 Cloudflare Pages(Direct Upload,Gitea 无法走 Pages 的 Git 直连):`bash scripts/deploy_docs.sh` 组装 `dist/` 并经 wrangler 上传,站点地址 `https://<项目名>.pages.dev`;项目名默认 `qqbotsdk-docs`,可传参或 `PROJECT_NAME` 覆盖。CI 自动部署:Gitea 仓库配置 `CLOUDFLARE_API_TOKEN`(权限 Account → Cloudflare Pages → Edit)与 `CLOUDFLARE_ACCOUNT_ID` 两个 secrets 后,main 上文档文件变更即自动部署([.gitea/workflows/deploy-docs.yml](.gitea/workflows/deploy-docs.yml))。
## 待完善 ## 待完善
- 更多 OpenAPI 封装(按需在 `api.py` 的 `BotApi` 上加薄封装即可) - 更多 OpenAPI 封装(按需在 `api.py` 的 `BotApi` 上加薄封装即可)