mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
feat: add message-level markdown control for QQ Official platform (#6980)
* feat: add message-level markdown control for QQ Official platform * feat: propagate MessageChain metadata through RespondStage chain splitting
This commit is contained in:
@@ -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 @@ class MessageChain:
|
||||
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 组件的文本并拼接成一条消息。空格分隔。
|
||||
|
||||
|
||||
@@ -246,9 +246,9 @@ class RespondStage(Stage):
|
||||
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(
|
||||
@@ -271,7 +271,7 @@ class RespondStage(Stage):
|
||||
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:
|
||||
@@ -279,7 +279,7 @@ class RespondStage(Stage):
|
||||
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)
|
||||
|
||||
@@ -235,12 +235,20 @@ class QQOfficialMessageEvent(AstrMessageEvent):
|
||||
):
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user