84 lines
3.5 KiB
Python
84 lines
3.5 KiB
Python
import logging
|
||
|
||
from utils.metrics_tracker import emit as metrics_emit
|
||
|
||
logger = logging.getLogger("cs_agent")
|
||
|
||
|
||
async def transfer_to_human_flow(client, data: dict, transfer_msg: str = "", *, transfer_group_resolver=None):
|
||
"""
|
||
转接人工客服。
|
||
1. 优先调用 dispatch 服务 GET /assign 一键派单
|
||
2. 派单失败时,回退旧版 designer_roster 派单
|
||
3. 无人在线或未配置时,回退到 config/transfer_groups.json
|
||
设计师在线状态:仅在转人工时按需查询,不轮询。
|
||
"""
|
||
if not client.websocket:
|
||
logger.info("[%s] 错误: 未连接到服务器", client.get_time())
|
||
return
|
||
|
||
acc_id = data.get("acc_id", "")
|
||
group_id = None
|
||
assigned_to = ""
|
||
dispatch_res = await client._dispatch_assign_once()
|
||
if dispatch_res.get("success"):
|
||
assigned_to = str(dispatch_res.get("assigned_to", "") or "").strip()
|
||
logger.info(
|
||
"一键派单成功 | task_id=%s | assigned_to=%s | online_count=%s",
|
||
dispatch_res.get("task_id", ""),
|
||
assigned_to or "未知",
|
||
dispatch_res.get("online_count", 0),
|
||
)
|
||
metrics_emit(
|
||
"dispatch_assign_success",
|
||
acc_id=acc_id,
|
||
assigned_to=assigned_to,
|
||
online_count=dispatch_res.get("online_count", 0),
|
||
)
|
||
else:
|
||
logger.warning("一键派单失败,回退旧派单逻辑: %s", dispatch_res.get("reason", "unknown"))
|
||
metrics_emit("dispatch_assign_failed", acc_id=acc_id)
|
||
|
||
# 2. 派单失败时,回退旧版 designer_roster
|
||
if not dispatch_res.get("success"):
|
||
try:
|
||
from utils.designer_roster import poll_and_update_roster
|
||
from db.designer_roster_db import get_transfer_group_for_shop
|
||
await poll_and_update_roster()
|
||
group_id = get_transfer_group_for_shop(acc_id)
|
||
except Exception as e:
|
||
logger.debug("设计师派单未启用或异常: %s", e)
|
||
|
||
# 3. 无人在线时企微提醒(新旧两套都没拿到在线结果时)
|
||
online_count = int(dispatch_res.get("online_count", 0) or 0)
|
||
if online_count <= 0 and not group_id:
|
||
try:
|
||
from config.config import WECHAT_WEBHOOK
|
||
if WECHAT_WEBHOOK:
|
||
import httpx
|
||
|
||
async with httpx.AsyncClient(timeout=5) as c:
|
||
resp = await c.post(WECHAT_WEBHOOK, json={
|
||
"msgtype": "text",
|
||
"text": {"content": "谁在线啊"},
|
||
})
|
||
if resp.status_code != 200:
|
||
logger.warning("企微提醒发送失败: %s %s", resp.status_code, resp.text)
|
||
else:
|
||
logger.debug("未配置 WECHAT_WEBHOOK,跳过企微提醒")
|
||
except Exception as e:
|
||
logger.warning("企微提醒发送异常: %s", e)
|
||
|
||
# 4. 构造转接命令:有 assigned_to 用人名,否则回退分组
|
||
if assigned_to:
|
||
cmd = f"正在为你转接人工|[转移会话],{assigned_to},无原因"
|
||
await client.send_reply(data, cmd)
|
||
logger.info("[%s] 已发送转接请求 (店铺:%s -> 设计师:%s)", client.get_time(), acc_id or "未知", assigned_to)
|
||
return
|
||
|
||
if not group_id:
|
||
group_id = transfer_group_resolver(acc_id) if transfer_group_resolver else "20252916034"
|
||
cmd = f"话术|[转移会话],分组{group_id},无原因"
|
||
await client.send_reply(data, cmd)
|
||
logger.info("[%s] 已发送转接请求 (店铺:%s -> 分组:%s)", client.get_time(), acc_id or "未知", group_id)
|