该提交新增了完整的BlueBubbles渠道插件,支持通过BlueBubbles Server集成iMessage功能,包含以下核心能力: 1. 支持私聊和群聊会话管理,自动区分会话类型 2. 完整的消息收发支持,包括文本、图片、语音、文件、视频消息 3. 支持消息反应、已读回执、消息编辑与撤回 4. 内置去重、防抖处理机制 5. 支持Webhook和WebSocket两种事件接收方式 6. 完善的权限与安全校验机制 7. 历史消息同步与抓包功能 8. TTS语音合成与发送支持 9. 群组管理能力,包括重命名、修改头像、增减成员等
63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
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", []),
|
|
}
|