from __future__ import annotations import os from yuxi.channel.extensions.synology_chat.types import ( ACCOUNT_ID_DEFAULT, BOT_NAME_DEFAULT, RATE_LIMIT_DEFAULT, WEBHOOK_PATH_DEFAULT, WEBHOOK_PATH_SOURCE_DEFAULT, WEBHOOK_PATH_SOURCE_EXPLICIT, WEBHOOK_PATH_SOURCE_INHERITED, DM_POLICY_ALLOWLIST, ResolvedSynologyChatAccount, ) def list_account_ids(config: dict) -> list[str]: channel_cfg = config.get("channels", {}).get("synology-chat", {}) base_ids = [ACCOUNT_ID_DEFAULT] named = list(channel_cfg.get("accounts", {}).keys()) return base_ids + named def resolve_account(config: dict, account_id: str = ACCOUNT_ID_DEFAULT) -> ResolvedSynologyChatAccount: channel_cfg = config.get("channels", {}).get("synology-chat", {}) account_overrides = channel_cfg.get("accounts", {}).get(account_id, {}) if account_id != ACCOUNT_ID_DEFAULT else {} def _resolve(key: str, env_var: str | None = None, default: str | int | bool = "") -> str | int | bool: if key in account_overrides: return account_overrides[key] if key in channel_cfg: return channel_cfg[key] if env_var and account_id == ACCOUNT_ID_DEFAULT: env_val = os.environ.get(env_var, "") if env_val: return env_val return default def _resolve_list(key: str) -> list[str]: if key in account_overrides: val = account_overrides[key] return val if isinstance(val, list) else [] if key in channel_cfg: val = channel_cfg[key] return val if isinstance(val, list) else [] if account_id == ACCOUNT_ID_DEFAULT: env_val = os.environ.get("SYNOLOGY_ALLOWED_USER_IDS", "") if env_val: return [u.strip() for u in env_val.split(",") if u.strip()] return [] def _resolve_webhook_path_source() -> str: if account_overrides.get("webhookPath"): return WEBHOOK_PATH_SOURCE_EXPLICIT if account_id != ACCOUNT_ID_DEFAULT and channel_cfg.get("webhookPath"): return WEBHOOK_PATH_SOURCE_INHERITED return WEBHOOK_PATH_SOURCE_DEFAULT return ResolvedSynologyChatAccount( account_id=account_id, enabled=bool(_resolve("enabled", default=True)), token=str(_resolve("token", "SYNOLOGY_CHAT_TOKEN")), incoming_url=str(_resolve("incomingUrl", "SYNOLOGY_CHAT_INCOMING_URL")), nas_host=str(_resolve("nasHost", "SYNOLOGY_NAS_HOST", "localhost")), webhook_path=str(_resolve("webhookPath", default=WEBHOOK_PATH_DEFAULT)), webhook_path_source=_resolve_webhook_path_source(), dm_policy=str(_resolve("dmPolicy", default=DM_POLICY_ALLOWLIST)), allowed_user_ids=_resolve_list("allowedUserIds"), rate_limit_per_minute=int(_resolve("rateLimitPerMinute", "SYNOLOGY_RATE_LIMIT", RATE_LIMIT_DEFAULT)), bot_name=str(_resolve("botName", "OPENCLAW_BOT_NAME", BOT_NAME_DEFAULT)), allow_insecure_ssl=bool(_resolve("allowInsecureSsl", default=False)), dangerously_allow_name_matching=bool(_resolve("dangerouslyAllowNameMatching", default=False)), dangerously_allow_inherited_webhook_path=bool(_resolve("dangerouslyAllowInheritedWebhookPath", default=False)), )