feat: use assigned_to transfer command when dispatch assign succeeds
This commit is contained in:
@@ -1307,11 +1307,45 @@ class QingjianAPIClient:
|
||||
image_data['msg_type'] = 0 # 转为文本消息,让 agent_reply 处理
|
||||
self._fire_and_forget(self._agent_reply_serialized(image_data))
|
||||
|
||||
async def _dispatch_assign_once(self) -> Dict[str, Any]:
|
||||
"""
|
||||
调用新的一键派单接口:
|
||||
GET {DISPATCH_BASE_URL}/assign
|
||||
Header: X-API-Key
|
||||
"""
|
||||
base_url = os.getenv("DISPATCH_BASE_URL", "http://1.12.50.92:8006").strip().rstrip("/")
|
||||
api_key = os.getenv("DISPATCH_API_KEY", "tuhui_dispatch_key_2026").strip()
|
||||
timeout_s = float(os.getenv("DISPATCH_TIMEOUT_SECONDS", "5"))
|
||||
if not base_url or not api_key:
|
||||
return {"success": False, "reason": "dispatch config missing"}
|
||||
try:
|
||||
import httpx
|
||||
async with httpx.AsyncClient(timeout=timeout_s) as client:
|
||||
resp = await client.get(
|
||||
f"{base_url}/assign",
|
||||
headers={"X-API-Key": api_key},
|
||||
)
|
||||
if resp.status_code != 200:
|
||||
return {"success": False, "reason": f"http {resp.status_code}"}
|
||||
data = resp.json() if resp.content else {}
|
||||
ok = bool((data or {}).get("success", False))
|
||||
return {
|
||||
"success": ok,
|
||||
"task_id": str((data or {}).get("task_id", "") or ""),
|
||||
"assigned_to": str((data or {}).get("assigned_to", "") or ""),
|
||||
"online_count": int((data or {}).get("online_count", 0) or 0),
|
||||
"notification_sent": bool((data or {}).get("notification_sent", False)),
|
||||
"raw": data,
|
||||
}
|
||||
except Exception as e:
|
||||
return {"success": False, "reason": str(e)}
|
||||
|
||||
async def transfer_to_human(self, data: dict, transfer_msg: str = ""):
|
||||
"""
|
||||
转接人工客服。
|
||||
1. 优先从 designer_roster 轮询派单(在线设计师)
|
||||
2. 无人在线或未配置时,回退到 config/transfer_groups.json
|
||||
1. 优先调用 dispatch 服务 GET /assign 一键派单
|
||||
2. 派单失败时,回退旧版 designer_roster 派单
|
||||
3. 无人在线或未配置时,回退到 config/transfer_groups.json
|
||||
设计师在线状态:仅在转人工时按需查询,不轮询。
|
||||
"""
|
||||
if not self.websocket:
|
||||
@@ -1320,18 +1354,36 @@ class QingjianAPIClient:
|
||||
|
||||
acc_id = data.get("acc_id", "")
|
||||
group_id = None
|
||||
assigned_to = ""
|
||||
dispatch_res = await self._dispatch_assign_once()
|
||||
if dispatch_res.get("success"):
|
||||
assigned_to = str(dispatch_res.get("assigned_to", "") or "").strip()
|
||||
logger.info(
|
||||
f"一键派单成功 | task_id={dispatch_res.get('task_id','')} | assigned_to={assigned_to or '未知'} | online_count={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(f"一键派单失败,回退旧派单逻辑: {dispatch_res.get('reason', 'unknown')}")
|
||||
metrics_emit("dispatch_assign_failed", acc_id=acc_id)
|
||||
|
||||
# 1. 转人工时按需查询设计师在线状态(调用另一台 AI 的查询服务),再派单
|
||||
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(f"设计师派单未启用或异常: {e}")
|
||||
# 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(f"设计师派单未启用或异常: {e}")
|
||||
|
||||
# 2. 无人在线时企微提醒
|
||||
if not group_id:
|
||||
# 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:
|
||||
@@ -1348,13 +1400,15 @@ class QingjianAPIClient:
|
||||
except Exception as e:
|
||||
logger.warning(f"企微提醒发送异常: {e}")
|
||||
|
||||
# 3. 回退到静态配置
|
||||
# 4. 构造转接命令:有 assigned_to 用人名,否则回退分组
|
||||
if assigned_to:
|
||||
cmd = f"正在为你转接人工|[转移会话],{assigned_to},无原因"
|
||||
await self.send_reply(data, cmd)
|
||||
print(f"[{self.get_time()}] 已发送转接请求 (店铺:{acc_id or '未知'} -> 设计师:{assigned_to})")
|
||||
return
|
||||
|
||||
if not group_id:
|
||||
group_id = _get_transfer_group(acc_id)
|
||||
|
||||
# 先发一条提示语给客户
|
||||
await self.send_reply(data, "亲,正在为您转接人工客服,请稍等~")
|
||||
|
||||
cmd = f"话术|[转移会话],分组{group_id},无原因"
|
||||
await self.send_reply(data, cmd)
|
||||
print(f"[{self.get_time()}] 已发送转接请求 (店铺:{acc_id or '未知'} -> 分组:{group_id})")
|
||||
|
||||
Reference in New Issue
Block a user