import os import warnings from yuxi.channel.extensions.wechat_mp.types import WeChatAccount class WeChatMPConfig: ENV_MAP = { "app_id": "WECHAT_MP_APP_ID", "app_secret": "WECHAT_MP_APP_SECRET", "token": "WECHAT_MP_TOKEN", "encoding_aes_key": "WECHAT_MP_ENCODING_AES_KEY", "reply_mode": "WECHAT_MP_REPLY_MODE", "subscribe_msg": "WECHAT_MP_SUBSCRIBE_MSG", "remove_markdown": "WECHAT_MP_REMOVE_MD", } LEGACY_ENV_MAP = { "app_id": "WECHAT_APP_ID", "app_secret": "WECHAT_APP_SECRET", "token": "WECHAT_TOKEN", "encoding_aes_key": "WECHAT_ENCODING_AES_KEY", "reply_mode": "WECHAT_REPLY_MODE", "subscribe_msg": "WECHAT_SUBSCRIBE_MSG", "remove_markdown": "WECHAT_REMOVE_MD", } def list_account_ids(self, config: dict | None = None) -> list[str]: if self._resolve_app_id(): return ["default"] return [] def resolve_account(self, account_id: str = "default") -> WeChatAccount: app_id = self._resolve_app_id() return WeChatAccount( account_id=account_id, app_id=app_id or "", app_secret=self._env_or_config("app_secret") or "", token=self._env_or_config("token") or "", encoding_aes_key=self._env_or_config("encoding_aes_key") or "", dm_policy=self._env_or_config("dm_policy") or "open", reply_mode=self._env_or_config("reply_mode") or "active", subscribe_msg=self._env_or_config("subscribe_msg") or "", remove_markdown=self._env_or_config("remove_markdown") != "false", ) def is_configured(self, account: dict | None = None) -> bool: return bool( self._resolve_app_id() and self._env_or_config("app_secret") and self._env_or_config("token") and self._env_or_config("encoding_aes_key") ) def _resolve_app_id(self) -> str | None: return self._env_or_config("app_id") def _env_or_config(self, key: str) -> str | None: env_key = self.ENV_MAP.get(key, "") if env_key: val = os.getenv(env_key) if val: return val legacy_key = self.LEGACY_ENV_MAP.get(key, "") if legacy_key: val = os.getenv(legacy_key) if val: warnings.warn( f"环境变量 {legacy_key} 已废弃,请使用 {env_key}", DeprecationWarning, stacklevel=3, ) return val return None def config_schema(self) -> dict: return { "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "title": "微信公众号渠道配置", "properties": { "app_id": { "type": "string", "title": "AppID", "description": "微信公众号 AppID", }, "app_secret": { "type": "string", "title": "AppSecret", "x-ui-password": True, "description": "微信公众号 AppSecret", }, "token": { "type": "string", "title": "Token", "description": "消息签名 Token(自定义字符串)", }, "encoding_aes_key": { "type": "string", "title": "EncodingAESKey", "x-ui-password": True, "description": "消息加解密密钥(43 字符)", }, "dm_policy": { "type": "string", "enum": ["open", "pairing", "allowlist", "disabled"], "default": "open", "title": "DM 策略", }, "reply_mode": { "type": "string", "enum": ["passive", "active"], "default": "active", "title": "回复模式", "description": "passive=被动回复(未认证订阅号), active=客服消息(已认证)", }, "subscribe_msg": { "type": "string", "title": "关注欢迎语", "description": "用户关注公众号后自动回复的文本", }, "remove_markdown": { "type": "boolean", "default": True, "title": "移除 Markdown 格式", "description": "自动移除 AI 回复中的 Markdown 符号", }, }, "required": ["app_id", "app_secret", "token", "encoding_aes_key"], }