Twilio 支持的 laravel 应用程序使用 Laravel、AlpineJS、Twilio JS 客户端和 Twilio PHP SDK 实现 VOIP 浏览器调用功能

问题描述 投票:0回答:0

我正在构建一个由 Twilio API 驱动的 Laravel 应用程序。 Laravel 应用程序基本上应该是 Twilio API 的 UI,从而使用户更容易使用。我正在为其构建此应用程序的人希望用户仅提供他们的 accountSid 和 authToken,以及登录所需的电子邮件和密码。 这是 UI 的外观(未完成):

这里我已经面临一个问题:据我所知,ClientToken应该不再使用了吧? https://www.twilio.com/docs/voice/sdks/deprecated-pages/client/tutorials/capability-tokens

使用客户端令牌,我只需要 accountSid 和 authToken 以及一个 clientName。 但是,现在应该使用 AccessToken,而不是使用 ClientToken,或者? https://www.twilio.com/docs/iam/access-tokens 这里需要提供accountSid、apiKeySid和apiKeySecret。据我所知,当目标是执行浏览器 VOIP 调用时,甚至需要提供 twimlAppSid https://www.twilio.com/docs/iam/access-tokens#create-an-access-token-for-voice。这些令牌将存储在每个用户的 Laravel 数据库中。难道不能只提供指向 Laravel 端点的 VoiceUrl 参数而不是创建 TwimlApp,只是为了获取 twimlAppSid?

所以现在我的问题是 accountSid 和 authToken 是否足以满足我的客户的要求,我是否能够基于这两个令牌获取/生成其他所有内容,或者我真的需要 accountSid、apiKeySid、apiKeySecret 以及twimlAppSid?如果需要所有这些令牌,这对用户体验来说会非常糟糕,因为即使是用户也需要创建一个 twimlApp 并放置我正在构建的应用程序的正确 Laravel 端点,以便 Twilio 可以向该端点发出请求获取 TwiML 说明。

我将向您展示一些代码,但您可能不需要这些代码来回答我的问题。只是一些额外的信息,也许有用。

为了向您提供更多背景信息,这就是我目前拥有的。如果我是对的,我什至可能还需要将 twimlAppSid 存储在数据库中?它目前在 .env 文件中被硬编码为字符串。后端代币生成:

 public function getToken(Request $request)
{

    $accessToken = new AccessToken(
        auth()->user()->account_sid,
        auth()->user()->api_key_sid,
        auth()->user()->api_key_secret,
        3600,
        auth()->user()->id


    );
    $voiceGrant = new VoiceGrant();
    $voiceGrant->setOutgoingApplicationSid(config('twilio.twilio.connections.twilio.twimlAppSid'));

    $accessToken->addGrant($voiceGrant);

    $token = $accessToken->toJWT();
    return response()->json([
        'token' => $token,
    ]);
}

在前端,我通过以下方式使用 AlpineJS 获取令牌:

 startUp: function () {
    fetch('dialer/token').then(response => {
        return response.json()

    }).then(data => {
        this.token = data.token
        this.clientName = data.clientName
        this.initializeDevice()
    })


},


initializeDevice: function () {

    device = new Twilio.Device(this.token, {
        debug: true,

        codecPreferences: ['opus', 'pcmu'],

    })

    this.addDeviceListeners(device)

    device.register()

},

最后,Twilio 将调用提供此功能的 Laravel 端点:

  public function voiceViaTwilio(Request $request)
{

    $response = new VoiceResponse();

    $conferenceName = $request['ConferenceName'];

    $from = $request['From'];
    $to = $request['To'];
    $user = TwilioNumber::where('phone_number', $from)->first()->user;

    $twilio = new Client($user->account_sid, $user->auth_token);

    $twilio->conferences($conferenceName)
        ->participants
        ->create(
            $from,
            $to,
        );

    $dial = $response->dial();
    $dial->conference($conferenceName, [
        'startConferenceOnEnter' => true,
        'endConferenceOnExit' => true,

    ]);

    $dial = $response->dial();
    $dial->conference($conferenceName);

    return response($response)->header('Content-Type', 'text/xml');
}

这将使我(呼叫者)进入一个即时创建的会议。 为了向您展示单击模态中的呼叫按钮时会发生什么,请看一下前端:

 makeBrowserCall: async function () {
    // generate unique conference name
    const conferenceName = 'conference-' + Math.random().toString(36)
    if (device) {

        if (this.call && this.call.status() === 'open') {
            console.log('OPEN')

            fetch("/dialer/twilio/voice/conference/add", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "X-CSRF-TOKEN": "{{ csrf_token() }}"
                },

                body: JSON.stringify(
                    {
                        To: this.to,
                        From: this.dialFrom,
                        ConferenceName: conferenceName,
                    }
                ),
                success: function (data) {
                    console.log('success', data)
                }
            })


            return
        }

        console.log('showBrowserCallModal', this.dialFrom, this.to, this.callerId, conferenceName, this.clientName)

        this.call = await device.connect({ params: { To: this.to, From: this.dialFrom, CallerId: this.callerId, ConferenceName: conferenceName, ClientName: this.clientName } })

        this.call.on("accept", this.updateUIAcceptedOutgoingCall.bind(this))
        this.call.on("disconnect", this.updateUIDisconnectedOutgoingCall.bind(this))
        this.call.on("cancel", this.updateUIDisconnectedOutgoingCall.bind(this))


    }

},

一旦我拨打了第一个号码并且会议已经即时创建,因此

call.status()==='open'
,可以通过点击另一个端点来添加更多参与者
"/dialer/twilio/voice/conference/add"
这基本上是相同的:

 public function addParticipant(Request $request)
{
    $response = new VoiceResponse();

    // create conference and add subsequent callers to the conference, and end the conference when the last caller leaves, and use $request['To] as the caller to the conference

    $conferenceName = $request['ConferenceName'];

    $from = $request['From'];
    $to = $request['To'];
    $user = TwilioNumber::where('phone_number', $from)->first()->user;

    $twilio = new Client($user->account_sid, $user->auth_token);

    $twilio->conferences($conferenceName)
        ->participants
        ->create(
            $from,
            $to,
        );

    $dial = $response->dial();
    $dial->conference($conferenceName, [
        'startConferenceOnEnter' => true,
        'endConferenceOnExit' => true,

    ]);

    $dial = $response->dial();
    $dial->conference($conferenceName);



    return response($response)->header('Content-Type', 'text/xml');
}

非常感谢你:)

php twilio twilio-api twilio-twiml twilio-programmable-voice
© www.soinside.com 2019 - 2024. All rights reserved.