Twilio呼叫转接时播放等待语音并收集用户输入的实现问题
正确实现思路
你之前的写法问题在于Twilio的TwiML是按顺序执行的——先执行<Dial>,只有当转接失败(比如对方拒接、超时)才会走到后面的<Enqueue>,这根本没法实现「转接等待时播放带输入的语音」的需求。
核心解决方法是利用<Dial>的waitUrl属性:当你发起转接呼叫时,来电者会在等待对方接听的过程中,播放waitUrl返回的TwiML内容。你只需要在waitUrl对应的接口里返回带<Gather>的语音逻辑,就能实现等待时收集用户输入的功能。
主路由代码示例
const response = new VoiceResponse(); // 发起转接,同时指定等待时的语音逻辑接口 const dial = response.dial({ waitUrl: 'https://myapi.com/api/repondeur/wait-with-gather', hangupOnStar: true, // 允许来电者按*中断转接 timeout: 30 // 转接超时时间,单位秒 }); dial.number('+33611182299'); return response.toString();
waitUrl对应的接口代码(处理等待时的语音与输入收集)
const waitResponse = new VoiceResponse(); // 播放提示语音,同时收集用户按键 const gather = waitResponse.gather({ action: 'https://myapi.com/api/repondeur/handle-input', // 处理输入的接口 method: 'POST', timeout: 10, numDigits: 1 }); gather.say('您好,正在为您转接客服,请稍候。如果需要留言,请按1;继续等待请按2。'); // 如果用户没输入,循环播放提示 waitResponse.redirect('https://myapi.com/api/repondeur/wait-with-gather'); return waitResponse.toString();
输入处理接口示例(handle-input)
const inputResponse = new VoiceResponse(); const digit = req.body.Digits; switch(digit) { case '1': // 转语音信箱逻辑 inputResponse.say('请在提示音后留言,结束请按#'); inputResponse.record({ action: 'https://myapi.com/api/repondeur/save-message', finishOnKey: '#' }); break; case '2': // 返回等待逻辑,继续等待转接 inputResponse.redirect('https://myapi.com/api/repondeur/wait-with-gather'); break; default: inputResponse.say('输入无效,请重新选择'); inputResponse.redirect('https://myapi.com/api/repondeur/wait-with-gather'); } return inputResponse.toString();
关键说明
waitUrl的TwiML会在转接等待期间循环播放,直到对方接听、转接超时,或者来电者输入按键触发action。hangupOnStar参数让来电者可以按*直接中断转接,此时Twilio会向主路由的action(如果设置的话)发送请求,你可以在那里处理后续逻辑。- 确保
waitUrl和action接口能正确返回TwiML,并且公网可访问(Twilio需要能调用到这些接口)。
内容的提问来源于stack exchange,提问作者TOPKAT
相关产品推荐
相关产品推荐

