viseron-qqbotpy 0.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- viseron_qqbotpy-0.4.2/PKG-INFO +226 -0
- viseron_qqbotpy-0.4.2/README.md +194 -0
- viseron_qqbotpy-0.4.2/pyproject.toml +47 -0
- viseron_qqbotpy-0.4.2/setup.cfg +4 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/__init__.py +101 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/api.py +1294 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/client.py +317 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/dispatcher.py +209 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/env.py +61 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/errors.py +109 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/ext/__init__.py +18 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/ext/channel_jump.py +20 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/ext/command.py +62 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/ext/config.py +28 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/ext/convert_color.py +47 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/ext/scheduler.py +20 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/flags.py +218 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/gateway.py +276 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/group_store.py +157 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/http.py +164 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/logging.py +123 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/models.py +649 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/panel.py +339 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/py.typed +0 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/token.py +181 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/types.py +373 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy/webhook.py +74 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy.egg-info/PKG-INFO +226 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy.egg-info/SOURCES.txt +39 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy.egg-info/dependency_links.txt +1 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy.egg-info/requires.txt +13 -0
- viseron_qqbotpy-0.4.2/src/viseron_qqbotpy.egg-info/top_level.txt +1 -0
- viseron_qqbotpy-0.4.2/tests/test_docs_coverage.py +55 -0
- viseron_qqbotpy-0.4.2/tests/test_flags.py +26 -0
- viseron_qqbotpy-0.4.2/tests/test_group_api.py +187 -0
- viseron_qqbotpy-0.4.2/tests/test_group_store.py +62 -0
- viseron_qqbotpy-0.4.2/tests/test_live.py +54 -0
- viseron_qqbotpy-0.4.2/tests/test_media_api.py +199 -0
- viseron_qqbotpy-0.4.2/tests/test_message_card.py +123 -0
- viseron_qqbotpy-0.4.2/tests/test_panel.py +34 -0
- viseron_qqbotpy-0.4.2/tests/test_token.py +93 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: viseron-qqbotpy
|
|
3
|
+
Version: 0.4.2
|
|
4
|
+
Summary: A modern, asyncio-based Python SDK for the QQ Open Platform Bot API (api-v2).
|
|
5
|
+
Author: Viseron
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://bot.q.qq.com/wiki/develop/api-v2/
|
|
8
|
+
Project-URL: Documentation, https://bot.q.qq.com/wiki/develop/api-v2/
|
|
9
|
+
Keywords: qq,qqbot,qq-bot,qq机器人,sdk,websocket,bot
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: aiohttp<4,>=3.7.4
|
|
23
|
+
Provides-Extra: ext
|
|
24
|
+
Requires-Dist: PyYAML>=6; extra == "ext"
|
|
25
|
+
Requires-Dist: APScheduler>=3.10; extra == "ext"
|
|
26
|
+
Provides-Extra: webhook
|
|
27
|
+
Requires-Dist: cryptography>=41; extra == "webhook"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
31
|
+
Requires-Dist: python-dotenv>=1; extra == "dev"
|
|
32
|
+
|
|
33
|
+
# viseron-qqbotpy
|
|
34
|
+
|
|
35
|
+
一个基于 **asyncio + aiohttp** 的 QQ 机器人 Python SDK,针对
|
|
36
|
+
[QQ 机器人开放平台 API v2](https://bot.q.qq.com/wiki/develop/api-v2/) 重新设计。
|
|
37
|
+
|
|
38
|
+
它参考了旧版 qq-botpy 的 API 形状,但内部实现是重写的:共享 HTTP 会话、
|
|
39
|
+
无中断的 access_token 刷新、由 Hello 事件驱动的心跳、更清晰的错误与事件模型。
|
|
40
|
+
|
|
41
|
+
## 特性
|
|
42
|
+
|
|
43
|
+
- 使用 appid + secret 获取 access token,并支持 **过期前 60 秒无缝刷新**
|
|
44
|
+
- WebSocket 网关:Identify / Resume / Heartbeat / 分片 / 断线重连
|
|
45
|
+
- 覆盖频道、群聊、单聊、身份组、成员、消息、表情、日程、论坛、音频、公告、
|
|
46
|
+
接口权限、富媒体上传、入群审批、指令面板、自定义菜单等 API
|
|
47
|
+
- 本地文件分片上传一键封装:upload_group_media / upload_c2c_media
|
|
48
|
+
- 本地群聊状态管理:GroupStore 自动把机器人加入过的群记录到 groups.json
|
|
49
|
+
- 群成员管理:群成员列表/详情、批量移除、群黑名单查询与操作(平台 2026-09-03 新增,内邀能力)
|
|
50
|
+
- Markdown 素材管理:图片上传到平台并获取 qqbot-media:// 引用,一条 upload_markdown_image 搞定(平台 2026-10-21 新增)
|
|
51
|
+
- 图文卡片消息(msg_type=8)与群聊 @全部成员常量 AT_EVERYONE(平台 2026-10-26 / 10-28 新增)
|
|
52
|
+
- 指令面板管理:Panel / PanelStore 用 panels/panels.json 配置并同步到平台
|
|
53
|
+
- 事件模型为 dataclass,同时保留完整原始 payload(raw 字段)
|
|
54
|
+
- 可选 Webhook Ed25519 签名验证
|
|
55
|
+
|
|
56
|
+
## 使用文档
|
|
57
|
+
|
|
58
|
+
完整使用文档见 docs/ 目录:
|
|
59
|
+
|
|
60
|
+
- docs/getting-started.md:安装、快速开始、Intents、直接调用 API
|
|
61
|
+
- docs/core.md:SDK 基础能力,如 Client、TokenManager、BotAPI、日志、异常等
|
|
62
|
+
- docs/events.md:事件监听、事件表、事件对象字段
|
|
63
|
+
- docs/features.md:常见功能实现示例
|
|
64
|
+
- docs/api-reference.md:API 方法参考
|
|
65
|
+
- docs/ext.md:命令装饰器、颜色转换等扩展
|
|
66
|
+
- docs/management.md:面板与群管理、本地配置同步
|
|
67
|
+
- docs/automation.md:QQ 文档同步自动化任务与版本规则
|
|
68
|
+
- docs/webhook.md:Webhook 签名验证
|
|
69
|
+
- docs/publish.md:构建、上架 PyPI、安装与下载方式
|
|
70
|
+
|
|
71
|
+
## 安装
|
|
72
|
+
|
|
73
|
+
cd viseron-botpy
|
|
74
|
+
pip install -e .
|
|
75
|
+
|
|
76
|
+
开发模式安装额外依赖:
|
|
77
|
+
|
|
78
|
+
pip install -e ".[dev]"
|
|
79
|
+
|
|
80
|
+
## 快速开始
|
|
81
|
+
|
|
82
|
+
import os
|
|
83
|
+
from pathlib import Path
|
|
84
|
+
|
|
85
|
+
from viseron_qqbotpy import Client, Intents, Message, configure_logging, load_env
|
|
86
|
+
|
|
87
|
+
# 读取项目根目录的 .env
|
|
88
|
+
load_env(Path(__file__).resolve().parents[1] / ".env")
|
|
89
|
+
|
|
90
|
+
# 使用 SDK 默认日志格式,并写入 logs/viseron_qqbotpy.log
|
|
91
|
+
configure_logging()
|
|
92
|
+
|
|
93
|
+
APPID = os.getenv("APPID", "")
|
|
94
|
+
APPSECRET = os.getenv("APPSECRET", "")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class MyBot(Client):
|
|
98
|
+
async def on_ready(self):
|
|
99
|
+
print("机器人已上线")
|
|
100
|
+
|
|
101
|
+
async def on_at_message_create(self, message: Message):
|
|
102
|
+
await message.reply(content=f"收到: {message.content}")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
if __name__ == "__main__":
|
|
106
|
+
bot = MyBot(intents=Intents.default())
|
|
107
|
+
bot.run(appid=APPID, secret=APPSECRET)
|
|
108
|
+
|
|
109
|
+
更多事件与用法见 examples/ 和 docs/。
|
|
110
|
+
|
|
111
|
+
## 事件订阅
|
|
112
|
+
|
|
113
|
+
创建客户端时传入 Intents:
|
|
114
|
+
|
|
115
|
+
intents = Intents.default() # 公域事件
|
|
116
|
+
intents = Intents.all() # 全部事件(需私域权限)
|
|
117
|
+
intents = Intents(guilds=True, public_guild_messages=True)
|
|
118
|
+
|
|
119
|
+
网关事件名会映射为 on_<event_type小写>,例如:
|
|
120
|
+
|
|
121
|
+
- AT_MESSAGE_CREATE -> on_at_message_create
|
|
122
|
+
- GROUP_AT_MESSAGE_CREATE -> on_group_at_message_create
|
|
123
|
+
- C2C_MESSAGE_CREATE -> on_c2c_message_create
|
|
124
|
+
- INTERACTION_CREATE -> on_interaction_create
|
|
125
|
+
- GROUP_MEMBER_ADD -> on_group_member_add
|
|
126
|
+
- READY / RESUMED -> on_ready / on_resumed(无参数)
|
|
127
|
+
|
|
128
|
+
## 本地面板与群聊状态
|
|
129
|
+
|
|
130
|
+
SDK 可以把群聊状态和指令面板配置保存在本地:
|
|
131
|
+
|
|
132
|
+
- groups.json:机器人加入过的群,由 Client 自动维护,无需手动调用。
|
|
133
|
+
- panels/panels.json:你自己维护的面板配置;panels/store.json 由 SDK 记录 panel_id 映射。
|
|
134
|
+
|
|
135
|
+
from viseron_qqbotpy import Client, Intents, load_panels
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class MyBot(Client):
|
|
139
|
+
async def on_ready(self):
|
|
140
|
+
# 把 panels/panels.json 同步到平台
|
|
141
|
+
store = await load_panels(self.api, root_dir="panels")
|
|
142
|
+
await store.sync_from_config()
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
bot = MyBot(
|
|
147
|
+
intents=Intents.default(),
|
|
148
|
+
group_store_path="data/groups.json",
|
|
149
|
+
group_store_retention_days=30,
|
|
150
|
+
)
|
|
151
|
+
bot.run(appid=APPID, secret=APPSECRET)
|
|
152
|
+
|
|
153
|
+
详细说明见 docs/management.md。
|
|
154
|
+
|
|
155
|
+
## 直接调用 API
|
|
156
|
+
|
|
157
|
+
在 Client 子类中,可以直接使用 self.api:
|
|
158
|
+
|
|
159
|
+
class MyBot(Client):
|
|
160
|
+
async def on_ready(self):
|
|
161
|
+
guilds = await self.api.me_guilds()
|
|
162
|
+
print(guilds)
|
|
163
|
+
|
|
164
|
+
如果只需要 HTTP API,不连接 WebSocket:
|
|
165
|
+
|
|
166
|
+
import asyncio
|
|
167
|
+
|
|
168
|
+
from viseron_qqbotpy import BotAPI, HTTPClient, TokenManager
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
async def main():
|
|
172
|
+
token = TokenManager("你的 AppID", "你的 AppSecret")
|
|
173
|
+
http = HTTPClient(token)
|
|
174
|
+
api = BotAPI(http)
|
|
175
|
+
|
|
176
|
+
me = await api.me()
|
|
177
|
+
print(me)
|
|
178
|
+
|
|
179
|
+
await http.close()
|
|
180
|
+
await token.close()
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
asyncio.run(main())
|
|
184
|
+
|
|
185
|
+
## Access Token 刷新机制
|
|
186
|
+
|
|
187
|
+
- 平台 access token 默认 7200 秒有效。
|
|
188
|
+
- 在 token 剩余有效期进入最后 60 秒时,SDK 会透明地获取新 token 并切换;
|
|
189
|
+
此时新旧 token 都有效,因此不会中断正在执行的请求。
|
|
190
|
+
- 如果刷新失败但旧 token 尚未过期,SDK 会继续使用旧 token,并在下一次调用时重试。
|
|
191
|
+
- 可通过 TokenManager 单独使用该能力。
|
|
192
|
+
|
|
193
|
+
## Webhook 签名验证
|
|
194
|
+
|
|
195
|
+
from viseron_qqbotpy.webhook import verify_signature, sign_validation
|
|
196
|
+
|
|
197
|
+
ok = verify_signature(
|
|
198
|
+
secret="AppSecret",
|
|
199
|
+
timestamp=request.headers["X-Signature-Timestamp"],
|
|
200
|
+
body=request.body.decode(),
|
|
201
|
+
signature_hex=request.headers["X-Signature-Ed25519"],
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
## 项目结构
|
|
205
|
+
|
|
206
|
+
src/viseron_qqbotpy/
|
|
207
|
+
client.py # Client 入口
|
|
208
|
+
api.py # OpenAPI 封装
|
|
209
|
+
gateway.py # WebSocket 网关/分片/重连
|
|
210
|
+
token.py # access token 无缝刷新
|
|
211
|
+
http.py # HTTP 客户端
|
|
212
|
+
env.py # .env 文件加载
|
|
213
|
+
logging.py # 默认日志与 configure_logging
|
|
214
|
+
dispatcher.py # 事件解析与分发
|
|
215
|
+
models.py # 事件 dataclass
|
|
216
|
+
types.py # payload 类型提示
|
|
217
|
+
flags.py # Intents / Permission
|
|
218
|
+
errors.py # 异常体系
|
|
219
|
+
panel.py # 指令面板:Panel / PanelStore
|
|
220
|
+
group_store.py # 本地群聊状态:GroupStore
|
|
221
|
+
webhook.py # 可选 Webhook 签名
|
|
222
|
+
ext/ # 命令、颜色、频道跳转等扩展
|
|
223
|
+
|
|
224
|
+
## License
|
|
225
|
+
|
|
226
|
+
MIT
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# viseron-qqbotpy
|
|
2
|
+
|
|
3
|
+
一个基于 **asyncio + aiohttp** 的 QQ 机器人 Python SDK,针对
|
|
4
|
+
[QQ 机器人开放平台 API v2](https://bot.q.qq.com/wiki/develop/api-v2/) 重新设计。
|
|
5
|
+
|
|
6
|
+
它参考了旧版 qq-botpy 的 API 形状,但内部实现是重写的:共享 HTTP 会话、
|
|
7
|
+
无中断的 access_token 刷新、由 Hello 事件驱动的心跳、更清晰的错误与事件模型。
|
|
8
|
+
|
|
9
|
+
## 特性
|
|
10
|
+
|
|
11
|
+
- 使用 appid + secret 获取 access token,并支持 **过期前 60 秒无缝刷新**
|
|
12
|
+
- WebSocket 网关:Identify / Resume / Heartbeat / 分片 / 断线重连
|
|
13
|
+
- 覆盖频道、群聊、单聊、身份组、成员、消息、表情、日程、论坛、音频、公告、
|
|
14
|
+
接口权限、富媒体上传、入群审批、指令面板、自定义菜单等 API
|
|
15
|
+
- 本地文件分片上传一键封装:upload_group_media / upload_c2c_media
|
|
16
|
+
- 本地群聊状态管理:GroupStore 自动把机器人加入过的群记录到 groups.json
|
|
17
|
+
- 群成员管理:群成员列表/详情、批量移除、群黑名单查询与操作(平台 2026-09-03 新增,内邀能力)
|
|
18
|
+
- Markdown 素材管理:图片上传到平台并获取 qqbot-media:// 引用,一条 upload_markdown_image 搞定(平台 2026-10-21 新增)
|
|
19
|
+
- 图文卡片消息(msg_type=8)与群聊 @全部成员常量 AT_EVERYONE(平台 2026-10-26 / 10-28 新增)
|
|
20
|
+
- 指令面板管理:Panel / PanelStore 用 panels/panels.json 配置并同步到平台
|
|
21
|
+
- 事件模型为 dataclass,同时保留完整原始 payload(raw 字段)
|
|
22
|
+
- 可选 Webhook Ed25519 签名验证
|
|
23
|
+
|
|
24
|
+
## 使用文档
|
|
25
|
+
|
|
26
|
+
完整使用文档见 docs/ 目录:
|
|
27
|
+
|
|
28
|
+
- docs/getting-started.md:安装、快速开始、Intents、直接调用 API
|
|
29
|
+
- docs/core.md:SDK 基础能力,如 Client、TokenManager、BotAPI、日志、异常等
|
|
30
|
+
- docs/events.md:事件监听、事件表、事件对象字段
|
|
31
|
+
- docs/features.md:常见功能实现示例
|
|
32
|
+
- docs/api-reference.md:API 方法参考
|
|
33
|
+
- docs/ext.md:命令装饰器、颜色转换等扩展
|
|
34
|
+
- docs/management.md:面板与群管理、本地配置同步
|
|
35
|
+
- docs/automation.md:QQ 文档同步自动化任务与版本规则
|
|
36
|
+
- docs/webhook.md:Webhook 签名验证
|
|
37
|
+
- docs/publish.md:构建、上架 PyPI、安装与下载方式
|
|
38
|
+
|
|
39
|
+
## 安装
|
|
40
|
+
|
|
41
|
+
cd viseron-botpy
|
|
42
|
+
pip install -e .
|
|
43
|
+
|
|
44
|
+
开发模式安装额外依赖:
|
|
45
|
+
|
|
46
|
+
pip install -e ".[dev]"
|
|
47
|
+
|
|
48
|
+
## 快速开始
|
|
49
|
+
|
|
50
|
+
import os
|
|
51
|
+
from pathlib import Path
|
|
52
|
+
|
|
53
|
+
from viseron_qqbotpy import Client, Intents, Message, configure_logging, load_env
|
|
54
|
+
|
|
55
|
+
# 读取项目根目录的 .env
|
|
56
|
+
load_env(Path(__file__).resolve().parents[1] / ".env")
|
|
57
|
+
|
|
58
|
+
# 使用 SDK 默认日志格式,并写入 logs/viseron_qqbotpy.log
|
|
59
|
+
configure_logging()
|
|
60
|
+
|
|
61
|
+
APPID = os.getenv("APPID", "")
|
|
62
|
+
APPSECRET = os.getenv("APPSECRET", "")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class MyBot(Client):
|
|
66
|
+
async def on_ready(self):
|
|
67
|
+
print("机器人已上线")
|
|
68
|
+
|
|
69
|
+
async def on_at_message_create(self, message: Message):
|
|
70
|
+
await message.reply(content=f"收到: {message.content}")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
bot = MyBot(intents=Intents.default())
|
|
75
|
+
bot.run(appid=APPID, secret=APPSECRET)
|
|
76
|
+
|
|
77
|
+
更多事件与用法见 examples/ 和 docs/。
|
|
78
|
+
|
|
79
|
+
## 事件订阅
|
|
80
|
+
|
|
81
|
+
创建客户端时传入 Intents:
|
|
82
|
+
|
|
83
|
+
intents = Intents.default() # 公域事件
|
|
84
|
+
intents = Intents.all() # 全部事件(需私域权限)
|
|
85
|
+
intents = Intents(guilds=True, public_guild_messages=True)
|
|
86
|
+
|
|
87
|
+
网关事件名会映射为 on_<event_type小写>,例如:
|
|
88
|
+
|
|
89
|
+
- AT_MESSAGE_CREATE -> on_at_message_create
|
|
90
|
+
- GROUP_AT_MESSAGE_CREATE -> on_group_at_message_create
|
|
91
|
+
- C2C_MESSAGE_CREATE -> on_c2c_message_create
|
|
92
|
+
- INTERACTION_CREATE -> on_interaction_create
|
|
93
|
+
- GROUP_MEMBER_ADD -> on_group_member_add
|
|
94
|
+
- READY / RESUMED -> on_ready / on_resumed(无参数)
|
|
95
|
+
|
|
96
|
+
## 本地面板与群聊状态
|
|
97
|
+
|
|
98
|
+
SDK 可以把群聊状态和指令面板配置保存在本地:
|
|
99
|
+
|
|
100
|
+
- groups.json:机器人加入过的群,由 Client 自动维护,无需手动调用。
|
|
101
|
+
- panels/panels.json:你自己维护的面板配置;panels/store.json 由 SDK 记录 panel_id 映射。
|
|
102
|
+
|
|
103
|
+
from viseron_qqbotpy import Client, Intents, load_panels
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class MyBot(Client):
|
|
107
|
+
async def on_ready(self):
|
|
108
|
+
# 把 panels/panels.json 同步到平台
|
|
109
|
+
store = await load_panels(self.api, root_dir="panels")
|
|
110
|
+
await store.sync_from_config()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
if __name__ == "__main__":
|
|
114
|
+
bot = MyBot(
|
|
115
|
+
intents=Intents.default(),
|
|
116
|
+
group_store_path="data/groups.json",
|
|
117
|
+
group_store_retention_days=30,
|
|
118
|
+
)
|
|
119
|
+
bot.run(appid=APPID, secret=APPSECRET)
|
|
120
|
+
|
|
121
|
+
详细说明见 docs/management.md。
|
|
122
|
+
|
|
123
|
+
## 直接调用 API
|
|
124
|
+
|
|
125
|
+
在 Client 子类中,可以直接使用 self.api:
|
|
126
|
+
|
|
127
|
+
class MyBot(Client):
|
|
128
|
+
async def on_ready(self):
|
|
129
|
+
guilds = await self.api.me_guilds()
|
|
130
|
+
print(guilds)
|
|
131
|
+
|
|
132
|
+
如果只需要 HTTP API,不连接 WebSocket:
|
|
133
|
+
|
|
134
|
+
import asyncio
|
|
135
|
+
|
|
136
|
+
from viseron_qqbotpy import BotAPI, HTTPClient, TokenManager
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
async def main():
|
|
140
|
+
token = TokenManager("你的 AppID", "你的 AppSecret")
|
|
141
|
+
http = HTTPClient(token)
|
|
142
|
+
api = BotAPI(http)
|
|
143
|
+
|
|
144
|
+
me = await api.me()
|
|
145
|
+
print(me)
|
|
146
|
+
|
|
147
|
+
await http.close()
|
|
148
|
+
await token.close()
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
asyncio.run(main())
|
|
152
|
+
|
|
153
|
+
## Access Token 刷新机制
|
|
154
|
+
|
|
155
|
+
- 平台 access token 默认 7200 秒有效。
|
|
156
|
+
- 在 token 剩余有效期进入最后 60 秒时,SDK 会透明地获取新 token 并切换;
|
|
157
|
+
此时新旧 token 都有效,因此不会中断正在执行的请求。
|
|
158
|
+
- 如果刷新失败但旧 token 尚未过期,SDK 会继续使用旧 token,并在下一次调用时重试。
|
|
159
|
+
- 可通过 TokenManager 单独使用该能力。
|
|
160
|
+
|
|
161
|
+
## Webhook 签名验证
|
|
162
|
+
|
|
163
|
+
from viseron_qqbotpy.webhook import verify_signature, sign_validation
|
|
164
|
+
|
|
165
|
+
ok = verify_signature(
|
|
166
|
+
secret="AppSecret",
|
|
167
|
+
timestamp=request.headers["X-Signature-Timestamp"],
|
|
168
|
+
body=request.body.decode(),
|
|
169
|
+
signature_hex=request.headers["X-Signature-Ed25519"],
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
## 项目结构
|
|
173
|
+
|
|
174
|
+
src/viseron_qqbotpy/
|
|
175
|
+
client.py # Client 入口
|
|
176
|
+
api.py # OpenAPI 封装
|
|
177
|
+
gateway.py # WebSocket 网关/分片/重连
|
|
178
|
+
token.py # access token 无缝刷新
|
|
179
|
+
http.py # HTTP 客户端
|
|
180
|
+
env.py # .env 文件加载
|
|
181
|
+
logging.py # 默认日志与 configure_logging
|
|
182
|
+
dispatcher.py # 事件解析与分发
|
|
183
|
+
models.py # 事件 dataclass
|
|
184
|
+
types.py # payload 类型提示
|
|
185
|
+
flags.py # Intents / Permission
|
|
186
|
+
errors.py # 异常体系
|
|
187
|
+
panel.py # 指令面板:Panel / PanelStore
|
|
188
|
+
group_store.py # 本地群聊状态:GroupStore
|
|
189
|
+
webhook.py # 可选 Webhook 签名
|
|
190
|
+
ext/ # 命令、颜色、频道跳转等扩展
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "viseron-qqbotpy"
|
|
7
|
+
version = "0.4.2"
|
|
8
|
+
description = "A modern, asyncio-based Python SDK for the QQ Open Platform Bot API (api-v2)."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Viseron" }]
|
|
13
|
+
keywords = ["qq", "qqbot", "qq-bot", "qq机器人", "sdk", "websocket", "bot"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Framework :: AsyncIO",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"aiohttp>=3.7.4,<4",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
ext = ["PyYAML>=6", "APScheduler>=3.10"]
|
|
32
|
+
webhook = ["cryptography>=41"]
|
|
33
|
+
dev = ["pytest>=7", "pytest-asyncio>=0.21", "python-dotenv>=1"]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://bot.q.qq.com/wiki/develop/api-v2/"
|
|
37
|
+
Documentation = "https://bot.q.qq.com/wiki/develop/api-v2/"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools.packages.find]
|
|
40
|
+
where = ["src"]
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.package-data]
|
|
43
|
+
viseron_qqbotpy = ["py.typed"]
|
|
44
|
+
|
|
45
|
+
[tool.pytest.ini_options]
|
|
46
|
+
asyncio_mode = "auto"
|
|
47
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""viseron-qqbotpy: a modern QQ Open Platform bot SDK.
|
|
2
|
+
|
|
3
|
+
The package exposes the main Client, Intents, event models and exceptions.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .client import Client
|
|
7
|
+
from .api import AT_EVERYONE, BotAPI
|
|
8
|
+
from .env import load_env
|
|
9
|
+
from .http import HTTPClient, Route
|
|
10
|
+
from .token import AccessToken, TokenManager
|
|
11
|
+
from .flags import Intents, Permission
|
|
12
|
+
from .group_store import GroupStore, load_group_store
|
|
13
|
+
from .panel import Panel, PanelItem, PanelStore, load_panels
|
|
14
|
+
from .errors import (
|
|
15
|
+
APIError,
|
|
16
|
+
AuthenticationFailedError,
|
|
17
|
+
ForbiddenError,
|
|
18
|
+
MethodNotAllowedError,
|
|
19
|
+
NotFoundError,
|
|
20
|
+
RateLimitError,
|
|
21
|
+
ServerError,
|
|
22
|
+
TokenError,
|
|
23
|
+
ViseronError,
|
|
24
|
+
WebSocketError,
|
|
25
|
+
)
|
|
26
|
+
from .models import (
|
|
27
|
+
AudioAction,
|
|
28
|
+
C2CManageEvent,
|
|
29
|
+
C2CMessage,
|
|
30
|
+
Channel,
|
|
31
|
+
DirectMessage,
|
|
32
|
+
ForumThread,
|
|
33
|
+
GroupJoinRequestEvent,
|
|
34
|
+
GroupManageEvent,
|
|
35
|
+
GroupMemberEvent,
|
|
36
|
+
GroupMessage,
|
|
37
|
+
Guild,
|
|
38
|
+
Interaction,
|
|
39
|
+
Member,
|
|
40
|
+
Message,
|
|
41
|
+
MessageAudit,
|
|
42
|
+
OpenForumThread,
|
|
43
|
+
PublicAudio,
|
|
44
|
+
Reaction,
|
|
45
|
+
SubscribeMessageStatusEvent,
|
|
46
|
+
User,
|
|
47
|
+
)
|
|
48
|
+
from .logging import configure_logging, get_logger
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
"APIError",
|
|
52
|
+
"AT_EVERYONE",
|
|
53
|
+
"AccessToken",
|
|
54
|
+
"AudioAction",
|
|
55
|
+
"BotAPI",
|
|
56
|
+
"AuthenticationFailedError",
|
|
57
|
+
"C2CManageEvent",
|
|
58
|
+
"C2CMessage",
|
|
59
|
+
"Channel",
|
|
60
|
+
"Client",
|
|
61
|
+
"DirectMessage",
|
|
62
|
+
"ForbiddenError",
|
|
63
|
+
"ForumThread",
|
|
64
|
+
"GroupJoinRequestEvent",
|
|
65
|
+
"GroupManageEvent",
|
|
66
|
+
"GroupMemberEvent",
|
|
67
|
+
"GroupMessage",
|
|
68
|
+
"GroupStore",
|
|
69
|
+
"Guild",
|
|
70
|
+
"Intents",
|
|
71
|
+
"HTTPClient",
|
|
72
|
+
"Interaction",
|
|
73
|
+
"load_env",
|
|
74
|
+
"Member",
|
|
75
|
+
"Message",
|
|
76
|
+
"MessageAudit",
|
|
77
|
+
"MethodNotAllowedError",
|
|
78
|
+
"NotFoundError",
|
|
79
|
+
"OpenForumThread",
|
|
80
|
+
"Panel",
|
|
81
|
+
"PanelItem",
|
|
82
|
+
"PanelStore",
|
|
83
|
+
"Permission",
|
|
84
|
+
"PublicAudio",
|
|
85
|
+
"RateLimitError",
|
|
86
|
+
"Reaction",
|
|
87
|
+
"Route",
|
|
88
|
+
"ServerError",
|
|
89
|
+
"SubscribeMessageStatusEvent",
|
|
90
|
+
"TokenError",
|
|
91
|
+
"TokenManager",
|
|
92
|
+
"User",
|
|
93
|
+
"ViseronError",
|
|
94
|
+
"WebSocketError",
|
|
95
|
+
"configure_logging",
|
|
96
|
+
"get_logger",
|
|
97
|
+
"load_group_store",
|
|
98
|
+
"load_panels",
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
__version__ = "0.4.2"
|