ErisPulse-SnowLumaAdapter 0.1.0__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.
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: ErisPulse-SnowLumaAdapter
3
+ Version: 0.1.0
4
+ Summary: ErisPulse的SnowLuma协议适配模块(NTQQ hook,OneBot v11 兼容)
5
+ Author-email: wsu2059q <wsu2059@qq.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 WSu2059
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: homepage, https://github.com/ErisPulse/ErisPulse-SnowLumaAdapter
29
+ Keywords: erispulse,erispulse-adapter,snowluma,onebot11,ntqq
30
+ Requires-Python: >=3.10
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Requires-Dist: filetype>=1.2.0
34
+ Dynamic: license-file
35
+
36
+ <div align="center">
37
+
38
+ <img src=".github/assets/ErisPulseLogo.png" width="180" alt="ErisPulse SnowLumaAdapter" />
39
+
40
+ # ErisPulse SnowLumaAdapter
41
+
42
+ **基于 NTQQ hook 的 QQ 协议适配器 —— 原生合并转发 · 全面兼容 NapCat。**
43
+
44
+ 基于 ErisPulse 框架的 SnowLuma 协议适配器。[SnowLuma](https://github.com/SnowLuma/SnowLuma) 通过 hook 注入 QQ 桌面客户端(NTQQ),以 OneBot v11 协议对外暴露 API;本适配器同时可直接连接 **NapCat** 后端。支持多账户、合并转发三级回退、拍一拍/QQ空间/群文件/消息历史等 60+ 类型化扩展方法。
45
+
46
+ <p>
47
+ <a href="https://pypi.org/project/ErisPulse-SnowLumaAdapter/"><img src="https://img.shields.io/pypi/v/ErisPulse-SnowLumaAdapter?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI"></a>
48
+ <a href="https://pypi.org/project/ErisPulse-SnowLumaAdapter/"><img src="https://img.shields.io/badge/Python-3.10+-FFD43B?style=for-the-badge&logo=python&logoColor=blue" alt="Python"></a>
49
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="License"></a>
50
+ <a href="https://github.com/wsu2059q/ErisPulse-SnowLuma"><img src="https://img.shields.io/github/stars/wsu2059q/ErisPulse-SnowLuma?style=for-the-badge&logo=github&color=brightgreen" alt="Stars"></a>
51
+ <a href="https://github.com/ErisPulse/ErisPulse"><img src="https://img.shields.io/badge/Powered_by-ErisPulse-FF6B9D?style=for-the-badge&logo=bookstack&logoColor=white" alt="ErisPulse"></a>
52
+ </p>
53
+
54
+ </div>
55
+
56
+ ---
57
+
58
+ ## 特性
59
+
60
+ - **完整 OneBot v11 协议**:OB12 标准 ApiDSL 自动映射动作名(`get_self_info` → `get_login_info` 等)
61
+ - **合并转发**:`MergeForward` 三级回退(专用端点 → `upload_forward_msg` resid → 直发 node 段),`Raw_ob12` 纯 node 段自动路由
62
+ - **全面兼容 NapCat**:`url` 指向 NapCat 正向 WS 即可直接使用,或以 server 模式接收 NapCat 反向 WS
63
+ - **60+ 类型化扩展方法**(IDE 补全):拍一拍 / QQ空间 / 群文件 / 群相册 / 消息历史 / 精华 / 已读状态 / OCR 等
64
+ - **109 个扩展动作**均可通过 `Api.call("action_name", ...)` 调用(NapCat/SnowLuma 通用)
65
+ - **多账户 + bot_id 自动识别**:无需配置 QQ 号,`event.reply()` 自动路由到来源账户
66
+ - **5 语言 i18n**(zh-CN / zh-TW / en / ja / ru)
67
+
68
+ ## 安装
69
+
70
+ ```bash
71
+ epsdk install SnowLumaAdapter
72
+ ```
73
+
74
+ 或直接安装:
75
+
76
+ ```bash
77
+ pip install ErisPulse-SnowLumaAdapter
78
+ ```
79
+
80
+ ## 配置
81
+
82
+ 在 `config/config.toml` 中添加:
83
+
84
+ ```toml
85
+ [SnowLuma_Adapter.accounts.default]
86
+ mode = "client" # client=主动连接(推荐)/ server=被动监听
87
+ url = "ws://127.0.0.1:3001" # SnowLuma 默认 WS 端口 3001
88
+ token = "your_access_token"
89
+ enabled = true
90
+
91
+ # 多账户示例
92
+ [SnowLuma_Adapter.accounts.second]
93
+ mode = "client"
94
+ url = "ws://192.168.1.100:3001"
95
+ token = "another_token"
96
+ enabled = true
97
+ ```
98
+
99
+ ### 配置字段
100
+
101
+ | 字段 | 类型 | 必填 | 说明 |
102
+ |------|------|------|------|
103
+ | `mode` | string | 否 | 运行模式:`"client"`(主动连接,默认)或 `"server"`(被动监听) |
104
+ | `url` | string | 否 | Client 模式的 WebSocket 地址(默认 `ws://127.0.0.1:3001`) |
105
+ | `token` | string | 否 | 访问令牌(Bearer 认证) |
106
+ | `server_path` | string | 否 | Server 模式的 WebSocket 路径(默认 `/`) |
107
+ | `enabled` | bool | 否 | 是否启用(默认 true) |
108
+
109
+ > `bot_id`(QQ 号)无需配置:适配器连接后自动识别。连接 NapCat 时把 `url` 指向其 OneBot11 正向 WS 地址即可,标准动作、扩展动作与合并转发均可直接使用。
110
+
111
+ ## 快速开始
112
+
113
+ ```python
114
+ from ErisPulse import sdk
115
+ from ErisPulse.Core.Event import command, message
116
+
117
+ @command("hello")
118
+ async def hello_handler(event):
119
+ await event.reply("Hello from SnowLuma!")
120
+
121
+ async def main():
122
+ await sdk.run(keep_running=True)
123
+
124
+ if __name__ == "__main__":
125
+ import asyncio
126
+ asyncio.run(main())
127
+ ```
128
+
129
+ ## 消息发送
130
+
131
+ 所有发送方法通过链式 DSL 调用:
132
+
133
+ ```python
134
+ snowluma = sdk.adapter.get("snowluma")
135
+
136
+ # 文本消息(链式修饰:@ + 回复)
137
+ await snowluma.Send.To("group", 123456).At(789012).Reply(msg_id).Text("Hello World!")
138
+
139
+ # 私聊 / 图片 / 语音 / 视频 / 文件(支持 URL、Base64、bytes)
140
+ await snowluma.Send.To("user", 789012).Text("私聊消息")
141
+ await snowluma.Send.To("group", 123456).Image("https://example.com/img.png")
142
+
143
+ # 合并转发(三级回退,SnowLuma / NapCat 均适用)
144
+ nodes = [
145
+ {
146
+ "type": "node",
147
+ "data": {
148
+ "user_id": "10000",
149
+ "nickname": "MyBot",
150
+ "content": [{"type": "text", "data": {"text": "【1/3】标题\n正文…"}}],
151
+ },
152
+ },
153
+ ]
154
+ await snowluma.Send.To("group", 123456).MergeForward(nodes)
155
+
156
+ # 群操作(需 To("group", group_id))
157
+ await snowluma.Send.To("group", 123456).Ban(789012, duration=3600) # 禁言
158
+ await snowluma.Send.To("group", 123456).Kick(789012) # 踢出
159
+ await snowluma.Send.To("group", 123456).SetCard(789012, card="新名片")
160
+
161
+ # 拍一拍 / QQ空间 / 消息历史
162
+ await snowluma.Send.To("group", 123456).GroupPoke(789012)
163
+ await snowluma.Send.QzoneMsg("发表说说")
164
+ result = await snowluma.Send.To("group", 123456).GetGroupMsgHistory(count=20)
165
+
166
+ # OneBot12 组合消息(纯 node 段列表自动路由合并转发)
167
+ ob12_message = [
168
+ {"type": "text", "data": {"text": "你好!"}},
169
+ {"type": "reply", "data": {"message_id": "12345"}},
170
+ ]
171
+ await snowluma.Send.To("group", 123456).Raw_ob12(ob12_message)
172
+
173
+ # 多账户指定账户发送
174
+ await snowluma.Send.Using("second").To("group", 123456).Text("来自第二个账户")
175
+ ```
176
+
177
+ ## API 调用
178
+
179
+ ```python
180
+ # OB12 标准 ApiDSL(自动映射动作名)
181
+ info = await snowluma.Api.get_self_info()
182
+ await snowluma.Api.delete_message(message_id=123456)
183
+
184
+ # 类型化扩展方法(IDE 补全)
185
+ await snowluma.Api.send_poke(user_id=789, group_id=123456)
186
+ await snowluma.Api.set_msg_emoji_like(message_id=123, emoji_id="76")
187
+ result = await snowluma.Api.get_group_msg_history(group_id=123456, count=20)
188
+ result = await snowluma.Api.get_group_file_url(group_id=123456, file_id="...")
189
+
190
+ # 解析已收到的合并转发消息(入站 forward 段 data.id 为 resid)
191
+ result = await snowluma.Api.get_forward_msg(id="resid_xxx")
192
+
193
+ # 未封装的动作用 call()(NapCat/SnowLuma 通用)
194
+ result = await snowluma.Api.call("send_group_ai_record", group_id=123456, content="...")
195
+ ```
196
+
197
+ ## 事件
198
+
199
+ 事件遵循 OneBot12 规范:消息事件 `detail_type` 为 `private` / `group`,通知事件映射为标准命名;平台特有事件(poke/honor 等)使用 `snowluma_` 前缀,未识别的 CQ 码以 `onebot11_{type}` 透传,原始数据保留在 `snowluma_raw` 字段。
200
+
201
+ ## 依赖
202
+
203
+ - `filetype`:媒体类型检测
204
+
205
+ ## 许可证
206
+
207
+ MIT License
@@ -0,0 +1,17 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ ErisPulse_SnowLumaAdapter.egg-info/PKG-INFO
5
+ ErisPulse_SnowLumaAdapter.egg-info/SOURCES.txt
6
+ ErisPulse_SnowLumaAdapter.egg-info/dependency_links.txt
7
+ ErisPulse_SnowLumaAdapter.egg-info/entry_points.txt
8
+ ErisPulse_SnowLumaAdapter.egg-info/requires.txt
9
+ ErisPulse_SnowLumaAdapter.egg-info/top_level.txt
10
+ SnowLumaAdapter/Converter.py
11
+ SnowLumaAdapter/Core.py
12
+ SnowLumaAdapter/__init__.py
13
+ SnowLumaAdapter/i18n.py
14
+ SnowLumaAdapter/ob11_extensions.py
15
+ test/test_call_api.py
16
+ test/test_converter.py
17
+ test/test_extensions.py
@@ -0,0 +1,2 @@
1
+ [erispulse.adapter]
2
+ snowluma = SnowLumaAdapter:SnowLumaAdapter
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 WSu2059
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: ErisPulse-SnowLumaAdapter
3
+ Version: 0.1.0
4
+ Summary: ErisPulse的SnowLuma协议适配模块(NTQQ hook,OneBot v11 兼容)
5
+ Author-email: wsu2059q <wsu2059@qq.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 WSu2059
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: homepage, https://github.com/ErisPulse/ErisPulse-SnowLumaAdapter
29
+ Keywords: erispulse,erispulse-adapter,snowluma,onebot11,ntqq
30
+ Requires-Python: >=3.10
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Requires-Dist: filetype>=1.2.0
34
+ Dynamic: license-file
35
+
36
+ <div align="center">
37
+
38
+ <img src=".github/assets/ErisPulseLogo.png" width="180" alt="ErisPulse SnowLumaAdapter" />
39
+
40
+ # ErisPulse SnowLumaAdapter
41
+
42
+ **基于 NTQQ hook 的 QQ 协议适配器 —— 原生合并转发 · 全面兼容 NapCat。**
43
+
44
+ 基于 ErisPulse 框架的 SnowLuma 协议适配器。[SnowLuma](https://github.com/SnowLuma/SnowLuma) 通过 hook 注入 QQ 桌面客户端(NTQQ),以 OneBot v11 协议对外暴露 API;本适配器同时可直接连接 **NapCat** 后端。支持多账户、合并转发三级回退、拍一拍/QQ空间/群文件/消息历史等 60+ 类型化扩展方法。
45
+
46
+ <p>
47
+ <a href="https://pypi.org/project/ErisPulse-SnowLumaAdapter/"><img src="https://img.shields.io/pypi/v/ErisPulse-SnowLumaAdapter?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI"></a>
48
+ <a href="https://pypi.org/project/ErisPulse-SnowLumaAdapter/"><img src="https://img.shields.io/badge/Python-3.10+-FFD43B?style=for-the-badge&logo=python&logoColor=blue" alt="Python"></a>
49
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="License"></a>
50
+ <a href="https://github.com/wsu2059q/ErisPulse-SnowLuma"><img src="https://img.shields.io/github/stars/wsu2059q/ErisPulse-SnowLuma?style=for-the-badge&logo=github&color=brightgreen" alt="Stars"></a>
51
+ <a href="https://github.com/ErisPulse/ErisPulse"><img src="https://img.shields.io/badge/Powered_by-ErisPulse-FF6B9D?style=for-the-badge&logo=bookstack&logoColor=white" alt="ErisPulse"></a>
52
+ </p>
53
+
54
+ </div>
55
+
56
+ ---
57
+
58
+ ## 特性
59
+
60
+ - **完整 OneBot v11 协议**:OB12 标准 ApiDSL 自动映射动作名(`get_self_info` → `get_login_info` 等)
61
+ - **合并转发**:`MergeForward` 三级回退(专用端点 → `upload_forward_msg` resid → 直发 node 段),`Raw_ob12` 纯 node 段自动路由
62
+ - **全面兼容 NapCat**:`url` 指向 NapCat 正向 WS 即可直接使用,或以 server 模式接收 NapCat 反向 WS
63
+ - **60+ 类型化扩展方法**(IDE 补全):拍一拍 / QQ空间 / 群文件 / 群相册 / 消息历史 / 精华 / 已读状态 / OCR 等
64
+ - **109 个扩展动作**均可通过 `Api.call("action_name", ...)` 调用(NapCat/SnowLuma 通用)
65
+ - **多账户 + bot_id 自动识别**:无需配置 QQ 号,`event.reply()` 自动路由到来源账户
66
+ - **5 语言 i18n**(zh-CN / zh-TW / en / ja / ru)
67
+
68
+ ## 安装
69
+
70
+ ```bash
71
+ epsdk install SnowLumaAdapter
72
+ ```
73
+
74
+ 或直接安装:
75
+
76
+ ```bash
77
+ pip install ErisPulse-SnowLumaAdapter
78
+ ```
79
+
80
+ ## 配置
81
+
82
+ 在 `config/config.toml` 中添加:
83
+
84
+ ```toml
85
+ [SnowLuma_Adapter.accounts.default]
86
+ mode = "client" # client=主动连接(推荐)/ server=被动监听
87
+ url = "ws://127.0.0.1:3001" # SnowLuma 默认 WS 端口 3001
88
+ token = "your_access_token"
89
+ enabled = true
90
+
91
+ # 多账户示例
92
+ [SnowLuma_Adapter.accounts.second]
93
+ mode = "client"
94
+ url = "ws://192.168.1.100:3001"
95
+ token = "another_token"
96
+ enabled = true
97
+ ```
98
+
99
+ ### 配置字段
100
+
101
+ | 字段 | 类型 | 必填 | 说明 |
102
+ |------|------|------|------|
103
+ | `mode` | string | 否 | 运行模式:`"client"`(主动连接,默认)或 `"server"`(被动监听) |
104
+ | `url` | string | 否 | Client 模式的 WebSocket 地址(默认 `ws://127.0.0.1:3001`) |
105
+ | `token` | string | 否 | 访问令牌(Bearer 认证) |
106
+ | `server_path` | string | 否 | Server 模式的 WebSocket 路径(默认 `/`) |
107
+ | `enabled` | bool | 否 | 是否启用(默认 true) |
108
+
109
+ > `bot_id`(QQ 号)无需配置:适配器连接后自动识别。连接 NapCat 时把 `url` 指向其 OneBot11 正向 WS 地址即可,标准动作、扩展动作与合并转发均可直接使用。
110
+
111
+ ## 快速开始
112
+
113
+ ```python
114
+ from ErisPulse import sdk
115
+ from ErisPulse.Core.Event import command, message
116
+
117
+ @command("hello")
118
+ async def hello_handler(event):
119
+ await event.reply("Hello from SnowLuma!")
120
+
121
+ async def main():
122
+ await sdk.run(keep_running=True)
123
+
124
+ if __name__ == "__main__":
125
+ import asyncio
126
+ asyncio.run(main())
127
+ ```
128
+
129
+ ## 消息发送
130
+
131
+ 所有发送方法通过链式 DSL 调用:
132
+
133
+ ```python
134
+ snowluma = sdk.adapter.get("snowluma")
135
+
136
+ # 文本消息(链式修饰:@ + 回复)
137
+ await snowluma.Send.To("group", 123456).At(789012).Reply(msg_id).Text("Hello World!")
138
+
139
+ # 私聊 / 图片 / 语音 / 视频 / 文件(支持 URL、Base64、bytes)
140
+ await snowluma.Send.To("user", 789012).Text("私聊消息")
141
+ await snowluma.Send.To("group", 123456).Image("https://example.com/img.png")
142
+
143
+ # 合并转发(三级回退,SnowLuma / NapCat 均适用)
144
+ nodes = [
145
+ {
146
+ "type": "node",
147
+ "data": {
148
+ "user_id": "10000",
149
+ "nickname": "MyBot",
150
+ "content": [{"type": "text", "data": {"text": "【1/3】标题\n正文…"}}],
151
+ },
152
+ },
153
+ ]
154
+ await snowluma.Send.To("group", 123456).MergeForward(nodes)
155
+
156
+ # 群操作(需 To("group", group_id))
157
+ await snowluma.Send.To("group", 123456).Ban(789012, duration=3600) # 禁言
158
+ await snowluma.Send.To("group", 123456).Kick(789012) # 踢出
159
+ await snowluma.Send.To("group", 123456).SetCard(789012, card="新名片")
160
+
161
+ # 拍一拍 / QQ空间 / 消息历史
162
+ await snowluma.Send.To("group", 123456).GroupPoke(789012)
163
+ await snowluma.Send.QzoneMsg("发表说说")
164
+ result = await snowluma.Send.To("group", 123456).GetGroupMsgHistory(count=20)
165
+
166
+ # OneBot12 组合消息(纯 node 段列表自动路由合并转发)
167
+ ob12_message = [
168
+ {"type": "text", "data": {"text": "你好!"}},
169
+ {"type": "reply", "data": {"message_id": "12345"}},
170
+ ]
171
+ await snowluma.Send.To("group", 123456).Raw_ob12(ob12_message)
172
+
173
+ # 多账户指定账户发送
174
+ await snowluma.Send.Using("second").To("group", 123456).Text("来自第二个账户")
175
+ ```
176
+
177
+ ## API 调用
178
+
179
+ ```python
180
+ # OB12 标准 ApiDSL(自动映射动作名)
181
+ info = await snowluma.Api.get_self_info()
182
+ await snowluma.Api.delete_message(message_id=123456)
183
+
184
+ # 类型化扩展方法(IDE 补全)
185
+ await snowluma.Api.send_poke(user_id=789, group_id=123456)
186
+ await snowluma.Api.set_msg_emoji_like(message_id=123, emoji_id="76")
187
+ result = await snowluma.Api.get_group_msg_history(group_id=123456, count=20)
188
+ result = await snowluma.Api.get_group_file_url(group_id=123456, file_id="...")
189
+
190
+ # 解析已收到的合并转发消息(入站 forward 段 data.id 为 resid)
191
+ result = await snowluma.Api.get_forward_msg(id="resid_xxx")
192
+
193
+ # 未封装的动作用 call()(NapCat/SnowLuma 通用)
194
+ result = await snowluma.Api.call("send_group_ai_record", group_id=123456, content="...")
195
+ ```
196
+
197
+ ## 事件
198
+
199
+ 事件遵循 OneBot12 规范:消息事件 `detail_type` 为 `private` / `group`,通知事件映射为标准命名;平台特有事件(poke/honor 等)使用 `snowluma_` 前缀,未识别的 CQ 码以 `onebot11_{type}` 透传,原始数据保留在 `snowluma_raw` 字段。
200
+
201
+ ## 依赖
202
+
203
+ - `filetype`:媒体类型检测
204
+
205
+ ## 许可证
206
+
207
+ MIT License
@@ -0,0 +1,172 @@
1
+ <div align="center">
2
+
3
+ <img src=".github/assets/ErisPulseLogo.png" width="180" alt="ErisPulse SnowLumaAdapter" />
4
+
5
+ # ErisPulse SnowLumaAdapter
6
+
7
+ **基于 NTQQ hook 的 QQ 协议适配器 —— 原生合并转发 · 全面兼容 NapCat。**
8
+
9
+ 基于 ErisPulse 框架的 SnowLuma 协议适配器。[SnowLuma](https://github.com/SnowLuma/SnowLuma) 通过 hook 注入 QQ 桌面客户端(NTQQ),以 OneBot v11 协议对外暴露 API;本适配器同时可直接连接 **NapCat** 后端。支持多账户、合并转发三级回退、拍一拍/QQ空间/群文件/消息历史等 60+ 类型化扩展方法。
10
+
11
+ <p>
12
+ <a href="https://pypi.org/project/ErisPulse-SnowLumaAdapter/"><img src="https://img.shields.io/pypi/v/ErisPulse-SnowLumaAdapter?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI"></a>
13
+ <a href="https://pypi.org/project/ErisPulse-SnowLumaAdapter/"><img src="https://img.shields.io/badge/Python-3.10+-FFD43B?style=for-the-badge&logo=python&logoColor=blue" alt="Python"></a>
14
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="License"></a>
15
+ <a href="https://github.com/wsu2059q/ErisPulse-SnowLuma"><img src="https://img.shields.io/github/stars/wsu2059q/ErisPulse-SnowLuma?style=for-the-badge&logo=github&color=brightgreen" alt="Stars"></a>
16
+ <a href="https://github.com/ErisPulse/ErisPulse"><img src="https://img.shields.io/badge/Powered_by-ErisPulse-FF6B9D?style=for-the-badge&logo=bookstack&logoColor=white" alt="ErisPulse"></a>
17
+ </p>
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## 特性
24
+
25
+ - **完整 OneBot v11 协议**:OB12 标准 ApiDSL 自动映射动作名(`get_self_info` → `get_login_info` 等)
26
+ - **合并转发**:`MergeForward` 三级回退(专用端点 → `upload_forward_msg` resid → 直发 node 段),`Raw_ob12` 纯 node 段自动路由
27
+ - **全面兼容 NapCat**:`url` 指向 NapCat 正向 WS 即可直接使用,或以 server 模式接收 NapCat 反向 WS
28
+ - **60+ 类型化扩展方法**(IDE 补全):拍一拍 / QQ空间 / 群文件 / 群相册 / 消息历史 / 精华 / 已读状态 / OCR 等
29
+ - **109 个扩展动作**均可通过 `Api.call("action_name", ...)` 调用(NapCat/SnowLuma 通用)
30
+ - **多账户 + bot_id 自动识别**:无需配置 QQ 号,`event.reply()` 自动路由到来源账户
31
+ - **5 语言 i18n**(zh-CN / zh-TW / en / ja / ru)
32
+
33
+ ## 安装
34
+
35
+ ```bash
36
+ epsdk install SnowLumaAdapter
37
+ ```
38
+
39
+ 或直接安装:
40
+
41
+ ```bash
42
+ pip install ErisPulse-SnowLumaAdapter
43
+ ```
44
+
45
+ ## 配置
46
+
47
+ 在 `config/config.toml` 中添加:
48
+
49
+ ```toml
50
+ [SnowLuma_Adapter.accounts.default]
51
+ mode = "client" # client=主动连接(推荐)/ server=被动监听
52
+ url = "ws://127.0.0.1:3001" # SnowLuma 默认 WS 端口 3001
53
+ token = "your_access_token"
54
+ enabled = true
55
+
56
+ # 多账户示例
57
+ [SnowLuma_Adapter.accounts.second]
58
+ mode = "client"
59
+ url = "ws://192.168.1.100:3001"
60
+ token = "another_token"
61
+ enabled = true
62
+ ```
63
+
64
+ ### 配置字段
65
+
66
+ | 字段 | 类型 | 必填 | 说明 |
67
+ |------|------|------|------|
68
+ | `mode` | string | 否 | 运行模式:`"client"`(主动连接,默认)或 `"server"`(被动监听) |
69
+ | `url` | string | 否 | Client 模式的 WebSocket 地址(默认 `ws://127.0.0.1:3001`) |
70
+ | `token` | string | 否 | 访问令牌(Bearer 认证) |
71
+ | `server_path` | string | 否 | Server 模式的 WebSocket 路径(默认 `/`) |
72
+ | `enabled` | bool | 否 | 是否启用(默认 true) |
73
+
74
+ > `bot_id`(QQ 号)无需配置:适配器连接后自动识别。连接 NapCat 时把 `url` 指向其 OneBot11 正向 WS 地址即可,标准动作、扩展动作与合并转发均可直接使用。
75
+
76
+ ## 快速开始
77
+
78
+ ```python
79
+ from ErisPulse import sdk
80
+ from ErisPulse.Core.Event import command, message
81
+
82
+ @command("hello")
83
+ async def hello_handler(event):
84
+ await event.reply("Hello from SnowLuma!")
85
+
86
+ async def main():
87
+ await sdk.run(keep_running=True)
88
+
89
+ if __name__ == "__main__":
90
+ import asyncio
91
+ asyncio.run(main())
92
+ ```
93
+
94
+ ## 消息发送
95
+
96
+ 所有发送方法通过链式 DSL 调用:
97
+
98
+ ```python
99
+ snowluma = sdk.adapter.get("snowluma")
100
+
101
+ # 文本消息(链式修饰:@ + 回复)
102
+ await snowluma.Send.To("group", 123456).At(789012).Reply(msg_id).Text("Hello World!")
103
+
104
+ # 私聊 / 图片 / 语音 / 视频 / 文件(支持 URL、Base64、bytes)
105
+ await snowluma.Send.To("user", 789012).Text("私聊消息")
106
+ await snowluma.Send.To("group", 123456).Image("https://example.com/img.png")
107
+
108
+ # 合并转发(三级回退,SnowLuma / NapCat 均适用)
109
+ nodes = [
110
+ {
111
+ "type": "node",
112
+ "data": {
113
+ "user_id": "10000",
114
+ "nickname": "MyBot",
115
+ "content": [{"type": "text", "data": {"text": "【1/3】标题\n正文…"}}],
116
+ },
117
+ },
118
+ ]
119
+ await snowluma.Send.To("group", 123456).MergeForward(nodes)
120
+
121
+ # 群操作(需 To("group", group_id))
122
+ await snowluma.Send.To("group", 123456).Ban(789012, duration=3600) # 禁言
123
+ await snowluma.Send.To("group", 123456).Kick(789012) # 踢出
124
+ await snowluma.Send.To("group", 123456).SetCard(789012, card="新名片")
125
+
126
+ # 拍一拍 / QQ空间 / 消息历史
127
+ await snowluma.Send.To("group", 123456).GroupPoke(789012)
128
+ await snowluma.Send.QzoneMsg("发表说说")
129
+ result = await snowluma.Send.To("group", 123456).GetGroupMsgHistory(count=20)
130
+
131
+ # OneBot12 组合消息(纯 node 段列表自动路由合并转发)
132
+ ob12_message = [
133
+ {"type": "text", "data": {"text": "你好!"}},
134
+ {"type": "reply", "data": {"message_id": "12345"}},
135
+ ]
136
+ await snowluma.Send.To("group", 123456).Raw_ob12(ob12_message)
137
+
138
+ # 多账户指定账户发送
139
+ await snowluma.Send.Using("second").To("group", 123456).Text("来自第二个账户")
140
+ ```
141
+
142
+ ## API 调用
143
+
144
+ ```python
145
+ # OB12 标准 ApiDSL(自动映射动作名)
146
+ info = await snowluma.Api.get_self_info()
147
+ await snowluma.Api.delete_message(message_id=123456)
148
+
149
+ # 类型化扩展方法(IDE 补全)
150
+ await snowluma.Api.send_poke(user_id=789, group_id=123456)
151
+ await snowluma.Api.set_msg_emoji_like(message_id=123, emoji_id="76")
152
+ result = await snowluma.Api.get_group_msg_history(group_id=123456, count=20)
153
+ result = await snowluma.Api.get_group_file_url(group_id=123456, file_id="...")
154
+
155
+ # 解析已收到的合并转发消息(入站 forward 段 data.id 为 resid)
156
+ result = await snowluma.Api.get_forward_msg(id="resid_xxx")
157
+
158
+ # 未封装的动作用 call()(NapCat/SnowLuma 通用)
159
+ result = await snowluma.Api.call("send_group_ai_record", group_id=123456, content="...")
160
+ ```
161
+
162
+ ## 事件
163
+
164
+ 事件遵循 OneBot12 规范:消息事件 `detail_type` 为 `private` / `group`,通知事件映射为标准命名;平台特有事件(poke/honor 等)使用 `snowluma_` 前缀,未识别的 CQ 码以 `onebot11_{type}` 透传,原始数据保留在 `snowluma_raw` 字段。
165
+
166
+ ## 依赖
167
+
168
+ - `filetype`:媒体类型检测
169
+
170
+ ## 许可证
171
+
172
+ MIT License