Twilio外呼对接Google Voice呼叫筛选时响应提前触发问题咨询
Twilio外呼适配Google Voice呼叫筛选的落地方案
首先明确核心原因:Google Voice的呼叫筛选是被叫平台侧的提前接起逻辑——筛选流程启动时GV平台会先接起线路播放拦截提示,对Twilio而言线路已接通,会立刻触发初始url的TwiML拉取,此时被叫用户还没实际接听,这也是你配置固定Pause、基础AMD后仍会提前播报的根本原因,且主叫侧没有任何方式可以绕过被叫侧的强制筛选流程,只能通过检测逻辑延后业务TwiML的执行时机。
方案1:优化AMD异步检测逻辑(推荐,覆盖90%以上场景)
你之前配置的AMD存在两个问题:检测超时时间过短、未使用异步检测回调,导致业务TwiML和检测流程并行执行,才会出现提前播报。调整为以下配置即可:
$call = $client->calls->create( $to, $from, array( // 初始url返回的TwiML仅保留等待逻辑,不要放任何业务播报内容 "url" => $initialWaitUrl, "statusCallback" => $statusURL, "statusCallbackMethod" => 'POST', "machineDetection" => "DetectMessageEnd", // 拉长检测超时到12秒,覆盖GV筛选提示的最长时长 "machineDetectionTimeout" => 12, // 调整语音检测阈值,过滤GV的合成提示音 "machineDetectionSpeechThreshold" => 2500, // 开启异步AMD,检测完成前不会执行业务逻辑 "asyncAmd" => "true", "asyncAmdStatusCallback" => $amdResultUrl, "asyncAmdStatusCallbackMethod" => "POST" ) );
配套逻辑说明:
- 初始
$initialWaitUrl返回的TwiML仅需写<Response><Pause length="12"/></Response>即可,不加入任何播报、按键收集逻辑 - AMD检测完成后会向
$amdResultUrl推送检测结果,读取返回参数中的AnsweredBy字段:- 若值为
human,说明用户已完成筛选实际接听,此时调用Twilio Call更新接口,将当前通话的TwiML地址替换为你的业务播报+Gather的正式TwiML即可 - 若值为
machine/fax/unknown,说明当前是GV筛选提示、语音信箱或其他自动应答,可直接挂断或走语音信箱留言逻辑
- 若值为
Google Voice的筛选提示是固定合成音,调整检测阈值后AMD会将其识别为机器音,不会误判为真人接听,直到用户按1接起、发出真人声音后才会标记为human。
方案2:基于呼叫状态事件触发业务逻辑
不要依赖in-progress状态作为业务启动的信号,该状态仅代表远端线路被接起,包含了GV筛选、运营商彩铃、语音信箱等非用户接听场景。
- 监听
statusCallback推送的事件,只有当事件中CallStatus为answered且AnsweredBy为human时,再主动更新通话的TwiML为业务逻辑 - 该方案不需要依赖AMD检测,适合对播报延迟要求高的场景,但识别准确率略低于优化后的异步AMD方案。
方案3:GV号码单独适配
如果你的业务可以提前做号码类型识别,可通过号码属性查询接口提前筛出Google Voice等VoIP类号码:
- 对这类号码单独配置初始等待TwiML,不设置固定Pause时长,而是加入静音状态下的人声检测,只有检测到连续2秒以上的真人发声后,再跳转执行业务TwiML
- 不要在初始阶段配置Gather收集按键,GV筛选阶段用户按的1只会提交给GV平台,不会透传到主叫侧,无法作为接听判断依据。
不推荐方案说明
固定写死<Pause length="10"/>的方式适配性极差:不同用户的GV筛选超时设置从5秒到15秒不等,固定时长要么仍会提前播报,要么等待时间过长导致用户主动挂断。
内容的提问来源于stack exchange,提问作者KarmoP
相关产品推荐
相关产品推荐

