🐛 fix(command): 修复 Event 对象无 reply 方法

- events() 返回的是 Event(data=GroupMessageEvent) 包装对象
- 改用 event.data(消息事件实体)构建回复
- 手动构建 MessageArray + add_reply 实现引用回复
- 群聊默认 @发送者,at_sender=false 可关闭
This commit is contained in:
2026-05-02 20:38:09 +08:00
parent 601bce8847
commit 89461b6ed6

View File

@@ -76,17 +76,38 @@ async def send_command_callback(data: dict, event, api, logger) -> None:
if not isinstance(result, dict):
return
await _handle_reply(result, event, api, logger)
await _handle_reply(result, event.data, api, logger)
except Exception as exc:
logger.error("命令回调异常: url=%s error=%s", COMMAND_CALLBACK_URL, exc)
async def _handle_reply(result: dict, event, api, logger) -> None:
"""处理回调响应,引用原消息自动回复。"""
async def _handle_reply(result: dict, msg_event, api, logger) -> None:
"""处理回调响应,引用原消息自动回复。msg_event 是 GroupMessageEvent / PrivateMessageEvent。"""
at_sender = result.get("at_sender", True)
messages = result.get("messages")
reply = result.get("reply")
group_id = getattr(msg_event, "group_id", None)
user_id = msg_event.user_id
message_id = msg_event.message_id
# 构造引用消息段
from ncatbot.types import MessageArray, Reply
def build_reply_msg(text=None, image=None, video=None) -> MessageArray:
"""构建带引用的消息段。"""
msg = MessageArray()
msg.add_reply(message_id)
if group_id and at_sender:
msg.add_at(user_id)
msg.add_text(" ")
if text is not None:
msg.add_text(text)
if image is not None:
msg.add_image(image)
if video is not None:
msg.add_video(video)
return msg
# 批量回复:引用 + 批量消息段
if messages and isinstance(messages, list):
@@ -107,20 +128,23 @@ async def _handle_reply(result: dict, event, api, logger) -> None:
file_msgs.append(msg)
text = "\n".join(text_parts) if text_parts else None
group_id = getattr(event.data, "group_id", None)
try:
# 组合消息用 event.reply 引用原消息
# 组合消息(带引用)
if text or image_url or video_url:
await event.reply(text=text, image=image_url, video=video_url, at_sender=at_sender)
# 文件单独发file 是独占段)
reply_msg = build_reply_msg(text=text, image=image_url, video=video_url)
if group_id:
await api.qq.post_group_array_msg(group_id=group_id, msg=reply_msg)
else:
await api.qq.post_private_array_msg(user_id=user_id, msg=reply_msg)
# 文件单独发
for fm in file_msgs:
url = fm.get("url", "")
filename = url.split("/")[-1]
if group_id:
await api.qq.send_group_file(group_id=group_id, file=url, name=filename)
else:
await api.qq.send_private_file(user_id=event.data.user_id, file=url, name=filename)
await api.qq.send_private_file(user_id=user_id, file=url, name=filename)
except Exception as exc:
logger.error("命令回复失败: %s", exc)
return
@@ -128,6 +152,10 @@ async def _handle_reply(result: dict, event, api, logger) -> None:
# 纯文本回复:引用原消息
if reply and isinstance(reply, str):
try:
await event.reply(text=reply, at_sender=at_sender)
reply_msg = build_reply_msg(text=reply)
if group_id:
await api.qq.post_group_array_msg(group_id=group_id, msg=reply_msg)
else:
await api.qq.post_private_array_msg(user_id=user_id, msg=reply_msg)
except Exception as exc:
logger.error("命令回复失败: %s", exc)