satori-python-adapter-qq 0.2.0__tar.gz → 0.3.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.
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/.mina/adapter_qq.toml +3 -3
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/PKG-INFO +5 -5
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/README.md +2 -2
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/pyproject.toml +3 -3
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/api.py +8 -2
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/events/group.py +5 -1
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/events/guild.py +2 -2
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/events/message.py +15 -5
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/main.py +3 -0
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/message.py +38 -6
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/utils.py +7 -6
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/websocket.py +20 -6
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/LICENSE +0 -0
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/__init__.py +0 -0
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/audit_store.py +0 -0
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/events/__init__.py +0 -0
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/events/base.py +0 -0
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/events/interaction.py +0 -0
- {satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/exception.py +0 -0
|
@@ -6,7 +6,7 @@ raw-dependencies = [
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "satori-python-adapter-qq"
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "0.3.0"
|
|
10
10
|
authors = [
|
|
11
11
|
{name = "RF-Tar-Railt", email = "rf_tar_railt@qq.com"}
|
|
12
12
|
]
|
|
@@ -19,11 +19,11 @@ classifiers = [
|
|
|
19
19
|
"Typing :: Typed",
|
|
20
20
|
"Development Status :: 4 - Beta",
|
|
21
21
|
"License :: OSI Approved :: MIT License",
|
|
22
|
-
"Programming Language :: Python :: 3.8",
|
|
23
|
-
"Programming Language :: Python :: 3.9",
|
|
24
22
|
"Programming Language :: Python :: 3.10",
|
|
25
23
|
"Programming Language :: Python :: 3.11",
|
|
26
24
|
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
27
|
"Operating System :: OS Independent",
|
|
28
28
|
]
|
|
29
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: satori-python-adapter-qq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Satori Protocol SDK for python, adapter for QQ
|
|
5
5
|
Home-page: https://github.com/RF-Tar-Railt/satori-python
|
|
6
6
|
Author-Email: RF-Tar-Railt <rf_tar_railt@qq.com>
|
|
@@ -8,11 +8,11 @@ License: MIT
|
|
|
8
8
|
Classifier: Typing :: Typed
|
|
9
9
|
Classifier: Development Status :: 4 - Beta
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
13
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
17
|
Project-URL: Homepage, https://github.com/RF-Tar-Railt/satori-python
|
|
18
18
|
Project-URL: Repository, https://github.com/RF-Tar-Railt/satori-python
|
|
@@ -28,11 +28,11 @@ Description-Content-Type: text/markdown
|
|
|
28
28
|
[](https://pypi.org/project/satori-python)
|
|
29
29
|
[](https://www.python.org/)
|
|
30
30
|
|
|
31
|
-
基于 [Satori](https://satori.chat/zh-CN/) 协议的 Python 开发工具包
|
|
31
|
+
基于 [Satori](https://satori.chat/zh-CN/protocol) 协议的 Python 开发工具包
|
|
32
32
|
|
|
33
33
|
## 协议介绍
|
|
34
34
|
|
|
35
|
-
[Satori Protocol](https://satori.chat/zh-CN/)
|
|
35
|
+
[Satori Protocol](https://satori.chat/zh-CN/protocol)
|
|
36
36
|
|
|
37
37
|
### 协议端
|
|
38
38
|
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
[](https://pypi.org/project/satori-python)
|
|
6
6
|
[](https://www.python.org/)
|
|
7
7
|
|
|
8
|
-
基于 [Satori](https://satori.chat/zh-CN/) 协议的 Python 开发工具包
|
|
8
|
+
基于 [Satori](https://satori.chat/zh-CN/protocol) 协议的 Python 开发工具包
|
|
9
9
|
|
|
10
10
|
## 协议介绍
|
|
11
11
|
|
|
12
|
-
[Satori Protocol](https://satori.chat/zh-CN/)
|
|
12
|
+
[Satori Protocol](https://satori.chat/zh-CN/protocol)
|
|
13
13
|
|
|
14
14
|
### 协议端
|
|
15
15
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "satori-python-adapter-qq"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name = "RF-Tar-Railt", email = "rf_tar_railt@qq.com" },
|
|
6
6
|
]
|
|
@@ -15,11 +15,11 @@ classifiers = [
|
|
|
15
15
|
"Typing :: Typed",
|
|
16
16
|
"Development Status :: 4 - Beta",
|
|
17
17
|
"License :: OSI Approved :: MIT License",
|
|
18
|
-
"Programming Language :: Python :: 3.8",
|
|
19
|
-
"Programming Language :: Python :: 3.9",
|
|
20
18
|
"Programming Language :: Python :: 3.10",
|
|
21
19
|
"Programming Language :: Python :: 3.11",
|
|
22
20
|
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
23
|
"Operating System :: OS Independent",
|
|
24
24
|
]
|
|
25
25
|
|
{satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/api.py
RENAMED
|
@@ -29,7 +29,7 @@ from satori.server.route import (
|
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
from .message import QQGroupMessageEncoder, QQGuildMessageEncoder, decode_segments
|
|
32
|
-
from .utils import QQBotNetwork, decode_channel, decode_guild, decode_member, decode_user
|
|
32
|
+
from .utils import ROLE_MAPPING, QQBotNetwork, decode_channel, decode_guild, decode_member, decode_user
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def apply(
|
|
@@ -356,7 +356,13 @@ def apply(
|
|
|
356
356
|
"get",
|
|
357
357
|
f"guilds/{guild_id}/roles",
|
|
358
358
|
)
|
|
359
|
-
roles = [Role(role["id"], role.get("name", "")) for role in res]
|
|
359
|
+
# roles = [Role(role["id"], role.get("name", "")) for role in res]
|
|
360
|
+
roles = []
|
|
361
|
+
for role in res:
|
|
362
|
+
if role["id"] in ROLE_MAPPING:
|
|
363
|
+
roles.append(ROLE_MAPPING[role["id"]])
|
|
364
|
+
else:
|
|
365
|
+
roles.append(Role(role["id"], role.get("name", "")))
|
|
360
366
|
return PageResult(roles, next=None)
|
|
361
367
|
raise NotFoundException("qq platform does not support guild.role.list")
|
|
362
368
|
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
|
|
5
5
|
from satori import EventType
|
|
6
|
-
from satori.model import Event, Guild, User
|
|
6
|
+
from satori.model import Channel, ChannelType, Event, Guild, User
|
|
7
7
|
|
|
8
8
|
from ..utils import Payload
|
|
9
9
|
from .base import register_event
|
|
@@ -27,6 +27,8 @@ async def friend_event(login, guild_login, net, payload: Payload):
|
|
|
27
27
|
),
|
|
28
28
|
login,
|
|
29
29
|
user=user,
|
|
30
|
+
channel=Channel(f"private:{user.id}", type=ChannelType.DIRECT),
|
|
31
|
+
referrer={"event_id": payload.id},
|
|
30
32
|
)
|
|
31
33
|
|
|
32
34
|
|
|
@@ -52,5 +54,7 @@ async def group_event(login, guild_login, net, payload: Payload):
|
|
|
52
54
|
),
|
|
53
55
|
login,
|
|
54
56
|
guild=guild,
|
|
57
|
+
channel=Channel(guild.id, type=ChannelType.TEXT),
|
|
55
58
|
operator=operator,
|
|
59
|
+
referrer={"event_id": payload.id},
|
|
56
60
|
)
|
|
@@ -5,7 +5,7 @@ from datetime import datetime
|
|
|
5
5
|
from satori import EventType
|
|
6
6
|
from satori.model import Event, Guild, Member, Role, User
|
|
7
7
|
|
|
8
|
-
from ..utils import Payload, decode_channel, decode_guild, decode_user
|
|
8
|
+
from ..utils import ROLE_MAPPING, Payload, decode_channel, decode_guild, decode_user
|
|
9
9
|
from .base import register_event
|
|
10
10
|
|
|
11
11
|
|
|
@@ -57,7 +57,7 @@ async def guild_member_event(login, guild_login, net, payload: Payload):
|
|
|
57
57
|
nick=raw["nick"],
|
|
58
58
|
avatar=user.avatar,
|
|
59
59
|
joined_at=datetime.fromisoformat(raw["joined_at"]),
|
|
60
|
-
roles=[Role(r) for r in raw["roles"]],
|
|
60
|
+
roles=[(ROLE_MAPPING.get(r) or Role(r)) for r in raw["roles"]],
|
|
61
61
|
)
|
|
62
62
|
operator = User(raw["op_user_id"])
|
|
63
63
|
return Event(t, datetime.now(), guild_login, guild=guild, user=user, member=member, operator=operator)
|
|
@@ -6,7 +6,7 @@ from satori import At, EventType, Text
|
|
|
6
6
|
from satori.model import Channel, ChannelType, EmojiObject, Event, Guild, Member, MessageObject, Role, User
|
|
7
7
|
|
|
8
8
|
from ..message import decode_segments
|
|
9
|
-
from ..utils import USER_AVATAR_URL, Payload, decode_user
|
|
9
|
+
from ..utils import ROLE_MAPPING, USER_AVATAR_URL, Payload, decode_user
|
|
10
10
|
from .base import register_event
|
|
11
11
|
|
|
12
12
|
|
|
@@ -21,7 +21,7 @@ async def at_message(login, guild_login, net, payload: Payload):
|
|
|
21
21
|
user,
|
|
22
22
|
avatar=user.avatar,
|
|
23
23
|
joined_at=datetime.fromisoformat(raw["member"]["joined_at"]),
|
|
24
|
-
roles=[Role(r) for r in raw["member"]["roles"]],
|
|
24
|
+
roles=[(ROLE_MAPPING.get(r) or Role(r)) for r in raw["member"]["roles"]],
|
|
25
25
|
)
|
|
26
26
|
msg = decode_segments(raw)
|
|
27
27
|
if len(msg) >= 2 and isinstance(msg[0], At) and isinstance(msg[1], Text):
|
|
@@ -90,13 +90,17 @@ async def group_at_message_create(login, guild_login, net, payload: Payload):
|
|
|
90
90
|
else:
|
|
91
91
|
channel = Channel(raw["group_id"], ChannelType.TEXT)
|
|
92
92
|
app_id = net.bot_id_mapping[login.id]
|
|
93
|
+
name = raw["author"].get("username")
|
|
93
94
|
if "member_openid" in raw["author"]:
|
|
94
95
|
user = User(
|
|
95
96
|
raw["author"]["member_openid"],
|
|
97
|
+
name=name,
|
|
96
98
|
avatar=USER_AVATAR_URL.format(app_id=app_id, user_id=raw["author"]["member_openid"]),
|
|
97
99
|
)
|
|
98
100
|
else:
|
|
99
|
-
user = User(
|
|
101
|
+
user = User(
|
|
102
|
+
raw["author"]["id"], name=name, avatar=USER_AVATAR_URL.format(app_id=app_id, user_id=raw["author"]["id"])
|
|
103
|
+
)
|
|
100
104
|
member = Member(user, avatar=user.avatar)
|
|
101
105
|
msg = decode_segments(raw)
|
|
102
106
|
msg.insert(0, At(login.id))
|
|
@@ -122,6 +126,7 @@ async def group_at_message_create(login, guild_login, net, payload: Payload):
|
|
|
122
126
|
referrer={
|
|
123
127
|
"msg_id": raw["id"],
|
|
124
128
|
"msg_seq": -1,
|
|
129
|
+
"msg_scene": raw["message_scene"],
|
|
125
130
|
},
|
|
126
131
|
)
|
|
127
132
|
|
|
@@ -130,13 +135,17 @@ async def group_at_message_create(login, guild_login, net, payload: Payload):
|
|
|
130
135
|
async def c2c_message_create(login, guild_login, net, payload: Payload):
|
|
131
136
|
raw = payload.data
|
|
132
137
|
app_id = net.bot_id_mapping[login.id]
|
|
138
|
+
name = raw["author"].get("username")
|
|
133
139
|
if "user_openid" in raw["author"]:
|
|
134
140
|
user = User(
|
|
135
141
|
raw["author"]["user_openid"],
|
|
142
|
+
name,
|
|
136
143
|
avatar=USER_AVATAR_URL.format(app_id=app_id, user_id=raw["author"]["user_openid"]),
|
|
137
144
|
)
|
|
138
145
|
else:
|
|
139
|
-
user = User(
|
|
146
|
+
user = User(
|
|
147
|
+
raw["author"]["id"], name, avatar=USER_AVATAR_URL.format(app_id=app_id, user_id=raw["author"]["id"])
|
|
148
|
+
)
|
|
140
149
|
channel = Channel(f"private:{user.id}", ChannelType.DIRECT)
|
|
141
150
|
return Event(
|
|
142
151
|
EventType.MESSAGE_CREATED,
|
|
@@ -153,6 +162,7 @@ async def c2c_message_create(login, guild_login, net, payload: Payload):
|
|
|
153
162
|
"direct": True,
|
|
154
163
|
"msg_id": raw["id"],
|
|
155
164
|
"msg_seq": -1,
|
|
165
|
+
"msg_scene": raw["message_scene"],
|
|
156
166
|
},
|
|
157
167
|
)
|
|
158
168
|
|
|
@@ -169,7 +179,7 @@ async def message_delete(login, guild_login, new, payload: Payload):
|
|
|
169
179
|
user,
|
|
170
180
|
avatar=user.avatar,
|
|
171
181
|
joined_at=datetime.fromisoformat(raw["message"]["member"]["joined_at"]),
|
|
172
|
-
roles=[Role(r) for r in raw["message"]["member"]["roles"]],
|
|
182
|
+
roles=[(ROLE_MAPPING.get(r) or Role(r)) for r in raw["message"]["member"]["roles"]],
|
|
173
183
|
)
|
|
174
184
|
return Event(
|
|
175
185
|
EventType.MESSAGE_DELETED,
|
{satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/message.py
RENAMED
|
@@ -9,7 +9,7 @@ from pathlib import Path
|
|
|
9
9
|
|
|
10
10
|
from loguru import logger
|
|
11
11
|
|
|
12
|
-
from satori.element import Button, Custom, E, Element, select, transform
|
|
12
|
+
from satori.element import Button, Custom, E, Element, Raw, select, transform
|
|
13
13
|
from satori.model import Login, MessageObject
|
|
14
14
|
from satori.parser import Element as RawElement
|
|
15
15
|
from satori.parser import parse
|
|
@@ -241,9 +241,12 @@ class QQGroupMessageEncoder(QQBotMessageEncoder):
|
|
|
241
241
|
def __init__(self, login: Login, net: QQBotNetwork, channel_id: str, referrer: dict | None = None):
|
|
242
242
|
super().__init__(login, net, channel_id, referrer)
|
|
243
243
|
self.use_markdown = False
|
|
244
|
+
self.has_ark = False
|
|
244
245
|
self.content = ""
|
|
246
|
+
self.reference = ""
|
|
245
247
|
self.attachment: dict | None = None
|
|
246
248
|
self.rows: list[list[dict]] = []
|
|
249
|
+
self.md_templates: dict | None = None
|
|
247
250
|
# self.file_url = ""
|
|
248
251
|
# self.file_data = {} # value, content_type, filename
|
|
249
252
|
|
|
@@ -251,24 +254,33 @@ class QQGroupMessageEncoder(QQBotMessageEncoder):
|
|
|
251
254
|
if not self.content and not self.attachment and not self.rows:
|
|
252
255
|
return
|
|
253
256
|
self.strip_buttons()
|
|
257
|
+
event_id = self.referrer.get("event_id") if self.referrer else None
|
|
254
258
|
msg_id = self.referrer.get("msg_id") if self.referrer else None
|
|
255
259
|
msg_seq = self.referrer.get("msg_seq") if self.referrer else None
|
|
260
|
+
msg_scene = self.referrer.get("msg_scene", {}) if self.referrer else {}
|
|
261
|
+
refidx = msg_scene.get("ext", ["="])[0].partition("=")[-1]
|
|
256
262
|
data = {
|
|
257
263
|
"content": self.content,
|
|
264
|
+
"message_reference": {"message_id": refidx or self.reference} if refidx or self.reference else None,
|
|
258
265
|
"msg_type": 0,
|
|
266
|
+
"event_id": event_id,
|
|
259
267
|
"msg_id": msg_id,
|
|
260
268
|
"msg_seq": (msg_seq + 1) if isinstance(msg_seq, int) else 0,
|
|
261
269
|
}
|
|
262
|
-
if self.
|
|
270
|
+
if self.has_ark:
|
|
271
|
+
data["msg_type"] = 3
|
|
272
|
+
data["ark"] = json.loads(self.content) if self.content else {}
|
|
273
|
+
elif self.attachment:
|
|
263
274
|
if not self.content:
|
|
264
275
|
self.content = " "
|
|
265
276
|
data["media"] = self.attachment
|
|
266
277
|
data["msg_type"] = 7
|
|
267
|
-
|
|
278
|
+
elif self.use_markdown:
|
|
268
279
|
data["msg_type"] = 2
|
|
269
280
|
del data["content"]
|
|
270
281
|
data["markdown"] = {
|
|
271
|
-
"content": escape_markdown(self.content) or " ",
|
|
282
|
+
"content": self.content or " ", # escape_markdown(self.content) or " ",
|
|
283
|
+
**(self.md_templates or {}),
|
|
272
284
|
}
|
|
273
285
|
if self.rows:
|
|
274
286
|
data["keyboard"] = {"content": {"rows": self.export_buttons()}}
|
|
@@ -286,6 +298,7 @@ class QQGroupMessageEncoder(QQBotMessageEncoder):
|
|
|
286
298
|
resp = await self.net.call_api("post", endpoint, remove_empty(data))
|
|
287
299
|
referrer = self.referrer.copy() if self.referrer else {}
|
|
288
300
|
referrer |= {
|
|
301
|
+
"event_id": event_id,
|
|
289
302
|
"msg_id": msg_id,
|
|
290
303
|
"msg_seq": data["msg_seq"],
|
|
291
304
|
}
|
|
@@ -293,8 +306,11 @@ class QQGroupMessageEncoder(QQBotMessageEncoder):
|
|
|
293
306
|
except Exception as e:
|
|
294
307
|
logger.error(f"Failed to send message to {self.channel_id}: {self._raw_content}\nError: {e}")
|
|
295
308
|
self.content = ""
|
|
309
|
+
self.reference = ""
|
|
296
310
|
self.attachment = None
|
|
311
|
+
self.has_ark = False
|
|
297
312
|
self.use_markdown = False
|
|
313
|
+
self.md_templates = None
|
|
298
314
|
self.rows = []
|
|
299
315
|
|
|
300
316
|
async def send_file(self, type_: str, attrs: dict) -> dict | None:
|
|
@@ -340,7 +356,7 @@ class QQGroupMessageEncoder(QQBotMessageEncoder):
|
|
|
340
356
|
self.content += attrs["text"]
|
|
341
357
|
case "img" | "image":
|
|
342
358
|
if attrs.get("src") or attrs.get("url"):
|
|
343
|
-
await self.flush()
|
|
359
|
+
# await self.flush()
|
|
344
360
|
if data := (await self.send_file(type_, attrs)):
|
|
345
361
|
self.attachment = data
|
|
346
362
|
case "video" | "audio" | "file":
|
|
@@ -357,6 +373,11 @@ class QQGroupMessageEncoder(QQBotMessageEncoder):
|
|
|
357
373
|
await self.render(children)
|
|
358
374
|
if not self.content.endswith("\n"):
|
|
359
375
|
self.content += "\n"
|
|
376
|
+
case "qq:ark":
|
|
377
|
+
await self.flush()
|
|
378
|
+
self.has_ark = True
|
|
379
|
+
await self.render(children)
|
|
380
|
+
await self.flush()
|
|
360
381
|
case "qq:button-group":
|
|
361
382
|
self.use_markdown = True
|
|
362
383
|
self.rows.append([])
|
|
@@ -369,10 +390,21 @@ class QQGroupMessageEncoder(QQBotMessageEncoder):
|
|
|
369
390
|
case "markdown":
|
|
370
391
|
self.use_markdown = True
|
|
371
392
|
await self.render(children)
|
|
393
|
+
case "qq:markdown":
|
|
394
|
+
self.use_markdown = True
|
|
395
|
+
if attrs.get("template_id"):
|
|
396
|
+
self.md_templates = {
|
|
397
|
+
"custom_template_id": attrs["template_id"],
|
|
398
|
+
"params": [{"key": k, "value": v} for k, v in attrs.items() if k != "template_id"],
|
|
399
|
+
}
|
|
400
|
+
await self.render(children)
|
|
372
401
|
case "message":
|
|
373
402
|
await self.flush()
|
|
374
403
|
await self.render(children)
|
|
375
404
|
await self.flush()
|
|
405
|
+
case "quote":
|
|
406
|
+
self.reference = attrs["id"]
|
|
407
|
+
await self.flush()
|
|
376
408
|
case _:
|
|
377
409
|
await self.render(children)
|
|
378
410
|
|
|
@@ -466,5 +498,5 @@ def decode_segments(event: dict) -> list[Element]:
|
|
|
466
498
|
for i in embeds:
|
|
467
499
|
result.append(Custom("qq:embed", i))
|
|
468
500
|
if ark := event.get("ark"):
|
|
469
|
-
result.append(Custom("qq:ark", ark))
|
|
501
|
+
result.append(Custom("qq:ark", children=[Raw(json.dumps(ark, ensure_ascii=False))]))
|
|
470
502
|
return result
|
{satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/utils.py
RENAMED
|
@@ -122,15 +122,16 @@ def decode_member(profile: dict) -> Member:
|
|
|
122
122
|
decode_user(profile["user"]) if "user" in profile else None,
|
|
123
123
|
profile.get("nick"),
|
|
124
124
|
joined_at=datetime.fromisoformat(profile["joined_at"]) if "joined_at" in profile else None,
|
|
125
|
-
roles=[Role(r) for r in profile["roles"]],
|
|
125
|
+
roles=[(ROLE_MAPPING.get(r) or Role(r)) for r in profile["roles"]],
|
|
126
126
|
)
|
|
127
127
|
|
|
128
128
|
|
|
129
129
|
USER_AVATAR_URL = "https://q.qlogo.cn/qqapp/{app_id}/{user_id}/100"
|
|
130
130
|
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
ROLE_MAPPING = {
|
|
133
|
+
"1": Role("member", "成员"),
|
|
134
|
+
"5": Role("channel_admin", "子频道管理员"),
|
|
135
|
+
"2": Role("admin", "管理员"),
|
|
136
|
+
"4": Role("owner", "创建者"),
|
|
137
|
+
}
|
|
@@ -55,25 +55,36 @@ QQ_GUILD_FEATURES = [
|
|
|
55
55
|
@dataclass
|
|
56
56
|
class Intents:
|
|
57
57
|
guilds: bool = True
|
|
58
|
+
"""频道和子频道的基础事件"""
|
|
58
59
|
guild_members: bool = True
|
|
60
|
+
"""频道成员事件"""
|
|
59
61
|
guild_messages: bool = False
|
|
60
|
-
"""
|
|
62
|
+
"""频道消息事件,仅私域机器人能够设置此 intents。"""
|
|
61
63
|
guild_message_reactions: bool = True
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
"""频道消息表态事件"""
|
|
65
|
+
direct_messages: bool = False
|
|
66
|
+
"""频道私信消息事件"""
|
|
64
67
|
open_forum_event: bool = False
|
|
65
68
|
audio_live_member: bool = False
|
|
66
69
|
c2c_group_at_messages: bool = False
|
|
70
|
+
"""群聊和单聊事件"""
|
|
67
71
|
interaction: bool = False
|
|
72
|
+
"""互动事件(由按钮等组件触发的事件)"""
|
|
68
73
|
message_audit: bool = True
|
|
74
|
+
"""频道消息审核事件(由消息审核结果触发的事件)"""
|
|
69
75
|
forum_event: bool = False
|
|
76
|
+
"""频道论坛事件,仅私域机器人能够设置此 intents。"""
|
|
70
77
|
audio_action: bool = False
|
|
78
|
+
"""语音频道事件"""
|
|
71
79
|
at_messages: bool = True
|
|
72
|
-
"""
|
|
80
|
+
"""频道消息事件(只包含被 @ 的消息),为公域的消息事件"""
|
|
73
81
|
|
|
74
82
|
def __post_init__(self):
|
|
75
83
|
if self.at_messages and self.guild_messages:
|
|
76
|
-
logger.warning(
|
|
84
|
+
logger.warning(
|
|
85
|
+
"检测到 at_messages 和 guild_messages 同时开启。"
|
|
86
|
+
"请确认 bot 是否为公域机器人,若为公域机器人,则开启 guild_messages 将导致连接鉴权失败。"
|
|
87
|
+
)
|
|
77
88
|
|
|
78
89
|
def to_int(self) -> int:
|
|
79
90
|
return (
|
|
@@ -81,7 +92,7 @@ class Intents:
|
|
|
81
92
|
| self.guild_members << 1
|
|
82
93
|
| self.guild_messages << 9
|
|
83
94
|
| self.guild_message_reactions << 10
|
|
84
|
-
| self.
|
|
95
|
+
| self.direct_messages << 12
|
|
85
96
|
| self.open_forum_event << 18
|
|
86
97
|
| self.audio_live_member << 19
|
|
87
98
|
| self.c2c_group_at_messages << 25
|
|
@@ -554,5 +565,8 @@ class QQBotWebsocketAdapter(BaseAdapter):
|
|
|
554
565
|
logger.info(f"{self} Reconnecting...")
|
|
555
566
|
continue
|
|
556
567
|
|
|
568
|
+
def __str__(self):
|
|
569
|
+
return self.id
|
|
570
|
+
|
|
557
571
|
|
|
558
572
|
__all__ = ["QQBotWebsocketAdapter", "Intents"]
|
|
File without changes
|
{satori_python_adapter_qq-0.2.0 → satori_python_adapter_qq-0.3.0}/src/satori/adapters/qq/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|