""" 菜单插件 用户发送 /菜单、/帮助 等指令时,按顺序发送菜单图片 图片命名格式:menu1.png、menu2.png、menu3.png ... """ import re import asyncio from pathlib import Path from loguru import logger from utils.plugin_base import PluginBase from utils.decorators import on_text_message class Menu(PluginBase): """菜单插件""" # 插件元数据 description = "菜单插件,发送帮助图片" author = "ShiHao" version = "1.0.0" def __init__(self): super().__init__() self.menu_dir = None self.trigger_commands = ["/菜单", "/帮助", "/help", "/menu"] self.send_interval = 0.5 # 发送间隔(秒),避免发送过快 async def async_init(self): """插件异步初始化""" # 设置菜单图片目录 self.menu_dir = Path(__file__).parent / "images" self.menu_dir.mkdir(exist_ok=True) # 扫描现有图片 images = self._get_menu_images() logger.info(f"菜单插件已加载,图片目录: {self.menu_dir},找到 {len(images)} 张菜单图片") def _get_menu_images(self) -> list: """ 获取所有符合命名规范的菜单图片,按序号排序 命名格式:menu1.png、menu2.jpg、menu3.jpeg 等 """ if not self.menu_dir or not self.menu_dir.exists(): return [] # 匹配 menu + 数字 + 图片扩展名 pattern = re.compile(r'^menu(\d+)\.(png|jpg|jpeg|gif|bmp)$', re.IGNORECASE) images = [] for file in self.menu_dir.iterdir(): if file.is_file(): match = pattern.match(file.name) if match: seq_num = int(match.group(1)) images.append((seq_num, file)) # 按序号排序 images.sort(key=lambda x: x[0]) # 只返回文件路径 return [img[1] for img in images] @on_text_message(priority=60) async def handle_menu_command(self, bot, message: dict): """处理菜单指令""" content = message.get("Content", "").strip() from_wxid = message.get("FromWxid", "") # 检查是否是菜单指令 if content not in self.trigger_commands: return True # 继续传递给其他插件 logger.info(f"收到菜单指令: {content}, from: {from_wxid}") # 获取菜单图片 images = self._get_menu_images() if not images: await bot.send_text(from_wxid, "暂无菜单图片,请联系管理员添加") logger.warning(f"菜单图片目录为空: {self.menu_dir}") return False # 按顺序发送图片 for i, image_path in enumerate(images): try: await bot.send_image(from_wxid, str(image_path)) logger.debug(f"已发送菜单图片 {i+1}/{len(images)}: {image_path.name}") # 发送间隔,避免发送过快 if i < len(images) - 1: await asyncio.sleep(self.send_interval) except Exception as e: logger.error(f"发送菜单图片失败: {image_path}, 错误: {e}") logger.success(f"菜单图片发送完成,共 {len(images)} 张") return False # 阻止继续传递