ForcePilot/backend/package/yuxi/channel/extensions/bluebubbles/probe.py
Kris b018e3eda4 feat(bluebubbles): 新增BlueBubbles(iMessage)渠道插件完整实现
该提交新增了完整的BlueBubbles渠道插件,支持通过BlueBubbles Server集成iMessage功能,包含以下核心能力:
1.  支持私聊和群聊会话管理,自动区分会话类型
2.  完整的消息收发支持,包括文本、图片、语音、文件、视频消息
3.  支持消息反应、已读回执、消息编辑与撤回
4.  内置去重、防抖处理机制
5.  支持Webhook和WebSocket两种事件接收方式
6.  完善的权限与安全校验机制
7.  历史消息同步与抓包功能
8.  TTS语音合成与发送支持
9.  群组管理能力,包括重命名、修改头像、增减成员等
2026-05-21 10:40:33 +08:00

64 lines
1.7 KiB
Python

import time
import re
from dataclasses import dataclass
from yuxi.channel.extensions.bluebubbles.client import BlueBubblesClient
@dataclass
class ServerInfo:
os_version: str | None = None
macos_major: int | None = None
private_api_enabled: bool = False
imessage_logged_in: bool = False
fetched_at: float = 0.0
_info_cache: dict[str, ServerInfo] = {}
_CACHE_TTL = 600
async def probe_server(client: BlueBubblesClient) -> bool:
return await client.ping()
async def fetch_server_info(client: BlueBubblesClient) -> ServerInfo:
now = time.time()
cached = _info_cache.get(client.account_id)
if cached and (now - cached.fetched_at) < _CACHE_TTL:
return cached
try:
resp = await client.get("/api/v1/server/info")
data = resp.json().get("data", resp.json())
info = ServerInfo(
os_version=data.get("os_version"),
macos_major=_parse_macos_major(data.get("os_version", "")),
private_api_enabled=data.get("private_api", False),
imessage_logged_in=data.get("imessage", {}).get("logged_in", False),
fetched_at=now,
)
except Exception:
info = ServerInfo(fetched_at=now)
_info_cache[client.account_id] = info
return info
def _parse_macos_major(os_version: str) -> int | None:
m = re.search(r"macOS\s+(\d+)", os_version, re.IGNORECASE)
return int(m.group(1)) if m else None
def is_macos26_or_higher(info: ServerInfo) -> bool:
return info.macos_major is not None and info.macos_major >= 26
async def get_private_api_status(client: BlueBubblesClient) -> bool:
info = await fetch_server_info(client)
return info.private_api_enabled
def clear_probe_cache():
_info_cache.clear()