新增 Signal 渠道扩展,支持在 Yuxi 平台中集成 Signal 加密即时通讯渠道。 包含以下功能模块: - client: Signal 客户端封装 - daemon: signald 守护进程管理 - config_schema: 配置模式 - send: 消息发送 - accounts: 账户管理 - account_management: 账户综合管理 - access_policy: 访问策略 - identity: 身份管理 - profiles: 用户资料 - groups: 群组管理 - format: 消息格式转换 - normalize: 消息规范化 - dedupe: 消息去重 - monitor: 渠道状态监控 - probe: 健康探测 - sse_reconnect: SSE 重连机制
95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
from dataclasses import dataclass, field
|
|
|
|
|
|
@dataclass
|
|
class ResolvedSignalAccount:
|
|
account_id: str
|
|
name: str = ""
|
|
enabled: bool = True
|
|
configured: bool = False
|
|
base_url: str = ""
|
|
config: dict = field(default_factory=dict)
|
|
|
|
|
|
def resolve_signal_account(cfg: dict, account_id: str | None = None) -> ResolvedSignalAccount:
|
|
channel_cfg = cfg.get("channels", {}).get("signal", {})
|
|
accounts = channel_cfg.get("accounts", {})
|
|
|
|
if account_id and account_id in accounts:
|
|
account_cfg = _resolve_account_config(channel_cfg, accounts[account_id])
|
|
base_url = _resolve_base_url(account_cfg)
|
|
return ResolvedSignalAccount(
|
|
account_id=account_id,
|
|
name=account_cfg.get("name", account_id),
|
|
enabled=account_cfg.get("enabled", True),
|
|
configured=bool(account_cfg.get("account")),
|
|
base_url=base_url,
|
|
config=account_cfg,
|
|
)
|
|
|
|
if not account_id and accounts:
|
|
account_id = next(iter(accounts))
|
|
account_cfg = _resolve_account_config(channel_cfg, accounts[account_id])
|
|
base_url = _resolve_base_url(account_cfg)
|
|
return ResolvedSignalAccount(
|
|
account_id=account_id,
|
|
name=account_cfg.get("name", account_id),
|
|
enabled=account_cfg.get("enabled", True),
|
|
configured=bool(account_cfg.get("account")),
|
|
base_url=base_url,
|
|
config=account_cfg,
|
|
)
|
|
|
|
base_url = _resolve_base_url(channel_cfg)
|
|
return ResolvedSignalAccount(
|
|
account_id="default",
|
|
name="default",
|
|
enabled=channel_cfg.get("enabled", True),
|
|
configured=bool(channel_cfg.get("account")),
|
|
base_url=base_url,
|
|
config=channel_cfg,
|
|
)
|
|
|
|
|
|
def list_signal_account_ids(cfg: dict) -> list[str]:
|
|
channel_cfg = cfg.get("channels", {}).get("signal", {})
|
|
accounts = channel_cfg.get("accounts", {})
|
|
if accounts:
|
|
return list(accounts.keys())
|
|
if channel_cfg.get("account"):
|
|
return ["default"]
|
|
return []
|
|
|
|
|
|
def _resolve_account_config(channel_cfg: dict, account_cfg: dict) -> dict:
|
|
merged = dict(channel_cfg)
|
|
for key in (
|
|
"account",
|
|
"account_uuid",
|
|
"http_url",
|
|
"http_host",
|
|
"http_port",
|
|
"cli_path",
|
|
"auto_start",
|
|
"receive_mode",
|
|
"send_read_receipts",
|
|
"dm_policy",
|
|
"allow_from",
|
|
"group_policy",
|
|
"group_allow_from",
|
|
"media_max_mb",
|
|
"enabled",
|
|
):
|
|
if key in account_cfg:
|
|
merged[key] = account_cfg[key]
|
|
return merged
|
|
|
|
|
|
def _resolve_base_url(cfg: dict) -> str:
|
|
http_url = cfg.get("http_url", "")
|
|
if http_url:
|
|
return http_url.rstrip("/")
|
|
host = cfg.get("http_host", "127.0.0.1")
|
|
port = cfg.get("http_port", 8080)
|
|
return f"http://{host}:{port}"
|