ForcePilot/backend/package/yuxi/channel/extensions/signal/accounts.py
Kris 6713dc2d0d feat(channel): 添加 Signal 渠道扩展
新增 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 重连机制
2026-05-21 11:41:55 +08:00

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}"