ForcePilot/backend/package/yuxi/channel/extensions/taobao/outbound.py
Kris 904ab9a6c2 feat(channel): 添加淘宝渠道扩展
新增淘宝(Taobao)渠道扩展,支持在 Yuxi 平台中集成淘宝电商客服渠道。

包含以下功能模块:
- client: 淘宝 API 客户端封装
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- webhook: Webhook 事件处理
- outbound: 外发消息管理
- message: 消息处理
- pairing: 用户配对与绑定
- security: 安全校验
- crypto: 加解密处理
- status: 会话状态管理
- tools: Agent 工具集成
- types: 类型定义
2026-05-21 11:46:45 +08:00

90 lines
2.2 KiB
Python

import logging
from yuxi.channel.extensions.taobao.client import TaobaoAPIError, TaobaoClient
logger = logging.getLogger(__name__)
MAX_TEXT_LENGTH = 2000
_GLOBAL_CLIENT: TaobaoClient | None = None
def set_global_client(client: TaobaoClient | None) -> None:
global _GLOBAL_CLIENT
_GLOBAL_CLIENT = client
def get_client() -> TaobaoClient | None:
return _GLOBAL_CLIENT
async def send_text(
target_id: str,
content: str,
*,
reply_to_id: str | None = None,
thread_id: str | None = None,
account_id: str | None = None,
session: str | None = None,
) -> None:
client = _GLOBAL_CLIENT
if client is None:
logger.error("Taobao client not initialized")
return
try:
resp = await client.send_customer_message(
to_user=target_id,
content=content[:MAX_TEXT_LENGTH],
msg_type=0,
session=session,
)
logger.debug("Taobao message sent to %s: %s", target_id, resp)
except TaobaoAPIError as e:
logger.error("Taobao send_text failed to %s: %s", target_id, e)
async def send_media(
target_id: str,
media_url: str,
media_type: str,
*,
reply_to_id: str | None = None,
thread_id: str | None = None,
session: str | None = None,
) -> None:
client = _GLOBAL_CLIENT
if client is None:
logger.error("Taobao client not initialized")
return
msg_type = _media_type_to_int(media_type)
try:
await client.send_customer_message(
to_user=target_id,
content="",
msg_type=msg_type,
media_id=media_url,
session=session,
)
except TaobaoAPIError as e:
logger.error("Taobao send_media failed to %s: %s", target_id, e)
def _media_type_to_int(media_type: str) -> int:
mapping = {"image": 1, "file": 4}
return mapping.get(media_type, 1)
def chunk_text(text: str, limit: int = MAX_TEXT_LENGTH) -> list[str]:
chunks = []
while len(text) > limit:
split_at = text.rfind("\n", 0, limit)
if split_at == -1:
split_at = limit
chunks.append(text[:split_at])
text = text[split_at:].lstrip("\n")
if text:
chunks.append(text)
return chunks