ForcePilot/backend/package/yuxi/channel/extensions/signal/account_management.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

143 lines
3.8 KiB
Python

import logging
from typing import Any
from yuxi.channel.extensions.signal.client import SignalRpcClient
logger = logging.getLogger(__name__)
async def register_account(
client: SignalRpcClient,
account: str,
voice_verification: bool = False,
captcha: str | None = None,
) -> None:
params: dict[str, Any] = {"account": account}
if voice_verification:
params["voice"] = True
if captcha:
params["captcha"] = captcha
await client.call("register", params, account=account)
async def verify_account(
client: SignalRpcClient,
account: str,
verification_code: str,
pin: str | None = None,
) -> None:
params: dict[str, Any] = {"account": account, "verificationCode": verification_code}
if pin:
params["pin"] = pin
await client.call("verify", params, account=account)
async def list_devices(client: SignalRpcClient, *, account: str | None = None) -> list[dict]:
result = await client.call("listDevices", account=account)
if isinstance(result, list):
return result
if isinstance(result, dict):
return result.get("devices", [])
return []
async def add_device(
client: SignalRpcClient,
uri: str,
*,
account: str | None = None,
) -> None:
params: dict[str, Any] = {"uri": uri}
if account:
params["account"] = account
await client.call("addDevice", params, account=account)
async def remove_device(
client: SignalRpcClient,
device_id: int,
*,
account: str | None = None,
) -> None:
params: dict[str, Any] = {"deviceId": device_id}
if account:
params["account"] = account
await client.call("removeDevice", params, account=account)
async def list_identities(
client: SignalRpcClient,
identifier: str | None = None,
*,
account: str | None = None,
) -> list[dict]:
params: dict[str, Any] = {}
if identifier:
params["number"] = identifier
if account:
params["account"] = account
result = await client.call("listIdentities", params, account=account)
if isinstance(result, list):
return result
if isinstance(result, dict):
return result.get("identities", [])
return []
async def trust_identity(
client: SignalRpcClient,
identifier: str,
verified_safety_number: str,
*,
account: str | None = None,
trust_all: bool = False,
) -> None:
params: dict[str, Any] = {
"account": identifier,
"verifiedSafetyNumber": verified_safety_number,
}
if trust_all:
params["trustAll"] = True
if account:
params["account"] = account
await client.call("trust", params, account=account)
async def set_account_attributes(
client: SignalRpcClient,
*,
pin: str | None = None,
registration_lock_pin: str | None = None,
unregister_account: bool = False,
discoverable_by_number: bool | None = None,
number_sharing: bool | None = None,
account: str | None = None,
) -> None:
params: dict[str, Any] = {}
if pin is not None:
params["pin"] = pin
if registration_lock_pin is not None:
params["registrationLockPin"] = registration_lock_pin
if unregister_account:
params["unregister"] = True
if discoverable_by_number is not None:
params["discoverableByNumber"] = discoverable_by_number
if number_sharing is not None:
params["numberSharing"] = number_sharing
if account:
params["account"] = account
await client.call("setAccountAttributes", params, account=account)
async def submit_rate_limit_challenge(
client: SignalRpcClient,
challenge: str,
captcha: str,
*,
account: str | None = None,
) -> None:
params: dict[str, Any] = {"challenge": challenge, "captcha": captcha}
if account:
params["account"] = account
await client.call("submitRateLimitChallenge", params, account=account)