ForcePilot/backend/package/yuxi/channel/extensions/bluebubbles/history.py

63 lines
2.0 KiB
Python
Raw Normal View History

import logging
logger = logging.getLogger(__name__)
MAX_HISTORY_FETCH_LIMIT = 100
MAX_HISTORY_BODY_CHARS = 2000
async def fetch_chat_history(
client,
chat_guid: str,
limit: int = 50,
before_guid: str | None = None,
) -> list[dict]:
params = {"limit": min(limit, MAX_HISTORY_FETCH_LIMIT)}
if before_guid:
params["before"] = before_guid
for path, extra_params in _history_api_paths(chat_guid):
merged = {**params, **extra_params}
try:
resp = await client.get(path, params=merged)
if resp.status_code < 300:
data = _extract_message_list(resp.json())
return [_normalize_history_message(m) for m in data]
except Exception as e:
logger.debug("History fetch failed for %s: %s", path, e)
continue
return []
def _history_api_paths(chat_guid: str) -> list[tuple[str, dict]]:
return [
(f"/api/v1/chat/{chat_guid}/messages", {"sort": "DESC"}),
("/api/v1/messages", {"chatGuid": chat_guid}),
(f"/api/v1/chat/{chat_guid}/message", {}),
]
def _extract_message_list(response_data) -> list[dict]:
if isinstance(response_data, list):
return response_data
if isinstance(response_data, dict):
for key in ("data", "messages", "results"):
val = response_data.get(key)
if isinstance(val, list):
return val
return []
def _normalize_history_message(msg: dict) -> dict:
body = msg.get("text", msg.get("message", msg.get("body", "")))
return {
"guid": msg.get("guid", ""),
"text": body[:MAX_HISTORY_BODY_CHARS],
"sender": msg.get("sender", msg.get("handle", {}).get("id", "")),
"date": msg.get("dateDelivered", msg.get("date_delivered", msg.get("date", 0))),
"is_from_me": msg.get("isFromMe", msg.get("is_from_me", False)),
"chat_guid": msg.get("chatGuid", msg.get("chat_guid", "")),
"attachments": msg.get("attachments", []),
}