Skip to content

Commit b98bd38

Browse files
authored
feat: update QQOfficialPlatformAdapter to support async parsing and attachment preparation (#7007)
fixes: #6853
1 parent 81f4bd4 commit b98bd38

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

astrbot/core/pipeline/preprocess_stage/stage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ async def process(
7676
return
7777
message_chain = event.get_messages()
7878
for idx, component in enumerate(message_chain):
79-
if isinstance(component, Record) and component.url:
80-
path = component.url.removeprefix("file://")
79+
if isinstance(component, Record):
80+
path = await component.convert_to_file_path()
8181
retry = 5
8282
for i in range(retry):
8383
try:

astrbot/core/platform/sources/qqofficial/qqofficial_platform_adapter.py

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import os
66
import random
77
import time
8+
import uuid
9+
from pathlib import Path
810
from types import SimpleNamespace
911
from typing import Any, cast
1012

@@ -24,6 +26,8 @@
2426
)
2527
from astrbot.core.message.components import BaseMessageComponent
2628
from astrbot.core.platform.astr_message_event import MessageSesion
29+
from astrbot.core.utils.astrbot_path import get_astrbot_temp_path
30+
from astrbot.core.utils.io import download_file
2731

2832
from ...register import register_platform_adapter
2933
from .qqofficial_message_event import QQOfficialMessageEvent
@@ -42,7 +46,7 @@ def set_platform(self, platform: QQOfficialPlatformAdapter) -> None:
4246
async def on_group_at_message_create(
4347
self, message: botpy.message.GroupMessage
4448
) -> None:
45-
abm = QQOfficialPlatformAdapter._parse_from_qqofficial(
49+
abm = await QQOfficialPlatformAdapter._parse_from_qqofficial(
4650
message,
4751
MessageType.GROUP_MESSAGE,
4852
)
@@ -53,7 +57,7 @@ async def on_group_at_message_create(
5357

5458
# 收到频道消息
5559
async def on_at_message_create(self, message: botpy.message.Message) -> None:
56-
abm = QQOfficialPlatformAdapter._parse_from_qqofficial(
60+
abm = await QQOfficialPlatformAdapter._parse_from_qqofficial(
5761
message,
5862
MessageType.GROUP_MESSAGE,
5963
)
@@ -66,7 +70,7 @@ async def on_at_message_create(self, message: botpy.message.Message) -> None:
6670
async def on_direct_message_create(
6771
self, message: botpy.message.DirectMessage
6872
) -> None:
69-
abm = QQOfficialPlatformAdapter._parse_from_qqofficial(
73+
abm = await QQOfficialPlatformAdapter._parse_from_qqofficial(
7074
message,
7175
MessageType.FRIEND_MESSAGE,
7276
)
@@ -76,7 +80,7 @@ async def on_direct_message_create(
7680

7781
# 收到 C2C 消息
7882
async def on_c2c_message_create(self, message: botpy.message.C2CMessage) -> None:
79-
abm = QQOfficialPlatformAdapter._parse_from_qqofficial(
83+
abm = await QQOfficialPlatformAdapter._parse_from_qqofficial(
8084
message,
8185
MessageType.FRIEND_MESSAGE,
8286
)
@@ -336,7 +340,22 @@ def _normalize_attachment_url(url: str | None) -> str:
336340
return f"https://{url}"
337341

338342
@staticmethod
339-
def _append_attachments(
343+
async def _prepare_audio_attachment(
344+
url: str,
345+
filename: str,
346+
) -> Record:
347+
temp_dir = Path(get_astrbot_temp_path())
348+
temp_dir.mkdir(parents=True, exist_ok=True)
349+
350+
ext = Path(filename).suffix.lower()
351+
source_ext = ext or ".audio"
352+
source_path = temp_dir / f"qqofficial_{uuid.uuid4().hex}{source_ext}"
353+
await download_file(url, str(source_path))
354+
355+
return Record(file=str(source_path), url=str(source_path))
356+
357+
@staticmethod
358+
async def _append_attachments(
340359
msg: list[BaseMessageComponent],
341360
attachments: list | None,
342361
) -> None:
@@ -363,7 +382,7 @@ def _append_attachments(
363382
or getattr(attachment, "name", None)
364383
or "attachment",
365384
)
366-
ext = os.path.splitext(filename)[1].lower()
385+
ext = Path(filename).suffix.lower()
367386
image_exts = {".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"}
368387
audio_exts = {
369388
".mp3",
@@ -381,8 +400,21 @@ def _append_attachments(
381400
".webm",
382401
}
383402

384-
if content_type.startswith("audio") or ext in audio_exts:
385-
msg.append(Record.fromURL(url))
403+
if content_type.startswith("voice") or ext in audio_exts:
404+
try:
405+
msg.append(
406+
await QQOfficialPlatformAdapter._prepare_audio_attachment(
407+
url,
408+
filename,
409+
)
410+
)
411+
except Exception as e:
412+
logger.warning(
413+
"[QQOfficial] Failed to prepare audio attachment %s: %s",
414+
url,
415+
e,
416+
)
417+
msg.append(Record.fromURL(url))
386418
elif content_type.startswith("video") or ext in video_exts:
387419
msg.append(Video.fromURL(url))
388420
elif content_type.startswith("image") or ext in image_exts:
@@ -432,13 +464,13 @@ def replace_face(match):
432464
return re.sub(r"<faceType=\d+[^>]*>", replace_face, content)
433465

434466
@staticmethod
435-
def _parse_from_qqofficial(
467+
async def _parse_from_qqofficial(
436468
message: botpy.message.Message
437469
| botpy.message.GroupMessage
438470
| botpy.message.DirectMessage
439471
| botpy.message.C2CMessage,
440472
message_type: MessageType,
441-
):
473+
) -> AstrBotMessage:
442474
abm = AstrBotMessage()
443475
abm.type = message_type
444476
abm.timestamp = int(time.time())
@@ -463,7 +495,9 @@ def _parse_from_qqofficial(
463495
abm.self_id = "unknown_selfid"
464496
msg.append(At(qq="qq_official"))
465497
msg.append(Plain(abm.message_str))
466-
QQOfficialPlatformAdapter._append_attachments(msg, message.attachments)
498+
await QQOfficialPlatformAdapter._append_attachments(
499+
msg, message.attachments
500+
)
467501
abm.message = msg
468502

469503
elif isinstance(message, botpy.message.Message) or isinstance(
@@ -482,7 +516,9 @@ def _parse_from_qqofficial(
482516
).strip()
483517
)
484518

485-
QQOfficialPlatformAdapter._append_attachments(msg, message.attachments)
519+
await QQOfficialPlatformAdapter._append_attachments(
520+
msg, message.attachments
521+
)
486522
abm.message = msg
487523
abm.message_str = plain_content
488524
abm.sender = MessageMember(

astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def set_platform(self, platform: "QQOfficialWebhookPlatformAdapter") -> None:
3131
async def on_group_at_message_create(
3232
self, message: botpy.message.GroupMessage
3333
) -> None:
34-
abm = QQOfficialPlatformAdapter._parse_from_qqofficial(
34+
abm = await QQOfficialPlatformAdapter._parse_from_qqofficial(
3535
message,
3636
MessageType.GROUP_MESSAGE,
3737
)
@@ -42,7 +42,7 @@ async def on_group_at_message_create(
4242

4343
# 收到频道消息
4444
async def on_at_message_create(self, message: botpy.message.Message) -> None:
45-
abm = QQOfficialPlatformAdapter._parse_from_qqofficial(
45+
abm = await QQOfficialPlatformAdapter._parse_from_qqofficial(
4646
message,
4747
MessageType.GROUP_MESSAGE,
4848
)
@@ -55,7 +55,7 @@ async def on_at_message_create(self, message: botpy.message.Message) -> None:
5555
async def on_direct_message_create(
5656
self, message: botpy.message.DirectMessage
5757
) -> None:
58-
abm = QQOfficialPlatformAdapter._parse_from_qqofficial(
58+
abm = await QQOfficialPlatformAdapter._parse_from_qqofficial(
5959
message,
6060
MessageType.FRIEND_MESSAGE,
6161
)
@@ -65,7 +65,7 @@ async def on_direct_message_create(
6565

6666
# 收到 C2C 消息
6767
async def on_c2c_message_create(self, message: botpy.message.C2CMessage) -> None:
68-
abm = QQOfficialPlatformAdapter._parse_from_qqofficial(
68+
abm = await QQOfficialPlatformAdapter._parse_from_qqofficial(
6969
message,
7070
MessageType.FRIEND_MESSAGE,
7171
)

0 commit comments

Comments
 (0)