新增拼多多(Pinduoduo)渠道扩展,支持在 Yuxi 平台中集成拼多多电商客服渠道。 包含以下功能模块: - client: 拼多多 API 客户端封装 - config: 渠道配置管理 - gateway: SSE/WebSocket 网关接入 - webhook: Webhook 事件处理 - outbound: 外发消息管理 - pairing: 用户配对与绑定 - security: 安全校验 - signature: 请求签名验证 - token: Token 管理 - dedupe: 消息去重 - monitor: 渠道状态监控 - status: 会话状态管理 - tools: Agent 工具集成 - window: 窗口管理 - types: 类型定义
93 lines
2.9 KiB
Python
93 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from yuxi.channel.extensions.pinduoduo.client import PddCSClient
|
|
from yuxi.channel.extensions.pinduoduo.format import (
|
|
pdd_split_long_text,
|
|
pdd_strip_markdown,
|
|
)
|
|
from yuxi.channel.extensions.pinduoduo.types import PinduoduoAccount
|
|
from yuxi.channel.extensions.pinduoduo.window import PinduoduoWindowTracker
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PinduoduoOutbound:
|
|
def __init__(
|
|
self,
|
|
cs_client: PddCSClient,
|
|
account: PinduoduoAccount,
|
|
window_tracker: PinduoduoWindowTracker | None = None,
|
|
):
|
|
self._cs = cs_client
|
|
self._account = account
|
|
self._window_tracker = window_tracker
|
|
|
|
async def send_text(
|
|
self,
|
|
session_id: str,
|
|
buyer_id: str,
|
|
content: str,
|
|
) -> None:
|
|
if self._window_tracker and not self._window_tracker.can_reply(buyer_id):
|
|
logger.warning(
|
|
"48h 窗口期已过,跳过发送 buyer=%s session=%s",
|
|
buyer_id,
|
|
session_id,
|
|
)
|
|
return
|
|
|
|
clean = pdd_strip_markdown(content)
|
|
|
|
if len(clean) <= 2000:
|
|
await self._send_single(session_id, buyer_id, clean)
|
|
else:
|
|
chunks = pdd_split_long_text(clean)
|
|
for chunk in chunks:
|
|
await self._send_single(session_id, buyer_id, chunk)
|
|
|
|
async def _send_single(self, session_id: str, buyer_id: str, text: str) -> None:
|
|
try:
|
|
await self._cs.send_text(
|
|
session_id=session_id,
|
|
from_user=self._account.mall_id,
|
|
to_user=buyer_id,
|
|
mall_id=self._account.mall_id,
|
|
content=text,
|
|
)
|
|
except Exception:
|
|
logger.exception(
|
|
"Failed to send text to buyer=%s in session=%s",
|
|
buyer_id,
|
|
session_id,
|
|
)
|
|
|
|
async def send_image(self, session_id: str, buyer_id: str, image_url: str) -> None:
|
|
try:
|
|
await self._cs.send_image(
|
|
session_id=session_id,
|
|
from_user=self._account.mall_id,
|
|
to_user=buyer_id,
|
|
mall_id=self._account.mall_id,
|
|
image_url=image_url,
|
|
)
|
|
except Exception:
|
|
logger.exception("Failed to send image to buyer=%s", buyer_id)
|
|
|
|
async def send_order_card(self, session_id: str, buyer_id: str, order_sn: str) -> None:
|
|
try:
|
|
await self._cs.send_order_card(
|
|
session_id=session_id,
|
|
from_user=self._account.mall_id,
|
|
to_user=buyer_id,
|
|
mall_id=self._account.mall_id,
|
|
order_sn=order_sn,
|
|
)
|
|
except Exception:
|
|
logger.exception(
|
|
"Failed to send order card to buyer=%s, order=%s",
|
|
buyer_id,
|
|
order_sn,
|
|
)
|