新增六边形架构核心代码包,包含: 1. 协议适配器层:HTTP/SMTP/IMAP/SSH/GRPC等多协议适配器实现 2. 认证插件体系:基础认证、API密钥、HMAC等多类型认证插件 3. 执行编排框架:工具执行器、上下文构建、运行时治理组件 4. 用例端口与DTO:定义领域服务端口与数据传输对象 5. 厂商集成包框架:支持第三方系统集成扩展 6. 基础设施装配层:实现依赖注入与服务装配 所有代码遵循六边形架构设计原则,实现端口与适配器解耦,支持动态扩展与自动发现。
111 lines
4.1 KiB
Python
111 lines
4.1 KiB
Python
"""Zendesk 厂商集成元数据。
|
||
|
||
定义 ``IntegrationMetadata(key="zendesk", ...)``,由 ``__init__.py`` 自注册到
|
||
``IntegrationRegistry``。元数据为内存态,不持久化到数据库。
|
||
|
||
同时提供:
|
||
|
||
- ``ZendeskConnectionConfig``:Zendesk 连接配置 Schema(含 ``subdomain`` / ``base_url``),
|
||
供前端动态表单与校验。
|
||
- ``resolve_oauth_endpoints``:根据 ``base_url`` 拼接 Zendesk 实例级 OAuth 端点,
|
||
供 handler 在 OAuth2 模式下注入到 ``auth_config``。
|
||
|
||
认证设计(见设计文档 §3):
|
||
|
||
- ``oauth2_authorization_code``:复用框架级插件,handler 内通过
|
||
``resolve_oauth_endpoints`` 注入 ``token_url``。
|
||
- ``basic``(API Token 模式):复用框架级 ``BasicAuthPlugin``,
|
||
``username="{email}/token"``,``password=api_token``。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pydantic import BaseModel, Field, model_validator
|
||
|
||
from yuxi.external_systems.integrations.schemas import IntegrationMetadata
|
||
|
||
ZENDESK_METADATA = IntegrationMetadata(
|
||
key="zendesk",
|
||
display_name="Zendesk",
|
||
description="客服 / 工单平台,基于 Support REST API 集成",
|
||
adapter_type="http",
|
||
source_types=["zendesk"],
|
||
supported_auth_types=[
|
||
"oauth2_authorization_code", # 标准 OAuth2
|
||
"basic", # API Token 模式(username="{email}/token", password=api_token)
|
||
],
|
||
tags=["customer_support", "ticketing", "crm"],
|
||
icon="zendesk",
|
||
docs_url="https://developer.zendesk.com/api-reference/",
|
||
connection_extra_schema={
|
||
"type": "object",
|
||
"properties": {
|
||
"subdomain": {"type": "string", "description": "Zendesk 子域名,如 acme"},
|
||
"base_url": {
|
||
"type": "string",
|
||
"description": "完整 base_url(优先级高于 subdomain)",
|
||
},
|
||
},
|
||
},
|
||
example_config={
|
||
"connection_config": {
|
||
"subdomain": "acme",
|
||
},
|
||
"auth_config": {
|
||
"auth_type": "basic",
|
||
"username": "agent@acme.com/token",
|
||
"password": "ref://zendesk/acme/api_token",
|
||
},
|
||
},
|
||
dependency_note=(
|
||
"1. 调用账号需对 tickets / users / organizations / ticket_fields / "
|
||
"user_fields / organization_fields / search 具备 READ 权限;"
|
||
"2. OAuth2 应用需在 Zendesk 后台注册并配置回调地址;"
|
||
"3. API Token 在 Zendesk 后台 Admin > Channels > API 中生成,"
|
||
"auth_type=basic,username='{email}/token',password=api_token;"
|
||
"4. api_token 建议使用 ref:// 密钥引用;"
|
||
"5. 通用 API 限流 OAuth2 700/min、basic 200/min,搜索 API 30/min。"
|
||
),
|
||
)
|
||
|
||
|
||
class ZendeskConnectionConfig(BaseModel):
|
||
"""Zendesk 连接配置 Schema(供前端动态表单与校验)。
|
||
|
||
``base_url`` 优先级高于 ``subdomain``,支持自定义域名场景。两者至少填写一项,
|
||
仅填写 ``subdomain`` 时自动拼接为 ``https://{subdomain}.zendesk.com``。
|
||
"""
|
||
|
||
subdomain: str | None = Field(
|
||
default=None,
|
||
description="Zendesk 子域名,如 acme(对应 https://acme.zendesk.com)",
|
||
)
|
||
base_url: str | None = Field(
|
||
default=None,
|
||
description="完整 base_url,优先级高于 subdomain;用于自定义域名或私有部署",
|
||
)
|
||
|
||
@model_validator(mode="after")
|
||
def _ensure_url(self) -> ZendeskConnectionConfig:
|
||
if not self.base_url and not self.subdomain:
|
||
raise ValueError("subdomain 与 base_url 至少填写一项")
|
||
if not self.base_url:
|
||
self.base_url = f"https://{self.subdomain}.zendesk.com"
|
||
return self
|
||
|
||
|
||
def resolve_oauth_endpoints(base_url: str) -> dict[str, str]:
|
||
"""根据 base_url 拼接 Zendesk 实例级 OAuth 端点。
|
||
|
||
Args:
|
||
base_url: Zendesk 实例 base_url(如 ``https://acme.zendesk.com``)。
|
||
|
||
Returns:
|
||
含 ``authorize_url`` / ``token_url`` 的字典,供 handler 注入到
|
||
``auth_config`` 后传给框架级 OAuth2 插件消费。
|
||
"""
|
||
return {
|
||
"authorize_url": f"{base_url}/oauth/authorizations/new",
|
||
"token_url": f"{base_url}/oauth/tokens",
|
||
}
|