🀄️

VCR を使ったブラウザ発着信の実装

はじめに

みなさん、こんにちは。KDDI ウェブコミュニケーションズで CPaaS のエバンジェリストをしている高橋です。
この記事では、VCR(Vonage Cloud Runtime)を使った、ブラウザベースの電話の受発信について解説します。

本記事の対象となる読者

  • Vonage のアプリケーションをホスティングするサーバーを探している方
  • Node.js + Express の仕組みをなんとなく理解している方
  • ブラウザベースの電話の受発信システムを作ってみたい方
  • Vonage Cloud Runtime を始めてみたい方

事前準備

本記事の内容を実装するためには、あらかじめ以下の準備が必要です。

  • Vonage アカウントを保有していること
  • Vonage で電話番号を購入していること
  • Vonage クーポンコード(トライアルアカウントで電話番号を購入する際に必要です)

アカウントを持っていない方は、以下の記事を参考にアカウントを開設してください。

電話番号を持っていない方は、以下の記事を参考に電話番号を購入してください。

Vonage とは

Vonage_logo

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 ダッシュボードにログインをします。
  • 左側のメニューからドキュメントを新規タブで開きます。
    Select Document
  • Code Hubタブを選択します。
    Select Code Hub Tab
  • サーチボックスに「Starter Project」と入力すると、該当するプロダクトが4つ表示されるので、その中のStarter Projectを選択します。
    Search Starter Project
  • Get Codeタブを選択します。
  • 右上のリージョン選択リストから「US Virginia」を選択します。
  • Create a new development environmentボタンを押します。
    Select Get Code tab
  • Workspace name欄に、「Click Call」と入力し、Continueボタンを押します。
    Set Workspace Name
  • しばらく待つと、以下のようなプロジェクトが作成されます。
    Starter Project

GitHub からテンプレートを取得

ではさっそくブラウザで発着信を行うコーディングをしてみましょう。
一から作成するのは大変なので、今回はすでに作成済みのコードを GitHub から取得します。

  • Terminalメニューの中のNew 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

以下のように、特にエラーが出なければ今回使うソースファイルや関連ファイルが取り込まれます。

Git pull

vcr.yml の設定

次に、VCR の環境ファイル(vcr.yml)を設定します。

  • 左側のエクスプローラーから、vcr-back.ymlを開きます。
  • application-idの値をコピーしておきます。
    Copy application id
  • vcr-sample.ymlを開き、application-idの値を、今コピーした値で上書きします。
  • さらに、environmentの中のVONAGE_NUMBERのvalueを、Vonage で購入した電話番号に置き換えます。
    Change vcr.yml
  • ターミナルウィンドウで、以下のコマンドを実行します。
mv vcr-sample.yml vcr.yml

電話番号の紐づけ

では最後に、Vonage で購入した電話番号を今作成したアプリケーションに紐づけます。

  • Vonage ダッシュボードのアプリケーションを選択します。
  • Click Callというアプリケーションができているはずなので、そちらを選択します。
    Select new application
  • 番号をリンクタブの中に、購入した Vonage 電話番号のリストが表示されます。
  • 右側のリンクボタンを押して、このアプリケーションに電話番号を紐づけます。
    Link the number

デバッグモードで起動

ではいよいよテストをしましょう。

  • 左側のRun and Debugアイコンを選択します。
  • 上に表示されている小さな緑色の矢印を押して、デバッグをスタートします。
    Start debug
  • ターミナルウィンドウに移動します。
  • しばらくするとデバッグモードが起動します。ログの中のApplication Hostに書かれている URL をコピーします。
    Deploy Started
  • ブラウザの新しいタブを開き、今コピーしたURLを貼り付けます。末尾に?number=ご自分の電話番号(例:090.../080...)を指定します。
  • ブラウザのデバッグウィンドウを開いておきます(MacOSならOpt+Cmd+i,WindowsならCtrl+Shift+i)。
    Open browser
  • 発信ボタンを押します。
  • 初回はマイクの利用許可が表示されるので、許可するを押します。
    Click button
  • 電話がかかってきて、ブラウザと通話することができることを確認します。

デバッグモードを終了

  • デバッグツールの中にある停止ボタン(赤い□)を押します。
    Stop debugging

プロジェクトをデプロイ

  • ターミナルウィンドウで以下のコマンドを実行します。デプロイにはしばらく時間がかかります。
vcr deploy
  • ログの中に表示されるInstance host addressのURLをコピーします。
    deployed
  • 先ほどと同じようにブラウザにURLを貼り付け、末尾に?number=ご自分の電話番号を指定します。
  • 発信ボタンを押して、電話がかかることを確認します。

プログラムの解説

ではここから、今回作成したプログラムの解説をします。

発信のフローは以下のとおりです。
Dial Sequence

一番左がブラウザで、VCR の中のpublic/index.htmlが実行されます。
真ん中が、VCR の中のindex.jsで実行されるサーバー側プログラムです。
一番右が皆さんの電話機になります。

サーバー側の初期動作

VCR でプロジェクトが起動すると、index.jsが実行されます。
起動時の重要な動作は、セッションの作成とVoiceアプリケーションの初期化、さらにセッション内で着信があった場合のコールバックの指定とイベント発生時のコールバックの指定です。
Server init prepare

これにより、先ほど実装時にアプリケーションに対してリンクした電話番号に着信があると、onCallが呼ばれるようになります。

ブラウザを開いたときの動作

ブラウザでindex.htmlを開くと、最初にサーバーの/getTokenが呼ばれます。このときにオペレーター名をパラメーターとして付与します。
サーバー側では、オペレーター情報を含む JWT(JSON Web Token)を生成します。JWTには有効期限を設定できます(今回は24時間にしてあります)。
JWT を受け取ったブラウザは、セッションを生成します。セッションというのは、ブラウザ(オペレーター)とVonageがやり取りをするための空間です。
セッションでは各種イベントが発火します。たとえば、電話を発信するとlegStatusUpdateイベントが発火しますし、着信があるとcallInviteイベント、電話が切断されるとcallHangupイベントが発火します。
ブラウザは、このイベントを処理することで関連する動作を行えます。
Events

ブラウザで発信ボタンを押したときの動作

ブラウザ側の処理は非常にシンプルで、発信したい電話番号をパラメーターとして設定し、client.serverCall()を呼ぶだけです。
戻り値としてcallIdが取得できます。これは切断をするときに使うので変数に格納しておきます。
client.serverCall()を実行すると、サーバーに対して着信が発生します。直接相手側に架電が始まるわけではない、というのがポイントです。

着信を受けたときのサーバー側の動作

ブラウザからの着信なのか、電話からの着信なのかを判定するために、サーバー側はパラメーターの有無で判断します。
ブラウザから着信した場合は、from_userパラメーターが含まれますが、fromパラメーターは含まれません。
また逆に、電話からの着信にはfromパラメーターが含まれますが、from_userパラメーターは含まれません。
以下がその判定をしている部分です。

onCall function

ブラウザからの着信の場合は、指定された電話番号に電話をかける必要があるため、以下のような 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イベントが発火します。
今回のプログラムでは、着信時にオペレーターが気がつくように着信音を鳴らしていますが、このような動作もプログラミングしておく必要があります。

callInvite event

ちなみに着信音はpublicフォルダの中に MP3 形式の音声ファイルとして保存しておき、以下のようにプログラム内で利用できるよう定義しています。

const ringtone = new Audio('./ringtone.mp3'); // 着信音のファイルパスを指定

着信に気がついたオペレーターが着信を受け入れる際には、client.answer(callId)を呼び出す必要があります(callIdは着信時に渡されるコールIDです)。

answer

着信時にブラウザを閉じていたり、JWT の有効期限が切れていたりした場合は、サーバー側の呼び出しが失敗します。
サーバー側のイベントハンドラを使うことで失敗したことを判定することで、呼び出し失敗時の処理を実装することができます。ただし、今回はそこまでの実装はしていません。

まとめ

今回は、Vonage 上でプログラムを実行できる Vonage Cloud Runtime を使ってブラウザの発着信ができることを確認しました。
ブラウザの機能を使って電話をかけたり受けたりすることができるので、Webアプリだけでなく、ブラウザコンポーネントが使える kintone や Claris FileMaker などでも架電アプリケーションを作成できるようになります。

KWCPLUS

Discussion