Twilio asyncAMD回调早于初始Twiml提示播放完成触发如何解决
问题场景
- IVR系统外呼用户,播放一段约251字符的较长Twiml提示音,提示播放完毕后收集用户输入
- 若检测到非人类接听,通过asyncAMD回调获取AMD检测结果后给对方留语音留言
现有代码说明
发起外呼的核心代码如下:
var call = CallResource.Create( machineDetection: "DetectMessageEnd", asyncAmd: "true", asyncAmdStatusCallback: new Uri("[URI to callback]"), asyncAmdStatusCallbackMethod: HttpMethod.Post, twiml: new Twilio.Types.Twiml("<Response><Say>[MyMessage]</Say></Response>"), from: new Twilio.Types.PhoneNumber(configuration["fromPhoneNumber"]), to: new Twilio.Types.PhoneNumber(configuration["toPhoneNumber"]) );
其中[MyMessage]长度约251字符。当前应答机检测功能正常,非人类接听时可正常留语音留言,但人类接听场景下asyncAMD回调会在初始提示音播放完毕前就触发,已尝试调整所有官方AMD调优参数仍未解决。核心需求为:非人类接听时可正常留语音留言,人类接听时asyncAMD回调触发的后续逻辑需在初始提示音播放完成后执行。
可行解决方案
方案1:拆分呼叫流程(最稳妥,无兼容性问题)
不需要调整AMD参数,也不用切换阻塞式AMD,仅调整现有流程逻辑即可:
- 创建呼叫时,不要直接传入带251字提示音的Twiml,仅保留AMD相关配置,初始Twiml留空即可,不会影响通话接通
- 收到asyncAMD回调后先做判断:
- 检测结果为非人类接听:直接更新通话Twiml为留言内容,正常走留言逻辑
- 检测结果为人类接听:再调用
CallResource.Update接口,给当前通话传入带长提示音和收集用户输入逻辑的Twiml
这个流程下,人类接听场景的提示音是在AMD回调返回后才开始播放,完全不会出现回调触发早于提示音播放完成的问题,也不会影响非人类场景的留言功能。
方案2:回调侧对齐播放时长
如果不想改动现有呼叫创建逻辑,可以用这个轻量方案:
先实际测试一遍你这段251字符提示音的TTS实际播放时长,记为X秒。在asyncAMD回调判断为人类接听后,先等待X秒再执行后续收集输入的逻辑即可,注意如果有用户按键打断提示音的需求,要加对应逻辑提前终止等待。
无需切换阻塞式AMD
阻塞式AMD会导致用户接通后听到数秒的静默,严重影响通话体验,完全没有必要切换,调整现有流程即可解决问题。
内容的提问来源于stack exchange,提问作者Michael McCarthy
相关产品推荐
相关产品推荐

