diff --git a/astrbot/core/config/default.py b/astrbot/core/config/default.py index e96a74ef2..afbae30cc 100644 --- a/astrbot/core/config/default.py +++ b/astrbot/core/config/default.py @@ -24,6 +24,7 @@ DEFAULT_CONFIG = { "wl_ignore_admin_on_friend": True, "reply_with_mention": False, "reply_with_quote": False, + "path_mapping": [] }, "provider": [], "provider_settings": { @@ -220,6 +221,12 @@ CONFIG_METADATA_2 = { "type": "bool", "hint": "启用后,机器人回复消息时会引用原消息。实际效果以具体的平台适配器为准。", }, + "path_mapping": { + "description": "路径映射", + "type": "list", + "obvious_hint": True, + "hint": "此功能解决由于文件系统不一致导致路径不存在的问题。格式为 <原路径>:<映射路径>。如 `/app/.config/QQ:/var/lib/docker/volumes/xxxx/_data`。这样,当消息平台下发的事件中图片和语音路径以 `/app/.config/QQ` 开头时,开头被替换为 `/var/lib/docker/volumes/xxxx/_data`。这在 AstrBot 或者平台协议端使用 Docker 部署时特别有用。", + } }, }, "content_safety": { diff --git a/astrbot/core/pipeline/preprocess_stage/stage.py b/astrbot/core/pipeline/preprocess_stage/stage.py index 64242010b..15bfac2e2 100644 --- a/astrbot/core/pipeline/preprocess_stage/stage.py +++ b/astrbot/core/pipeline/preprocess_stage/stage.py @@ -5,7 +5,7 @@ from ..stage import Stage, register_stage from ..context import PipelineContext from astrbot.core.platform.astr_message_event import AstrMessageEvent from astrbot.core import logger -from astrbot.core.message.components import Plain, Record +from astrbot.core.message.components import Plain, Record, Image @register_stage class PreProcessStage(Stage): @@ -16,13 +16,31 @@ class PreProcessStage(Stage): self.plugin_manager = ctx.plugin_manager self.stt_settings: dict = self.config.get('provider_stt_settings', {}) + self.platform_settings: dict = self.config.get('platform_settings', {}) async def process(self, event: AstrMessageEvent) -> Union[None, AsyncGenerator[None, None]]: '''在处理事件之前的预处理''' - + # 路径映射 + if mappings := self.platform_settings.get('path_mapping', []): + # 支持 Record,Image 消息段的路径映射。 + message_chain = event.get_messages() + + for idx, component in enumerate(message_chain): + if isinstance(component, (Record, Image)) and component.url: + for mapping in mappings: + from_, to_ = mapping.split(":") + from_ = from_.removesuffix("/") + to_ = to_.removesuffix("/") + + url = component.url.removeprefix("file://") + if url.startswith(from_): + component.url = url.replace(from_, to_, 1) + logger.debug(f"路径映射: {url} -> {component.url}") + message_chain[idx] = component + + # STT if self.stt_settings.get('enable', False): - # STT 处理 # TODO: 独立 stt_provider = self.plugin_manager.context.provider_manager.curr_stt_provider_inst if stt_provider: