feat(message_summary): add group overview stats section
This commit is contained in:
@@ -557,3 +557,37 @@ class MessageStorageDB(BaseDBOperator):
|
||||
group_id)
|
||||
result = self.execute_query(sql, params)
|
||||
return result[0]['count'] if result else 0
|
||||
|
||||
def get_message_stats_by_date_range(self, group_id: str, start_time: datetime, end_time: datetime) -> Dict:
|
||||
"""统计指定时间范围内的群消息概览"""
|
||||
sql = """
|
||||
SELECT
|
||||
COUNT(*) AS total_count,
|
||||
COUNT(DISTINCT sender) AS participant_count,
|
||||
SUM(CASE WHEN message_type = 1 THEN 1 ELSE 0 END) AS text_count,
|
||||
SUM(CASE WHEN message_type = 3 THEN 1 ELSE 0 END) AS image_count,
|
||||
SUM(CASE WHEN message_type IN (43, 62) THEN 1 ELSE 0 END) AS video_count,
|
||||
SUM(CASE WHEN message_type = 49 THEN 1 ELSE 0 END) AS link_count,
|
||||
SUM(CASE WHEN message_type IN (47, 1048625, 1090519089) THEN 1 ELSE 0 END) AS emoji_count
|
||||
FROM messages
|
||||
WHERE timestamp >= %s
|
||||
AND timestamp <= %s
|
||||
AND group_id = %s
|
||||
AND sender IS NOT NULL
|
||||
AND sender <> ''
|
||||
"""
|
||||
params = (
|
||||
start_time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
end_time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
group_id,
|
||||
)
|
||||
result = self.execute_query(sql, params, fetch_one=True) or {}
|
||||
return {
|
||||
"total_count": int(result.get("total_count") or 0),
|
||||
"participant_count": int(result.get("participant_count") or 0),
|
||||
"text_count": int(result.get("text_count") or 0),
|
||||
"image_count": int(result.get("image_count") or 0),
|
||||
"video_count": int(result.get("video_count") or 0),
|
||||
"link_count": int(result.get("link_count") or 0),
|
||||
"emoji_count": int(result.get("emoji_count") or 0),
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
||||
return False, None
|
||||
period_start, period_end = self._resolve_manual_summary_range(custom_date)
|
||||
message_count = self.message_storage.count_messages_by_date_range(group_id, period_start, period_end)
|
||||
message_stats = self.message_storage.get_message_stats_by_date_range(group_id, period_start, period_end)
|
||||
if message_count < 100:
|
||||
await self.bot.send_text_message(
|
||||
group_id,
|
||||
@@ -191,6 +192,7 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
||||
period_start=period_start,
|
||||
period_end=period_end,
|
||||
message_count=message_count,
|
||||
message_stats=message_stats,
|
||||
)
|
||||
if res:
|
||||
return True, "异步总结已启动"
|
||||
@@ -210,11 +212,12 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
||||
period_start: Optional[datetime] = None,
|
||||
period_end: Optional[datetime] = None,
|
||||
message_count: Optional[int] = None,
|
||||
message_stats: Optional[Dict[str, int]] = None,
|
||||
):
|
||||
"""异步生成并发送总结"""
|
||||
try:
|
||||
# 生成总结
|
||||
summary, image_path = await self._generate_summary(chat_content, group_name)
|
||||
summary, image_path = await self._generate_summary(chat_content, group_name, message_stats=message_stats)
|
||||
|
||||
if image_path:
|
||||
# 图片生成成功,发送图片
|
||||
@@ -449,7 +452,12 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
||||
self.LOG.error(f"群总结入库失败: group_id={group_id}, period_key={summary_record['period_key']}")
|
||||
return saved
|
||||
|
||||
async def _generate_summary(self, chat_content: str, group_name: str) -> Tuple[str, Optional[str]]:
|
||||
async def _generate_summary(
|
||||
self,
|
||||
chat_content: str,
|
||||
group_name: str,
|
||||
message_stats: Optional[Dict[str, int]] = None,
|
||||
) -> Tuple[str, Optional[str]]:
|
||||
"""生成总结"""
|
||||
content_compress = chat_content
|
||||
try:
|
||||
@@ -483,6 +491,7 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
||||
answer = self._clean_summary_output(response.get("text", ""))
|
||||
metadata = {"usage": response.get("usage", {}) or {}}
|
||||
spath = ""
|
||||
answer = self._prepend_stats_section(answer, message_stats or {})
|
||||
answer = self._append_usage_info(answer, metadata)
|
||||
|
||||
if answer and len(answer.strip()) > 0:
|
||||
@@ -513,6 +522,25 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
||||
|
||||
return "生成总结时出错", None
|
||||
|
||||
@staticmethod
|
||||
def _prepend_stats_section(summary: str, message_stats: Dict[str, int]) -> str:
|
||||
stats = message_stats or {}
|
||||
if not summary or not summary.strip():
|
||||
return summary
|
||||
|
||||
section_lines = [
|
||||
"## 群概览",
|
||||
f"- 总统计条目数:{int(stats.get('total_count') or 0)}",
|
||||
f"- 参与人数:{int(stats.get('participant_count') or 0)}",
|
||||
f"- 文本消息:{int(stats.get('text_count') or 0)}",
|
||||
f"- 图片消息:{int(stats.get('image_count') or 0)}",
|
||||
f"- 视频消息:{int(stats.get('video_count') or 0)}",
|
||||
f"- 链接消息:{int(stats.get('link_count') or 0)}",
|
||||
f"- 表情消息:{int(stats.get('emoji_count') or 0)}",
|
||||
]
|
||||
section = "\n".join(section_lines)
|
||||
return f"{section}\n\n{summary.strip()}"
|
||||
|
||||
async def daily_summary_job(self):
|
||||
"""定时任务:每天早上9点总结昨天的聊天信息"""
|
||||
try:
|
||||
@@ -561,6 +589,11 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
||||
continue
|
||||
|
||||
self.LOG.info(f"群 {group_id} 昨天有 {message_count} 条消息,开始获取内容")
|
||||
message_stats = self.message_storage.get_message_stats_by_date_range(
|
||||
group_id,
|
||||
yesterday_start,
|
||||
yesterday_end,
|
||||
)
|
||||
|
||||
# 获取群成员信息
|
||||
group_members = ContactManager.get_instance().get_group_members(group_id)
|
||||
@@ -592,7 +625,11 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
||||
)
|
||||
|
||||
# 生成总结
|
||||
summary, image_path = await self._generate_summary(chat_content, group_name)
|
||||
summary, image_path = await self._generate_summary(
|
||||
chat_content,
|
||||
group_name,
|
||||
message_stats=message_stats,
|
||||
)
|
||||
|
||||
if image_path:
|
||||
# 图片生成成功,发送图片
|
||||
|
||||
@@ -551,6 +551,27 @@ class MessageStorage:
|
||||
logger.error(f"统计消息数量出错: {e}")
|
||||
return 0
|
||||
|
||||
def get_message_stats_by_date_range(self, group_id, start_time: datetime, end_time: datetime) -> Dict:
|
||||
"""获取指定时间范围内的群消息概览统计"""
|
||||
try:
|
||||
stats = self.message_db.get_message_stats_by_date_range(group_id, start_time, end_time)
|
||||
logger.info(
|
||||
f"群 {group_id} 在 {start_time} 至 {end_time} 的消息概览: "
|
||||
f"total={stats.get('total_count', 0)}, participants={stats.get('participant_count', 0)}"
|
||||
)
|
||||
return stats
|
||||
except Exception as e:
|
||||
logger.error(f"获取消息概览统计出错: {e}")
|
||||
return {
|
||||
"total_count": 0,
|
||||
"participant_count": 0,
|
||||
"text_count": 0,
|
||||
"image_count": 0,
|
||||
"video_count": 0,
|
||||
"link_count": 0,
|
||||
"emoji_count": 0,
|
||||
}
|
||||
|
||||
def _format_messages_optimized(self, messages: list, all_contacts: dict) -> str:
|
||||
"""优化的消息格式化方法,减少冗余
|
||||
|
||||
|
||||
Reference in New Issue
Block a user