ForcePilot/backend/package/yuxi/channel/extensions/imessage/targets.py
Kris 4d52f634fe feat(imessage): 新增iMessage渠道插件完整实现
该提交新增了基于BlueBubbles的iMessage渠道插件,支持单聊和群组消息,包含文本、图片、语音、文件和视频消息收发,支持消息编辑、撤回、回复、 reactions和输入状态提示,同时实现了账号配置、安全校验、配对授权、消息格式化与分片等完整功能。
2026-05-21 10:50:15 +08:00

56 lines
1.5 KiB
Python

from __future__ import annotations
import re
_E164_CLEAN = re.compile(r"[^\d+]")
def normalize_imessage_handle(handle: str) -> str:
handle = handle.strip()
for prefix in ("imessage:", "sms:", "auto:"):
if handle.lower().startswith(prefix):
handle = handle[len(prefix):]
if "@" in handle:
return handle.lower().strip()
return normalize_e164(handle)
def normalize_e164(handle: str) -> str:
cleaned = _E164_CLEAN.sub("", handle)
if not cleaned:
return handle
if not cleaned.startswith("+"):
cleaned = "+" + cleaned
return cleaned
def parse_target(target: str) -> tuple[str, str | None]:
"""Parse a target string into (format, value)."""
target = target.strip()
if target.startswith("chat_guid:"):
return ("chat_guid", target[len("chat_guid:"):])
if target.startswith("chat_identifier:"):
return ("chat_identifier", target[len("chat_identifier:"):])
return ("handle", normalize_imessage_handle(target))
def build_session_key(
channel_type: str,
account_id: str,
chat_type: str,
identifier: str,
) -> str:
return f"{channel_type}:{account_id}:{chat_type}:{identifier}"
def parse_session_key(session_key: str) -> dict | None:
parts = session_key.split(":")
if len(parts) < 4:
return None
return {
"channel_type": parts[0],
"account_id": parts[1],
"chat_type": parts[2],
"identifier": ":".join(parts[3:]),
}