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

使用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终止通话:

  1. 发起呼叫时保存$call->sid(Call SID)。
  2. 前端点击挂断按钮时,向后端发送请求并携带Call SID。
  3. 后端调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:15:59