新增 iMessage 通道适配器完整实现,包含: 1. 核心适配器与工具工厂导出 2. 运行时存储、反射防护、会话路由等基础组件 3. 消息信封、线程管理、回复上下文格式化 4. Tapback 表情反应处理、自定义异常体系 5. 审批按钮、联系人解析、速率限制功能 6. 文本净化、目标解析、缓存管理模块 7. 配置 schema、多账户支持、安装向导等配置模块 8. 审计日志、媒体AI处理等扩展功能
68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
from __future__ import annotations
|
||
|
||
import re
|
||
|
||
_CONTROL_CHAR_RE = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]")
|
||
_MULTI_NEWLINE_RE = re.compile(r"\n{3,}")
|
||
_LENGTH_PREFIX_RE = re.compile(r"^(\d+)\n")
|
||
_TERMINAL_ESCAPE_RE = re.compile(r"\x1b\[[0-9;]*[a-zA-Z]")
|
||
_MAX_TERMINAL_MSG_LEN = 200
|
||
|
||
|
||
def sanitize_terminal_text(text: str, max_len: int = _MAX_TERMINAL_MSG_LEN) -> str:
|
||
"""净化终端输出文本,移除 ANSI 转义序列和控制字符。
|
||
|
||
用于日志记录和错误消息净化。
|
||
"""
|
||
if not text:
|
||
return ""
|
||
text = _TERMINAL_ESCAPE_RE.sub("", text)
|
||
text = _CONTROL_CHAR_RE.sub("", text)
|
||
if len(text) > max_len:
|
||
text = text[:max_len] + "..."
|
||
return text
|
||
|
||
|
||
def sanitize_outbound_text(text: str) -> str:
|
||
"""净化出站文本,移除 iMessage 中不支持的格式。
|
||
|
||
- 去除 \\r 字符(换行标准化)
|
||
- 去除长度前缀损坏(如 "42\\nThis is message")
|
||
- 过滤控制字符
|
||
- 合并多余空白行
|
||
"""
|
||
text = text.replace("\r", "")
|
||
|
||
text = _strip_length_prefix(text)
|
||
|
||
text = _CONTROL_CHAR_RE.sub("", text)
|
||
|
||
text = _MULTI_NEWLINE_RE.sub("\n\n", text)
|
||
text = text.strip()
|
||
|
||
return text
|
||
|
||
|
||
def _strip_length_prefix(text: str) -> str:
|
||
match = _LENGTH_PREFIX_RE.match(text)
|
||
if match:
|
||
prefix_len = int(match.group(1))
|
||
remaining = text[match.end() :]
|
||
if abs(len(remaining) - prefix_len) <= 5:
|
||
return remaining
|
||
return text
|
||
|
||
|
||
def media_placeholder(media_type: str) -> str:
|
||
"""为纯媒体消息生成占位文本。
|
||
|
||
OpenClaw 在无文本媒体消息中生成 <media:image> 等占位符。
|
||
"""
|
||
placeholders = {
|
||
"image": "<media:image>",
|
||
"video": "<media:video>",
|
||
"audio": "<media:audio>",
|
||
"file": "<media:file>",
|
||
}
|
||
return placeholders.get(media_type, "<media:file>")
|