feat:统一加载插件,区分内部插件和外部插件,提供示例命令发送插件
This commit is contained in:
1 parent
450dad2355
commit
c44811815a
22 files changed
+2029
-182
No files matched your search
@@ -0,0 +1,4 @@
|
||||
"""示例命令包
|
||||
|
||||
包含示例命令的实现
|
||||
"""
|
||||
@@ -0,0 +1,58 @@
|
||||
from src.common.logger_manager import get_logger
|
||||
from src.chat.message_receive.command_handler import BaseCommand, register_command
|
||||
from typing import Tuple, Optional
|
||||
import random
|
||||
|
||||
logger = get_logger("custom_prefix_command")
|
||||
|
||||
@register_command
|
||||
class DiceCommand(BaseCommand):
|
||||
"""骰子命令,使用!前缀而不是/前缀"""
|
||||
|
||||
command_name = "dice"
|
||||
command_description = "骰子命令,随机生成1-6的数字"
|
||||
command_pattern = r"^[!!](?:dice|骰子)(?:\s+(?P<count>\d+))?$" # 匹配 !dice 或 !骰子,可选参数为骰子数量
|
||||
command_help = "使用方法: !dice [数量] 或 !骰子 [数量] - 掷骰子,默认掷1个"
|
||||
command_examples = ["!dice", "!骰子", "!dice 3", "!骰子 5"]
|
||||
enable_command = True
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行骰子命令
|
||||
|
||||
Returns:
|
||||
Tuple[bool, Optional[str]]: (是否执行成功, 回复消息)
|
||||
"""
|
||||
try:
|
||||
# 获取骰子数量,默认为1
|
||||
count_str = self.matched_groups.get("count")
|
||||
|
||||
# 确保count_str不为None
|
||||
if count_str is None:
|
||||
count = 1 # 默认值
|
||||
else:
|
||||
try:
|
||||
count = int(count_str)
|
||||
if count <= 0:
|
||||
return False, "骰子数量必须大于0"
|
||||
if count > 10: # 限制最大数量
|
||||
return False, "一次最多只能掷10个骰子"
|
||||
except ValueError:
|
||||
return False, "骰子数量必须是整数"
|
||||
|
||||
# 生成随机数
|
||||
results = [random.randint(1, 6) for _ in range(count)]
|
||||
|
||||
# 构建回复消息
|
||||
if count == 1:
|
||||
message = f"🎲 掷出了 {results[0]} 点"
|
||||
else:
|
||||
dice_results = ", ".join(map(str, results))
|
||||
total = sum(results)
|
||||
message = f"🎲 掷出了 {count} 个骰子: [{dice_results}],总点数: {total}"
|
||||
|
||||
logger.info(f"{self.log_prefix} 执行骰子命令: {message}")
|
||||
return True, message
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 执行骰子命令时出错: {e}")
|
||||
return False, f"执行命令时出错: {str(e)}"
|
||||
@@ -0,0 +1,115 @@
|
||||
from src.common.logger_manager import get_logger
|
||||
from src.chat.message_receive.command_handler import BaseCommand, register_command, _COMMAND_REGISTRY
|
||||
from typing import Tuple, Optional
|
||||
|
||||
logger = get_logger("help_command")
|
||||
|
||||
@register_command
|
||||
class HelpCommand(BaseCommand):
|
||||
"""帮助命令,显示所有可用命令的帮助信息"""
|
||||
|
||||
command_name = "help"
|
||||
command_description = "显示所有可用命令的帮助信息"
|
||||
command_pattern = r"^/help(?:\s+(?P<command>\w+))?$" # 匹配 /help 或 /help 命令名
|
||||
command_help = "使用方法: /help [命令名] - 显示所有命令或特定命令的帮助信息"
|
||||
command_examples = ["/help", "/help echo"]
|
||||
enable_command = True
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行帮助命令
|
||||
|
||||
Returns:
|
||||
Tuple[bool, Optional[str]]: (是否执行成功, 回复消息)
|
||||
"""
|
||||
try:
|
||||
# 获取匹配到的命令名(如果有)
|
||||
command_name = self.matched_groups.get("command")
|
||||
|
||||
# 如果指定了命令名,显示该命令的详细帮助
|
||||
if command_name:
|
||||
logger.info(f"{self.log_prefix} 查询命令帮助: {command_name}")
|
||||
return self._show_command_help(command_name)
|
||||
|
||||
# 否则,显示所有命令的简要帮助
|
||||
logger.info(f"{self.log_prefix} 查询所有命令帮助")
|
||||
return self._show_all_commands()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 执行帮助命令时出错: {e}")
|
||||
return False, f"执行命令时出错: {str(e)}"
|
||||
|
||||
def _show_command_help(self, command_name: str) -> Tuple[bool, str]:
|
||||
"""显示特定命令的详细帮助信息
|
||||
|
||||
Args:
|
||||
command_name: 命令名称
|
||||
|
||||
Returns:
|
||||
Tuple[bool, str]: (是否执行成功, 回复消息)
|
||||
"""
|
||||
# 查找命令
|
||||
command_cls = _COMMAND_REGISTRY.get(command_name)
|
||||
|
||||
if not command_cls:
|
||||
return False, f"未找到命令: {command_name}"
|
||||
|
||||
# 获取命令信息
|
||||
description = getattr(command_cls, "command_description", "无描述")
|
||||
help_text = getattr(command_cls, "command_help", "无帮助信息")
|
||||
examples = getattr(command_cls, "command_examples", [])
|
||||
|
||||
# 构建帮助信息
|
||||
help_info = [
|
||||
f"【命令】: {command_name}",
|
||||
f"【描述】: {description}",
|
||||
f"【用法】: {help_text}"
|
||||
]
|
||||
|
||||
# 添加示例
|
||||
if examples:
|
||||
help_info.append("【示例】:")
|
||||
for example in examples:
|
||||
help_info.append(f" {example}")
|
||||
|
||||
return True, "\n".join(help_info)
|
||||
|
||||
def _show_all_commands(self) -> Tuple[bool, str]:
|
||||
"""显示所有可用命令的简要帮助信息
|
||||
|
||||
Returns:
|
||||
Tuple[bool, str]: (是否执行成功, 回复消息)
|
||||
"""
|
||||
# 获取所有已启用的命令
|
||||
enabled_commands = {
|
||||
name: cls for name, cls in _COMMAND_REGISTRY.items()
|
||||
if getattr(cls, "enable_command", True)
|
||||
}
|
||||
|
||||
if not enabled_commands:
|
||||
return True, "当前没有可用的命令"
|
||||
|
||||
# 构建命令列表
|
||||
command_list = ["可用命令列表:"]
|
||||
for name, cls in sorted(enabled_commands.items()):
|
||||
description = getattr(cls, "command_description", "无描述")
|
||||
# 获取命令前缀示例
|
||||
examples = getattr(cls, "command_examples", [])
|
||||
prefix = ""
|
||||
if examples and len(examples) > 0:
|
||||
# 从第一个示例中提取前缀
|
||||
example = examples[0]
|
||||
# 找到第一个空格前的内容作为前缀
|
||||
space_pos = example.find(" ")
|
||||
if space_pos > 0:
|
||||
prefix = example[:space_pos]
|
||||
else:
|
||||
prefix = example
|
||||
else:
|
||||
# 默认使用/name作为前缀
|
||||
prefix = f"/{name}"
|
||||
|
||||
command_list.append(f"{prefix} - {description}")
|
||||
|
||||
command_list.append("\n使用 /help <命令名> 获取特定命令的详细帮助")
|
||||
|
||||
return True, "\n".join(command_list)
|
||||
@@ -0,0 +1,282 @@
|
||||
from src.common.logger_manager import get_logger
|
||||
from src.chat.message_receive.command_handler import BaseCommand, register_command
|
||||
from typing import Tuple, Optional
|
||||
import json
|
||||
|
||||
logger = get_logger("message_info_command")
|
||||
|
||||
@register_command
|
||||
class MessageInfoCommand(BaseCommand):
|
||||
"""消息信息查看命令,展示发送命令的原始消息和相关信息"""
|
||||
|
||||
command_name = "msginfo"
|
||||
command_description = "查看发送命令的原始消息信息"
|
||||
command_pattern = r"^/msginfo(?:\s+(?P<detail>full|simple))?$"
|
||||
command_help = "使用方法: /msginfo [full|simple] - 查看当前消息的详细信息"
|
||||
command_examples = ["/msginfo", "/msginfo full", "/msginfo simple"]
|
||||
enable_command = True
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行消息信息查看命令"""
|
||||
try:
|
||||
detail_level = self.matched_groups.get("detail", "simple")
|
||||
|
||||
logger.info(f"{self.log_prefix} 查看消息信息,详细级别: {detail_level}")
|
||||
|
||||
if detail_level == "full":
|
||||
info_text = self._get_full_message_info()
|
||||
else:
|
||||
info_text = self._get_simple_message_info()
|
||||
|
||||
return True, info_text
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 获取消息信息时出错: {e}")
|
||||
return False, f"获取消息信息失败: {str(e)}"
|
||||
|
||||
def _get_simple_message_info(self) -> str:
|
||||
"""获取简化的消息信息"""
|
||||
message = self.message
|
||||
|
||||
# 基础信息
|
||||
info_lines = [
|
||||
"📨 消息信息概览",
|
||||
f"🆔 消息ID: {message.message_info.message_id}",
|
||||
f"⏰ 时间: {message.message_info.time}",
|
||||
f"🌐 平台: {message.message_info.platform}",
|
||||
]
|
||||
|
||||
# 发送者信息
|
||||
user = message.message_info.user_info
|
||||
info_lines.extend([
|
||||
"",
|
||||
"👤 发送者信息:",
|
||||
f" 用户ID: {user.user_id}",
|
||||
f" 昵称: {user.user_nickname}",
|
||||
f" 群名片: {user.user_cardname or '无'}",
|
||||
])
|
||||
|
||||
# 群聊信息(如果是群聊)
|
||||
if message.message_info.group_info:
|
||||
group = message.message_info.group_info
|
||||
info_lines.extend([
|
||||
"",
|
||||
"👥 群聊信息:",
|
||||
f" 群ID: {group.group_id}",
|
||||
f" 群名: {group.group_name or '未知'}",
|
||||
])
|
||||
else:
|
||||
info_lines.extend([
|
||||
"",
|
||||
"💬 消息类型: 私聊消息",
|
||||
])
|
||||
|
||||
# 消息内容
|
||||
info_lines.extend([
|
||||
"",
|
||||
"📝 消息内容:",
|
||||
f" 原始文本: {message.processed_plain_text}",
|
||||
f" 是否表情: {'是' if getattr(message, 'is_emoji', False) else '否'}",
|
||||
])
|
||||
|
||||
# 聊天流信息
|
||||
if hasattr(message, 'chat_stream') and message.chat_stream:
|
||||
chat_stream = message.chat_stream
|
||||
info_lines.extend([
|
||||
"",
|
||||
"🔄 聊天流信息:",
|
||||
f" 流ID: {chat_stream.stream_id}",
|
||||
f" 是否激活: {'是' if chat_stream.is_active else '否'}",
|
||||
])
|
||||
|
||||
return "\n".join(info_lines)
|
||||
|
||||
def _get_full_message_info(self) -> str:
|
||||
"""获取完整的消息信息(包含技术细节)"""
|
||||
message = self.message
|
||||
|
||||
info_lines = [
|
||||
"📨 完整消息信息",
|
||||
"=" * 40,
|
||||
]
|
||||
|
||||
# 消息基础信息
|
||||
info_lines.extend([
|
||||
"",
|
||||
"🔍 基础消息信息:",
|
||||
f" 消息ID: {message.message_info.message_id}",
|
||||
f" 时间戳: {message.message_info.time}",
|
||||
f" 平台: {message.message_info.platform}",
|
||||
f" 处理后文本: {message.processed_plain_text}",
|
||||
f" 详细文本: {message.detailed_plain_text[:100]}{'...' if len(message.detailed_plain_text) > 100 else ''}",
|
||||
])
|
||||
|
||||
# 用户详细信息
|
||||
user = message.message_info.user_info
|
||||
info_lines.extend([
|
||||
"",
|
||||
"👤 发送者详细信息:",
|
||||
f" 用户ID: {user.user_id}",
|
||||
f" 昵称: {user.user_nickname}",
|
||||
f" 群名片: {user.user_cardname or '无'}",
|
||||
f" 平台: {user.platform}",
|
||||
])
|
||||
|
||||
# 群聊详细信息
|
||||
if message.message_info.group_info:
|
||||
group = message.message_info.group_info
|
||||
info_lines.extend([
|
||||
"",
|
||||
"👥 群聊详细信息:",
|
||||
f" 群ID: {group.group_id}",
|
||||
f" 群名: {group.group_name or '未知'}",
|
||||
f" 平台: {group.platform}",
|
||||
])
|
||||
else:
|
||||
info_lines.append("\n💬 消息类型: 私聊消息")
|
||||
|
||||
# 消息段信息
|
||||
if message.message_segment:
|
||||
info_lines.extend([
|
||||
"",
|
||||
"📦 消息段信息:",
|
||||
f" 类型: {message.message_segment.type}",
|
||||
f" 数据类型: {type(message.message_segment.data).__name__}",
|
||||
f" 数据预览: {str(message.message_segment.data)[:200]}{'...' if len(str(message.message_segment.data)) > 200 else ''}",
|
||||
])
|
||||
|
||||
# 聊天流详细信息
|
||||
if hasattr(message, 'chat_stream') and message.chat_stream:
|
||||
chat_stream = message.chat_stream
|
||||
info_lines.extend([
|
||||
"",
|
||||
"🔄 聊天流详细信息:",
|
||||
f" 流ID: {chat_stream.stream_id}",
|
||||
f" 平台: {chat_stream.platform}",
|
||||
f" 是否激活: {'是' if chat_stream.is_active else '否'}",
|
||||
f" 用户信息: {chat_stream.user_info.user_nickname} ({chat_stream.user_info.user_id})",
|
||||
f" 群信息: {getattr(chat_stream.group_info, 'group_name', '私聊') if chat_stream.group_info else '私聊'}",
|
||||
])
|
||||
|
||||
# 回复信息
|
||||
if hasattr(message, 'reply') and message.reply:
|
||||
info_lines.extend([
|
||||
"",
|
||||
"↩️ 回复信息:",
|
||||
f" 回复消息ID: {message.reply.message_info.message_id}",
|
||||
f" 回复内容: {message.reply.processed_plain_text[:100]}{'...' if len(message.reply.processed_plain_text) > 100 else ''}",
|
||||
])
|
||||
|
||||
# 原始消息数据(如果存在)
|
||||
if hasattr(message, 'raw_message') and message.raw_message:
|
||||
info_lines.extend([
|
||||
"",
|
||||
"🗂️ 原始消息数据:",
|
||||
f" 数据类型: {type(message.raw_message).__name__}",
|
||||
f" 数据大小: {len(str(message.raw_message))} 字符",
|
||||
])
|
||||
|
||||
return "\n".join(info_lines)
|
||||
|
||||
|
||||
@register_command
|
||||
class SenderInfoCommand(BaseCommand):
|
||||
"""发送者信息命令,快速查看发送者信息"""
|
||||
|
||||
command_name = "whoami"
|
||||
command_description = "查看发送命令的用户信息"
|
||||
command_pattern = r"^/whoami$"
|
||||
command_help = "使用方法: /whoami - 查看你的用户信息"
|
||||
command_examples = ["/whoami"]
|
||||
enable_command = True
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行发送者信息查看命令"""
|
||||
try:
|
||||
user = self.message.message_info.user_info
|
||||
group = self.message.message_info.group_info
|
||||
|
||||
info_lines = [
|
||||
"👤 你的身份信息",
|
||||
f"🆔 用户ID: {user.user_id}",
|
||||
f"📝 昵称: {user.user_nickname}",
|
||||
f"🏷️ 群名片: {user.user_cardname or '无'}",
|
||||
f"🌐 平台: {user.platform}",
|
||||
]
|
||||
|
||||
if group:
|
||||
info_lines.extend([
|
||||
"",
|
||||
"👥 当前群聊:",
|
||||
f"🆔 群ID: {group.group_id}",
|
||||
f"📝 群名: {group.group_name or '未知'}",
|
||||
])
|
||||
else:
|
||||
info_lines.append("\n💬 当前在私聊中")
|
||||
|
||||
return True, "\n".join(info_lines)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 获取发送者信息时出错: {e}")
|
||||
return False, f"获取发送者信息失败: {str(e)}"
|
||||
|
||||
|
||||
@register_command
|
||||
class ChatStreamInfoCommand(BaseCommand):
|
||||
"""聊天流信息命令"""
|
||||
|
||||
command_name = "streaminfo"
|
||||
command_description = "查看当前聊天流的详细信息"
|
||||
command_pattern = r"^/streaminfo$"
|
||||
command_help = "使用方法: /streaminfo - 查看当前聊天流信息"
|
||||
command_examples = ["/streaminfo"]
|
||||
enable_command = True
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行聊天流信息查看命令"""
|
||||
try:
|
||||
if not hasattr(self.message, 'chat_stream') or not self.message.chat_stream:
|
||||
return False, "无法获取聊天流信息"
|
||||
|
||||
chat_stream = self.message.chat_stream
|
||||
|
||||
info_lines = [
|
||||
"🔄 聊天流信息",
|
||||
f"🆔 流ID: {chat_stream.stream_id}",
|
||||
f"🌐 平台: {chat_stream.platform}",
|
||||
f"⚡ 状态: {'激活' if chat_stream.is_active else '非激活'}",
|
||||
]
|
||||
|
||||
# 用户信息
|
||||
if chat_stream.user_info:
|
||||
info_lines.extend([
|
||||
"",
|
||||
"👤 关联用户:",
|
||||
f" ID: {chat_stream.user_info.user_id}",
|
||||
f" 昵称: {chat_stream.user_info.user_nickname}",
|
||||
])
|
||||
|
||||
# 群信息
|
||||
if chat_stream.group_info:
|
||||
info_lines.extend([
|
||||
"",
|
||||
"👥 关联群聊:",
|
||||
f" 群ID: {chat_stream.group_info.group_id}",
|
||||
f" 群名: {chat_stream.group_info.group_name or '未知'}",
|
||||
])
|
||||
else:
|
||||
info_lines.append("\n💬 类型: 私聊流")
|
||||
|
||||
# 最近消息统计
|
||||
if hasattr(chat_stream, 'last_messages'):
|
||||
msg_count = len(chat_stream.last_messages)
|
||||
info_lines.extend([
|
||||
"",
|
||||
f"📈 消息统计: 记录了 {msg_count} 条最近消息",
|
||||
])
|
||||
|
||||
return True, "\n".join(info_lines)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 获取聊天流信息时出错: {e}")
|
||||
return False, f"获取聊天流信息失败: {str(e)}"
|
||||
@@ -0,0 +1,119 @@
|
||||
from src.common.logger_manager import get_logger
|
||||
from src.chat.message_receive.command_handler import BaseCommand, register_command
|
||||
from src.chat.actions.plugin_api.message_api import MessageAPI
|
||||
from typing import Tuple, Optional
|
||||
|
||||
logger = get_logger("send_msg_command")
|
||||
|
||||
@register_command
|
||||
class SendMessageCommand(BaseCommand, MessageAPI):
|
||||
"""发送消息命令,可以向指定群聊或私聊发送消息"""
|
||||
|
||||
command_name = "send"
|
||||
command_description = "向指定群聊或私聊发送消息"
|
||||
command_pattern = r"^/send\s+(?P<target_type>group|user)\s+(?P<target_id>\d+)\s+(?P<content>.+)$"
|
||||
command_help = "使用方法: /send <group|user> <ID> <消息内容> - 发送消息到指定群聊或用户"
|
||||
command_examples = [
|
||||
"/send group 123456789 大家好!",
|
||||
"/send user 987654321 私聊消息"
|
||||
]
|
||||
enable_command = True
|
||||
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
# 初始化MessageAPI需要的服务(虽然这里不会用到,但保持一致性)
|
||||
self._services = {}
|
||||
self.log_prefix = f"[Command:{self.command_name}]"
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行发送消息命令
|
||||
|
||||
Returns:
|
||||
Tuple[bool, Optional[str]]: (是否执行成功, 回复消息)
|
||||
"""
|
||||
try:
|
||||
# 获取匹配到的参数
|
||||
target_type = self.matched_groups.get("target_type") # group 或 user
|
||||
target_id = self.matched_groups.get("target_id") # 群ID或用户ID
|
||||
content = self.matched_groups.get("content") # 消息内容
|
||||
|
||||
if not all([target_type, target_id, content]):
|
||||
return False, "命令参数不完整,请检查格式"
|
||||
|
||||
logger.info(f"{self.log_prefix} 执行发送消息命令: {target_type}:{target_id} -> {content[:50]}...")
|
||||
|
||||
# 根据目标类型调用不同的发送方法
|
||||
if target_type == "group":
|
||||
success = await self._send_to_group(target_id, content)
|
||||
target_desc = f"群聊 {target_id}"
|
||||
elif target_type == "user":
|
||||
success = await self._send_to_user(target_id, content)
|
||||
target_desc = f"用户 {target_id}"
|
||||
else:
|
||||
return False, f"不支持的目标类型: {target_type},只支持 group 或 user"
|
||||
|
||||
# 返回执行结果
|
||||
if success:
|
||||
return True, f"✅ 消息已成功发送到 {target_desc}"
|
||||
else:
|
||||
return False, f"❌ 消息发送失败,可能是目标 {target_desc} 不存在或没有权限"
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 执行发送消息命令时出错: {e}")
|
||||
return False, f"命令执行出错: {str(e)}"
|
||||
|
||||
async def _send_to_group(self, group_id: str, content: str) -> bool:
|
||||
"""发送消息到群聊
|
||||
|
||||
Args:
|
||||
group_id: 群聊ID
|
||||
content: 消息内容
|
||||
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
try:
|
||||
success = await self.send_text_to_group(
|
||||
text=content,
|
||||
group_id=group_id,
|
||||
platform="qq" # 默认使用QQ平台
|
||||
)
|
||||
|
||||
if success:
|
||||
logger.info(f"{self.log_prefix} 成功发送消息到群聊 {group_id}")
|
||||
else:
|
||||
logger.warning(f"{self.log_prefix} 发送消息到群聊 {group_id} 失败")
|
||||
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 发送群聊消息时出错: {e}")
|
||||
return False
|
||||
|
||||
async def _send_to_user(self, user_id: str, content: str) -> bool:
|
||||
"""发送消息到私聊
|
||||
|
||||
Args:
|
||||
user_id: 用户ID
|
||||
content: 消息内容
|
||||
|
||||
Returns:
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
try:
|
||||
success = await self.send_text_to_user(
|
||||
text=content,
|
||||
user_id=user_id,
|
||||
platform="qq" # 默认使用QQ平台
|
||||
)
|
||||
|
||||
if success:
|
||||
logger.info(f"{self.log_prefix} 成功发送消息到用户 {user_id}")
|
||||
else:
|
||||
logger.warning(f"{self.log_prefix} 发送消息到用户 {user_id} 失败")
|
||||
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 发送私聊消息时出错: {e}")
|
||||
return False
|
||||
@@ -0,0 +1,170 @@
|
||||
from src.common.logger_manager import get_logger
|
||||
from src.chat.message_receive.command_handler import BaseCommand, register_command
|
||||
from src.chat.actions.plugin_api.message_api import MessageAPI
|
||||
from typing import Tuple, Optional
|
||||
|
||||
logger = get_logger("send_msg_enhanced")
|
||||
|
||||
@register_command
|
||||
class SendMessageEnhancedCommand(BaseCommand, MessageAPI):
|
||||
"""增强版发送消息命令,支持多种消息类型和平台"""
|
||||
|
||||
command_name = "sendfull"
|
||||
command_description = "增强版消息发送命令,支持多种类型和平台"
|
||||
command_pattern = r"^/sendfull\s+(?P<msg_type>text|image|emoji)\s+(?P<target_type>group|user)\s+(?P<target_id>\d+)(?:\s+(?P<platform>\w+))?\s+(?P<content>.+)$"
|
||||
command_help = "使用方法: /sendfull <消息类型> <目标类型> <ID> [平台] <内容>"
|
||||
command_examples = [
|
||||
"/sendfull text group 123456789 qq 大家好!这是文本消息",
|
||||
"/sendfull image user 987654321 https://example.com/image.jpg",
|
||||
"/sendfull emoji group 123456789 😄",
|
||||
"/sendfull text user 987654321 qq 私聊消息"
|
||||
]
|
||||
enable_command = True
|
||||
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
self._services = {}
|
||||
self.log_prefix = f"[Command:{self.command_name}]"
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行增强版发送消息命令"""
|
||||
try:
|
||||
# 获取匹配参数
|
||||
msg_type = self.matched_groups.get("msg_type") # 消息类型: text/image/emoji
|
||||
target_type = self.matched_groups.get("target_type") # 目标类型: group/user
|
||||
target_id = self.matched_groups.get("target_id") # 目标ID
|
||||
platform = self.matched_groups.get("platform") or "qq" # 平台,默认qq
|
||||
content = self.matched_groups.get("content") # 内容
|
||||
|
||||
if not all([msg_type, target_type, target_id, content]):
|
||||
return False, "命令参数不完整,请检查格式"
|
||||
|
||||
# 验证消息类型
|
||||
valid_types = ["text", "image", "emoji"]
|
||||
if msg_type not in valid_types:
|
||||
return False, f"不支持的消息类型: {msg_type},支持的类型: {', '.join(valid_types)}"
|
||||
|
||||
# 验证目标类型
|
||||
if target_type not in ["group", "user"]:
|
||||
return False, "目标类型只能是 group 或 user"
|
||||
|
||||
logger.info(f"{self.log_prefix} 执行发送命令: {msg_type} -> {target_type}:{target_id} (平台:{platform})")
|
||||
|
||||
# 根据消息类型和目标类型发送消息
|
||||
is_group = (target_type == "group")
|
||||
success = await self.send_message_to_target(
|
||||
message_type=msg_type,
|
||||
content=content,
|
||||
platform=platform,
|
||||
target_id=target_id,
|
||||
is_group=is_group
|
||||
)
|
||||
|
||||
# 构建结果消息
|
||||
target_desc = f"{'群聊' if is_group else '用户'} {target_id} (平台: {platform})"
|
||||
msg_type_desc = {
|
||||
"text": "文本",
|
||||
"image": "图片",
|
||||
"emoji": "表情"
|
||||
}.get(msg_type, msg_type)
|
||||
|
||||
if success:
|
||||
return True, f"✅ {msg_type_desc}消息已成功发送到 {target_desc}"
|
||||
else:
|
||||
return False, f"❌ {msg_type_desc}消息发送失败,可能是目标 {target_desc} 不存在或没有权限"
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 执行增强发送命令时出错: {e}")
|
||||
return False, f"命令执行出错: {str(e)}"
|
||||
|
||||
|
||||
@register_command
|
||||
class SendQuickCommand(BaseCommand, MessageAPI):
|
||||
"""快速发送文本消息命令"""
|
||||
|
||||
command_name = "msg"
|
||||
command_description = "快速发送文本消息到群聊"
|
||||
command_pattern = r"^/msg\s+(?P<group_id>\d+)\s+(?P<content>.+)$"
|
||||
command_help = "使用方法: /msg <群ID> <消息内容> - 快速发送文本到指定群聊"
|
||||
command_examples = [
|
||||
"/msg 123456789 大家好!",
|
||||
"/msg 987654321 这是一条快速消息"
|
||||
]
|
||||
enable_command = True
|
||||
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
self._services = {}
|
||||
self.log_prefix = f"[Command:{self.command_name}]"
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行快速发送消息命令"""
|
||||
try:
|
||||
group_id = self.matched_groups.get("group_id")
|
||||
content = self.matched_groups.get("content")
|
||||
|
||||
if not all([group_id, content]):
|
||||
return False, "命令参数不完整"
|
||||
|
||||
logger.info(f"{self.log_prefix} 快速发送到群 {group_id}: {content[:50]}...")
|
||||
|
||||
success = await self.send_text_to_group(
|
||||
text=content,
|
||||
group_id=group_id,
|
||||
platform="qq"
|
||||
)
|
||||
|
||||
if success:
|
||||
return True, f"✅ 消息已发送到群 {group_id}"
|
||||
else:
|
||||
return False, f"❌ 发送到群 {group_id} 失败"
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 快速发送命令出错: {e}")
|
||||
return False, f"发送失败: {str(e)}"
|
||||
|
||||
|
||||
@register_command
|
||||
class SendPrivateCommand(BaseCommand, MessageAPI):
|
||||
"""发送私聊消息命令"""
|
||||
|
||||
command_name = "pm"
|
||||
command_description = "发送私聊消息到指定用户"
|
||||
command_pattern = r"^/pm\s+(?P<user_id>\d+)\s+(?P<content>.+)$"
|
||||
command_help = "使用方法: /pm <用户ID> <消息内容> - 发送私聊消息"
|
||||
command_examples = [
|
||||
"/pm 123456789 你好!",
|
||||
"/pm 987654321 这是私聊消息"
|
||||
]
|
||||
enable_command = True
|
||||
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
self._services = {}
|
||||
self.log_prefix = f"[Command:{self.command_name}]"
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行私聊发送命令"""
|
||||
try:
|
||||
user_id = self.matched_groups.get("user_id")
|
||||
content = self.matched_groups.get("content")
|
||||
|
||||
if not all([user_id, content]):
|
||||
return False, "命令参数不完整"
|
||||
|
||||
logger.info(f"{self.log_prefix} 发送私聊到用户 {user_id}: {content[:50]}...")
|
||||
|
||||
success = await self.send_text_to_user(
|
||||
text=content,
|
||||
user_id=user_id,
|
||||
platform="qq"
|
||||
)
|
||||
|
||||
if success:
|
||||
return True, f"✅ 私聊消息已发送到用户 {user_id}"
|
||||
else:
|
||||
return False, f"❌ 发送私聊到用户 {user_id} 失败"
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 私聊发送命令出错: {e}")
|
||||
return False, f"私聊发送失败: {str(e)}"
|
||||
@@ -0,0 +1,253 @@
|
||||
from src.common.logger_manager import get_logger
|
||||
from src.chat.message_receive.command_handler import BaseCommand, register_command
|
||||
from src.chat.actions.plugin_api.message_api import MessageAPI
|
||||
from typing import Tuple, Optional
|
||||
import time
|
||||
|
||||
logger = get_logger("send_msg_with_context")
|
||||
|
||||
@register_command
|
||||
class ContextAwareSendCommand(BaseCommand, MessageAPI):
|
||||
"""上下文感知的发送消息命令,展示如何利用原始消息信息"""
|
||||
|
||||
command_name = "csend"
|
||||
command_description = "带上下文感知的发送消息命令"
|
||||
command_pattern = r"^/csend\s+(?P<target_type>group|user|here|reply)\s+(?P<target_id_or_content>.*?)(?:\s+(?P<content>.*))?$"
|
||||
command_help = "使用方法: /csend <target_type> <参数> [内容]"
|
||||
command_examples = [
|
||||
"/csend group 123456789 大家好!",
|
||||
"/csend user 987654321 私聊消息",
|
||||
"/csend here 在当前聊天发送",
|
||||
"/csend reply 回复当前群/私聊"
|
||||
]
|
||||
enable_command = True
|
||||
|
||||
# 管理员用户ID列表(示例)
|
||||
ADMIN_USERS = ["123456789", "987654321"] # 可以从配置文件读取
|
||||
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
self._services = {}
|
||||
self.log_prefix = f"[Command:{self.command_name}]"
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""执行上下文感知的发送命令"""
|
||||
try:
|
||||
# 获取命令发送者信息
|
||||
sender = self.message.message_info.user_info
|
||||
current_group = self.message.message_info.group_info
|
||||
|
||||
# 权限检查
|
||||
if not self._check_permission(sender.user_id):
|
||||
return False, f"❌ 权限不足,只有管理员可以使用此命令\n你的ID: {sender.user_id}"
|
||||
|
||||
# 解析命令参数
|
||||
target_type = self.matched_groups.get("target_type")
|
||||
target_id_or_content = self.matched_groups.get("target_id_or_content", "")
|
||||
content = self.matched_groups.get("content", "")
|
||||
|
||||
# 根据目标类型处理不同情况
|
||||
if target_type == "here":
|
||||
# 发送到当前聊天
|
||||
return await self._send_to_current_chat(target_id_or_content, sender, current_group)
|
||||
|
||||
elif target_type == "reply":
|
||||
# 回复到当前聊天,带发送者信息
|
||||
return await self._send_reply_with_context(target_id_or_content, sender, current_group)
|
||||
|
||||
elif target_type in ["group", "user"]:
|
||||
# 发送到指定目标
|
||||
if not content:
|
||||
return False, "指定群聊或用户时需要提供消息内容"
|
||||
return await self._send_to_target(target_type, target_id_or_content, content, sender)
|
||||
|
||||
else:
|
||||
return False, f"不支持的目标类型: {target_type}"
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 执行上下文感知发送命令时出错: {e}")
|
||||
return False, f"命令执行出错: {str(e)}"
|
||||
|
||||
def _check_permission(self, user_id: str) -> bool:
|
||||
"""检查用户权限"""
|
||||
return user_id in self.ADMIN_USERS
|
||||
|
||||
async def _send_to_current_chat(self, content: str, sender, current_group) -> Tuple[bool, str]:
|
||||
"""发送到当前聊天"""
|
||||
if not content:
|
||||
return False, "消息内容不能为空"
|
||||
|
||||
# 构建带发送者信息的消息
|
||||
timestamp = time.strftime("%H:%M:%S", time.localtime())
|
||||
if current_group:
|
||||
# 群聊
|
||||
formatted_content = f"[管理员转发 {timestamp}] {sender.user_nickname}({sender.user_id}): {content}"
|
||||
success = await self.send_text_to_group(
|
||||
text=formatted_content,
|
||||
group_id=current_group.group_id,
|
||||
platform="qq"
|
||||
)
|
||||
target_desc = f"当前群聊 {current_group.group_name}({current_group.group_id})"
|
||||
else:
|
||||
# 私聊
|
||||
formatted_content = f"[管理员消息 {timestamp}]: {content}"
|
||||
success = await self.send_text_to_user(
|
||||
text=formatted_content,
|
||||
user_id=sender.user_id,
|
||||
platform="qq"
|
||||
)
|
||||
target_desc = "当前私聊"
|
||||
|
||||
if success:
|
||||
return True, f"✅ 消息已发送到{target_desc}"
|
||||
else:
|
||||
return False, f"❌ 发送到{target_desc}失败"
|
||||
|
||||
async def _send_reply_with_context(self, content: str, sender, current_group) -> Tuple[bool, str]:
|
||||
"""发送回复,带完整上下文信息"""
|
||||
if not content:
|
||||
return False, "回复内容不能为空"
|
||||
|
||||
# 获取当前时间和环境信息
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
|
||||
# 构建上下文信息
|
||||
context_info = [
|
||||
f"📢 管理员回复 [{timestamp}]",
|
||||
f"👤 发送者: {sender.user_nickname}({sender.user_id})",
|
||||
]
|
||||
|
||||
if current_group:
|
||||
context_info.append(f"👥 当前群聊: {current_group.group_name}({current_group.group_id})")
|
||||
target_desc = f"群聊 {current_group.group_name}"
|
||||
else:
|
||||
context_info.append("💬 当前环境: 私聊")
|
||||
target_desc = "私聊"
|
||||
|
||||
context_info.extend([
|
||||
f"📝 回复内容: {content}",
|
||||
"─" * 30
|
||||
])
|
||||
|
||||
formatted_content = "\n".join(context_info)
|
||||
|
||||
# 发送消息
|
||||
if current_group:
|
||||
success = await self.send_text_to_group(
|
||||
text=formatted_content,
|
||||
group_id=current_group.group_id,
|
||||
platform="qq"
|
||||
)
|
||||
else:
|
||||
success = await self.send_text_to_user(
|
||||
text=formatted_content,
|
||||
user_id=sender.user_id,
|
||||
platform="qq"
|
||||
)
|
||||
|
||||
if success:
|
||||
return True, f"✅ 带上下文的回复已发送到{target_desc}"
|
||||
else:
|
||||
return False, f"❌ 发送上下文回复到{target_desc}失败"
|
||||
|
||||
async def _send_to_target(self, target_type: str, target_id: str, content: str, sender) -> Tuple[bool, str]:
|
||||
"""发送到指定目标,带发送者追踪信息"""
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
|
||||
# 构建带追踪信息的消息
|
||||
tracking_info = f"[管理转发 {timestamp}] 来自 {sender.user_nickname}({sender.user_id})"
|
||||
formatted_content = f"{tracking_info}\n{content}"
|
||||
|
||||
if target_type == "group":
|
||||
success = await self.send_text_to_group(
|
||||
text=formatted_content,
|
||||
group_id=target_id,
|
||||
platform="qq"
|
||||
)
|
||||
target_desc = f"群聊 {target_id}"
|
||||
else: # user
|
||||
success = await self.send_text_to_user(
|
||||
text=formatted_content,
|
||||
user_id=target_id,
|
||||
platform="qq"
|
||||
)
|
||||
target_desc = f"用户 {target_id}"
|
||||
|
||||
if success:
|
||||
return True, f"✅ 带追踪信息的消息已发送到{target_desc}"
|
||||
else:
|
||||
return False, f"❌ 发送到{target_desc}失败"
|
||||
|
||||
|
||||
@register_command
|
||||
class MessageContextCommand(BaseCommand):
|
||||
"""消息上下文命令,展示如何获取和利用上下文信息"""
|
||||
|
||||
command_name = "context"
|
||||
command_description = "显示当前消息的完整上下文信息"
|
||||
command_pattern = r"^/context$"
|
||||
command_help = "使用方法: /context - 显示当前环境的上下文信息"
|
||||
command_examples = ["/context"]
|
||||
enable_command = True
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
||||
"""显示上下文信息"""
|
||||
try:
|
||||
message = self.message
|
||||
user = message.message_info.user_info
|
||||
group = message.message_info.group_info
|
||||
|
||||
# 构建上下文信息
|
||||
context_lines = [
|
||||
"🌐 当前上下文信息",
|
||||
"=" * 30,
|
||||
"",
|
||||
"⏰ 时间信息:",
|
||||
f" 消息时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(message.message_info.time))}",
|
||||
f" 时间戳: {message.message_info.time}",
|
||||
"",
|
||||
"👤 发送者:",
|
||||
f" 用户ID: {user.user_id}",
|
||||
f" 昵称: {user.user_nickname}",
|
||||
f" 群名片: {user.user_cardname or '无'}",
|
||||
f" 平台: {user.platform}",
|
||||
]
|
||||
|
||||
if group:
|
||||
context_lines.extend([
|
||||
"",
|
||||
"👥 群聊环境:",
|
||||
f" 群ID: {group.group_id}",
|
||||
f" 群名: {group.group_name or '未知'}",
|
||||
f" 平台: {group.platform}",
|
||||
])
|
||||
else:
|
||||
context_lines.extend([
|
||||
"",
|
||||
"💬 私聊环境",
|
||||
])
|
||||
|
||||
# 添加聊天流信息
|
||||
if hasattr(message, 'chat_stream') and message.chat_stream:
|
||||
chat_stream = message.chat_stream
|
||||
context_lines.extend([
|
||||
"",
|
||||
"🔄 聊天流:",
|
||||
f" 流ID: {chat_stream.stream_id}",
|
||||
f" 激活状态: {'激活' if chat_stream.is_active else '非激活'}",
|
||||
])
|
||||
|
||||
# 添加消息内容信息
|
||||
context_lines.extend([
|
||||
"",
|
||||
"📝 消息内容:",
|
||||
f" 原始内容: {message.processed_plain_text}",
|
||||
f" 消息长度: {len(message.processed_plain_text)} 字符",
|
||||
f" 消息ID: {message.message_info.message_id}",
|
||||
])
|
||||
|
||||
return True, "\n".join(context_lines)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 获取上下文信息时出错: {e}")
|
||||
return False, f"获取上下文失败: {str(e)}"
|
||||
Reference in new issue
Block a user