ForcePilot/backend/package/yuxi/channel/extensions/helpscout/config.py
Kris 432d5db970 feat(helpscout): 新增Help Scout客服工单渠道插件
完成Help Scout渠道的完整功能实现,包含API客户端、webhook处理、轮询同步、自动回复、工单标签分配、客户资料管理等核心能力,附带完整的配置Schema与插件元信息
2026-05-21 10:49:56 +08:00

90 lines
3.5 KiB
Python

from __future__ import annotations
import logging
import os
logger = logging.getLogger(__name__)
ENV_MAP = {
"app_id": "HELPSCOUT_APP_ID",
"app_secret": "HELPSCOUT_APP_SECRET",
"mailbox_id": "HELPSCOUT_MAILBOX_ID",
"mode": "HELPSCOUT_MODE",
"webhook_url": "HELPSCOUT_WEBHOOK_URL",
"webhook_secret": "HELPSCOUT_WEBHOOK_SECRET",
"auto_reply_mode": "HELPSCOUT_AUTO_REPLY_MODE",
"customer_allowlist": "HELPSCOUT_CUSTOMER_ALLOWLIST",
"poll_interval": "HELPSCOUT_POLL_INTERVAL",
"streaming_mode": "HELPSCOUT_STREAMING_MODE",
"language_detection": "HELPSCOUT_LANGUAGE_DETECTION",
"auto_register_webhook": "HELPSCOUT_AUTO_REGISTER_WEBHOOK",
"auto_unregister_webhook": "HELPSCOUT_AUTO_UNREGISTER_WEBHOOK",
}
def _env_or_config(key: str) -> str | None:
env_key = ENV_MAP.get(key, "")
if env_key:
return os.getenv(env_key)
return None
def resolve_account(account_id: str = "default") -> dict:
allowlist_str = _env_or_config("customer_allowlist") or ""
lang_str = _env_or_config("language_detection") or "true"
return {
"account_id": account_id,
"app_id": _env_or_config("app_id") or "",
"app_secret": _env_or_config("app_secret") or "",
"mailbox_id": int(_env_or_config("mailbox_id") or "0"),
"mode": _env_or_config("mode") or "webhook",
"webhook_url": _env_or_config("webhook_url") or "",
"webhook_secret": _env_or_config("webhook_secret") or "",
"auto_reply_mode": _env_or_config("auto_reply_mode") or "draft",
"customer_allowlist": [e.strip() for e in allowlist_str.split(",") if e.strip()],
"poll_interval": int(_env_or_config("poll_interval") or "30"),
"streaming_mode": _env_or_config("streaming_mode") or "block",
"language_detection": lang_str.lower() == "true",
"auto_register_webhook": (_env_or_config("auto_register_webhook") or "false").lower() == "true",
"auto_unregister_webhook": (_env_or_config("auto_unregister_webhook") or "false").lower() == "true",
}
class HelpScoutConfigAdapter:
def list_account_ids(self, config: dict) -> list[str]:
accounts = config.get("accounts", [])
if accounts:
return [a.get("account_id", "default") for a in accounts]
return ["default"]
async def resolve_account(self, account_id: str) -> dict:
return resolve_account(account_id)
def is_configured(self, account: dict) -> bool:
return bool(account.get("app_id") and account.get("app_secret") and int(account.get("mailbox_id", 0)) > 0)
def is_enabled(self, account: dict, config: dict | None = None) -> bool:
cfg = config or {}
return cfg.get("enabled", False)
def describe_account(self, account: dict, config: dict | None = None) -> dict:
return {
"account_id": account.get("account_id", "default"),
"mailbox_id": account.get("mailbox_id"),
"mode": account.get("mode", "webhook"),
}
def config_schema(self) -> dict:
from yuxi.channel.extensions.helpscout.config_schema import schema
return schema
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 | int] | None:
account = resolve_account(account_id or "default")
allowlist = account.get("customer_allowlist", [])
return allowlist if allowlist else None