diff --git a/commands/handlers.py b/commands/handlers.py index 6fa40b7..6d150e8 100644 --- a/commands/handlers.py +++ b/commands/handlers.py @@ -9,138 +9,6 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: from .context import MessageContext -def handle_help(ctx: 'MessageContext', match: Optional[Match]) -> bool: - """ - 处理 "帮助" 命令 - - 匹配: info/帮助/指令 - """ - help_text = [ - "🤖 泡泡的指令列表 🤖", - "", - "【实用工具】", - "- 天气/温度 [城市名]", - "- 天气预报/预报 [城市名]", - "- 新闻", - "- ask [问题]", - "", - "【提醒】", - "- 提醒xxxxx:一次性、每日、每周", - "- 查看提醒/我的提醒/提醒列表", - "- 删..提醒..", - "", - "【群聊工具】", - "- summary/总结", - "- clearmessages/清除历史", - "" - ] - help_text = "\n".join(help_text) - - # 发送消息 - return ctx.send_text(help_text) - -def handle_summary(ctx: 'MessageContext', match: Optional[Match]) -> bool: - """ - 处理 "消息总结" 命令 - - 匹配: summary/总结 - """ - if not ctx.is_group: - ctx.send_text("⚠️ 消息总结功能仅支持群聊") - return True - - try: - # 获取群聊ID - chat_id = ctx.msg.roomid - - # 使用MessageSummary生成总结 - if ctx.robot and hasattr(ctx.robot, "message_summary") and hasattr(ctx.robot, "chat"): - summary = ctx.robot.message_summary.summarize_messages(chat_id, ctx.robot.chat) - - # 发送总结 - ctx.send_text(summary) - - return True - else: - ctx.send_text("⚠️ 消息总结功能不可用") - return False - except Exception as e: - if ctx.logger: - ctx.logger.error(f"生成消息总结出错: {e}") - ctx.send_text("⚠️ 生成消息总结失败") - return False - -def handle_clear_messages(ctx: 'MessageContext', match: Optional[Match]) -> bool: - """ - 处理 "清除消息历史" 命令 - - 匹配: clearmessages/清除消息/清除历史 - """ - if not ctx.is_group: - ctx.send_text("⚠️ 消息历史管理功能仅支持群聊") - return True - - try: - # 获取群聊ID - chat_id = ctx.msg.roomid - - # 清除历史 - if ctx.robot and hasattr(ctx.robot, "message_summary"): - if ctx.robot.message_summary.clear_message_history(chat_id): - ctx.send_text("✅ 已清除本群的消息历史记录") - else: - ctx.send_text("⚠️ 本群没有消息历史记录") - - return True - else: - ctx.send_text("⚠️ 消息历史管理功能不可用") - return False - except Exception as e: - if ctx.logger: - ctx.logger.error(f"清除消息历史出错: {e}") - ctx.send_text("⚠️ 清除消息历史失败") - return False - -def handle_news_request(ctx: 'MessageContext', match: Optional[Match]) -> bool: - """ - 处理 "新闻" 命令 - - 匹配: 新闻 - """ - if ctx.logger: - ctx.logger.info(f"收到来自 {ctx.sender_name} (群聊: {ctx.msg.roomid if ctx.is_group else '无'}) 的新闻请求") - - try: - from function.func_news import News - news_instance = News() - # 调用方法,接收返回的元组(is_today, news_content) - is_today, news_content = news_instance.get_important_news() - - receiver = ctx.get_receiver() - sender_for_at = ctx.msg.sender if ctx.is_group else "" # 群聊中@请求者 - - if is_today: - # 是当天新闻,直接发送 - ctx.send_text(f"📰 今日要闻来啦:\n{news_content}", sender_for_at) - else: - # 不是当天新闻或获取失败 - if news_content: - # 有内容,说明是旧闻 - prompt = "ℹ️ 今日新闻暂未发布,为您找到最近的一条新闻:" - ctx.send_text(f"{prompt}\n{news_content}", sender_for_at) - else: - # 内容为空,说明获取彻底失败 - ctx.send_text("❌ 获取新闻失败,请稍后重试或联系管理员。", sender_for_at) - - return True # 无论结果如何,命令本身算成功处理 - - except Exception as e: - if ctx.logger: ctx.logger.error(f"处理新闻请求时出错: {e}") - receiver = ctx.get_receiver() - sender_for_at = ctx.msg.sender if ctx.is_group else "" - ctx.send_text("❌ 获取新闻时发生错误,请稍后重试。", sender_for_at) - return False # 处理失败 - def handle_chitchat(ctx: 'MessageContext', match: Optional[Match]) -> bool: """ 处理闲聊,调用AI模型生成回复 @@ -291,76 +159,6 @@ def handle_chitchat(ctx: 'MessageContext', match: Optional[Match]) -> bool: ctx.logger.error(f"获取AI回复时出错: {e}") return False -def handle_insult(ctx: 'MessageContext', match: Optional[Match]) -> bool: - """ - 处理 "骂人" 命令 - - 匹配: 骂一下@XX - """ - if not ctx.is_group: - ctx.send_text("❌ 骂人功能只支持群聊哦~") - return True - - if not match: - return False - - # 获取目标名称 - target_mention_name = match.group(1).strip() - - if ctx.logger: - ctx.logger.info(f"群聊 {ctx.msg.roomid} 中检测到骂人指令,提及目标:{target_mention_name}") - - # 默认使用提及的名称 - actual_target_name = target_mention_name - target_wxid = None - - # 尝试查找实际群成员昵称和wxid - try: - found = False - for wxid, name in ctx.room_members.items(): - # 优先完全匹配,其次部分匹配 - if target_mention_name == name: - target_wxid = wxid - actual_target_name = name - found = True - break - if not found: # 如果完全匹配不到,再尝试部分匹配 - for wxid, name in ctx.room_members.items(): - if target_mention_name in name: - target_wxid = wxid - actual_target_name = name - break - except Exception as e: - if ctx.logger: - ctx.logger.error(f"查找群成员信息时出错: {e}") - # 出错时继续使用提及的名称 - - # 禁止骂机器人自己 - if target_wxid and target_wxid == ctx.robot_wxid: - ctx.send_text("😅 不行,我不能骂我自己。") - return True - - # 即使找不到wxid,仍然尝试使用提及的名字骂 - try: - from function.func_insult import generate_random_insult - insult_text = generate_random_insult(actual_target_name) - ctx.send_text(insult_text) - - if ctx.logger: - ctx.logger.info(f"已发送骂人消息至群 {ctx.msg.roomid},目标: {actual_target_name}") - - return True - except ImportError: - if ctx.logger: - ctx.logger.error("无法导入 func_insult 模块。") - ctx.send_text("Oops,我的骂人模块好像坏了...") - return True - except Exception as e: - if ctx.logger: - ctx.logger.error(f"生成或发送骂人消息时出错: {e}") - ctx.send_text("呃,我想骂但出错了...") - return True - def handle_perplexity_ask(ctx: 'MessageContext', match: Optional[Match]) -> bool: """ 处理 "ask" 命令,调用 Perplexity AI @@ -983,73 +781,4 @@ def handle_delete_reminder(ctx: 'MessageContext', match: Optional[Match]) -> boo ctx.send_text(f"❌ 处理删除提醒时发生意外错误。", at_list) if ctx.logger: ctx.logger.error(f"handle_delete_reminder AI 部分顶层错误: {e}", exc_info=True) - return True - -def handle_weather_forecast(ctx: 'MessageContext', match: Optional[Match]) -> bool: - """ - 处理 "天气预报" 或 "预报" 命令 - - 匹配: 天气预报 [城市名] 或 预报 [城市名] - """ - if not match: - return False - - city_name = match.group(1).strip() - if not city_name: - ctx.send_text("🤔 请告诉我你想查询哪个城市的天气预报,例如:天气预报 北京") - return True - - if ctx.logger: - ctx.logger.info(f"天气预报查询指令匹配: 城市={city_name}") - - # --- 加载城市代码 --- - city_codes: Dict[str, str] = {} - city_code_path = os.path.join(os.path.dirname(__file__), '..', 'function', 'main_city.json') # 确保路径正确 - try: - with open(city_code_path, 'r', encoding='utf-8') as f: - city_codes = json.load(f) - except FileNotFoundError: - if ctx.logger: - ctx.logger.error(f"城市代码文件未找到: {city_code_path}") - ctx.send_text("⚠️ 抱歉,天气功能所需的城市列表文件丢失了。") - return True - except json.JSONDecodeError: - if ctx.logger: - ctx.logger.error(f"无法解析城市代码文件: {city_code_path}") - ctx.send_text("⚠️ 抱歉,天气功能的城市列表文件格式错误。") - return True - except Exception as e: - if ctx.logger: - ctx.logger.error(f"加载城市代码时发生未知错误: {e}", exc_info=True) - ctx.send_text("⚠️ 抱歉,加载城市代码时发生错误。") - return True - # --- 城市代码加载完毕 --- - - city_code = city_codes.get(city_name) - - if not city_code: - # 尝试模糊匹配 (可选,如果需要) - found = False - for name, code in city_codes.items(): - if city_name in name: # 如果输入的名字是城市全名的一部分 - city_code = code - city_name = name # 使用找到的完整城市名 - if ctx.logger: - ctx.logger.info(f"城市 '{match.group(1).strip()}' 未精确匹配,使用模糊匹配结果: {city_name} ({city_code})") - found = True - break - if not found: - ctx.send_text(f"😕 找不到城市 '{city_name}' 的天气信息,请检查城市名称是否正确。") - return True - - # 获取天气信息 (包含预报) - try: - from function.func_weather import Weather - weather_info = Weather(city_code).get_weather(include_forecast=True) # 注意这里传入True - ctx.send_text(weather_info) - except Exception as e: - if ctx.logger: - ctx.logger.error(f"获取城市 {city_name}({city_code}) 天气预报时出错: {e}", exc_info=True) - ctx.send_text(f"😥 获取 {city_name} 天气预报时遇到问题,请稍后再试。") - - return True + return True \ No newline at end of file