新增 iMessage 通道适配器完整实现,包含: 1. 核心适配器与工具工厂导出 2. 运行时存储、反射防护、会话路由等基础组件 3. 消息信封、线程管理、回复上下文格式化 4. Tapback 表情反应处理、自定义异常体系 5. 审批按钮、联系人解析、速率限制功能 6. 文本净化、目标解析、缓存管理模块 7. 配置 schema、多账户支持、安装向导等配置模块 8. 审计日志、媒体AI处理等扩展功能
92 lines
2.7 KiB
Python
92 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
if TYPE_CHECKING:
|
|
from yuxi.channels.adapters.imessage.bridge_client import BlueBubblesClient
|
|
|
|
_rpc_support_cache: dict[str, bool] = {}
|
|
|
|
|
|
def get_rpc_support_cached(server_url: str) -> bool | None:
|
|
return _rpc_support_cache.get(server_url)
|
|
|
|
|
|
def set_rpc_support_cached(server_url: str, supported: bool) -> None:
|
|
_rpc_support_cache[server_url] = supported
|
|
|
|
|
|
def clear_rpc_support_cache() -> None:
|
|
_rpc_support_cache.clear()
|
|
|
|
|
|
async def probe_bridge(bridge_client: BlueBubblesClient) -> dict[str, Any]:
|
|
"""探测 BlueBubbles Server 状态和 iMessage 登录状态"""
|
|
server_info = await bridge_client.probe_server()
|
|
handle_info = await bridge_client.get_handle()
|
|
|
|
return {
|
|
"bridge_version": server_info.get("version"),
|
|
"bridge_os_version": server_info.get("os_version"),
|
|
"imessage_connected": handle_info.get("connected", False),
|
|
"imessage_handle": handle_info.get("handle"),
|
|
"server_info": server_info,
|
|
"handle_info": handle_info,
|
|
}
|
|
|
|
|
|
async def run_doctor_diagnosis(
|
|
bridge_client: BlueBubblesClient,
|
|
security_warnings: list[str],
|
|
adapter_status: str,
|
|
self_handle: str | None,
|
|
pairing_info: dict[str, Any],
|
|
) -> dict[str, Any]:
|
|
"""全量 health + warning 报告。
|
|
|
|
Returns:
|
|
dict with status, connectivity, security, pairing sections
|
|
"""
|
|
diagnosis: dict[str, Any] = {
|
|
"status": adapter_status,
|
|
"timestamp": None,
|
|
"connectivity": {},
|
|
"security": {
|
|
"warnings": security_warnings,
|
|
"assessment": _assess_security(security_warnings),
|
|
},
|
|
"pairing": pairing_info,
|
|
}
|
|
|
|
try:
|
|
server_info = await bridge_client.probe_server()
|
|
handle_info = await bridge_client.get_handle()
|
|
|
|
diagnosis["connectivity"] = {
|
|
"server_reachable": True,
|
|
"bridge_version": server_info.get("version", "unknown"),
|
|
"bridge_os_version": server_info.get("os_version", "unknown"),
|
|
"imessage_connected": handle_info.get("connected", False),
|
|
"imessage_handle": handle_info.get("handle", ""),
|
|
"self_handle": self_handle,
|
|
}
|
|
diagnosis["timestamp"] = None
|
|
except Exception as e:
|
|
diagnosis["connectivity"] = {
|
|
"server_reachable": False,
|
|
"error": str(e)[:200],
|
|
}
|
|
|
|
return diagnosis
|
|
|
|
|
|
def _assess_security(warnings: list[str]) -> str:
|
|
if not warnings:
|
|
return "secure"
|
|
critical_keywords = ["disabled", "empty", "open"]
|
|
for w in warnings:
|
|
for kw in critical_keywords:
|
|
if kw in w.lower():
|
|
return "at_risk"
|
|
return "needs_attention"
|