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)