使用PHP SDK实现Twilio外呼无法真实接通及无挂断按钮问题求助
Twilio PHP SDK外呼问题解决方案
问题1:呼叫仅响铃/接听后立即断开
你的两段代码存在逻辑错误,导致通话异常:
- 第一段代码使用Twilio的demo语音XML,该文件仅播放音乐,目标号码接听后只会听到音乐,不会建立你预期的“真实通话”,这可能让你误以为未接通。
- 第二段代码中,你在
To参数指定目标号码后,又在TwiML里用<Dial>再次呼叫同一个号码。Twilio呼叫目标号码并接通后,会尝试再次拨打该号码,但该号码已处于通话状态,直接导致通话立即断开。
正确代码示例
场景1:目标号码接听后播放语音
require __DIR__ . '/vendor/twilio/sdk/src/Twilio/autoload.php'; $sid = "ACdefc6a240fXXXXXXXXXXXXXXXXXXXXXX"; $token = "bceedc5daf3XXXXXXXXXXXXXXXXXXXXX"; $client = new Twilio\Rest\Client($sid, $token); $call = $client->calls->create( $to_number, // 目标号码 $from_number, // 已验证的Twilio号码 [ "twiml" => "<Say>您好,这是来自Twilio的测试呼叫。</Say>" ] ); print_r($call);
场景2:目标号码接听后连接到其他号码(如坐席)
如果需要让目标号码与其他号码通话,<Dial>标签内应填写要连接的号码,而非目标号码本身:
require __DIR__ . '/vendor/twilio/sdk/src/Twilio/autoload.php'; $sid = "ACdefc6a240fXXXXXXXXXXXXXXXXXXXXXX"; $token = "bceedc5daf3XXXXXXXXXXXXXXXXXXXXX"; $client = new Twilio\Rest\Client($sid, $token); $call = $client->calls->create( $to_number, // 目标号码 $from_number, // 你的Twilio号码 [ "twiml" => "<Dial>要连接的坐席号码</Dial>" ] ); print_r($call);
额外排查步骤
- 登录Twilio控制台查看呼叫详情(Call Logs),里面会显示TwiML执行情况和错误信息,帮助定位问题。
- 确保
$from_number是Twilio控制台中已验证或购买的号码。
问题2:浏览器端添加挂断按钮
根据呼叫发起方式,有两种实现方案:
方案1:通过Twilio Client JS发起呼叫(浏览器直接控制)
这种方式下,通话由浏览器端的Twilio Client管理,可直接控制挂断:
后端生成认证Token(PHP)
require __DIR__ . '/vendor/twilio/sdk/src/Twilio/autoload.php'; use Twilio\Jwt\ClientToken; $accountSid = "ACdefc6a240fXXXXXXXXXXXXXXXXXXXXXX"; $authToken = "bceedc5daf3XXXXXXXXXXXXXXXXXXXXX"; $appSid = "你的Twilio Voice应用SID"; // 在Twilio控制台创建Voice App获取 $token = new ClientToken($accountSid, $authToken, $appSid); echo $token->generateToken();
前端代码(HTML+JS)
<button id="call-button">发起呼叫</button> <button id="hangup-button" disabled>挂断</button> <script src="https://sdk.twilio.com/js/client/v1.13/twilio.min.js"></script> <script> // 从后端获取Token fetch('/get-token.php') .then(res => res.text()) .then(token => { const device = new Twilio.Device(token); let activeCall = null; // 发起呼叫 document.getElementById('call-button').addEventListener('click', () => { activeCall = device.connect({ to: '目标号码' }); document.getElementById('call-button').disabled = true; document.getElementById('hangup-button').disabled = false; }); // 挂断呼叫 document.getElementById('hangup-button').addEventListener('click', () => { if (activeCall) { activeCall.disconnect(); } }); // 通话结束后重置按钮状态 device.on('disconnect', () => { activeCall = null; document.getElementById('call-button').disabled = false; document.getElementById('hangup-button').disabled = true; }); }); </script>
方案2:通过PHP API发起呼叫,浏览器端触发挂断
如果呼叫是通过PHP API在服务器端发起的,需要通过Call SID终止通话:
- 发起呼叫时保存
$call->sid(Call SID)。 - 前端点击挂断按钮时,向后端发送请求并携带Call SID。
- 后端调用Twilio API终止通话:
require __DIR__ . '/vendor/twilio/sdk/src/Twilio/autoload.php'; $sid = "ACdefc6a240fXXXXXXXXXXXXXXXXXXXXXX"; $token = "bceedc5daf3XXXXXXXXXXXXXXXXXXXXX"; $client = new Twilio\Rest\Client($sid, $token); $callSid = $_POST['call_sid']; // 从前端获取Call SID $client->calls($callSid)->update(["status" => "completed"]);
内容的提问来源于stack exchange,提问作者Anuj
相关产品推荐
相关产品推荐

