from __future__ import annotations from typing import Any from yuxi.channel.extensions.wechat_ilink.types import ILinkAccount def resolve_account(config: dict[str, Any], account_id: str | None = None) -> ILinkAccount | None: accounts: list[dict[str, Any]] = config.get("accounts", []) if not accounts: return None if account_id: for acct in accounts: if acct.get("account_id") == account_id: return _parse_account(acct) else: return _parse_account(accounts[0]) return None def list_accounts(config: dict[str, Any]) -> list[ILinkAccount]: accounts: list[dict[str, Any]] = config.get("accounts", []) return [_parse_account(acct) for acct in accounts] def _parse_account(data: dict[str, Any]) -> ILinkAccount: return ILinkAccount( account_id=data.get("account_id", "default"), bot_token=data.get("bot_token", ""), refresh_token=data.get("refresh_token", ""), bot_user_id=data.get("bot_user_id", ""), bot_nickname=data.get("bot_nickname", ""), token_expires_at=data.get("token_expires_at", 0.0), dm_policy=data.get("dm_policy", "open"), group_policy=data.get("group_policy", "open"), allow_from=data.get("allow_from", []), enabled=data.get("enabled", True), proxy=data.get("proxy"), poll_timeout=data.get("poll_timeout", 25), poll_interval=data.get("poll_interval", 0.25), max_retries=data.get("max_retries", 100), ilink_bot_id=data.get("ilink_bot_id", ""), ilink_user_id=data.get("ilink_user_id", ""), base_url=data.get("base_url", "https://ilinkai.weixin.qq.com"), ) def serialize_account(account: ILinkAccount) -> dict[str, Any]: return { "account_id": account.account_id, "bot_token": account.bot_token, "refresh_token": account.refresh_token, "bot_user_id": account.bot_user_id, "bot_nickname": account.bot_nickname, "token_expires_at": account.token_expires_at, "dm_policy": account.dm_policy, "group_policy": account.group_policy, "allow_from": account.allow_from, "enabled": account.enabled, "proxy": account.proxy, "poll_timeout": account.poll_timeout, "poll_interval": account.poll_interval, "max_retries": account.max_retries, "ilink_bot_id": account.ilink_bot_id, "ilink_user_id": account.ilink_user_id, "base_url": account.base_url, } def config_schema() -> dict: return { "type": "object", "title": "微信个人号 (iLink) 渠道配置", "properties": { "enabled": {"type": "boolean", "default": True}, "dm_policy": { "type": "string", "enum": ["open", "allowlist", "pairing", "disabled"], "default": "open", "description": "私聊策略:open=无限制, allowlist=白名单, pairing=配对验证, disabled=禁用", }, "group_policy": { "type": "string", "enum": ["open", "allowlist", "disabled"], "default": "open", "description": "群聊策略", }, "allow_from": { "type": "array", "items": {"type": "string"}, "description": "白名单用户/群组 ID 列表", }, "poll_timeout": {"type": "integer", "default": 25, "description": "长轮询超时(秒)"}, "poll_interval": {"type": "number", "default": 0.25, "description": "轮询间隔(秒)"}, "max_retries": {"type": "integer", "default": 100, "description": "最大重试次数"}, "proxy": {"type": "string", "description": "HTTP 代理地址"}, "base_url": { "type": "string", "default": "https://ilinkai.weixin.qq.com", "description": "iLink API 基础地址", }, "accounts": { "type": "object", "additionalProperties": { "type": "object", "properties": { "bot_token": {"type": "string", "description": "Bot Token"}, "refresh_token": {"type": "string"}, "bot_user_id": {"type": "string"}, "bot_nickname": {"type": "string"}, "token_expires_at": {"type": "number"}, "dm_policy": {"type": "string", "enum": ["open", "allowlist", "pairing", "disabled"]}, "group_policy": {"type": "string", "enum": ["open", "allowlist", "disabled"]}, "allow_from": {"type": "array", "items": {"type": "string"}}, "enabled": {"type": "boolean", "default": True}, "proxy": {"type": "string"}, "poll_timeout": {"type": "integer", "default": 25}, "poll_interval": {"type": "number", "default": 0.25}, "max_retries": {"type": "integer", "default": 100}, "ilink_bot_id": {"type": "string"}, "ilink_user_id": {"type": "string"}, "base_url": {"type": "string", "default": "https://ilinkai.weixin.qq.com"}, }, }, }, }, }