action, command, event_handler易用方法更新,增加语音,混合,转发消息的发送
This commit is contained in:
@@ -2,9 +2,10 @@ import time
|
||||
import asyncio
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Tuple, Optional, TYPE_CHECKING, Dict
|
||||
from typing import Tuple, Optional, TYPE_CHECKING, Dict, List
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.common.data_models.message_data_model import ReplyContentType, ReplyContent, ReplySetModel, ForwardNode
|
||||
from src.chat.message_receive.chat_stream import ChatStream
|
||||
from src.plugin_system.base.component_types import ActionActivationType, ActionInfo, ComponentType
|
||||
from src.plugin_system.apis import send_api, database_api, message_api
|
||||
@@ -171,12 +172,15 @@ class BaseAction(ABC):
|
||||
set_reply: bool = False,
|
||||
reply_message: Optional["DatabaseMessages"] = None,
|
||||
typing: bool = False,
|
||||
storage_message: bool = True,
|
||||
) -> bool:
|
||||
"""发送文本消息
|
||||
|
||||
Args:
|
||||
content: 文本内容
|
||||
reply_to: 回复消息,格式为"发送者:消息内容"
|
||||
set_reply: 是否作为回复发送
|
||||
reply_message: 回复的消息对象(当set_reply为True时必填)
|
||||
typing: 是否计算输入时间
|
||||
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
@@ -191,15 +195,22 @@ class BaseAction(ABC):
|
||||
set_reply=set_reply,
|
||||
reply_message=reply_message,
|
||||
typing=typing,
|
||||
storage_message=storage_message,
|
||||
)
|
||||
|
||||
async def send_emoji(
|
||||
self, emoji_base64: str, set_reply: bool = False, reply_message: Optional["DatabaseMessages"] = None
|
||||
self,
|
||||
emoji_base64: str,
|
||||
set_reply: bool = False,
|
||||
reply_message: Optional["DatabaseMessages"] = None,
|
||||
storage_message: bool = True,
|
||||
) -> bool:
|
||||
"""发送表情包
|
||||
|
||||
Args:
|
||||
emoji_base64: 表情包的base64编码
|
||||
set_reply: 是否作为回复发送
|
||||
reply_message: 回复的消息对象(当set_reply为True时必填)
|
||||
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
@@ -209,16 +220,26 @@ class BaseAction(ABC):
|
||||
return False
|
||||
|
||||
return await send_api.emoji_to_stream(
|
||||
emoji_base64, self.chat_id, set_reply=set_reply, reply_message=reply_message
|
||||
emoji_base64,
|
||||
self.chat_id,
|
||||
set_reply=set_reply,
|
||||
reply_message=reply_message,
|
||||
storage_message=storage_message,
|
||||
)
|
||||
|
||||
async def send_image(
|
||||
self, image_base64: str, set_reply: bool = False, reply_message: Optional["DatabaseMessages"] = None
|
||||
self,
|
||||
image_base64: str,
|
||||
set_reply: bool = False,
|
||||
reply_message: Optional["DatabaseMessages"] = None,
|
||||
storage_message: bool = True,
|
||||
) -> bool:
|
||||
"""发送图片
|
||||
|
||||
Args:
|
||||
image_base64: 图片的base64编码
|
||||
set_reply: 是否作为回复发送
|
||||
reply_message: 回复的消息对象(当set_reply为True时必填)
|
||||
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
@@ -228,7 +249,11 @@ class BaseAction(ABC):
|
||||
return False
|
||||
|
||||
return await send_api.image_to_stream(
|
||||
image_base64, self.chat_id, set_reply=set_reply, reply_message=reply_message
|
||||
image_base64,
|
||||
self.chat_id,
|
||||
set_reply=set_reply,
|
||||
reply_message=reply_message,
|
||||
storage_message=storage_message,
|
||||
)
|
||||
|
||||
async def send_command(
|
||||
@@ -237,13 +262,9 @@ class BaseAction(ABC):
|
||||
args: Optional[dict] = None,
|
||||
display_message: str = "",
|
||||
storage_message: bool = True,
|
||||
set_reply: bool = False,
|
||||
reply_message: Optional["DatabaseMessages"] = None,
|
||||
) -> bool:
|
||||
"""发送命令消息
|
||||
|
||||
使用stream API发送命令
|
||||
|
||||
Args:
|
||||
command_name: 命令名称
|
||||
args: 命令参数
|
||||
@@ -253,34 +274,20 @@ class BaseAction(ABC):
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
try:
|
||||
if not self.chat_id:
|
||||
logger.error(f"{self.log_prefix} 缺少聊天ID")
|
||||
return False
|
||||
|
||||
# 构造命令数据
|
||||
command_data = {"name": command_name, "args": args or {}}
|
||||
|
||||
success = await send_api.command_to_stream(
|
||||
command=command_data,
|
||||
stream_id=self.chat_id,
|
||||
storage_message=storage_message,
|
||||
display_message=display_message,
|
||||
set_reply=set_reply,
|
||||
reply_message=reply_message,
|
||||
)
|
||||
|
||||
if success:
|
||||
logger.info(f"{self.log_prefix} 成功发送命令: {command_name}")
|
||||
else:
|
||||
logger.error(f"{self.log_prefix} 发送命令失败: {command_name}")
|
||||
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 发送命令时出错: {e}")
|
||||
if not self.chat_id:
|
||||
logger.error(f"{self.log_prefix} 缺少聊天ID")
|
||||
return False
|
||||
|
||||
# 构造命令数据
|
||||
command_data = {"name": command_name, "args": args or {}}
|
||||
|
||||
return await send_api.command_to_stream(
|
||||
command=command_data,
|
||||
stream_id=self.chat_id,
|
||||
storage_message=storage_message,
|
||||
display_message=display_message,
|
||||
)
|
||||
|
||||
async def send_custom(
|
||||
self,
|
||||
message_type: str,
|
||||
@@ -288,6 +295,7 @@ class BaseAction(ABC):
|
||||
typing: bool = False,
|
||||
set_reply: bool = False,
|
||||
reply_message: Optional["DatabaseMessages"] = None,
|
||||
storage_message: bool = True,
|
||||
) -> bool:
|
||||
"""发送自定义类型消息
|
||||
|
||||
@@ -295,7 +303,9 @@ class BaseAction(ABC):
|
||||
message_type: 消息类型,如"video"、"file"、"audio"等
|
||||
content: 消息内容
|
||||
typing: 是否显示正在输入
|
||||
reply_to: 回复消息,格式为"发送者:消息内容"
|
||||
set_reply: 是否作为回复发送
|
||||
reply_message: 回复的消息对象(set_reply 为 True时必填)
|
||||
storage_message: 是否存储消息到数据库
|
||||
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
@@ -311,6 +321,101 @@ class BaseAction(ABC):
|
||||
typing=typing,
|
||||
set_reply=set_reply,
|
||||
reply_message=reply_message,
|
||||
storage_message=storage_message,
|
||||
)
|
||||
|
||||
async def send_hybrid(
|
||||
self,
|
||||
message_tuple_list: List[Tuple[ReplyContentType | str, str]],
|
||||
typing: bool = False,
|
||||
set_reply: bool = False,
|
||||
reply_message: Optional["DatabaseMessages"] = None,
|
||||
storage_message: bool = True,
|
||||
) -> bool:
|
||||
"""
|
||||
发送混合类型消息
|
||||
|
||||
Args:
|
||||
message_tuple_list: 包含消息类型和内容的元组列表,格式为 [(内容类型, 内容), ...]
|
||||
typing: 是否计算打字时间
|
||||
set_reply: 是否作为回复发送
|
||||
reply_message: 回复的消息对象
|
||||
"""
|
||||
if not self.chat_id:
|
||||
logger.error(f"{self.log_prefix} 缺少聊天ID")
|
||||
return False
|
||||
reply_set = ReplySetModel()
|
||||
reply_set.add_hybrid_content_by_raw(message_tuple_list)
|
||||
return await send_api.custom_reply_set_to_stream(
|
||||
reply_set=reply_set,
|
||||
stream_id=self.chat_id,
|
||||
typing=typing,
|
||||
set_reply=set_reply,
|
||||
reply_message=reply_message,
|
||||
storage_message=storage_message,
|
||||
)
|
||||
|
||||
async def send_forward(
|
||||
self,
|
||||
messages_list: List[Tuple[str, str, List[Tuple[ReplyContentType | str, str]]] | str],
|
||||
storage_message: bool = True,
|
||||
) -> bool:
|
||||
"""转发消息
|
||||
|
||||
Args:
|
||||
messages_list: 包含消息信息的列表,当传入自行生成的数据时,元素格式为 (sender_id, nickname, 消息体);当传入消息ID时,元素格式为 "message_id"
|
||||
其中消息体的格式为 [(内容类型, 内容), ...]
|
||||
任意长度的消息都需要使用列表的形式传入
|
||||
storage_message: 是否存储消息到数据库
|
||||
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
if not self.chat_id:
|
||||
logger.error(f"{self.log_prefix} 缺少聊天ID")
|
||||
return False
|
||||
reply_set = ReplySetModel()
|
||||
forward_message_nodes: List[ForwardNode] = []
|
||||
for message in messages_list:
|
||||
if isinstance(message, str):
|
||||
forward_message_node = ForwardNode.construct_as_id_reference(message)
|
||||
elif isinstance(message, Tuple) and len(message) == 3:
|
||||
sender_id, nickname, content_list = message
|
||||
single_node_content_list: List[ReplyContent] = []
|
||||
for node_content_type, node_content in content_list:
|
||||
reply_node_content = ReplyContent(content_type=node_content_type, content=node_content)
|
||||
single_node_content_list.append(reply_node_content)
|
||||
forward_message_node = ForwardNode.construct_as_created_node(
|
||||
user_id=sender_id, user_nickname=nickname, content=single_node_content_list
|
||||
)
|
||||
else:
|
||||
logger.warning(f"{self.log_prefix} 转发消息时遇到无效的消息格式: {message}")
|
||||
continue
|
||||
forward_message_nodes.append(forward_message_node)
|
||||
reply_set.add_forward_content(forward_message_nodes)
|
||||
return await send_api.custom_reply_set_to_stream(
|
||||
reply_set=reply_set,
|
||||
stream_id=self.chat_id,
|
||||
storage_message=storage_message,
|
||||
)
|
||||
|
||||
async def send_voice(self, audio_base64: str) -> bool:
|
||||
"""
|
||||
发送语音消息
|
||||
Args:
|
||||
audio_base64: 语音的base64编码
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
if not audio_base64:
|
||||
logger.error(f"{self.log_prefix} 缺少音频内容")
|
||||
return False
|
||||
reply_set = ReplySetModel()
|
||||
reply_set.add_voice_content(audio_base64)
|
||||
return await send_api.custom_reply_set_to_stream(
|
||||
reply_set=reply_set,
|
||||
stream_id=self.chat_id,
|
||||
storage_message=False,
|
||||
)
|
||||
|
||||
async def store_action_info(
|
||||
|
||||
Reference in New Issue
Block a user