实现抖音转接客服
This commit is contained in:
@@ -117,23 +117,33 @@ class DouYinBackendService:
|
|||||||
or self.current_store_id
|
or self.current_store_id
|
||||||
or '')
|
or '')
|
||||||
|
|
||||||
msg_type = platform_message.get('msg_type', 'text')
|
# 检查消息类型,如果是特殊类型(如staff_list),保持原格式
|
||||||
content_for_backend = platform_message.get('content', '')
|
message_type = platform_message.get('type', 'message')
|
||||||
|
|
||||||
pin_image = platform_message.get('pin_image')
|
if message_type == 'staff_list':
|
||||||
if not pin_image:
|
# 对于客服列表消息,直接转发原始格式
|
||||||
pin_image = ""
|
msg = platform_message.copy()
|
||||||
|
# 确保store_id正确
|
||||||
|
msg['store_id'] = store_id
|
||||||
else:
|
else:
|
||||||
pass
|
# 对于普通消息,使用原有的格式转换逻辑
|
||||||
# 构造标准消息格式
|
msg_type = platform_message.get('msg_type', 'text')
|
||||||
msg = {
|
content_for_backend = platform_message.get('content', '')
|
||||||
'type': 'message',
|
|
||||||
'content': content_for_backend,
|
pin_image = platform_message.get('pin_image')
|
||||||
'pin_image': pin_image,
|
if not pin_image:
|
||||||
'msg_type': msg_type,
|
pin_image = ""
|
||||||
'sender': {'id': sender_id},
|
else:
|
||||||
'store_id': store_id
|
pass
|
||||||
}
|
# 构造标准消息格式
|
||||||
|
msg = {
|
||||||
|
'type': 'message',
|
||||||
|
'content': content_for_backend,
|
||||||
|
'pin_image': pin_image,
|
||||||
|
'msg_type': msg_type,
|
||||||
|
'sender': {'id': sender_id},
|
||||||
|
'store_id': store_id
|
||||||
|
}
|
||||||
|
|
||||||
backend.send_message(msg)
|
backend.send_message(msg)
|
||||||
return None
|
return None
|
||||||
@@ -302,7 +312,9 @@ class DouYinMessageHandler:
|
|||||||
# 发送到后端
|
# 发送到后端
|
||||||
await self.ai_service.send_message_to_backend(message_template.to_dict())
|
await self.ai_service.send_message_to_backend(message_template.to_dict())
|
||||||
self._log(f"发送客服列表消息的结构体为: {message_template.to_json()}")
|
self._log(f"发送客服列表消息的结构体为: {message_template.to_json()}")
|
||||||
self._log(f"✅ 成功发送客服列表到后端,共 {len(staff_infos)} 个客服", "SUCCESS")
|
self._log(f"✅ [DY] 成功发送客服列表到后端,共 {len(staff_infos)} 个客服", "SUCCESS")
|
||||||
|
print(f"🔥 [DY] 客服列表已上传到后端: {len(staff_infos)} 个客服")
|
||||||
|
print(f"[DY] 客服详情: {[{'id': s['staff_id'], 'name': s['name']} for s in staff_infos]}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1823,6 +1835,17 @@ class DouYinListenerForGUI:
|
|||||||
if not message_handler_success:
|
if not message_handler_success:
|
||||||
self._log("❌ 消息处理器启动失败", "ERROR")
|
self._log("❌ 消息处理器启动失败", "ERROR")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# 发送客服列表到后端
|
||||||
|
try:
|
||||||
|
staff_list_success = await self.douyin_bot.message_handler.send_staff_list_to_backend()
|
||||||
|
if staff_list_success:
|
||||||
|
print(f"🔥 [DY] 客服列表已上传到后端")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ [DY] 客服列表上传失败")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ [DY] 客服列表上传异常: {e}")
|
||||||
|
self._log(f"❌ 抖音客服列表上传异常: {e}", "ERROR")
|
||||||
|
|
||||||
# 注册到全局管理器
|
# 注册到全局管理器
|
||||||
dy_manager = DouYinWebsocketManager()
|
dy_manager = DouYinWebsocketManager()
|
||||||
|
|||||||
@@ -574,7 +574,8 @@ class ChatPdd:
|
|||||||
# 通过后端服务发送
|
# 通过后端服务发送
|
||||||
await self.backend_service.send_message_to_backend(message_template.to_dict())
|
await self.backend_service.send_message_to_backend(message_template.to_dict())
|
||||||
self._log(f"发送客服列表消息的结构体为: {message_template.to_json()}")
|
self._log(f"发送客服列表消息的结构体为: {message_template.to_json()}")
|
||||||
self._log(f"✅ 成功发送客服列表到后端,共 {len(self.customer_list)} 个客服", "SUCCESS")
|
self._log(f"✅ [PDD] 成功发送客服列表到后端,共 {len(self.customer_list)} 个客服", "SUCCESS")
|
||||||
|
print(f"🔥 [PDD] 客服列表已上传到后端: {len(self.customer_list)} 个客服")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -660,6 +660,150 @@ class BackendClient:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[PDD Transfer] 拼多多转接失败: {e}")
|
print(f"[PDD Transfer] 拼多多转接失败: {e}")
|
||||||
|
|
||||||
|
def _transfer_to_jd(self, customer_service_id: str, user_id: str, store_id: str):
|
||||||
|
"""执行京东平台转接操作"""
|
||||||
|
try:
|
||||||
|
from Utils.JD.JdUtils import WebsocketManager as JDWSManager
|
||||||
|
jd_mgr = JDWSManager()
|
||||||
|
shop_key = f"京东:{store_id}"
|
||||||
|
entry = jd_mgr.get_connection(shop_key)
|
||||||
|
|
||||||
|
if not entry:
|
||||||
|
print(f"[JD Transfer] 未找到京东连接: {shop_key}")
|
||||||
|
return
|
||||||
|
|
||||||
|
platform_info = entry.get('platform', {})
|
||||||
|
websocket = platform_info.get('ws') # 京东使用'ws'字段
|
||||||
|
aid = platform_info.get('aid', '')
|
||||||
|
pin_zj = platform_info.get('pin_zj', '')
|
||||||
|
|
||||||
|
print(f"[JD Transfer] 找到京东连接,准备执行转接: user_id={user_id}, cs_id={customer_service_id}")
|
||||||
|
print(f"[JD Transfer] 连接信息: has_ws={bool(websocket)}, aid={aid}, pin_zj={pin_zj}")
|
||||||
|
|
||||||
|
if websocket:
|
||||||
|
# 执行转接操作
|
||||||
|
def transfer_in_loop():
|
||||||
|
try:
|
||||||
|
# 导入京东工具类
|
||||||
|
from Utils.JD.JdUtils import FixJdCookie
|
||||||
|
|
||||||
|
# 创建临时实例用于转接
|
||||||
|
jd_instance = FixJdCookie()
|
||||||
|
|
||||||
|
# 执行转接操作
|
||||||
|
loop = asyncio.new_event_loop()
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
|
try:
|
||||||
|
result = loop.run_until_complete(
|
||||||
|
jd_instance.transfer_customer(
|
||||||
|
websocket, aid, user_id, pin_zj, customer_service_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
print(f"[JD Transfer] ✅ 转接成功: user_id={user_id} -> cs_id={customer_service_id}")
|
||||||
|
else:
|
||||||
|
print(f"[JD Transfer] ❌ 转接失败: user_id={user_id}")
|
||||||
|
finally:
|
||||||
|
loop.close()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[JD Transfer] 转接过程异常: {e}")
|
||||||
|
|
||||||
|
# 在新线程中执行转接操作
|
||||||
|
import threading
|
||||||
|
transfer_thread = threading.Thread(target=transfer_in_loop, daemon=True)
|
||||||
|
transfer_thread.start()
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"[JD Transfer] 条件不足: has_ws={bool(websocket)}, aid='{aid}', pin_zj='{pin_zj}'")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[JD Transfer] 京东转接失败: {e}")
|
||||||
|
|
||||||
|
def _transfer_to_dy(self, customer_service_id: str, user_id: str, store_id: str):
|
||||||
|
"""执行抖音平台转接操作"""
|
||||||
|
try:
|
||||||
|
from Utils.Dy.DyUtils import DouYinWebsocketManager as DYWSManager
|
||||||
|
dy_mgr = DYWSManager()
|
||||||
|
shop_key = f"抖音:{store_id}"
|
||||||
|
entry = dy_mgr.get_connection(shop_key)
|
||||||
|
|
||||||
|
if not entry:
|
||||||
|
print(f"[DY Transfer] 未找到抖音连接: {shop_key}")
|
||||||
|
return
|
||||||
|
|
||||||
|
platform_info = entry.get('platform', {})
|
||||||
|
dy_instance = platform_info.get('douyin_bot') # 修正字段名称
|
||||||
|
cookie_dict = platform_info.get('cookie', {})
|
||||||
|
|
||||||
|
print(f"[DY Transfer] 找到抖音连接,准备执行转接: user_id={user_id}, cs_id={customer_service_id}")
|
||||||
|
print(f"[DY Transfer] 连接信息: has_douyin_bot={bool(dy_instance)}, has_cookie={bool(cookie_dict)}")
|
||||||
|
|
||||||
|
if dy_instance:
|
||||||
|
# 执行转接操作
|
||||||
|
def transfer_in_loop():
|
||||||
|
try:
|
||||||
|
# 抖音转接通过message_handler执行
|
||||||
|
if dy_instance and hasattr(dy_instance, 'message_handler') and dy_instance.message_handler:
|
||||||
|
# 获取实际的抖音店铺ID(从cookie中获取)
|
||||||
|
shop_id = cookie_dict.get('SHOP_ID', store_id) # 优先使用cookie中的SHOP_ID
|
||||||
|
print(f"[DY Transfer] 使用shop_id: {shop_id}")
|
||||||
|
print(f"[DY Transfer] 转接参数: receiver_id={user_id}, shop_id={shop_id}, staff_id={customer_service_id}")
|
||||||
|
|
||||||
|
# 检查是否是自己转给自己的情况
|
||||||
|
try:
|
||||||
|
# 获取可用客服列表来验证
|
||||||
|
staff_list = dy_instance.message_handler.get_casl()
|
||||||
|
if staff_list:
|
||||||
|
print(f"[DY Transfer] 当前可用客服数量: {len(staff_list)}")
|
||||||
|
if len(staff_list) <= 1:
|
||||||
|
print(f"[DY Transfer] ⚠️ 只有一个客服在线,可能无法转接")
|
||||||
|
|
||||||
|
# 查找目标客服信息
|
||||||
|
target_staff = None
|
||||||
|
for staff in staff_list:
|
||||||
|
if str(staff.get('staffId', '')) == str(customer_service_id):
|
||||||
|
target_staff = staff
|
||||||
|
break
|
||||||
|
|
||||||
|
if target_staff:
|
||||||
|
print(f"[DY Transfer] 找到目标客服: {target_staff.get('staffName', 'Unknown')} (ID: {customer_service_id})")
|
||||||
|
else:
|
||||||
|
print(f"[DY Transfer] ⚠️ 未找到目标客服ID: {customer_service_id}")
|
||||||
|
print(f"[DY Transfer] 可用客服列表: {[{'id': s.get('staffId'), 'name': s.get('staffName')} for s in staff_list]}")
|
||||||
|
else:
|
||||||
|
print(f"[DY Transfer] ⚠️ 无法获取客服列表")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[DY Transfer] 获取客服列表时出错: {e}")
|
||||||
|
|
||||||
|
# 执行同步转接操作
|
||||||
|
result = dy_instance.message_handler.transfer_conversation(
|
||||||
|
receiver_id=user_id,
|
||||||
|
shop_id=shop_id,
|
||||||
|
staff_id=customer_service_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
print(f"[DY Transfer] ✅ 转接成功: user_id={user_id} -> cs_id={customer_service_id}")
|
||||||
|
else:
|
||||||
|
print(f"[DY Transfer] ❌ 转接失败: user_id={user_id}")
|
||||||
|
print(f"[DY Transfer] 💡 可能原因:1) 只有一个客服无法转接 2) 客服ID不存在 3) 权限不足 4) 会话状态不允许转接")
|
||||||
|
else:
|
||||||
|
print(f"[DY Transfer] ⚠️ 抖音实例或message_handler不可用")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[DY Transfer] 转接过程异常: {e}")
|
||||||
|
|
||||||
|
# 在新线程中执行转接操作
|
||||||
|
import threading
|
||||||
|
transfer_thread = threading.Thread(target=transfer_in_loop, daemon=True)
|
||||||
|
transfer_thread.start()
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"[DY Transfer] 条件不足: has_douyin_bot={bool(dy_instance)}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[DY Transfer] 抖音转接失败: {e}")
|
||||||
|
|
||||||
def _transfer_to_qianniu(self, customer_service_id: str, user_id: str, store_id: str):
|
def _transfer_to_qianniu(self, customer_service_id: str, user_id: str, store_id: str):
|
||||||
"""执行千牛平台转接操作"""
|
"""执行千牛平台转接操作"""
|
||||||
try:
|
try:
|
||||||
@@ -683,11 +827,11 @@ class BackendClient:
|
|||||||
platform_type = self._get_platform_by_store_id(store_id)
|
platform_type = self._get_platform_by_store_id(store_id)
|
||||||
|
|
||||||
if platform_type == "京东":
|
if platform_type == "京东":
|
||||||
# 京东转接逻辑 - 待实现
|
# 京东转接逻辑
|
||||||
print(f"[JD Transfer] 京东平台转接功能待实现")
|
self._transfer_to_jd(customer_service_id, user_id, store_id)
|
||||||
elif platform_type == "抖音":
|
elif platform_type == "抖音":
|
||||||
# 抖音转接逻辑 - 待实现
|
# 抖音转接逻辑
|
||||||
print(f"[DY Transfer] 抖音平台转接功能待实现")
|
self._transfer_to_dy(customer_service_id, user_id, store_id)
|
||||||
elif platform_type == "千牛":
|
elif platform_type == "千牛":
|
||||||
# 千牛转接逻辑
|
# 千牛转接逻辑
|
||||||
self._transfer_to_qianniu(customer_service_id, user_id, store_id)
|
self._transfer_to_qianniu(customer_service_id, user_id, store_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user