nonebot-adapter-qq 1.5.0__py3-none-any.whl → 1.5.2__py3-none-any.whl
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.
- nonebot/adapters/qq/__init__.py +2 -2
- nonebot/adapters/qq/adapter.py +12 -8
- nonebot/adapters/qq/bot.py +45 -29
- nonebot/adapters/qq/config.py +3 -3
- nonebot/adapters/qq/event.py +7 -4
- nonebot/adapters/qq/message.py +114 -3
- nonebot/adapters/qq/models/__init__.py +3 -3
- nonebot/adapters/qq/models/common.py +14 -12
- nonebot/adapters/qq/models/guild.py +15 -15
- nonebot/adapters/qq/models/payload.py +4 -3
- nonebot/adapters/qq/models/qq.py +3 -3
- nonebot/adapters/qq/store.py +2 -2
- nonebot/adapters/qq/utils.py +7 -17
- {nonebot_adapter_qq-1.5.0.dist-info → nonebot_adapter_qq-1.5.2.dist-info}/METADATA +1 -1
- nonebot_adapter_qq-1.5.2.dist-info/RECORD +20 -0
- nonebot_adapter_qq-1.5.0.dist-info/RECORD +0 -20
- {nonebot_adapter_qq-1.5.0.dist-info → nonebot_adapter_qq-1.5.2.dist-info}/LICENSE +0 -0
- {nonebot_adapter_qq-1.5.0.dist-info → nonebot_adapter_qq-1.5.2.dist-info}/WHEEL +0 -0
nonebot/adapters/qq/__init__.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
from .event import *
|
2
|
-
from .permission import *
|
3
1
|
from .bot import Bot as Bot
|
4
2
|
from .utils import log as log
|
3
|
+
from .event import * # noqa: F403
|
5
4
|
from .utils import escape as escape
|
6
5
|
from .adapter import Adapter as Adapter
|
7
6
|
from .message import Message as Message
|
7
|
+
from .permission import * # noqa: F403
|
8
8
|
from .utils import unescape as unescape
|
9
9
|
from .exception import ActionFailed as ActionFailed
|
10
10
|
from .exception import NetworkError as NetworkError
|
nonebot/adapters/qq/adapter.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import sys
|
2
2
|
import asyncio
|
3
3
|
from typing_extensions import override
|
4
|
-
from typing import Any,
|
4
|
+
from typing import Any, Literal, Optional
|
5
5
|
|
6
6
|
from nonebot.utils import escape_tag
|
7
7
|
from nonebot.exception import WebSocketClosed
|
@@ -46,7 +46,7 @@ class Adapter(BaseAdapter):
|
|
46
46
|
|
47
47
|
self.qq_config: Config = Config(**self.config.dict())
|
48
48
|
|
49
|
-
self.tasks:
|
49
|
+
self.tasks: list["asyncio.Task"] = []
|
50
50
|
self.setup()
|
51
51
|
|
52
52
|
@classmethod
|
@@ -137,7 +137,7 @@ class Adapter(BaseAdapter):
|
|
137
137
|
# wait for session start concurrency limit
|
138
138
|
await asyncio.sleep(gateway_info.session_start_limit.max_concurrency or 1)
|
139
139
|
|
140
|
-
async def _forward_ws(self, bot: Bot, ws_url: URL, shard:
|
140
|
+
async def _forward_ws(self, bot: Bot, ws_url: URL, shard: tuple[int, int]) -> None:
|
141
141
|
# ws setup request
|
142
142
|
request = Request(
|
143
143
|
"GET",
|
@@ -236,7 +236,7 @@ class Adapter(BaseAdapter):
|
|
236
236
|
)
|
237
237
|
|
238
238
|
async def _authenticate(
|
239
|
-
self, bot: Bot, ws: WebSocket, shard:
|
239
|
+
self, bot: Bot, ws: WebSocket, shard: tuple[int, int]
|
240
240
|
) -> Optional[Literal[True]]:
|
241
241
|
"""鉴权连接"""
|
242
242
|
if not bot.ready:
|
@@ -318,7 +318,7 @@ class Adapter(BaseAdapter):
|
|
318
318
|
)
|
319
319
|
|
320
320
|
if ready_event:
|
321
|
-
asyncio.create_task(bot.handle_event(ready_event))
|
321
|
+
asyncio.create_task(bot.handle_event(ready_event)) # noqa: RUF006
|
322
322
|
|
323
323
|
return True
|
324
324
|
|
@@ -354,7 +354,7 @@ class Adapter(BaseAdapter):
|
|
354
354
|
else:
|
355
355
|
if isinstance(event, MessageAuditEvent):
|
356
356
|
audit_result.add_result(event)
|
357
|
-
asyncio.create_task(bot.handle_event(event))
|
357
|
+
asyncio.create_task(bot.handle_event(event)) # noqa: RUF006
|
358
358
|
elif isinstance(payload, HeartbeatAck):
|
359
359
|
log("TRACE", "Heartbeat ACK")
|
360
360
|
continue
|
@@ -405,10 +405,14 @@ class Adapter(BaseAdapter):
|
|
405
405
|
EventClass = EVENT_CLASSES.get(payload.type, None)
|
406
406
|
if EventClass is None:
|
407
407
|
log("WARNING", f"Unknown payload type: {payload.type}")
|
408
|
-
event = type_validate_python(
|
408
|
+
event = type_validate_python(
|
409
|
+
Event, {"event_id": payload.id, **payload.data}
|
410
|
+
)
|
409
411
|
event.__type__ = payload.type # type: ignore
|
410
412
|
return event
|
411
|
-
return type_validate_python(
|
413
|
+
return type_validate_python(
|
414
|
+
EventClass, {"event_id": payload.id, **payload.data}
|
415
|
+
)
|
412
416
|
|
413
417
|
@override
|
414
418
|
async def _call_api(self, bot: Bot, api: str, **data: Any) -> Any:
|
nonebot/adapters/qq/bot.py
CHANGED
@@ -6,8 +6,6 @@ from typing import (
|
|
6
6
|
IO,
|
7
7
|
TYPE_CHECKING,
|
8
8
|
Any,
|
9
|
-
Dict,
|
10
|
-
List,
|
11
9
|
Union,
|
12
10
|
Literal,
|
13
11
|
NoReturn,
|
@@ -42,6 +40,7 @@ from .event import (
|
|
42
40
|
QQMessageEvent,
|
43
41
|
GuildMessageEvent,
|
44
42
|
C2CMessageCreateEvent,
|
43
|
+
InteractionCreateEvent,
|
45
44
|
DirectMessageCreateEvent,
|
46
45
|
GroupAtMessageCreateEvent,
|
47
46
|
)
|
@@ -110,7 +109,7 @@ async def _check_reply(
|
|
110
109
|
if event.reply.author.id == bot.self_info.id:
|
111
110
|
event.to_me = True
|
112
111
|
except Exception as e:
|
113
|
-
log("WARNING", f"Error when getting message reply info: {
|
112
|
+
log("WARNING", f"Error when getting message reply info: {e!r}", e)
|
114
113
|
|
115
114
|
|
116
115
|
def _check_at_me(
|
@@ -264,7 +263,7 @@ class Bot(BaseBot):
|
|
264
263
|
return f"QQBot {await self.get_access_token()}"
|
265
264
|
return f"Bot {self.bot_info.id}.{self.bot_info.token}"
|
266
265
|
|
267
|
-
async def get_authorization_header(self) ->
|
266
|
+
async def get_authorization_header(self) -> dict[str, str]:
|
268
267
|
"""获取当前 Bot 的鉴权信息"""
|
269
268
|
headers = {"Authorization": await self._get_authorization_header()}
|
270
269
|
if self.bot_info.is_group_bot:
|
@@ -284,7 +283,7 @@ class Bot(BaseBot):
|
|
284
283
|
return _message
|
285
284
|
|
286
285
|
@staticmethod
|
287
|
-
def _extract_send_message(message: Message) ->
|
286
|
+
def _extract_send_message(message: Message) -> dict[str, Any]:
|
288
287
|
kwargs = {}
|
289
288
|
content = message.extract_content() or None
|
290
289
|
kwargs["content"] = content
|
@@ -301,7 +300,7 @@ class Bot(BaseBot):
|
|
301
300
|
return kwargs
|
302
301
|
|
303
302
|
@staticmethod
|
304
|
-
def _extract_guild_image(message: Message) ->
|
303
|
+
def _extract_guild_image(message: Message) -> dict[str, Any]:
|
305
304
|
kwargs = {}
|
306
305
|
if image := (message["image"] or None):
|
307
306
|
kwargs["image"] = image[-1].data["url"]
|
@@ -310,7 +309,7 @@ class Bot(BaseBot):
|
|
310
309
|
return kwargs
|
311
310
|
|
312
311
|
@staticmethod
|
313
|
-
def _extract_qq_media(message: Message) ->
|
312
|
+
def _extract_qq_media(message: Message) -> dict[str, Any]:
|
314
313
|
kwargs = {}
|
315
314
|
if image := message["image"]:
|
316
315
|
kwargs["file_type"] = 1
|
@@ -433,7 +432,7 @@ class Bot(BaseBot):
|
|
433
432
|
msg_type = 4
|
434
433
|
elif kwargs.get("ark"):
|
435
434
|
msg_type = 3
|
436
|
-
elif kwargs.get("markdown"):
|
435
|
+
elif kwargs.get("markdown") or kwargs.get("keyboard"):
|
437
436
|
msg_type = 2
|
438
437
|
elif (
|
439
438
|
message["image"]
|
@@ -507,6 +506,23 @@ class Bot(BaseBot):
|
|
507
506
|
msg_id=event.id,
|
508
507
|
msg_seq=event._reply_seq,
|
509
508
|
)
|
509
|
+
elif isinstance(event, InteractionCreateEvent):
|
510
|
+
if gid := event.group_openid:
|
511
|
+
return await self.send_to_group(
|
512
|
+
group_openid=gid, event_id=event.event_id, message=message
|
513
|
+
)
|
514
|
+
elif cid := event.channel_id:
|
515
|
+
return await self.send_to_channel(
|
516
|
+
channel_id=cid, event_id=event.event_id, message=message
|
517
|
+
)
|
518
|
+
elif uid := event.user_openid:
|
519
|
+
return await self.send_to_c2c(
|
520
|
+
openid=uid, event_id=event.event_id, message=message
|
521
|
+
)
|
522
|
+
elif gid := event.guild_id:
|
523
|
+
return await self.send_to_dms(
|
524
|
+
guild_id=gid, event_id=event.event_id, message=message
|
525
|
+
)
|
510
526
|
|
511
527
|
raise RuntimeError("Event cannot be replied to!")
|
512
528
|
|
@@ -589,13 +605,13 @@ class Bot(BaseBot):
|
|
589
605
|
before: Optional[str] = None,
|
590
606
|
after: Optional[str] = None,
|
591
607
|
limit: Optional[float] = None,
|
592
|
-
) ->
|
608
|
+
) -> list[Guild]:
|
593
609
|
request = Request(
|
594
610
|
"GET",
|
595
611
|
self.adapter.get_api_base().joinpath("users", "@me", "guilds"),
|
596
612
|
params=exclude_none({"before": before, "after": after, "limit": limit}),
|
597
613
|
)
|
598
|
-
return type_validate_python(
|
614
|
+
return type_validate_python(list[Guild], await self._request(request))
|
599
615
|
|
600
616
|
# Guild API
|
601
617
|
@API
|
@@ -608,12 +624,12 @@ class Bot(BaseBot):
|
|
608
624
|
|
609
625
|
# Channel API
|
610
626
|
@API
|
611
|
-
async def get_channels(self, *, guild_id: str) ->
|
627
|
+
async def get_channels(self, *, guild_id: str) -> list[Channel]:
|
612
628
|
request = Request(
|
613
629
|
"GET",
|
614
630
|
self.adapter.get_api_base().joinpath("guilds", guild_id, "channels"),
|
615
631
|
)
|
616
|
-
return type_validate_python(
|
632
|
+
return type_validate_python(list[Channel], await self._request(request))
|
617
633
|
|
618
634
|
@API
|
619
635
|
async def get_channel(self, *, channel_id: str) -> Channel:
|
@@ -634,10 +650,10 @@ class Bot(BaseBot):
|
|
634
650
|
position: Optional[int] = None,
|
635
651
|
parent_id: Optional[int] = None,
|
636
652
|
private_type: Optional[Union[PrivateType, int]] = None,
|
637
|
-
private_user_ids: Optional[
|
653
|
+
private_user_ids: Optional[list[str]] = None,
|
638
654
|
speak_permission: Optional[Union[SpeakPermission, int]] = None,
|
639
655
|
application_id: Optional[str] = None,
|
640
|
-
) ->
|
656
|
+
) -> list[Channel]:
|
641
657
|
request = Request(
|
642
658
|
"POST",
|
643
659
|
self.adapter.get_api_base().joinpath("guilds", guild_id, "channels"),
|
@@ -655,7 +671,7 @@ class Bot(BaseBot):
|
|
655
671
|
}
|
656
672
|
),
|
657
673
|
)
|
658
|
-
return type_validate_python(
|
674
|
+
return type_validate_python(list[Channel], await self._request(request))
|
659
675
|
|
660
676
|
@API
|
661
677
|
async def patch_channel(
|
@@ -705,13 +721,13 @@ class Bot(BaseBot):
|
|
705
721
|
guild_id: str,
|
706
722
|
after: Optional[str] = None,
|
707
723
|
limit: Optional[float] = None,
|
708
|
-
) ->
|
724
|
+
) -> list[Member]:
|
709
725
|
request = Request(
|
710
726
|
"GET",
|
711
727
|
self.adapter.get_api_base().joinpath("guilds", guild_id, "members"),
|
712
728
|
params=exclude_none({"after": after, "limit": limit}),
|
713
729
|
)
|
714
|
-
return type_validate_python(
|
730
|
+
return type_validate_python(list[Member], await self._request(request))
|
715
731
|
|
716
732
|
@API
|
717
733
|
async def get_role_members(
|
@@ -940,7 +956,7 @@ class Bot(BaseBot):
|
|
940
956
|
return type_validate_python(GuildMessage, result)
|
941
957
|
|
942
958
|
@staticmethod
|
943
|
-
def _parse_send_message(data:
|
959
|
+
def _parse_send_message(data: dict[str, Any]) -> dict[str, Any]:
|
944
960
|
data = exclude_none(data)
|
945
961
|
data = {
|
946
962
|
k: v.dict(exclude_none=True) if isinstance(v, BaseModel) else v
|
@@ -948,8 +964,8 @@ class Bot(BaseBot):
|
|
948
964
|
}
|
949
965
|
if file_image := data.pop("file_image", None):
|
950
966
|
# 使用 multipart/form-data
|
951
|
-
multipart_files:
|
952
|
-
multipart_data:
|
967
|
+
multipart_files: dict[str, Any] = {"file_image": ("file_image", file_image)}
|
968
|
+
multipart_data: dict[str, Any] = {}
|
953
969
|
for k, v in data.items():
|
954
970
|
if isinstance(v, (dict, list)):
|
955
971
|
# 当字段类型为对象或数组时需要将字段序列化为 JSON 字符串后进行调用
|
@@ -1154,10 +1170,10 @@ class Bot(BaseBot):
|
|
1154
1170
|
self,
|
1155
1171
|
*,
|
1156
1172
|
guild_id: str,
|
1157
|
-
user_ids:
|
1173
|
+
user_ids: list[str],
|
1158
1174
|
mute_end_timestamp: Optional[Union[int, datetime]] = None,
|
1159
1175
|
mute_seconds: Optional[Union[int, timedelta]] = None,
|
1160
|
-
) ->
|
1176
|
+
) -> list[int]:
|
1161
1177
|
if isinstance(mute_end_timestamp, datetime):
|
1162
1178
|
mute_end_timestamp = int(mute_end_timestamp.timestamp())
|
1163
1179
|
|
@@ -1175,7 +1191,7 @@ class Bot(BaseBot):
|
|
1175
1191
|
}
|
1176
1192
|
),
|
1177
1193
|
)
|
1178
|
-
return type_validate_python(
|
1194
|
+
return type_validate_python(list[int], await self._request(request))
|
1179
1195
|
|
1180
1196
|
# Announce API
|
1181
1197
|
@API
|
@@ -1186,7 +1202,7 @@ class Bot(BaseBot):
|
|
1186
1202
|
message_id: Optional[str] = None,
|
1187
1203
|
channel_id: Optional[str] = None,
|
1188
1204
|
announces_type: Optional[int] = None,
|
1189
|
-
recommend_channels: Optional[
|
1205
|
+
recommend_channels: Optional[list[RecommendChannel]] = None,
|
1190
1206
|
) -> None:
|
1191
1207
|
request = Request(
|
1192
1208
|
"POST",
|
@@ -1251,7 +1267,7 @@ class Bot(BaseBot):
|
|
1251
1267
|
@API
|
1252
1268
|
async def get_schedules(
|
1253
1269
|
self, *, channel_id: str, since: Optional[Union[int, datetime]] = None
|
1254
|
-
) ->
|
1270
|
+
) -> list[Schedule]:
|
1255
1271
|
if isinstance(since, datetime):
|
1256
1272
|
since = int(since.timestamp() * 1000)
|
1257
1273
|
|
@@ -1260,7 +1276,7 @@ class Bot(BaseBot):
|
|
1260
1276
|
self.adapter.get_api_base() / f"channels/{channel_id}/schedules",
|
1261
1277
|
json=exclude_none({"since": since}),
|
1262
1278
|
)
|
1263
|
-
return type_validate_python(
|
1279
|
+
return type_validate_python(list[Schedule], await self._request(request))
|
1264
1280
|
|
1265
1281
|
@API
|
1266
1282
|
async def get_schedule(self, *, channel_id: str, schedule_id: str) -> Schedule:
|
@@ -1442,7 +1458,7 @@ class Bot(BaseBot):
|
|
1442
1458
|
audio_url: Optional[str] = None,
|
1443
1459
|
text: Optional[str] = None,
|
1444
1460
|
status: Union[AudioStatus, int],
|
1445
|
-
) ->
|
1461
|
+
) -> dict[Never, Never]:
|
1446
1462
|
request = Request(
|
1447
1463
|
"POST",
|
1448
1464
|
self.adapter.get_api_base().joinpath("channels", channel_id, "audio"),
|
@@ -1453,7 +1469,7 @@ class Bot(BaseBot):
|
|
1453
1469
|
return await self._request(request)
|
1454
1470
|
|
1455
1471
|
@API
|
1456
|
-
async def put_mic(self, *, channel_id: str) ->
|
1472
|
+
async def put_mic(self, *, channel_id: str) -> dict[Never, Never]:
|
1457
1473
|
request = Request(
|
1458
1474
|
"PUT",
|
1459
1475
|
self.adapter.get_api_base().joinpath("channels", channel_id, "mic"),
|
@@ -1461,7 +1477,7 @@ class Bot(BaseBot):
|
|
1461
1477
|
return await self._request(request)
|
1462
1478
|
|
1463
1479
|
@API
|
1464
|
-
async def delete_mic(self, *, channel_id: str) ->
|
1480
|
+
async def delete_mic(self, *, channel_id: str) -> dict[Never, Never]:
|
1465
1481
|
request = Request(
|
1466
1482
|
"DELETE",
|
1467
1483
|
self.adapter.get_api_base().joinpath("channels", channel_id, "mic"),
|
nonebot/adapters/qq/config.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Optional
|
2
2
|
|
3
3
|
from pydantic import Field, HttpUrl, BaseModel
|
4
4
|
from nonebot.compat import PYDANTIC_V2, ConfigDict
|
@@ -53,7 +53,7 @@ class BotInfo(BaseModel):
|
|
53
53
|
id: str = Field(alias="id")
|
54
54
|
token: str = Field(alias="token")
|
55
55
|
secret: str = Field(alias="secret")
|
56
|
-
shard: Optional[
|
56
|
+
shard: Optional[tuple[int, int]] = None
|
57
57
|
intent: Intents = Field(default_factory=Intents)
|
58
58
|
|
59
59
|
@property
|
@@ -67,4 +67,4 @@ class Config(BaseModel):
|
|
67
67
|
qq_api_base: HttpUrl = Field("https://api.sgroup.qq.com/")
|
68
68
|
qq_sandbox_api_base: HttpUrl = Field("https://sandbox.api.sgroup.qq.com")
|
69
69
|
qq_auth_base: HttpUrl = Field("https://bots.qq.com/app/getAppAccessToken")
|
70
|
-
qq_bots:
|
70
|
+
qq_bots: list[BotInfo] = Field(default_factory=list)
|
nonebot/adapters/qq/event.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from enum import Enum
|
2
2
|
from datetime import datetime
|
3
3
|
from typing_extensions import override
|
4
|
-
from typing import
|
4
|
+
from typing import TypeVar, Optional, cast
|
5
5
|
|
6
6
|
from nonebot.utils import escape_tag
|
7
7
|
|
@@ -117,6 +117,9 @@ class EventType(str, Enum):
|
|
117
117
|
class Event(BaseEvent):
|
118
118
|
__type__: EventType
|
119
119
|
|
120
|
+
# event id from payload id
|
121
|
+
event_id: Optional[str] = None
|
122
|
+
|
120
123
|
@override
|
121
124
|
def get_event_name(self) -> str:
|
122
125
|
return self.__type__
|
@@ -142,10 +145,10 @@ class Event(BaseEvent):
|
|
142
145
|
return False
|
143
146
|
|
144
147
|
|
145
|
-
EVENT_CLASSES:
|
148
|
+
EVENT_CLASSES: dict[str, type[Event]] = {}
|
146
149
|
|
147
150
|
|
148
|
-
def register_event_class(event_class:
|
151
|
+
def register_event_class(event_class: type[E]) -> type[E]:
|
149
152
|
EVENT_CLASSES[event_class.__type__.value] = event_class
|
150
153
|
return event_class
|
151
154
|
|
@@ -163,7 +166,7 @@ class ReadyEvent(MetaEvent):
|
|
163
166
|
version: int
|
164
167
|
session_id: str
|
165
168
|
user: User
|
166
|
-
shard:
|
169
|
+
shard: tuple[int, int]
|
167
170
|
|
168
171
|
|
169
172
|
@register_event_class
|
nonebot/adapters/qq/message.py
CHANGED
@@ -2,8 +2,11 @@ import re
|
|
2
2
|
from io import BytesIO
|
3
3
|
from pathlib import Path
|
4
4
|
from dataclasses import dataclass
|
5
|
+
from collections.abc import Iterable
|
5
6
|
from typing_extensions import Self, override
|
6
|
-
from typing import TYPE_CHECKING,
|
7
|
+
from typing import TYPE_CHECKING, Union, Optional, TypedDict, overload
|
8
|
+
|
9
|
+
from nonebot.compat import type_validate_python
|
7
10
|
|
8
11
|
from nonebot.adapters import Message as BaseMessage
|
9
12
|
from nonebot.adapters import MessageSegment as BaseMessageSegment
|
@@ -24,7 +27,7 @@ from .models import (
|
|
24
27
|
class MessageSegment(BaseMessageSegment["Message"]):
|
25
28
|
@classmethod
|
26
29
|
@override
|
27
|
-
def get_message_class(cls) ->
|
30
|
+
def get_message_class(cls) -> type["Message"]:
|
28
31
|
return Message
|
29
32
|
|
30
33
|
@staticmethod
|
@@ -166,6 +169,32 @@ class MessageSegment(BaseMessageSegment["Message"]):
|
|
166
169
|
def is_text(self) -> bool:
|
167
170
|
return self.type == "text"
|
168
171
|
|
172
|
+
@classmethod
|
173
|
+
@override
|
174
|
+
def _validate(cls, value) -> Self:
|
175
|
+
if isinstance(value, cls):
|
176
|
+
return value
|
177
|
+
if isinstance(value, MessageSegment):
|
178
|
+
raise ValueError(f"Type {type(value)} can not be converted to {cls}")
|
179
|
+
if not isinstance(value, dict):
|
180
|
+
raise ValueError(f"Expected dict for MessageSegment, got {type(value)}")
|
181
|
+
if "type" not in value:
|
182
|
+
raise ValueError(
|
183
|
+
f"Expected dict with 'type' for MessageSegment, got {value}"
|
184
|
+
)
|
185
|
+
_type = value["type"]
|
186
|
+
if _type not in SEGMENT_TYPE_MAP:
|
187
|
+
raise ValueError(f"Invalid MessageSegment type: {_type}")
|
188
|
+
segment_type = SEGMENT_TYPE_MAP[_type]
|
189
|
+
|
190
|
+
# casting value to subclass of MessageSegment
|
191
|
+
if cls is MessageSegment:
|
192
|
+
return type_validate_python(segment_type, value)
|
193
|
+
# init segment instance directly if type matched
|
194
|
+
if cls is segment_type:
|
195
|
+
return segment_type(type=_type, data=value.get("data", {}))
|
196
|
+
raise ValueError(f"Segment type {_type!r} can not be converted to {cls}")
|
197
|
+
|
169
198
|
|
170
199
|
class _TextData(TypedDict):
|
171
200
|
text: str
|
@@ -278,6 +307,18 @@ class Embed(MessageSegment):
|
|
278
307
|
def __str__(self) -> str:
|
279
308
|
return f"<embed:{self.data['embed']!r}>"
|
280
309
|
|
310
|
+
@classmethod
|
311
|
+
@override
|
312
|
+
def _validate(cls, value) -> Self:
|
313
|
+
instance = super()._validate(value)
|
314
|
+
if "embed" not in instance.data:
|
315
|
+
raise ValueError(
|
316
|
+
f"Expected dict with 'embed' in 'data' for Embed, got {value}"
|
317
|
+
)
|
318
|
+
if not isinstance(embed := instance.data["embed"], MessageEmbed):
|
319
|
+
instance.data["embed"] = type_validate_python(MessageEmbed, embed)
|
320
|
+
return instance
|
321
|
+
|
281
322
|
|
282
323
|
class _ArkData(TypedDict):
|
283
324
|
ark: MessageArk
|
@@ -292,6 +333,16 @@ class Ark(MessageSegment):
|
|
292
333
|
def __str__(self) -> str:
|
293
334
|
return f"<ark:{self.data['ark']!r}>"
|
294
335
|
|
336
|
+
@classmethod
|
337
|
+
@override
|
338
|
+
def _validate(cls, value) -> Self:
|
339
|
+
instance = super()._validate(value)
|
340
|
+
if "ark" not in instance.data:
|
341
|
+
raise ValueError(f"Expected dict with 'ark' in 'data' for Ark, got {value}")
|
342
|
+
if not isinstance(ark := instance.data["ark"], MessageArk):
|
343
|
+
instance.data["ark"] = type_validate_python(MessageArk, ark)
|
344
|
+
return instance
|
345
|
+
|
295
346
|
|
296
347
|
class _ReferenceData(TypedDict):
|
297
348
|
reference: MessageReference
|
@@ -306,6 +357,20 @@ class Reference(MessageSegment):
|
|
306
357
|
def __str__(self) -> str:
|
307
358
|
return f"<reference:{self.data['reference'].message_id}>"
|
308
359
|
|
360
|
+
@classmethod
|
361
|
+
@override
|
362
|
+
def _validate(cls, value) -> Self:
|
363
|
+
instance = super()._validate(value)
|
364
|
+
if "reference" not in instance.data:
|
365
|
+
raise ValueError(
|
366
|
+
f"Expected dict with 'reference' in 'data' for Reference, got {value}"
|
367
|
+
)
|
368
|
+
if not isinstance(reference := instance.data["reference"], MessageReference):
|
369
|
+
instance.data["reference"] = type_validate_python(
|
370
|
+
MessageReference, reference
|
371
|
+
)
|
372
|
+
return instance
|
373
|
+
|
309
374
|
|
310
375
|
class _MarkdownData(TypedDict):
|
311
376
|
markdown: MessageMarkdown
|
@@ -320,6 +385,18 @@ class Markdown(MessageSegment):
|
|
320
385
|
def __str__(self) -> str:
|
321
386
|
return f"<markdown:{self.data['markdown']!r}>"
|
322
387
|
|
388
|
+
@classmethod
|
389
|
+
@override
|
390
|
+
def _validate(cls, value) -> Self:
|
391
|
+
instance = super()._validate(value)
|
392
|
+
if "markdown" not in instance.data:
|
393
|
+
raise ValueError(
|
394
|
+
f"Expected dict with 'markdown' in 'data' for Markdown, got {value}"
|
395
|
+
)
|
396
|
+
if not isinstance(markdown := instance.data["markdown"], MessageMarkdown):
|
397
|
+
instance.data["markdown"] = type_validate_python(MessageMarkdown, markdown)
|
398
|
+
return instance
|
399
|
+
|
323
400
|
|
324
401
|
class _KeyboardData(TypedDict):
|
325
402
|
keyboard: MessageKeyboard
|
@@ -334,11 +411,45 @@ class Keyboard(MessageSegment):
|
|
334
411
|
def __str__(self) -> str:
|
335
412
|
return f"<keyboard:{self.data['keyboard']!r}>"
|
336
413
|
|
414
|
+
@classmethod
|
415
|
+
@override
|
416
|
+
def _validate(cls, value) -> Self:
|
417
|
+
instance = super()._validate(value)
|
418
|
+
if "keyboard" not in instance.data:
|
419
|
+
raise ValueError(
|
420
|
+
f"Expected dict with 'keyboard' in 'data' for Keyboard, got {value}"
|
421
|
+
)
|
422
|
+
if not isinstance(keyboard := instance.data["keyboard"], MessageKeyboard):
|
423
|
+
instance.data["keyboard"] = type_validate_python(MessageKeyboard, keyboard)
|
424
|
+
return instance
|
425
|
+
|
426
|
+
|
427
|
+
SEGMENT_TYPE_MAP: dict[str, type[MessageSegment]] = {
|
428
|
+
"text": Text,
|
429
|
+
"emoji": Emoji,
|
430
|
+
"mention_user": MentionUser,
|
431
|
+
"mention_channel": MentionChannel,
|
432
|
+
"mention_everyone": MentionEveryone,
|
433
|
+
"image": Attachment,
|
434
|
+
"file_image": LocalAttachment,
|
435
|
+
"audio": Attachment,
|
436
|
+
"file_audio": LocalAttachment,
|
437
|
+
"video": Attachment,
|
438
|
+
"file_video": LocalAttachment,
|
439
|
+
"file": Attachment,
|
440
|
+
"file_file": LocalAttachment,
|
441
|
+
"ark": Ark,
|
442
|
+
"embed": Embed,
|
443
|
+
"markdown": Markdown,
|
444
|
+
"keyboard": Keyboard,
|
445
|
+
"reference": Reference,
|
446
|
+
}
|
447
|
+
|
337
448
|
|
338
449
|
class Message(BaseMessage[MessageSegment]):
|
339
450
|
@classmethod
|
340
451
|
@override
|
341
|
-
def get_segment_class(cls) ->
|
452
|
+
def get_segment_class(cls) -> type[MessageSegment]:
|
342
453
|
return MessageSegment
|
343
454
|
|
344
455
|
@override
|
@@ -1,6 +1,6 @@
|
|
1
|
-
from .qq import *
|
2
|
-
from .guild import *
|
3
|
-
from .common import *
|
1
|
+
from .qq import * # noqa: F403
|
2
|
+
from .guild import * # noqa: F403
|
3
|
+
from .common import * # noqa: F403
|
4
4
|
from .payload import Hello as Hello
|
5
5
|
from .payload import Opcode as Opcode
|
6
6
|
from .payload import Resume as Resume
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from datetime import datetime
|
2
2
|
from urllib.parse import urlparse
|
3
|
-
from typing import
|
3
|
+
from typing import Literal, Optional
|
4
4
|
|
5
5
|
from pydantic import BaseModel
|
6
6
|
|
@@ -33,7 +33,7 @@ class MessageEmbed(BaseModel):
|
|
33
33
|
description: Optional[str] = None
|
34
34
|
prompt: str
|
35
35
|
thumbnail: Optional[MessageEmbedThumbnail] = None
|
36
|
-
fields: Optional[
|
36
|
+
fields: Optional[list[MessageEmbedField]] = None
|
37
37
|
|
38
38
|
|
39
39
|
# Message Ark
|
@@ -43,18 +43,18 @@ class MessageArkObjKv(BaseModel):
|
|
43
43
|
|
44
44
|
|
45
45
|
class MessageArkObj(BaseModel):
|
46
|
-
obj_kv: Optional[
|
46
|
+
obj_kv: Optional[list[MessageArkObjKv]] = None
|
47
47
|
|
48
48
|
|
49
49
|
class MessageArkKv(BaseModel):
|
50
50
|
key: Optional[str] = None
|
51
51
|
value: Optional[str] = None
|
52
|
-
obj: Optional[
|
52
|
+
obj: Optional[list[MessageArkObj]] = None
|
53
53
|
|
54
54
|
|
55
55
|
class MessageArk(BaseModel):
|
56
56
|
template_id: Optional[int] = None
|
57
|
-
kv: Optional[
|
57
|
+
kv: Optional[list[MessageArkKv]] = None
|
58
58
|
|
59
59
|
|
60
60
|
# Message Reference
|
@@ -66,21 +66,21 @@ class MessageReference(BaseModel):
|
|
66
66
|
# Message Markdown
|
67
67
|
class MessageMarkdownParams(BaseModel):
|
68
68
|
key: Optional[str] = None
|
69
|
-
values: Optional[
|
69
|
+
values: Optional[list[str]] = None
|
70
70
|
|
71
71
|
|
72
72
|
class MessageMarkdown(BaseModel):
|
73
73
|
template_id: Optional[int] = None
|
74
74
|
custom_template_id: Optional[str] = None
|
75
|
-
params: Optional[
|
75
|
+
params: Optional[list[MessageMarkdownParams]] = None
|
76
76
|
content: Optional[str] = None
|
77
77
|
|
78
78
|
|
79
79
|
# Message Keyboard
|
80
80
|
class Permission(BaseModel):
|
81
81
|
type: Optional[int] = None
|
82
|
-
specify_role_ids: Optional[
|
83
|
-
specify_user_ids: Optional[
|
82
|
+
specify_role_ids: Optional[list[str]] = None
|
83
|
+
specify_user_ids: Optional[list[str]] = None
|
84
84
|
|
85
85
|
|
86
86
|
class Action(BaseModel):
|
@@ -108,11 +108,11 @@ class Button(BaseModel):
|
|
108
108
|
|
109
109
|
|
110
110
|
class InlineKeyboardRow(BaseModel):
|
111
|
-
buttons: Optional[
|
111
|
+
buttons: Optional[list[Button]] = None
|
112
112
|
|
113
113
|
|
114
114
|
class InlineKeyboard(BaseModel):
|
115
|
-
rows: Optional[
|
115
|
+
rows: Optional[list[InlineKeyboardRow]] = None
|
116
116
|
|
117
117
|
|
118
118
|
class MessageKeyboard(BaseModel):
|
@@ -140,6 +140,8 @@ class ButtonInteractionContent(BaseModel):
|
|
140
140
|
feature_id: Optional[str] = None
|
141
141
|
button_id: Optional[str] = None
|
142
142
|
button_data: Optional[str] = None
|
143
|
+
checked: Optional[int] = None
|
144
|
+
feedback_opt: Optional[str] = None
|
143
145
|
|
144
146
|
|
145
147
|
class ButtonInteractionData(BaseModel):
|
@@ -148,7 +150,7 @@ class ButtonInteractionData(BaseModel):
|
|
148
150
|
|
149
151
|
class ButtonInteraction(BaseModel):
|
150
152
|
id: str
|
151
|
-
type: Literal[11, 12]
|
153
|
+
type: Literal[11, 12, 13]
|
152
154
|
version: int
|
153
155
|
timestamp: str
|
154
156
|
scene: str
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import json
|
2
2
|
from enum import IntEnum
|
3
3
|
from datetime import datetime
|
4
|
-
from typing import
|
4
|
+
from typing import Union, Generic, TypeVar, Optional
|
5
5
|
|
6
6
|
from pydantic import BaseModel
|
7
7
|
from nonebot.compat import PYDANTIC_V2, model_fields, type_validate_python
|
@@ -91,12 +91,12 @@ class Channel(BaseModel):
|
|
91
91
|
class Member(BaseModel):
|
92
92
|
user: Optional[User] = None
|
93
93
|
nick: Optional[str] = None
|
94
|
-
roles: Optional[
|
94
|
+
roles: Optional[list[str]] = None
|
95
95
|
joined_at: datetime
|
96
96
|
|
97
97
|
|
98
98
|
class GetRoleMembersReturn(BaseModel):
|
99
|
-
data:
|
99
|
+
data: list[Member]
|
100
100
|
next: str
|
101
101
|
|
102
102
|
|
@@ -112,7 +112,7 @@ class Role(BaseModel):
|
|
112
112
|
|
113
113
|
class GetGuildRolesReturn(BaseModel):
|
114
114
|
guild_id: str
|
115
|
-
roles:
|
115
|
+
roles: list[Role]
|
116
116
|
role_num_limit: int
|
117
117
|
|
118
118
|
|
@@ -145,9 +145,9 @@ class Message(BaseModel):
|
|
145
145
|
edited_timestamp: Optional[datetime] = None
|
146
146
|
mention_everyone: Optional[bool] = None
|
147
147
|
author: User
|
148
|
-
attachments: Optional[
|
149
|
-
embeds: Optional[
|
150
|
-
mentions: Optional[
|
148
|
+
attachments: Optional[list[MessageAttachment]] = None
|
149
|
+
embeds: Optional[list[MessageEmbed]] = None
|
150
|
+
mentions: Optional[list[User]] = None
|
151
151
|
member: Optional[Member] = None
|
152
152
|
ark: Optional[MessageArk] = None
|
153
153
|
seq: Optional[int] = None
|
@@ -166,7 +166,7 @@ class MessageDelete(BaseModel):
|
|
166
166
|
class MessageSetting(BaseModel):
|
167
167
|
disable_create_dm: bool
|
168
168
|
disable_push_msg: bool
|
169
|
-
channel_ids:
|
169
|
+
channel_ids: list[str]
|
170
170
|
channel_push_max_num: int
|
171
171
|
|
172
172
|
|
@@ -188,14 +188,14 @@ class Announces(BaseModel):
|
|
188
188
|
channel_id: Optional[str] = None
|
189
189
|
message_id: Optional[str] = None
|
190
190
|
announces_type: Optional[int] = None
|
191
|
-
recommend_channels: Optional[
|
191
|
+
recommend_channels: Optional[list[RecommendChannel]] = None
|
192
192
|
|
193
193
|
|
194
194
|
# Pins
|
195
195
|
class PinsMessage(BaseModel):
|
196
196
|
guild_id: str
|
197
197
|
channel_id: str
|
198
|
-
message_ids:
|
198
|
+
message_ids: list[str]
|
199
199
|
|
200
200
|
|
201
201
|
# Schedule
|
@@ -251,7 +251,7 @@ class MessageReaction(BaseModel):
|
|
251
251
|
|
252
252
|
|
253
253
|
class GetReactionUsersReturn(BaseModel):
|
254
|
-
users:
|
254
|
+
users: list[User]
|
255
255
|
cookie: str
|
256
256
|
is_end: bool
|
257
257
|
|
@@ -358,12 +358,12 @@ class ParagraphProps(BaseModel):
|
|
358
358
|
|
359
359
|
|
360
360
|
class Paragraph(BaseModel):
|
361
|
-
elems:
|
361
|
+
elems: list[Elem]
|
362
362
|
props: Optional[ParagraphProps] = None
|
363
363
|
|
364
364
|
|
365
365
|
class RichText(BaseModel):
|
366
|
-
paragraphs:
|
366
|
+
paragraphs: list[Paragraph]
|
367
367
|
|
368
368
|
|
369
369
|
class ThreadObjectInfo(BaseModel):
|
@@ -441,7 +441,7 @@ class ForumAuditResult(ForumSourceInfo):
|
|
441
441
|
|
442
442
|
|
443
443
|
class GetThreadsListReturn(BaseModel):
|
444
|
-
threads:
|
444
|
+
threads: list[Thread[str]]
|
445
445
|
is_finish: bool
|
446
446
|
|
447
447
|
|
@@ -476,7 +476,7 @@ class APIPermissionDemand(BaseModel):
|
|
476
476
|
|
477
477
|
|
478
478
|
class GetGuildAPIPermissionReturn(BaseModel):
|
479
|
-
apis:
|
479
|
+
apis: list[APIPermission]
|
480
480
|
|
481
481
|
|
482
482
|
# WebSocket
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from enum import IntEnum
|
2
|
-
from
|
3
|
-
from
|
2
|
+
from typing_extensions import Literal
|
3
|
+
from typing import Union, Optional, Annotated
|
4
4
|
|
5
5
|
from pydantic import Field, BaseModel
|
6
6
|
from nonebot.compat import PYDANTIC_V2, ConfigDict
|
@@ -43,6 +43,7 @@ class Dispatch(Payload):
|
|
43
43
|
data: dict
|
44
44
|
sequence: int
|
45
45
|
type: str
|
46
|
+
id: Optional[str] = None
|
46
47
|
|
47
48
|
|
48
49
|
class Heartbeat(Payload):
|
@@ -53,7 +54,7 @@ class Heartbeat(Payload):
|
|
53
54
|
class IdentifyData(BaseModel):
|
54
55
|
token: str
|
55
56
|
intents: int
|
56
|
-
shard:
|
57
|
+
shard: tuple[int, int]
|
57
58
|
properties: dict
|
58
59
|
|
59
60
|
if PYDANTIC_V2:
|
nonebot/adapters/qq/models/qq.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
from typing import Optional
|
1
2
|
from datetime import datetime
|
2
|
-
from typing import List, Optional
|
3
3
|
from urllib.parse import urlparse
|
4
4
|
|
5
5
|
from pydantic import BaseModel
|
@@ -40,7 +40,7 @@ class QQMessage(BaseModel):
|
|
40
40
|
id: str
|
41
41
|
content: str
|
42
42
|
timestamp: str
|
43
|
-
attachments: Optional[
|
43
|
+
attachments: Optional[list[Attachment]] = None
|
44
44
|
|
45
45
|
|
46
46
|
class PostC2CMessagesReturn(BaseModel):
|
@@ -71,7 +71,7 @@ class GroupMember(BaseModel):
|
|
71
71
|
|
72
72
|
|
73
73
|
class PostGroupMembersReturn(BaseModel):
|
74
|
-
members:
|
74
|
+
members: list[GroupMember]
|
75
75
|
next_index: Optional[int] = None
|
76
76
|
|
77
77
|
|
nonebot/adapters/qq/store.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import asyncio
|
2
|
-
from typing import TYPE_CHECKING,
|
2
|
+
from typing import TYPE_CHECKING, Optional
|
3
3
|
|
4
4
|
if TYPE_CHECKING:
|
5
5
|
from .event import MessageAuditEvent
|
@@ -7,7 +7,7 @@ if TYPE_CHECKING:
|
|
7
7
|
|
8
8
|
class AuditResultStore:
|
9
9
|
def __init__(self) -> None:
|
10
|
-
self._futures:
|
10
|
+
self._futures: dict[str, asyncio.Future] = {}
|
11
11
|
|
12
12
|
def add_result(self, result: "MessageAuditEvent"):
|
13
13
|
audit_id = result.audit_id
|
nonebot/adapters/qq/utils.py
CHANGED
@@ -1,17 +1,7 @@
|
|
1
1
|
from functools import partial
|
2
|
+
from collections.abc import Awaitable
|
2
3
|
from typing_extensions import ParamSpec, Concatenate
|
3
|
-
from typing import
|
4
|
-
TYPE_CHECKING,
|
5
|
-
Any,
|
6
|
-
Dict,
|
7
|
-
Type,
|
8
|
-
Generic,
|
9
|
-
TypeVar,
|
10
|
-
Callable,
|
11
|
-
Optional,
|
12
|
-
Awaitable,
|
13
|
-
overload,
|
14
|
-
)
|
4
|
+
from typing import TYPE_CHECKING, Any, Generic, TypeVar, Callable, Optional, overload
|
15
5
|
|
16
6
|
from nonebot.utils import logger_wrapper
|
17
7
|
|
@@ -33,7 +23,7 @@ def unescape(s: str) -> str:
|
|
33
23
|
return s.replace("<", "<").replace(">", ">").replace("&", "&")
|
34
24
|
|
35
25
|
|
36
|
-
def exclude_none(data:
|
26
|
+
def exclude_none(data: dict[str, Any]) -> dict[str, Any]:
|
37
27
|
return {k: v for k, v in data.items() if v is not None}
|
38
28
|
|
39
29
|
|
@@ -41,19 +31,19 @@ class API(Generic[B, P, R]):
|
|
41
31
|
def __init__(self, func: Callable[Concatenate[B, P], Awaitable[R]]) -> None:
|
42
32
|
self.func = func
|
43
33
|
|
44
|
-
def __set_name__(self, owner:
|
34
|
+
def __set_name__(self, owner: type[B], name: str) -> None:
|
45
35
|
self.name = name
|
46
36
|
|
47
37
|
@overload
|
48
|
-
def __get__(self, obj: None, objtype:
|
38
|
+
def __get__(self, obj: None, objtype: type[B]) -> "API[B, P, R]": ...
|
49
39
|
|
50
40
|
@overload
|
51
41
|
def __get__(
|
52
|
-
self, obj: B, objtype: Optional[
|
42
|
+
self, obj: B, objtype: Optional[type[B]]
|
53
43
|
) -> Callable[P, Awaitable[R]]: ...
|
54
44
|
|
55
45
|
def __get__(
|
56
|
-
self, obj: Optional[B], objtype: Optional[
|
46
|
+
self, obj: Optional[B], objtype: Optional[type[B]] = None
|
57
47
|
) -> "API[B, P, R] | Callable[P, Awaitable[R]]":
|
58
48
|
if obj is None:
|
59
49
|
return self
|
@@ -0,0 +1,20 @@
|
|
1
|
+
nonebot/adapters/qq/__init__.py,sha256=jm1QxHfhcYIrWhkXxF9gE4G3lkagrLCWsmVqKBTQSOw,815
|
2
|
+
nonebot/adapters/qq/adapter.py,sha256=Fa1dVykpC_-mIVgN7b37k45Ecu3cddt2KWwsZSJqrp4,14591
|
3
|
+
nonebot/adapters/qq/bot.py,sha256=AA2eGpTZxHRTj3Z7mzCa3K77QdKSL6O-wTcEJ4F7bmE,61394
|
4
|
+
nonebot/adapters/qq/compat.py,sha256=7g5QvRzWREesZ7MSEhNRh53UZwEyhQlxE3e_KpqQ0pw,768
|
5
|
+
nonebot/adapters/qq/config.py,sha256=vvTZ4JRJEQ60PyLh92IEnQkOltdUs41lGKZuYXxq6yA,2135
|
6
|
+
nonebot/adapters/qq/event.py,sha256=9URqXn-U0K2JwYR1TJkNjejWB1C_-LnflLZPsTNn32I,18802
|
7
|
+
nonebot/adapters/qq/exception.py,sha256=8Xa9NwYyO7Ih0owBAC_zmEiIRAA8GjgQcoJcF5ogo0g,2701
|
8
|
+
nonebot/adapters/qq/message.py,sha256=q4dhlpuQ-Fyiqj2_cL1TCaZutdF41fcyGXpiI6RucVg,15526
|
9
|
+
nonebot/adapters/qq/models/__init__.py,sha256=VsLh2rceTl9fK4hReYXBosOPZj6E1x7lDUdk7py_R8A,579
|
10
|
+
nonebot/adapters/qq/models/common.py,sha256=oQDNaPUNUO64-_bgQdHobQyZLdtdDNnkykzGjbRdAUM,4539
|
11
|
+
nonebot/adapters/qq/models/guild.py,sha256=8xyFLwXXzIk-LxqzSlkfkuJfPgxxIkLYWsrPRcX4lsM,11686
|
12
|
+
nonebot/adapters/qq/models/payload.py,sha256=_Q-4yHlSlzb5Lm2MLv8QxQ_ADVbjWJt3SCWN3_niH-Q,2851
|
13
|
+
nonebot/adapters/qq/models/qq.py,sha256=9gPQZBuuZEOvAsk7a6-w0Gh0Scf4qQL9y08pubdfk1o,1853
|
14
|
+
nonebot/adapters/qq/permission.py,sha256=0aedypl6xymhAV3UkW0vlvHTBkJeDmOef3SxG2tPcHQ,988
|
15
|
+
nonebot/adapters/qq/store.py,sha256=GKVbto6K7jI-oK9tSbw_xLxDiSA6Y9QnNQStKJU7mEY,868
|
16
|
+
nonebot/adapters/qq/utils.py,sha256=bzJwm1zWyHjFILr-bHrBKpKlkiveph9S4pLAXMcW9AY,1538
|
17
|
+
nonebot_adapter_qq-1.5.2.dist-info/LICENSE,sha256=4EZBnkZPQYBvtO2KFGaUQHTO8nZ26pGeaCFchdBq_AE,1064
|
18
|
+
nonebot_adapter_qq-1.5.2.dist-info/METADATA,sha256=8qgJba66rQN3Cd3OEp_btLfeSIck14KQrMAWKwwE1eg,2735
|
19
|
+
nonebot_adapter_qq-1.5.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
20
|
+
nonebot_adapter_qq-1.5.2.dist-info/RECORD,,
|
@@ -1,20 +0,0 @@
|
|
1
|
-
nonebot/adapters/qq/__init__.py,sha256=u2bR9HLdgIEV22nu2VJeUFscklTUj8DN4650q0k5SHw,787
|
2
|
-
nonebot/adapters/qq/adapter.py,sha256=ivVkSvUFcQEGIp9AmDTwP17HFNnrMmg6LYF1pfORi2s,14464
|
3
|
-
nonebot/adapters/qq/bot.py,sha256=GggOMoEp8lHU2O7cRsS-LtmyXu14ijJttjSYcJ9M364,60571
|
4
|
-
nonebot/adapters/qq/compat.py,sha256=7g5QvRzWREesZ7MSEhNRh53UZwEyhQlxE3e_KpqQ0pw,768
|
5
|
-
nonebot/adapters/qq/config.py,sha256=rdBWweI0db8-9KQF-lvNLMCMa55PJPOkvn9DVJMprac,2148
|
6
|
-
nonebot/adapters/qq/event.py,sha256=4VvHq7l5aQYmIEBLpjHrCL_neqYBTximeuPHQHnt384,18754
|
7
|
-
nonebot/adapters/qq/exception.py,sha256=8Xa9NwYyO7Ih0owBAC_zmEiIRAA8GjgQcoJcF5ogo0g,2701
|
8
|
-
nonebot/adapters/qq/message.py,sha256=JjUeqqMaw3N5-STrcvmjcWNx9VCSBGaLuZB4jg4gpM8,11422
|
9
|
-
nonebot/adapters/qq/models/__init__.py,sha256=AahR-O5B_1c8dMXHpDH68o4qojhF3vf4UPDGyH2MKjA,537
|
10
|
-
nonebot/adapters/qq/models/common.py,sha256=AgGtLf2vC_rxluKFp26PTq0nFFPKuI_ALcGKdwped7A,4468
|
11
|
-
nonebot/adapters/qq/models/guild.py,sha256=ZVSqYfm0_gP5hiTTQoPjhWZ06e7XzdaIVsPDyc2WrVs,11692
|
12
|
-
nonebot/adapters/qq/models/payload.py,sha256=WCjf9usGO4nlaYT99j3bsk8yLuUUlwfSK0gNqAONN6o,2819
|
13
|
-
nonebot/adapters/qq/models/qq.py,sha256=zzpHdXgSHoiT-tPyjmR2YjL4IZpLogc-tvAThh7WvdM,1859
|
14
|
-
nonebot/adapters/qq/permission.py,sha256=0aedypl6xymhAV3UkW0vlvHTBkJeDmOef3SxG2tPcHQ,988
|
15
|
-
nonebot/adapters/qq/store.py,sha256=X-NeSVCrxngQDPo9IXKWehERNa4sefdrYrZn5-yucF4,874
|
16
|
-
nonebot/adapters/qq/utils.py,sha256=rMHpOf1zUrVodCYULMTBr82pF54tGK3b5TMykSnY6jc,1568
|
17
|
-
nonebot_adapter_qq-1.5.0.dist-info/LICENSE,sha256=4EZBnkZPQYBvtO2KFGaUQHTO8nZ26pGeaCFchdBq_AE,1064
|
18
|
-
nonebot_adapter_qq-1.5.0.dist-info/METADATA,sha256=2UfZxU96zeAyAqSAyAdQ0K7_mq41IjnG-LzmWIemJNE,2735
|
19
|
-
nonebot_adapter_qq-1.5.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
20
|
-
nonebot_adapter_qq-1.5.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|