feat(file): 新增文件消息的接收与发送功能
本次更新为框架引入了完整的文件消息处理能力,涵盖了发送和接收两个方面,使机器人能够处理文件传输。 主要变更包括: - **发送功能**: - 在 `plugin_system.apis.send_api` 中新增了 `file_to_stream` 公共 API,允许插件向指定聊天流(私聊或群聊)发送本地文件。 - 为文件上传设置了更长的超时时间,并增加了临时的 WSL 路径转换逻辑。 - **接收功能**: - `chat.message_receive` 模块现在能够正确处理 `file` 类型的消息段,并生成可读的文本描述。 - NapCat 适配器增加了对文件消息 (`file`) 和群文件上传通知 (`group_upload`) 的解析能力。 - 通过智能识别和解析,能够将机器人自己发送文件后收到的 JSON 卡片回声消息,正确地转换回标准的文件消息段。 - **重构**: - 将接收消息的 `content_format` 属性改为根据消息段动态生成,提高了对复合消息类型的适应性。 - 将未知消息段的日志级别从 `info` 调整为 `warning`,以便更好地监控未处理的消息类型。
This commit is contained in:
@@ -27,6 +27,67 @@
|
||||
|
||||
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
async def file_to_stream(
|
||||
file_path: str,
|
||||
stream_id: str,
|
||||
file_name: str | None = None,
|
||||
storage_message: bool = True,
|
||||
set_reply: bool = True
|
||||
) -> bool:
|
||||
"""向指定流发送文件
|
||||
|
||||
Args:
|
||||
file_path: 文件的本地路径
|
||||
stream_id: 聊天流ID
|
||||
file_name: 发送到对方时显示的文件名,如果为 None 则使用原始文件名
|
||||
storage_message: 是否存储消息到数据库
|
||||
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
target_stream = await get_chat_manager().get_stream(stream_id)
|
||||
if not target_stream:
|
||||
logger.error(f"[SendAPI] 未找到聊天流: {stream_id}")
|
||||
return False
|
||||
|
||||
if not file_name:
|
||||
file_name = Path(file_path).name
|
||||
|
||||
# 临时的WSL路径转换方案
|
||||
if file_path.startswith("E:"):
|
||||
original_path = file_path
|
||||
file_path = "/mnt/e/" + file_path[3:].replace("\\", "/")
|
||||
logger.info(f"WSL路径转换: {original_path} -> {file_path}")
|
||||
|
||||
params = {
|
||||
"file": file_path,
|
||||
"name": file_name,
|
||||
}
|
||||
|
||||
action = ""
|
||||
if target_stream.group_info:
|
||||
action = "upload_group_file"
|
||||
params["group_id"] = target_stream.group_info.group_id
|
||||
else:
|
||||
action = "upload_private_file"
|
||||
params["user_id"] = target_stream.user_info.user_id
|
||||
|
||||
response = await adapter_command_to_stream(
|
||||
action=action,
|
||||
params=params,
|
||||
stream_id=stream_id,
|
||||
timeout=300.0 # 文件上传可能需要更长时间
|
||||
)
|
||||
|
||||
if response.get("status") == "ok":
|
||||
logger.info(f"文件 {file_name} 已成功发送到 {stream_id}")
|
||||
return True
|
||||
else:
|
||||
logger.error(f"文件 {file_name} 发送到 {stream_id} 失败: {response.get('message')}")
|
||||
return False
|
||||
|
||||
import asyncio
|
||||
import time
|
||||
|
||||
Reference in New Issue
Block a user