130 lines
5.4 KiB
Python
130 lines
5.4 KiB
Python
|
|
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"},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
}
|