# 消息总结定时任务使用说明 ## 功能概述 已为 `message_summary` 插件添加了定时任务功能,每天早上 9:00 自动总结昨天的群聊信息并发送到群聊中。 ## 实现原理 参考了 `game_task` 插件的定时任务策略,在 `message_summary` 插件初始化时注册定时任务: ```python async_job.at_times(["09:00"])(self.daily_summary_job) ``` ## 核心修改 ### 1. plugins/message_summary/main.py #### 添加导入 ```python from datetime import datetime, timedelta from utils.decorator.async_job import async_job import asyncio ``` #### 在 `__init__` 中注册定时任务 ```python def __init__(self): super().__init__() self.message_storage = None self.revoke = None self.feature = self.register_feature() # 注册定时任务:每天早上9点总结昨天的聊天信息 async_job.at_times(["09:00"])(self.daily_summary_job) ``` #### 添加定时任务方法 ```python async def daily_summary_job(self): """定时任务:每天早上9点总结昨天的聊天信息""" # 计算昨天的时间范围 yesterday = datetime.now() - timedelta(days=1) yesterday_start = yesterday.replace(hour=0, minute=0, second=0, microsecond=0) yesterday_end = yesterday.replace(hour=23, minute=59, second=59, microsecond=999999) # 获取所有启用了群机器人的群聊 all_groups = GroupBotManager.get_group_list() # 筛选出开启了总结功能的群聊 enabled_groups = [] for group_id in all_groups: if GroupBotManager.get_group_permission(group_id, self.feature) == PermissionStatus.ENABLED: enabled_groups.append(group_id) # 为每个群生成总结 for group_id in enabled_groups: # 获取昨天的聊天记录 chat_content = self.message_storage.get_messages_by_date_range( group_id, all_contacts, yesterday_start, yesterday_end ) # 生成并发送总结 summary, image_path = await self._generate_summary(chat_content, group_name) # 发送到群聊... ``` ### 2. db/message_storage.py 添加了按时间范围查询消息的方法: ```python def get_messages_by_date_range(self, group_id: str, start_time: datetime, end_time: datetime) -> List[Dict]: """获取指定时间范围内的消息""" sql = """ SELECT timestamp, sender, content, message_type FROM messages WHERE timestamp >= %s AND timestamp <= %s AND message_type in (1, 49) AND group_id = %s AND length(content) > 6 AND CHAR_LENGTH(content) < 300 AND content NOT LIKE '/%' ORDER BY timestamp ASC """ params = (start_time.strftime('%Y-%m-%d %H:%M:%S'), end_time.strftime('%Y-%m-%d %H:%M:%S'), group_id) return self.execute_query(sql, params) or [] ``` ### 3. utils/wechat/message_to_db.py 添加了对应的包装方法: ```python def get_messages_by_date_range(self, group_id, all_contacts: dict, start_time: datetime, end_time: datetime): """获取指定时间范围内的消息""" messages = self.message_db.get_messages_by_date_range(group_id, start_time, end_time) result_str = self._format_messages_optimized(messages, all_contacts) return result_str ``` ## 使用方法 ### 1. 启用插件 确保 `message_summary` 插件已启用,并且已在插件配置中开启。 ### 2. 配置群权限 对于需要自动总结的群聊,需要开启"群总结能力"功能: - 通过机器人群管理命令设置群权限为 `ENABLED` - 功能键:`SUMMARY_CAPABILITY` ### 3. 自动运行 - 定时任务会在每天早上 9:00 自动执行 - 只会总结昨天(00:00:00 - 23:59:59)的聊天记录 - **只有消息数量超过 50 条的群才会生成总结**(按消息条数统计,不是字符数) ### 4. 手动触发 除了定时任务外,原有的手动总结功能仍然保留: - 在群聊中发送 `#总结` 或 `#summary` - 会总结最近 8 小时的聊天记录 ## 特性说明 1. **智能过滤** - 只总结文本消息(message_type 1 和 49) - 过滤掉命令消息(以 `/` 开头) - 过滤掉过短(<6字)和过长(>300字)的消息 2. **权限控制** - 只有开启了总结功能的群才会自动总结 - 使用 `GroupBotManager` 管理群权限 3. **消息数量过滤** - **只有消息数量 >= 50 条的群才会生成总结** - 先统计消息数量,不足 50 条直接跳过,避免浪费资源 - 按消息条数统计,不是按字符数 4. **错误处理** - 如果某个群的总结失败,不会影响其他群 - 详细的日志记录便于排查问题 5. **性能优化** - 群之间间隔 2 秒,避免 API 请求过快 - 使用现有的消息格式化方法,保持一致性 ## 日志示例 ``` 2026-01-09 09:00:00 | INFO | 开始执行每日聊天总结任务 2026-01-09 09:00:00 | INFO | 总结时间范围: 2026-01-08 00:00:00 至 2026-01-08 23:59:59 2026-01-09 09:00:00 | INFO | 找到 3 个开启定时总结的群聊 2026-01-09 09:00:01 | INFO | 群 test_group_1 昨天有 234 条消息,开始获取内容 2026-01-09 09:00:01 | INFO | 群 test_group_2 昨天只有 35 条消息,不足50条,跳过总结 2026-01-09 09:00:01 | INFO | 群 test_group_3 昨天有 156 条消息,开始获取内容 2026-01-09 09:00:02 | INFO | 获取到 234 条消息(时间范围:2026-01-08 00:00:00 至 2026-01-08 23:59:59),格式化后长度: 12580 2026-01-09 09:00:02 | INFO | 开始为群 测试群1 生成总结,消息数量: 234,内容长度: 12580 2026-01-09 09:00:15 | INFO | 成功发送群 测试群 的昨日总结图片 2026-01-09 09:00:17 | INFO | 每日聊天总结任务执行完成 ``` ## 注意事项 1. **时间精度**:定时任务使用系统时间,确保服务器时间准确 2. **数据库时区**:确保数据库时区设置正确,存储的 timestamp 使用的是本地时间 3. **API 限流**:如果总结的群很多,注意调整 `await asyncio.sleep(2)` 的间隔时间 4. **消息量**:如果某个群昨天的消息量很大(>5000条),可能需要调整 `max_results` 参数 ## 自定义配置 如需修改执行时间,可以修改 `message_summary/main.py` 中的定时任务注册: ```python # 改为每天早上 8:00 async_job.at_times(["08:00"])(self.daily_summary_job) # 改为每天晚上 22:00 async_job.at_times(["22:00"])(self.daily_summary_job) # 改为每天多个时间点 async_job.at_times(["09:00", "21:00"])(self.daily_summary_job) ``` ## 测试方法 为了测试定时任务功能,可以临时修改时间: ```python # 临时修改为当前时间后 1 分钟(用于测试) import datetime next_minute = (datetime.datetime.now() + datetime.timedelta(minutes=1)).strftime("%H:%M") async_job.at_times([next_minute])(self.daily_summary_job) ``` 测试完成后记得改回 `["09:00"]`。