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

如何用JavaScript通过Twilio实现浏览器接收手机号来电

实现Twilio浏览器接收手机号来电的完整步骤

一、核心概念说明

  • Twilio Device需要的是Access Token(访问令牌),而非普通令牌。令牌需包含:你的Twilio账户凭证、语音权限、唯一的Identity(比如用户ID),以及绑定的Twilio语音应用SID。
  • 当手机号来电时,Twilio会根据你设置的号码路由规则,请求后端返回TwiML指令,将通话转接到对应Identity的浏览器Device。

二、步骤1:创建Twilio语音应用

  • 登录Twilio控制台,进入"Voice"->"Apps"->"Create new App"
  • 填写应用名称,在"Voice"标签页设置"Request URL"为你的后端TwiML接口地址(后续会实现),请求方法选POST
  • 保存后记录该应用的SID(后续生成令牌需要)

三、步骤2:后端生成Access Token

C# 示例

首先安装Twilio NuGet包:

Install-Package Twilio

代码:

using Twilio.Jwt.AccessToken;

public IActionResult GetPhoneToken()
{
    // 从Twilio控制台获取
    string accountSid = "你的Account SID";
    string authToken = "你的Auth Token";
    string twilioVoiceAppSid = "你的Twilio语音应用SID";
    string identity = "user123"; // 自定义唯一身份标识,比如用户ID

    var grant = new VoiceGrant
    {
        OutgoingApplicationSid = twilioVoiceAppSid,
        IncomingAllow = true // 允许接收来电
    };

    var token = new Token(
        accountSid,
        authToken,
        identity,
        grants: new[] { grant }
    );

    return Ok(token.ToJwt());
}

Node.js 示例

首先安装twilio库:

npm install twilio

代码:

const twilio = require('twilio');

app.get('/getPhoneToken', (req, res) => {
    const accountSid = '你的Account SID';
    const authToken = '你的Auth Token';
    const voiceAppSid = '你的Twilio语音应用SID';
    const identity = 'user123';

    const AccessToken = twilio.jwt.AccessToken;
    const VoiceGrant = AccessToken.VoiceGrant;

    const voiceGrant = new VoiceGrant({
        outgoingApplicationSid: voiceAppSid,
        incomingAllow: true
    });

    const token = new AccessToken(accountSid, authToken, identity);
    token.addGrant(voiceGrant);

    res.send(token.toJwt());
});

PHP 示例

首先安装Twilio PHP库:

composer require twilio/sdk

代码:

<?php
require_once 'vendor/autoload.php';

use Twilio\Jwt\AccessToken;
use Twilio\Jwt\Grants\VoiceGrant;

$accountSid = '你的Account SID';
$authToken = '你的Auth Token';
$voiceAppSid = '你的Twilio语音应用SID';
$identity = 'user123';

$voiceGrant = new VoiceGrant();
$voiceGrant->setOutgoingApplicationSid($voiceAppSid);
$voiceGrant->setIncomingAllow(true);

$token = new AccessToken(
    $accountSid,
    $authToken,
    $identity,
    3600, // 令牌有效期,单位秒
    [$voiceGrant]
);

echo $token->toJWT();
?>

四、步骤3:配置手机号来电路由

  • 登录Twilio控制台,进入"Phone Numbers"->"Manage"->"Active Numbers",找到你的语音号码
  • 找到"A call comes in"选项,选择"Webhook",输入你的后端TwiML接口地址(比如https://yourbackend.com/handle-incoming-call),请求方法选POST
  • 保存设置

五、步骤4:后端实现TwiML路由(处理来电)

当Twilio收到手机号来电时,会调用这个接口,返回TwiML指令将通话转接到浏览器Device:

C# 示例

public IActionResult HandleIncomingCall()
{
    var response = new Twilio.TwiML.VoiceResponse();
    // 这里的identity要和生成令牌时的一致
    var dial = new Twilio.TwiML.Voice.Dial();
    dial.Client("user123");
    response.Append(dial);
    return Content(response.ToString(), "application/xml");
}

Node.js 示例

const twilio = require('twilio');

app.post('/handle-incoming-call', (req, res) => {
    const twiml = new twilio.twiml.VoiceResponse();
    const dial = twiml.dial();
    dial.client('user123'); // 与令牌的identity一致
    res.type('text/xml');
    res.send(twiml.toString());
});

PHP 示例

<?php
require_once 'vendor/autoload.php';

use Twilio\TwiML\VoiceResponse;

$response = new VoiceResponse();
$dial = $response->dial();
$dial->client('user123'); // 与令牌的identity一致

header('Content-Type: text/xml');
echo $response;
?>

六、步骤5:完善浏览器端代码

你的原始代码需要修正,补充媒体权限请求和事件处理:

// 请求麦克风权限
async function getMediaPermissions() {
    try {
        await navigator.mediaDevices.getUserMedia({ audio: true });
        return true;
    } catch (err) {
        console.error('麦克风权限被拒绝:', err);
        return false;
    }
}

async function initTwilioDevice() {
    // 先获取权限
    const hasPermission = await getMediaPermissions();
    if (!hasPermission) return;

    // 获取令牌
    const response = await fetch('https://mybackend/getPhoneToken');
    const token = await response.text(); // 或response.json(),取决于后端返回格式

    const device = new Twilio.Device(token, {
        audioConstraints: { audio: true }
    });

    // 监听设备就绪事件
    device.on('ready', () => {
        console.log('Twilio Device已就绪,可以接收来电');
    });

    // 监听来电事件
    device.on('incoming', (call) => {
        console.log('收到来电,号码:', call.parameters.From);
        // 自动接听或提示用户手动接听
        call.accept();

        // 监听通话状态
        call.on('connect', () => {
            console.log('通话已连接');
        });

        call.on('disconnect', () => {
            console.log('通话已断开');
        });
    });

    // 监听错误事件
    device.on('error', (err) => {
        console.error('Twilio Device错误:', err);
    });
}

// 页面加载完成后初始化
window.addEventListener('load', initTwilioDevice);

七、测试流程

  1. 启动后端服务,确保/getPhoneToken和/handle-incoming-call接口可访问
  2. 打开前端页面,允许麦克风权限
  3. 用其他手机拨打你的Twilio语音号码
  4. 浏览器会收到来电并自动接听,即可通过麦克风/扬声器进行通话

内容的提问来源于stack exchange,提问作者Jose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:05:29