ForcePilot/backend/package/yuxi/channel/extensions/zoomchat/config.py
Kris d5e36d33b7 feat(channel): 添加 Zalo OA、Zoom Chat 和 Zulip 渠道扩展
新增 Zalo OA、Zoom Chat、Zulip 三个渠道扩展。

Zalo OA 渠道扩展主要模块:sidecar_client, config, gateway, outbound, streaming, pairing, security, auth, dedupe, directory, monitor, status, session, reactions, tools

Zoom Chat 渠道扩展主要模块:config, gateway, webhook, outbound, streaming, pairing, security, crypto, dedupe, actions, media, mentions, monitor, status, session, reactions, threading

Zulip 渠道扩展主要模块:client, config, gateway, outbound, streaming, pairing, security, monitor, status
2026-05-21 12:06:26 +08:00

158 lines
6.9 KiB
Python

import os
import logging
logger = logging.getLogger(__name__)
ENV_PREFIX = "ZOOMCHAT"
class ZoomConfigAdapter:
def __init__(self, config: dict | None = None):
self._config = config or {}
def list_account_ids(self, config: dict) -> list[str]:
accounts = config.get("accounts", {})
if not accounts:
return ["default"] if self._env_client_id() else []
return list(accounts.keys())
async def resolve_account(self, account_id: str = "default") -> dict:
accounts = self._get_raw_accounts()
raw = accounts.get(account_id, {})
if account_id == "default":
client_id = raw.get("client_id") or self._env_client_id()
client_secret = raw.get("client_secret") or os.environ.get(f"{ENV_PREFIX}_CLIENT_SECRET", "")
account_id_zoom = raw.get("account_id") or os.environ.get(f"{ENV_PREFIX}_ACCOUNT_ID", "")
webhook_secret = raw.get("webhook_secret") or os.environ.get(f"{ENV_PREFIX}_WEBHOOK_SECRET", "")
else:
upper = account_id.upper()
client_id = raw.get("client_id") or os.environ.get(f"{ENV_PREFIX}_CLIENT_ID_{upper}", "")
client_secret = raw.get("client_secret") or os.environ.get(f"{ENV_PREFIX}_CLIENT_SECRET_{upper}", "")
account_id_zoom = raw.get("account_id") or os.environ.get(f"{ENV_PREFIX}_ACCOUNT_ID_{upper}", "")
webhook_secret = raw.get("webhook_secret") or os.environ.get(f"{ENV_PREFIX}_WEBHOOK_SECRET_{upper}", "")
return {
"account_id": account_id_zoom,
"client_id": client_id,
"client_secret": client_secret,
"webhook_secret": webhook_secret,
"bot_user_id": raw.get("bot_user_id", ""),
"name": raw.get("name", account_id),
"dm_policy": raw.get("dm_policy", "open"),
"group_policy": raw.get("group_policy", "mentioned"),
"allow_from": raw.get("allow_from", []),
"api_base_url": raw.get("api_base_url", "https://api.zoom.us/v2"),
"text_chunk_limit": raw.get("text_chunk_limit", 3800),
"chunk_mode": raw.get("chunk_mode", "length"),
"webhook_host": raw.get("webhook_host", "0.0.0.0"),
"webhook_port": raw.get("webhook_port", 0),
"enabled": raw.get("enabled", True),
}
def is_configured(self, account: dict) -> bool:
return bool(
account.get("account_id")
and account.get("client_id")
and account.get("client_secret")
and account.get("webhook_secret")
)
def is_enabled(self, account: dict) -> bool:
return account.get("enabled", True)
def disabled_reason(self, account: dict) -> str:
if not self.is_configured(account):
return "Missing Zoom API credentials (account_id / client_id / client_secret / webhook_secret)"
if not self.is_enabled(account):
return "Account disabled in config"
return ""
def describe_account(self, account: dict) -> dict:
return {
"label": account.get("name", account.get("account_id", "Unknown")),
"bot_user_id": account.get("bot_user_id", "") or "(auto)",
"dm_policy": account.get("dm_policy", "open"),
"api_base_url": account.get("api_base_url", "https://api.zoom.us/v2"),
}
def config_schema(self) -> dict:
return {
"type": "object",
"title": "Zoom Team Chat 渠道配置",
"properties": {
"accounts": {
"type": "object",
"description": "Zoom account configurations",
"additionalProperties": {
"type": "object",
"properties": {
"client_id": {
"type": "string",
"title": "Client ID",
"description": "Zoom Marketplace App Client ID",
},
"client_secret": {
"type": "string",
"title": "Client Secret",
"description": "Zoom Marketplace App Client Secret",
"x-ui-password": True,
},
"account_id": {
"type": "string",
"title": "Account ID",
"description": "Zoom Account ID for S2S OAuth",
},
"webhook_secret": {
"type": "string",
"title": "Webhook Secret Token",
"description": "Zoom Webhook Secret Token",
"x-ui-password": True,
},
"bot_user_id": {
"type": "string",
"title": "Bot User ID",
"description": "Bot Zoom user ID (auto-resolved if empty)",
},
"dm_policy": {
"type": "string",
"title": "DM 策略",
"enum": ["open", "pairing", "allowlist", "disabled"],
},
"group_policy": {
"type": "string",
"title": "群组策略",
"enum": ["mentioned", "activated", "allowlist"],
},
"allow_from": {"type": "array", "items": {"type": "string"}, "title": "允许列表"},
"api_base_url": {
"type": "string",
"title": "API Base URL",
"description": "Custom API base URL for data residency",
},
"text_chunk_limit": {"type": "integer", "title": "文本分块上限", "default": 3800},
},
},
}
},
}
def default_account_id(self, config: dict) -> str:
return config.get("default_account", "default")
def resolve_allow_from(self, config: dict, account_id: str | None = None) -> list[str]:
aid = account_id or self.default_account_id(config)
accounts = config.get("accounts", {})
account = accounts.get(aid, {})
return account.get("allow_from", [])
def set_config(self, config: dict) -> None:
self._config = config
def _get_raw_accounts(self) -> dict:
return self._config.get("accounts", {})
@staticmethod
def _env_client_id() -> str:
return os.environ.get(f"{ENV_PREFIX}_CLIENT_ID", "")