Twilioでブラウザ電話を作るに際して、AIのコーディング支援を受けて実装すると、多くの場合に古いSDKでの実装が提示されていました。特にHTML+JSで構築しようと思うと、ほとんどがv1のコーデイングです。最初は自分で修正をしていたのですが、ネットの世界に落ちてる Voice JavaScript SDKのサンプルコードはほとんどがv1での実装だったので、困っている人がいるのではないかと思い、HTML + JSの組み合わせでのブラウザ電話の実装を記載します。
Voice JavaScript SDK v2を使用すると、開発者はWebアプリケーションに音声通話機能を組み込むことができます。このブログでは、最新のTwilio Voice SDK v2 を使用したブラウザベースの電話アプリケーションの実装例を紹介します。
Voice JavaScript SDK v2の主な特徴
- Promiseベースのアーキテクチャ: v1と異なり、SDK v2はPromiseとasync/awaitパターンを使用
-
強化されたエラー処理:
enableImprovedSignalingErrorPrecision
オプションによる詳細なシグナリングエラー情報 - エッジロケーションのサポート: レイテンシを改善するための優先エッジロケーション指定
- コーデック設定: 優先オーディオコーデックの構成が可能
- トークン管理: 簡素化されたトークン更新メカニズム
- 包括的なイベントシステム: 通話のライフサイクルを詳細に追跡できるイベント
- CDN経由でのSDKの提供が廃止: NPMまたは、Githubからjsファイルをダウンロードして利用
実装
サンプルコード
GitHubリポジトリ
TwilioのFuntions&Assetsで動作する最小限のコードだけをまとめたブラウザ電話の実装です。今回はこちらのコードから抜粋してv2の特徴を紹介します。
デバイスのセットアップ
Twilioデバイスの初期化は以下のように行います:
device = new Twilio.Device(data.token, {
allowIncomingWhileBusy: false, // 通話中の着信を許可するかどうか
closeProtection: true, // タブを閉じる際の警告表示
enableImprovedSignalingErrorPrecision: true, // 詳細なエラー情報の有効化
edge: ['tokyo','singapore'], // 優先エッジロケーション
logLevel: 1, // ログレベル
codecPreferences: ['opus', 'pcmu'], // 優先コーデック
});
注目すべき設定オプション:
-
closeProtection
: タブを閉じる際の誤切断を防止 -
edge
: 接続処理のための地域設定 -
codecPreferences
: 高音質のための優先オーディオコーデック
発信処理の実装
Voice SDK v2では、connect メソッドで await を使用する必要があります:
const call = await device.connect({ params: { To: number } });
callオブジェクトは通話の全ライフサイクルのイベントを提供します:
-
ringing
: 呼び出し開始時 -
accept
: 通話が応答された時 -
disconnect
: 通話終了時 -
error
: 問題発生時
call.on('ringing', hasEarlyMedia => {
updateStatus('呼び出しを開始');
if (!hasEarlyMedia) {
//音声をカスタマイズする関数を追加する
}
});
//発信用のTWIMLのDialパラメーターに、answerOnBridge: trueを設定することで
//相手が出た時にイベントが発生する
call.on('accept', call => {
updateStatus('通話開始');
});
call.on('cancel', () => {
updateStatus('通話がキャンセルされました');
});
call.on('reject', () => {
updateStatus('通話が拒否されました。');
});
call.on('disconnect', () => {
updateStatus('通話が切断されました');
});
call.on('error', (error) => {
console.log('An error has occurred: ', error);
updateStatus('エラーが発生しました。');
});
着信処理の実装
着信を受けるには、まずデバイスを登録する必要があります:
device.register();
そして着信イベントを処理します:
device.on("incoming", (call) => {
// 着信処理のロジック
call.on("accept", () => {
// 通話受諾時の処理
});
call.on("disconnect", () => {
// 通話終了時の処理
});
});
トークン管理
トークン管理は接続維持のために重要です。SDK V2ではupdateToken
メソッドでこれを簡素化しています:
async function refreshToken() {
const response = await fetch(token_url);
const data = await response.json();
if (device) {
await device.updateToken(data.token);
}
}
バックエンド連携
アプリケーションをサポートする2つの主要なバックエンドコンポーネント:
-
トークン生成 (
/token
エンドポイント):- VoiceGrantを含むJWTトークンを作成
- 発信アプリケーションと着信許可を設定
-
TwiMLレスポンス (
/voice
エンドポイント):- 通話ルーティング用のTwiMLを生成
-
answerOnBridge: true
で通話品質を向上 - 発信者IDを設定
実装時の実用的な考慮事項
Voice SDK V2を本番環境で実装する際の注意点:
- エラー処理: リトライロジックを含む包括的なエラー処理の実装
- トークンライフサイクル: 有効期限前の自動トークン更新の設定
- UI連携: 直感的な通話コントロールとステータス表示
-
通話品質メトリクス:
call.on('warning')
およびcall.on('warning-cleared')
イベントのモニタリング - デバイステスト: 異なるブラウザやネットワーク条件でのテスト
まとめ
Twilio Voice SDK v2は、Webアプリケーションに音声機能を組み込むための強力な基盤を提供します。Promiseベースのアーキテクチャ、包括的なイベントシステム、簡素化されたトークン管理により、信頼性の高い音声体験の作成がこれまで以上に容易になりました。
このデモアプリケーションのパターンに従うことで、独自のWebプロジェクトに音声通話機能を迅速に実装できます。
リンクまとめ
GitHubリポジトリ
Twilio Progarmmable Voice Javascript SDK v2 移行ガイド