You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Twilio呼叫转接问题:IVR连坐席未接听时转下一位的实现

解决Twilio通过IVR转接坐席时无人接听自动流转的问题

问题核心

需要将呼叫通过IVR(发送指定按键)转接坐席,若当前坐席无人接听则自动转至下一位。但实际中,IVR会先接听呼叫,即使坐席4铃未接,挂断后<Dial>状态仍为completed,无法触发原有的超时/无人接听逻辑,导致无法自动转下一位。

原因分析

Twilio的<Dial>状态是基于你拨打的**目标号码(即IVR号码)**的状态判断的:IVR已经接听了呼叫,所以无论后续坐席是否接听,<Dial>都会返回completed状态,而非预期的no-answer,原逻辑无法区分“IVR接听但坐席未接”和“坐席实际接听后挂断”两种场景。

解决方案

通过结合<Dial>的通话时长(DialCallDuration)来区分两种场景:

  • 维护一个坐席队列,记录每个坐席对应的IVR号码和按键序列
  • 在<Dial>的action回调中,除了判断DialCallStatus,还检查通话时长:
    • 若DialCallStatus为completed但时长远短于正常通话(比如小于10秒),判定为坐席未接听,继续转下一位
    • 若时长超过阈值,判定为坐席正常接听后挂断,结束流程
  • 调整<Dial>的timeout参数,确保足够IVR完成转接到坐席的流程(比如设为30秒,覆盖4铃+IVR转接时间)

修改后的代码示例

const twiml = new Twilio.twiml.VoiceResponse();
const functionPath = '/your-twilio-function-path'; // 替换为实际的Twilio Function路径

// 维护坐席队列:每个元素包含IVR号码和对应的按键
const agentQueue = [
  { ivrNumber: 'IVR号码1', digits: 'www3' },
  { ivrNumber: 'IVR号码2', digits: 'www4' },
  // 更多坐席...
];

// 获取当前要转接的坐席索引(可通过event参数传递,比如从query参数或存储的上下文获取)
let currentAgentIndex = parseInt(event.currentAgentIndex) || 0;

if (event.reason === "dialStatus") {
  const callStatus = event.DialCallStatus;
  const callDuration = parseInt(event.DialCallDuration) || 0;
  
  // 判定坐席未接听的条件:无应答/忙线,或completed但时长过短
  const shouldForwardToNextAgent = 
    (callStatus === "no-answer" || callStatus === "busy") || 
    (callStatus === "completed" && callDuration < 10);

  if (shouldForwardToNextAgent && currentAgentIndex < agentQueue.length - 1) {
    // 取下一位坐席
    currentAgentIndex++;
    const nextAgent = agentQueue[currentAgentIndex];
    const dial = twiml.dial({
      timeout: '30', // 延长超时,覆盖IVR转接坐席的时间
      action: `${functionPath}?reason=dialStatus&currentAgentIndex=${currentAgentIndex}`,
      hangupOnStar: true
    });
    dial.number({ sendDigits: nextAgent.digits }, nextAgent.ivrNumber);
  } else {
    // 所有坐席都尝试过,或坐席正常接听后挂断,结束呼叫
    twiml.hangup();
  }
  return callback(null, twiml);
}

// 首次呼叫:转第一个坐席
const firstAgent = agentQueue[currentAgentIndex];
const dial = twiml.dial({
  timeout: '30',
  action: `${functionPath}?reason=dialStatus&currentAgentIndex=${currentAgentIndex}`,
  hangupOnStar: true
});
dial.number({ sendDigits: firstAgent.digits }, firstAgent.ivrNumber);

callback(null, twiml);

关键说明

  • 坐席队列管理:通过currentAgentIndex跟踪当前尝试的坐席,每次失败后索引递增,直到所有坐席尝试完毕
  • 时长阈值:10秒是参考值,可根据你的IVR转接坐席的实际耗时调整(比如IVR转坐席需要5秒,坐席振铃4铃约20秒,总时长若低于25秒可判定为未接听)
  • Timeout参数:设为30秒确保IVR有足够时间完成转接流程,避免提前触发超时

内容的提问来源于stack exchange,提问作者Umair Ameen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:40:24