ForcePilot/backend/package/yuxi/channel/extensions/lazada/session.py
Kris d523babb91 feat(channel): 添加 Lazada 渠道扩展
新增 Lazada 渠道扩展,支持在 Yuxi 平台中集成 Lazada 电商客服渠道。

包含以下功能模块:
- client: Lazada API 客户端封装
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- webhook: Webhook 事件处理
- outbound: 外发消息管理
- pairing: 用户配对与绑定
- security: 安全校验
- signature: 请求签名验证
- dedupe: 消息去重
- monitor: 渠道状态监控
- status: 会话状态管理
- session: 会话管理
- tools: Agent 工具集成
- tools_config: 工具配置
- types: 类型定义
2026-05-21 11:13:39 +08:00

115 lines
4.4 KiB
Python

from __future__ import annotations
import logging
from yuxi.channel.extensions.lazada.client import LazadaAPIError
from yuxi.channel.extensions.lazada.gateway import LazadaGateway
from yuxi.channel.extensions.lazada.types import SessionInfo
logger = logging.getLogger(__name__)
class LazadaSessionManager:
def __init__(self, gateway: LazadaGateway):
self._gateway = gateway
self._sessions: dict[str, SessionInfo] = {}
self._buyer_sessions: dict[str, str] = {}
async def list_sessions(
self,
page_size: int = 20,
start_time: str | None = None,
) -> list[SessionInfo]:
try:
params = {"page_size": str(page_size)}
if start_time:
params["start_time"] = start_time
resp = await self._gateway.client.call(
"/im/session/list",
params=params,
)
sessions_data = resp.get("data", {}).get("sessions", [])
result = []
for s in sessions_data:
info = SessionInfo(
session_id=s.get("session_id", ""),
buyer_id=s.get("buyer_id", ""),
seller_id=s.get("seller_id", ""),
last_message_time=s.get("last_message_time", 0),
last_buyer_reply_time=s.get("last_buyer_reply_time", 0),
unread_count=s.get("unread_count", 0),
is_active=s.get("is_active", True),
site_id=s.get("site_id", self._gateway.account.site_code if self._gateway.account else "SG"),
)
self._sessions[info.session_id] = info
self._buyer_sessions[info.buyer_id] = info.session_id
result.append(info)
return result
except LazadaAPIError:
logger.exception("获取 Lazada 会话列表失败")
return []
async def get_session(self, session_id: str) -> SessionInfo | None:
try:
resp = await self._gateway.client.call(
"/im/session/get",
params={"session_id": session_id},
)
data = resp.get("data", {})
info = SessionInfo(
session_id=data.get("session_id", session_id),
buyer_id=data.get("buyer_id", ""),
seller_id=data.get("seller_id", ""),
last_message_time=data.get("last_message_time", 0),
last_buyer_reply_time=data.get("last_buyer_reply_time", 0),
unread_count=data.get("unread_count", 0),
is_active=data.get("is_active", True),
site_id=data.get("site_id", self._gateway.account.site_code if self._gateway.account else "SG"),
)
self._sessions[info.session_id] = info
return info
except LazadaAPIError:
return None
async def read_session(self, session_id: str) -> bool:
try:
await self._gateway.client.call(
"/im/session/read",
method="POST",
params={"session_id": session_id},
)
if session_id in self._sessions:
self._sessions[session_id].unread_count = 0
return True
except LazadaAPIError:
return False
async def open_session(self, order_id: str) -> str | None:
try:
resp = await self._gateway.client.call(
"/im/session/open",
method="POST",
params={"order_id": order_id},
)
data = resp.get("data", {})
session_id = data.get("session_id", "")
if session_id:
info = SessionInfo(
session_id=session_id,
buyer_id=data.get("buyer_id", ""),
seller_id=self._gateway.account.seller_id if self._gateway.account else "",
is_active=True,
site_id=self._gateway.account.site_code if self._gateway.account else "SG",
)
self._sessions[session_id] = info
return session_id
except LazadaAPIError:
return None
def resolve_session(self, peer_id: str) -> str | None:
return self._buyer_sessions.get(peer_id) or (peer_id if peer_id in self._sessions else None)
def get_daily_limit(self, session_id: str) -> int:
return self._gateway.get_daily_message_limit(session_id)