202 lines
6.8 KiB
Markdown
202 lines
6.8 KiB
Markdown
# 消息总结定时任务使用说明
|
||
|
||
## 功能概述
|
||
|
||
已为 `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"]`。
|