新增淘宝(Taobao)渠道扩展,支持在 Yuxi 平台中集成淘宝电商客服渠道。 包含以下功能模块: - client: 淘宝 API 客户端封装 - config: 渠道配置管理 - gateway: SSE/WebSocket 网关接入 - webhook: Webhook 事件处理 - outbound: 外发消息管理 - message: 消息处理 - pairing: 用户配对与绑定 - security: 安全校验 - crypto: 加解密处理 - status: 会话状态管理 - tools: Agent 工具集成 - types: 类型定义
73 lines
2.5 KiB
Python
73 lines
2.5 KiB
Python
import logging
|
|
import random
|
|
import string
|
|
import time
|
|
from collections import defaultdict
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
CODE_LENGTH = 6
|
|
CODE_TTL_SECONDS = 600
|
|
|
|
|
|
class TaobaoPairing:
|
|
id_label = "buyer_nick"
|
|
|
|
def __init__(self):
|
|
self._codes: dict[str, dict[str, tuple[str, float]]] = defaultdict(dict)
|
|
|
|
async def generate_code(self, peer_id: str, account_id: str = "default") -> str:
|
|
code = "".join(random.choices(string.digits, k=CODE_LENGTH))
|
|
self._codes[account_id][code] = (peer_id, time.monotonic())
|
|
self._cleanup_expired(account_id)
|
|
logger.info("Pairing code generated for %s:%s: %s", account_id, peer_id, code)
|
|
return code
|
|
|
|
async def verify_code(self, peer_id: str, code: str, account_id: str = "default") -> bool:
|
|
self._cleanup_expired(account_id)
|
|
|
|
account_codes = self._codes.get(account_id, {})
|
|
entry = account_codes.get(code)
|
|
if entry is None:
|
|
return False
|
|
|
|
stored_peer_id, created_at = entry
|
|
if time.monotonic() - created_at > CODE_TTL_SECONDS:
|
|
account_codes.pop(code, None)
|
|
return False
|
|
|
|
if stored_peer_id != peer_id:
|
|
return False
|
|
|
|
account_codes.pop(code, None)
|
|
logger.info("Pairing code verified for %s:%s", account_id, peer_id)
|
|
return True
|
|
|
|
def normalize_allow_entry(self, entry: str) -> str:
|
|
return entry.strip().lower()
|
|
|
|
async def notify_approval(self, config: dict, peer_id: str, account_id: str | None = None) -> None:
|
|
logger.info("Pairing approval notification for %s:%s", account_id, peer_id)
|
|
try:
|
|
from yuxi.channel.extensions.taobao.outbound import get_client
|
|
|
|
client = get_client()
|
|
if client is None:
|
|
logger.warning("Cannot notify approval: client not initialized")
|
|
return
|
|
|
|
await client.send_customer_message(
|
|
to_user=peer_id,
|
|
content="您的配对已通过审批,现在可以开始与我对话了!请问有什么可以帮助您的?",
|
|
msg_type=0,
|
|
)
|
|
except Exception as e:
|
|
logger.error("Failed to send approval notification to %s: %s", peer_id, e)
|
|
|
|
def _cleanup_expired(self, account_id: str):
|
|
now = time.monotonic()
|
|
account_codes = self._codes.get(account_id, {})
|
|
expired = [k for k, (_, created) in account_codes.items() if now - created > CODE_TTL_SECONDS]
|
|
for k in expired:
|
|
account_codes.pop(k, None)
|