ForcePilot/backend/package/yuxi/channels/adapters/qqbot/message_cache.py
Kris ef5483dc1a refactor(qqbot): 重构QQ机器人适配器代码,优化多项功能与结构
主要变更:
1. 修复速率限流器使用setdefault替代重复创建令牌桶
2. 重构交互注册表匹配逻辑,优化精确匹配查找
3. 重构去重缓存逻辑,移到适配器实例方法
4. 重构发送URL解析,增加合法性校验并拆分公共方法
5. 优化流式消息处理逻辑,简化flush_controller调用
6. 重构群聊类型判断代码,简化语法
7. 修复重连管理器对None类型关闭分类的处理
8. 新增消息缓存、线程模拟器、发送初始化模块
9. 重构凭证备份与会话存储逻辑,支持环境变量指定状态目录
10. 新增配置提示与向导二维码绑定功能
11. 优化媒体上传逻辑,增加重试机制与缓存
12. 新增审批键盘模板构建函数
13. 重构消息格式处理,修正媒体发送字段与长度限制
14. 修复令牌过期时间计算,使用time.time替代monotonic
15. 新增群组激活缓冲区与用户追踪器增强功能
16. 修复换行符问题,统一文件结尾格式
2026-05-13 16:13:48 +08:00

95 lines
2.7 KiB
Python

from __future__ import annotations
import logging
import time
from collections import OrderedDict
from dataclasses import dataclass, field
from yuxi.channels.models import DeliveryResult
logger = logging.getLogger(__name__)
@dataclass
class SentMessage:
message_id: str
chat_id: str
content: str = ""
sent_at: float = field(default_factory=time.time)
updated_at: float = 0.0
update_count: int = 0
status: str = "sent"
error: str = ""
class MessageCache:
def __init__(self, max_messages: int = 500, ttl_s: float = 3600.0):
self._max = max_messages
self._ttl = ttl_s
self._messages: OrderedDict[str, SentMessage] = OrderedDict()
def record_sent(self, result: DeliveryResult, chat_id: str, content: str = "") -> SentMessage | None:
if not result.message_id:
return None
msg = SentMessage(
message_id=result.message_id,
chat_id=chat_id,
content=content[:500],
status="sent" if result.success else "failed",
error=result.error or "",
)
self._messages[result.message_id] = msg
self._messages.move_to_end(result.message_id)
while len(self._messages) > self._max:
self._messages.popitem(last=False)
return msg
def record_update(self, message_id: str, content: str = "") -> SentMessage | None:
msg = self._messages.get(message_id)
if msg is None:
return None
msg.updated_at = time.time()
msg.update_count += 1
if content:
msg.content = content[:500]
return msg
def get(self, message_id: str) -> SentMessage | None:
return self._messages.get(message_id)
def get_by_chat(self, chat_id: str) -> list[SentMessage]:
return [m for m in self._messages.values() if m.chat_id == chat_id]
def cleanup_expired(self) -> int:
now = time.time()
expired = [mid for mid, msg in self._messages.items() if now - msg.sent_at > self._ttl]
for mid in expired:
del self._messages[mid]
return len(expired)
@property
def snapshot(self) -> dict:
return {
"total": len(self._messages),
"max": self._max,
"ttl_s": self._ttl,
"recent": [
{
"message_id": m.message_id,
"chat_id": m.chat_id,
"sent_at": m.sent_at,
"updates": m.update_count,
"status": m.status,
}
for m in list(self._messages.values())[-20:]
],
}
def clear(self) -> int:
count = len(self._messages)
self._messages.clear()
return count