VCR を使ったブラウザ発着信の実装
はじめに
みなさん、こんにちは。KDDI ウェブコミュニケーションズで CPaaS のエバンジェリストをしている高橋です。
この記事では、VCR(Vonage Cloud Runtime)を使った、ブラウザベースの電話の受発信について解説します。
本記事の対象となる読者
- Vonage のアプリケーションをホスティングするサーバーを探している方
- Node.js + Express の仕組みをなんとなく理解している方
- ブラウザベースの電話の受発信システムを作ってみたい方
- Vonage Cloud Runtime を始めてみたい方
事前準備
本記事の内容を実装するためには、あらかじめ以下の準備が必要です。
- Vonage アカウントを保有していること
- Vonage で電話番号を購入していること
- Vonage クーポンコード(トライアルアカウントで電話番号を購入する際に必要です)
アカウントを持っていない方は、以下の記事を参考にアカウントを開設してください。
電話番号を持っていない方は、以下の記事を参考に電話番号を購入してください。
Vonage とは
Vonage は、米国ニュージャージー州に本社を置く、CPaaS(Communication Platform as a Service)企業です。
もともとは VoIP(Voice over IP)企業としてスタートしましたが、いくつかの企業買収を行うことで、コミュニケーションサービス全般をサポートする企業に発展しました。現在はスウェーデンの大手通信機器会社エリクソンの傘下に入っています。
2024年2月14日より、株式会社KDDIウェブコミュニケーションズ(以後、KWC)が Vonage の再販事業を開始することとなりました。
KWC経由でアカウントを開設する場合、Vonage で直接開設したアカウントとは一部仕様が異なります。(※提供する機能面において違いはありません)
Vonage Cloud Runtime とは
Vonage Cloud Runtime (VCR)は、Vonage が提供するクラウド型のアプリケーションサーバーです。
VCR 上に構築されたアプリケーションは Vonage 上にホスティングされるため、ユーザーは自身で AWS などの外部サーバーを準備する必要がありません。
これにより、Vonage API を使ってすぐに PoC やテストが行えるほか、外部の API サービスと連携したアプリケーションを構築できます。
用語定義
用語 | 説明 |
---|---|
プロジェクト | VCR では、作成するアプリケーションのことをプロジェクトと呼びます。 |
ワークスペース | ブラウザベースでコーディングができる Visual Studio Code ベースの開発環境(コードエディタ)です。 |
インスタンス | ワークスペースをデプロイすることで立ち上がるサーバー環境です。 |
Code Hub | プロジェクトのテンプレートが公開されているマーケティングプレイスです。 |
リージョン | プロジェクトやインスタンスを管理する AWS リージョンで、Sydney、Singapore、US Virginia、Europe Ireland の4つから選択できます。 |
プロジェクトの作成
では最初に、Node.js ベースで動作する基本的なプロジェクトを作成します。
Code Hub から Starter Project を作成
- Vonage ダッシュボードにログインをします。
- 左側のメニューからドキュメントを新規タブで開きます。
-
Code Hubタブを選択します。
- サーチボックスに「Starter Project」と入力すると、該当するプロダクトが4つ表示されるので、その中のStarter Projectを選択します。
- Get Codeタブを選択します。
- 右上のリージョン選択リストから「US Virginia」を選択します。
-
Create a new development environmentボタンを押します。
-
Workspace name欄に、「Click Call」と入力し、Continueボタンを押します。
- しばらく待つと、以下のようなプロジェクトが作成されます。
GitHub からテンプレートを取得
ではさっそくブラウザで発着信を行うコーディングをしてみましょう。
一から作成するのは大変なので、今回はすでに作成済みのコードを GitHub から取得します。
- Terminalメニューの中のNew Terminalを選択します。
画面下部にターミナルウィンドウが開きます。
- ターミナルウィンドウで、以下のコマンドを実行します。
cp vcr.yml vcr-back.yml
git init
git remote remove origin
git remote add origin https://github.com/mobilebiz/claris-click-dialer.git
git config pull.rebase false
git pull origin main
git reset --hard origin/main
npm install
npm audit fix
以下のように、特にエラーが出なければ今回使うソースファイルや関連ファイルが取り込まれます。
vcr.yml の設定
次に、VCR の環境ファイル(vcr.yml)を設定します。
- 左側のエクスプローラーから、
vcr-back.yml
を開きます。 -
application-id
の値をコピーしておきます。
-
vcr-sample.yml
を開き、application-id
の値を、今コピーした値で上書きします。 - さらに、
environment
の中のVONAGE_NUMBER
のvalueを、Vonage で購入した電話番号に置き換えます。
- ターミナルウィンドウで、以下のコマンドを実行します。
mv vcr-sample.yml vcr.yml
電話番号の紐づけ
では最後に、Vonage で購入した電話番号を今作成したアプリケーションに紐づけます。
- Vonage ダッシュボードのアプリケーションを選択します。
-
Click Callというアプリケーションができているはずなので、そちらを選択します。
- 番号をリンクタブの中に、購入した Vonage 電話番号のリストが表示されます。
- 右側のリンクボタンを押して、このアプリケーションに電話番号を紐づけます。
デバッグモードで起動
ではいよいよテストをしましょう。
- 左側のRun and Debugアイコンを選択します。
- 上に表示されている小さな緑色の矢印を押して、デバッグをスタートします。
- ターミナルウィンドウに移動します。
- しばらくするとデバッグモードが起動します。ログの中の
Application Host
に書かれている URL をコピーします。
- ブラウザの新しいタブを開き、今コピーしたURLを貼り付けます。末尾に
?number=ご自分の電話番号
(例:090.../080...)を指定します。 - ブラウザのデバッグウィンドウを開いておきます(MacOSならOpt+Cmd+i,WindowsならCtrl+Shift+i)。
- 発信ボタンを押します。
- 初回はマイクの利用許可が表示されるので、許可するを押します。
- 電話がかかってきて、ブラウザと通話することができることを確認します。
デバッグモードを終了
- デバッグツールの中にある停止ボタン(赤い□)を押します。
プロジェクトをデプロイ
- ターミナルウィンドウで以下のコマンドを実行します。デプロイにはしばらく時間がかかります。
vcr deploy
- ログの中に表示される
Instance host address
のURLをコピーします。
- 先ほどと同じようにブラウザにURLを貼り付け、末尾に
?number=ご自分の電話番号
を指定します。 - 発信ボタンを押して、電話がかかることを確認します。
プログラムの解説
ではここから、今回作成したプログラムの解説をします。
発信のフローは以下のとおりです。
一番左がブラウザで、VCR の中のpublic/index.html
が実行されます。
真ん中が、VCR の中のindex.js
で実行されるサーバー側プログラムです。
一番右が皆さんの電話機になります。
サーバー側の初期動作
VCR でプロジェクトが起動すると、index.js
が実行されます。
起動時の重要な動作は、セッションの作成とVoiceアプリケーションの初期化、さらにセッション内で着信があった場合のコールバックの指定とイベント発生時のコールバックの指定です。
これにより、先ほど実装時にアプリケーションに対してリンクした電話番号に着信があると、onCall
が呼ばれるようになります。
ブラウザを開いたときの動作
ブラウザでindex.html
を開くと、最初にサーバーの/getToken
が呼ばれます。このときにオペレーター名をパラメーターとして付与します。
サーバー側では、オペレーター情報を含む JWT(JSON Web Token)を生成します。JWTには有効期限を設定できます(今回は24時間にしてあります)。
JWT を受け取ったブラウザは、セッションを生成します。セッションというのは、ブラウザ(オペレーター)とVonageがやり取りをするための空間です。
セッションでは各種イベントが発火します。たとえば、電話を発信するとlegStatusUpdate
イベントが発火しますし、着信があるとcallInvite
イベント、電話が切断されるとcallHangup
イベントが発火します。
ブラウザは、このイベントを処理することで関連する動作を行えます。
ブラウザで発信ボタンを押したときの動作
ブラウザ側の処理は非常にシンプルで、発信したい電話番号をパラメーターとして設定し、client.serverCall()
を呼ぶだけです。
戻り値としてcallId
が取得できます。これは切断をするときに使うので変数に格納しておきます。
client.serverCall()
を実行すると、サーバーに対して着信が発生します。直接相手側に架電が始まるわけではない、というのがポイントです。
着信を受けたときのサーバー側の動作
ブラウザからの着信なのか、電話からの着信なのかを判定するために、サーバー側はパラメーターの有無で判断します。
ブラウザから着信した場合は、from_user
パラメーターが含まれますが、from
パラメーターは含まれません。
また逆に、電話からの着信にはfrom
パラメーターが含まれますが、from_user
パラメーターは含まれません。
以下がその判定をしている部分です。
ブラウザからの着信の場合は、指定された電話番号に電話をかける必要があるため、以下のような NCCO を返します。
[
{
action: 'connect',
from: process.env.VONAGE_NUMBER,
endpoint: [{
type: 'phone',
number: req.body.to
}]
}
]
今回はブラウザからの着信を指定された電話番号に転送をするために、connect
アクションを利用しています。
日本の電話番号に対して転送をする場合、発信者番号には Vonage で購入した電話番号を指定する必要があるので、from
パラメーターに Vonage の番号を指定しています。
今回は環境変数(VONAGE_NUMBER)を指定していますが、これは先ほど皆さんがvcr.yml
に記述しています。
着信の動作
今回のシナリオで着信を受ける動作についても解説します。
サーバー側の動作
先に説明したように、今回のアプリケーションに紐づいた電話番号に着信が発生すると、onCall
イベントが発火します。
電話からの着信では以下のような NCCO を返すようにしています。
[
{
action: 'connect',
from: req.body.from,
endpoint: [{
type: 'app',
user: 'Operator'
}]
}
]
endpoint
のタイプにapp
を設定することで、ブラウザを指定しています。
今回は JWT を生成したときのオペレーター名であるOperator
を指定していますので、このオペレーターが待ち受け中の場合(JWTが有効な場合)は、このオペレーターのブラウザに着信通知が届きます。
もし複数のオペレーターが存在する場合は、着信させたいオペレーター名を指定することになりますが、どのオペレーターに着信させるかは皆さんのプログラム次第ということになります。
ブラウザ側での着信動作
サーバー側で指定したオペレーターに転送が発生すると、ブラウザ側ではcallInvite
イベントが発火します。
今回のプログラムでは、着信時にオペレーターが気がつくように着信音を鳴らしていますが、このような動作もプログラミングしておく必要があります。
ちなみに着信音はpublic
フォルダの中に MP3 形式の音声ファイルとして保存しておき、以下のようにプログラム内で利用できるよう定義しています。
const ringtone = new Audio('./ringtone.mp3'); // 着信音のファイルパスを指定
着信に気がついたオペレーターが着信を受け入れる際には、client.answer(callId)
を呼び出す必要があります(callId
は着信時に渡されるコールIDです)。
着信時にブラウザを閉じていたり、JWT の有効期限が切れていたりした場合は、サーバー側の呼び出しが失敗します。
サーバー側のイベントハンドラを使うことで失敗したことを判定することで、呼び出し失敗時の処理を実装することができます。ただし、今回はそこまでの実装はしていません。
まとめ
今回は、Vonage 上でプログラムを実行できる Vonage Cloud Runtime を使ってブラウザの発着信ができることを確認しました。
ブラウザの機能を使って電話をかけたり受けたりすることができるので、Webアプリだけでなく、ブラウザコンポーネントが使える kintone や Claris FileMaker などでも架電アプリケーションを作成できるようになります。
Discussion