diff --git a/astrbot/core/message/message_event_result.py b/astrbot/core/message/message_event_result.py index 0965fe7f7f..72dc481a23 100644 --- a/astrbot/core/message/message_event_result.py +++ b/astrbot/core/message/message_event_result.py @@ -27,9 +27,25 @@ class MessageChain: chain: list[BaseMessageComponent] = field(default_factory=list) use_t2i_: bool | None = None # None 为跟随用户设置 + use_markdown_: bool | None = ( + None # 是否使用 Markdown 发送消息。None 跟随平台默认,True 强制 Markdown,False 强制纯文本。 + ) type: str | None = None """消息链承载的消息的类型。可选,用于让消息平台区分不同业务场景的消息链。""" + def derive(self, chain: list[BaseMessageComponent] | None = None) -> "MessageChain": + """基于当前消息链创建一个新的 MessageChain,继承元数据(use_t2i_、use_markdown_ 等)。 + + Args: + chain: 新消息链的组件列表。如果为 None,则使用空列表。 + + """ + new = MessageChain(chain=chain if chain is not None else []) + new.use_t2i_ = self.use_t2i_ + new.use_markdown_ = self.use_markdown_ + new.type = self.type + return new + def message(self, message: str): """添加一条文本消息到消息链 `chain` 中。 @@ -118,6 +134,18 @@ def use_t2i(self, use_t2i: bool): self.use_t2i_ = use_t2i return self + def use_markdown(self, use: bool | None = True): + """设置是否使用 Markdown 发送消息。 + + 仅对支持 Markdown 的平台生效(如 QQ Official),不支持的平台会忽略此字段。 + + Args: + use: True 强制使用 Markdown,False 强制纯文本,None 跟随平台默认行为。 + + """ + self.use_markdown_ = use + return self + def get_plain_text(self, with_other_comps_mark: bool = False) -> str: """获取纯文本消息。这个方法将获取 chain 中所有 Plain 组件的文本并拼接成一条消息。空格分隔。 diff --git a/astrbot/core/pipeline/respond/stage.py b/astrbot/core/pipeline/respond/stage.py index 6a884a5181..559f2c1311 100644 --- a/astrbot/core/pipeline/respond/stage.py +++ b/astrbot/core/pipeline/respond/stage.py @@ -247,9 +247,9 @@ async def process( await asyncio.sleep(i) try: if comp.type in need_separately: - await event.send(MessageChain([comp])) + await event.send(result.derive([comp])) else: - await event.send(MessageChain([*header_comps, comp])) + await event.send(result.derive([*header_comps, comp])) header_comps.clear() except Exception as e: logger.error( @@ -272,7 +272,7 @@ async def process( modify_raw_chain=True, ) for comp in sep_comps: - chain = MessageChain([comp]) + chain = result.derive([comp]) try: await event.send(chain) except Exception as e: @@ -280,7 +280,7 @@ async def process( f"发送消息链失败: chain = {chain}, error = {e}", exc_info=True, ) - chain = MessageChain(result.chain) + chain = result.derive(result.chain) if result.chain and len(result.chain) > 0: try: await event.send(chain) diff --git a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py index 97b2b2fb49..8234bf1aef 100644 --- a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +++ b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py @@ -211,12 +211,20 @@ async def _post_send(self, stream: dict | None = None): ): plain_text = plain_text + "\n" - payload: dict = { - # "content": plain_text, - "markdown": MarkdownPayload(content=plain_text) if plain_text else None, - "msg_type": 2, - "msg_id": self.message_obj.message_id, - } + # 根据消息链的 use_markdown_ 标记决定发送模式 + use_md = getattr(self.send_buffer, "use_markdown_", None) + if use_md is False: + payload: dict = { + "content": plain_text, + "msg_type": 0, + "msg_id": self.message_obj.message_id, + } + else: + payload = { + "markdown": MarkdownPayload(content=plain_text) if plain_text else None, + "msg_type": 2, + "msg_id": self.message_obj.message_id, + } if not isinstance(source, botpy.message.Message | botpy.message.DirectMessage): payload["msg_seq"] = random.randint(1, 10000)