Twilio Programmable Voice、Python、JavaScriptを使用したブラウザーからの通話の発着信
読む所要時間: 30 分
このチュートリアルでは、Twilio Programmable Voice APIを使用してWebブラウザーで通話を発信または受信するアプリケーションを作成します。また、通話の発信、応答、拒否を可能にするUIも実装します。
このチュートリアルではと、次のようなアプリケーションを作成します。
チュートリアルの要件
チュートリアルを進めるには、以下が必要です。
- 無料または有料のTwilioアカウント。初めてTwilioを使用する場合は、すぐに無料アカウントを作成 してください。このリンク を使用してアカウントを作成し、後ほど有料アカウントにアップグレードする場合は、$10のクレジットを進呈します。
- 通話の発着信が可能なTwilioの電話番号。保有していない場合は今すぐ取得 してください。
- Python 3.6以降がインストールされていること。
- ngrok がインストールされていること。ngrokは、パブリックエンドポイントからローカルで実行されているWebサービスへのセキュアトンネルを作成するリバースプロキシサービスです。ngrokを使用し、作成したアプリケーションとTwilioを接続するためのセキュアなURLを作成します。
- 通話の発着信が可能な携帯電話または電話。プロジェクトのテストに使用。
基本的なコンセプトとアプリケーションロジック
このチュートリアルの目的は、ブラウザーでの通話の発着信を可能にするWebアプリケーションを構築することです。Flaskフレームワークを使用し、必要なWebhookの実装とクライアントアプリケーションの提供を行います。
アプリケーションクライアントは、Twilio Client JS SDK (twilio.js
)を使用してTwilioデバイスを作成します。
Twilioデバイス は、ブラウザーで通話を発着信するための主要なエントリーポイントです。 TwilioデバイスとTwilioのサーバー間の接続を確立するには、アプリケーションサーバーでアクセストークンを生成する必要があります。
アクセストークン は、クライアント側のアプリケーションに安全に配布できる短時間有効な認証情報であり、音声、会話、同期、ビデオなどのTwilio ClientのSDKの認証に使用できます。Twilioのサーバーでアクセストークンを生成するには、Twilio APIキーを使用する必要があります。
Twilio APIキーは、Twilio APIへのアクセスを許可する認証情報です。APIキーにより、次のことが可能になります。
- Twilio APIとの認証
- アクセストークンの作成、取り消し
アクセストークンは、クライアントにTwiMLアプリケーション (TwiMLアプリ)へのアクセスを許可します。Twilioは、アカウント内のTwiMLアプリケーションを使用し、サーバーとのやり取り方法を決定します。
TwiML (Twilio Markup Language)は、通話、SMS、ファックス受信時の動作をTwilioに指定できる一連の命令です。
プロジェクト構造の作成
このセクションでは、プロジェクトディレクトリを作成し、このディレクトリ内にFlaskアプリケーションの標準ディレクトリを作成します。続いて、仮想環境を作成し、アクティブ化します。最後に、このWebアプリケーションをビルドするために必要なPythonパッケージをインストールします。
ターミナルウィンドウを開き、次のコマンドを入力します。
ここでは、このチュートリアル用に作成されたスタータープロジェクト をクローンしてtwilio-in-browser-calls
の名前を設定した後、このプロジェクトディレクトリに移動しています。このプロジェクトには、アプリケーションのビルドに使用するボイラープレートコードが含まれています。
内部には、Flaskアプリケーション用の次の標準ディレクトリがあります。
static
: すべての静的ファイルが保存されます。templates
: すべてのテンプレートが保存されます。
static
サブディレクトリには以下が含まれています。
css
: すべての CSSファイルが保存されます。このサブディレクトリの中にあるstyle.css
という名前のファイルは、アプリケーションクライアントUIのスタイル設定に使用されます。images
: すべての画像が保存されます。この サブディレクトリの中にあるuser.png
という名前のファイルは、アプリケーションクライアントUIに表示されます。js
: すべてのJavaScriptファイルが保存されます。 このディレクトリの中にはmodals.js
という名前のファイルがあります。このファイルには、templates
ディレクトリに保存されているモーダルを管理するためのコードが含まれています。
templates
サブディレクトリには3つのファイルが含まれています(call_in_progress_modal.html
、dial_modal.html
、incoming_call_modal.html
)。
call_in_progress_modal.html
ファイルには、通話中に表示されるモーダルを実装するHTMLコードが含まれています。このモーダルには、通話の経過時間、相手先の電話番号、通話の終了ボタン(赤色の電話アイコン)が表示されます。次のような表示になります。
dial_modal.html
ファイルには、電話番号をダイヤルするときに表示されるモーダルを実装するHTMLコードが含まれています。このモーダルには、数字パッドとボタン(緑色の電話アイコン)が表示されます。次のような表示になります。
incoming_call_modal.html
ファイルには、通話着信時のみに表示されるモーダルを実装するテンプレートのHTMLコードが含まれています。このモーダルには、着信中の電話番号と2つのボタン(緑色の電話アイコンと赤色の電話アイコン)が表示されます。着信コールに応答する場合は緑色のボタン、拒否する場合は赤色のボタンを使用します。
作業ディレクトリ内に仮想環境を作成し、アクティブ化します。UnixまたはMac OSシステムを使用している場合は、次のコマンドを実行します。
Windowsでチュートリアルを実行する場合には、コマンドプロンプトウィンドウに以下のコマンドを入力します。
仮想環境の作成とアクティブ化が完了すると、アプリケーションの作成に必要なライブラリーをインストールできます。
上記のコマンドでは、Pythonパッケージインストーラーのpip
を使用し、本プロジェクトで使用する以下のパッケージをインストールしました。
- Twilio: Twilio APIと通信するためのPythonパッケージ。
- Flask: Webアプリケーションを構築するためのPythonマイクロフレームワーク。これを使用し、Twilioとやり取りするためのWebhookの作成、通話を発着信するためのクライアントUIの作成を行います。
- python-dotenv: ファイルからキーと値のペアを読み出し、それを環境変数として追加するライブラリー。このモジュールを使用し、
.env
設定ファイルに保存されているTwilio認証情報を取得します。
参考までに、このチュートリアルがリリースされた時点での上記パッケージのバージョンとテスト済みの依存関係を以下に掲載します。
上記のPythonパッケージとは別に、次のフロントエンドライブラリーを使用します。
- Bootstrap: 最新のWebサイトを作成するために使用される強力なフロントエンドフレームワーク。
- Twilio Client JS SDK(Twilio.js): Webブラウザーから音声通話を行うことができるライブラリー。
- jQueryは: HTMLドキュメントのトラバーサルや操作、イベント処理、アニメーション、Ajaxなどをより簡単にする、高速で小さく機能豊富なJavaScriptライブラリー。DOM操作やイベント処理を行うために使用します。
- Font Awesome: 広く利用されているアイコンのSVG、フォント、CSSツールキット。アプリケーションクライアントでは、これらによりデザインされたいくつかのアイコンを使用します。
TwiMLアプリケーションの作成
このセクションでは、Twilio Console を使用して「TwiMLアプリ」を作成します。このアプリには、後でビルドするWebhookのURLを保存します。
新しいブラウザーウィンドウを開き、Twilioアカウントのコンソール>[Voice](音声)>[TwiML]>[TwiML Apps](TwiMLアプリ)の順にアクセスします。[Create new TwiML App](新しいTwiMLアプリを作成)ボタンをクリックします。すでに他のTwiMLアプリがある場合は赤い[+]アイコンをクリックします。
[Friendly Name](フレンドリー名)フィールドにTwiMLアプリの名前を入力します(例: in-browser calls)。ここでは、他のフィールドは空白のままにしておきます。[Create](作成)ボタンをクリックし、TwiMLアプリケーションを作成します。
TwiML Appsダッシュボードにリダイレクトされます。作成したTwiMLアプリをクリックします。このアプリのページで、SID値を選択してクリップボードにコピーします。
プロジェクトのルートディレクトリに.env
という名前のファイルを作成し、その中に次の内容を入力します。
Twilio APIキーの作成
次のステップでは、Voice API用のTwilio APIキーを作成します。APIキーはアクセストークンを生成するために使用されます。アクセストークンにより、ブラウザーで実行されているフロントエンドがTwilio APIを呼び出すことができます。
ブラウザーでTwilio Console >[Voice](音声)>[Settings](設定)>[API Keys](APIキー)の順にアクセスします。[Create new API Key](新しいAPIキーを作成)ボタンをクリックします。すでに他のAPIキーがある場合は赤い[+]アイコンをクリックします。
[Friendly Name](フレンドリー名)フィールドにAPIキーの名前を入力します(例: in-browser calls)。[Key Type](キーのタイプ)は[Standard](標準)のままにします。[Create API Key](APIキーを作成)ボタンをクリックしてAPIキーを作成します。
新しいAPIキーに関する情報が記載されたページにリダイレクトされます。[SID]と[Secret](秘密)の値をコピーし、.env
ファイルにTWILIO_API_KEY_SID
、TWILIO_API_KEY_SECRET
として貼り付けます。.env
ファイルは次のように表示されます。
[Got it!]フィールドにチェックを入れ、[Done](完了)ボタンをクリックします。
次は、Twilio Consoleのホームページに移動し、TwilioアカウントのSID値を次のように.env
ファイルにコピーします。
次に、Twilioアカウントのコンソール>[Phone Numbers](電話番号)>[Manage Numbers](番号の管理)>[Active Numbers](アクティブな番号)の順にアクセスし、このチュートリアル用に購入した番号を選択すると、この番号を設定できるページにリダイレクトされます。[Phone Number](電話番号)フィールドを見つけ、このフィールドの下に表示されている電話番号をコピーし、.env
ファイルにTWILIO_NUMBER
として貼り付けます。数字の間のスペースは削除しますが、先頭のプラス記号は残し、番号がE.164形式であることを確認します。
電話番号が追加されると、.env
ファイルは次のようになります。
Flaskアプリケーションの作成
このセクションでは、Flaskアプリケーションのロジックを作成します。Flaskアプリケーションにより、フロントエンドでの通話の発着信に必要なサポート機能が提供されます。
アプリケーションサーバーの作成
このサブセクションでは、通話の発着信に必要なエンドポイントを作成します。次のエンドポイントを作成する必要があります。
/
- アプリケーションUI(クライアント)の提供を担当するエンドポイント。/token
- アクセストークンの生成とクライアントへの返送を担当するエンドポイント。/handle_calls
- 通話の発着信に必要なTwiML命令の生成を担うエンドポイント。
プロジェクトのルートディレクトリにmain.py
という名前のファイルを作成します。任意のテキストエディタを使用してファイルを開き、次のコードを追加します。
ここでは、サーバーアプリケーションの構築に必要なパッケージをすべてインポートしました。
flask
は、アプリケーションのエンドポイントを定義するために使用されます。- この
twilio
パッケージはTwilio APIとのやり取りに使用され、クライアントで作成されるTwilioデバイスを介して通話の発着信を行えます。 load_dotenv
は、.env
ファイルからTwilioアカウントの認証情報をインポートするために使用されます。pprint
は、Twilioが/handle_calls
エンドポイントにコールの存在を通知するリクエストを送信する際の受信データのフォーマットと印刷に使用されます。os
は、load_dotenv
と併用され、.env
ファイルに保存されている認証情報を取得するために使用されます。
次のコードをmain.py
ファイルの最後に追加します。
アプリケーションは最初に.env
ファイルに格納されている環境変数をインポートします。その際にload_dotenv()
を呼び出します。これにより、このアプリケーションに必要な5つの設定変数を取得できます。
次に、Flask
アプリケーションインスタンスをapp
という名前の変数に作成し、それを使用してアプリケーションのエンドポイント/
を作成します。このルートは、後で作成するhome.html
という名前のテンプレートを提供しています。
次のコードを/
ルートの下に追加します。
これにより、/token
エンドポイントが追加されます。このエンドポイントは、アクセストークンをリクエストするクライアントから呼び出されます。
このエンドポイントがトリガーされた後、identity
という名前の変数を作成し、Twilio番号を割り当てます。IDはユーザー固有のものであり、複数のデバイスで同時にサインインすることができます。複数のユーザーが使用するアプリケーションサーバーでは、送信されるトークンリクエストに基づいて、ユーザーが誰で、何を許可するかを決定する必要があります。ユーザーの本人確認(ユーザーID)には、既存のログインシステムを使用するか、IDプロバイダー(セッションCookie、APIトークン、APIリクエストの保護に使用されるその他のメカニズム)を使用します。ただし、このチュートリアルでは、私たちが唯一のユーザーであるため、複数のIDを使用する必要はありません。このチュートリアルのために購入したTwilio番号は、この目的に適合しています。
次に、account_sid
、api_key
、api_key_secret
、identity
を使用してアクセストークンを作成します。このトークンの「グラント(認可)」をプロビジョニングすると、トークンを送信したクライアントに実行が許可される操作が決定されます。このアプリケーションでは、Voiceグラントオブジェクトを作成し、先に作成したTwiMLアプリのsid
を使用して設定します。
エンドポイントを完成させるため、access_token
とidentity
をJSON形式でクライアントに返します。
次のコードを/token
ルートの下に追加します。
このブロックは、/handle_calls
という名前のエンドポイントを追加しています。このエンドポイントは、通話の発着信の都度Twilioから呼び出されます。
このエンドポイントがトリガーされた後、pprint
を使用してrequest.form
の内容を表示し、続いてTwiML
応答オブジェクトとTwiML
dialオブジェクトを作成します。dial
オブジェクトでは、このチュートリアル用に購入したTwilio番号にcallerId
を設定します。これにより、このアプリケーションを使用して電話をかけたとき、受信者の電話端末にanonymous
ではなくこの番号が表示されるようになります。
その後、条件付きロジックを使用し、request.form
オブジェクトにTo
という名前のプロパティがあるか、このプロパティの値がtwilio_number
と一致するかを確認します。このテストでは、エンドポイントの呼び出しが通話の発信(受信ではない)向けであったことを確認します。これが最初に処理するケースとなります。
発信リクエストであることを確認した後、ダイヤルする番号をrequest.form['To']
の値として設定し、dial
オブジェクトをresponse
オブジェクトに追加し、response
オブジェクトを文字列としてTwilioに返します。Twilioはこれらの命令を実行し、リクエストされた番号をダイヤルします。
スクリプトの下部は、コマンドラインからスクリプトが呼び出されたときにポート3000でFlask開発サーバーを実行する標準条件です。
アプリケーションクライアントの作成
このサブセクションでは、ブラウザーでの通話の発着信を可能にするフロントエンドを作成します。
ホームページの作成
home.html
という名前のファイルをtemplates
ディレクトリ内に作成します。これを開き、次のコードを追加します。
このテンプレートは、この後でJavaScriptを使用して作成するTwilioデバイスの状態を監視できるコンソールを表示するページを実装しています。このテンプレートに、このプロジェクトのボイラープレートに付属しているcall_in_progress_modal.html
、dial_modal.html
、incoming_call_modal.html
テンプレートを含めました。このページには、電話アイコンの付いたボタンも表示されます。このボタンを押すたびにモーダルが開き、通話を発信したい番号をこのモーダルに入力します。
このテンプレートには、Bootstrap、jQuery、FontAwesome、twilio.js
ファイル以外に次のファイルが含まれています。
style.css
- アプリケーションのスタイル設定に使用されるCSSの一部が含まれているファイル。main.js
- Twilioデバイスを作成し、それをTwiMLアプリケーションに接続するためのコードが含まれているjavascriptファイル。modals.js
- アプリケーションのモーダルを管理するためのコードが含まれているjavascriptファイル。
style.css
ファイルとmodals.js
ファイルは、プロジェクトのボイラープレートリポジトリ内にあります。main.js
ファイルは次のサブセクションで作成します。
Twilioデバイスの作成
main.js
という名前のファイルをstatic/js
ディレクトリ内に作成します。これを開き、次のコードを追加します。
ここでは、ブラウザーでの通話の発着信を可能にするTwilioデバイスを作成します。
まず、jQueryが提供するgetJSON()
関数を使用してアプリケーションサーバーの/token
エンドポイントにGETリクエストを送信し、アクセストークンを取得します。トークンを取得した後、twilio.js
とトークンを使用してTwilioデバイスを作成し、それをTwiMLアプリケーションに接続します。
Twilioデバイスを作成した後、デバイスにいくつかのイベントリスナーと、UIを使用してデバイスと対話できるようにするコードを追加します。
通話の発信
このセクションでは、作成したアプリケーションを使用して通話を発信します。先に、アプリケーションを実行し、ngrokを設定し、TwiMLアプリを設定しておく必要があります。
プロジェクトディレクトリで2つ目のターミナルウィンドウを開き、Python仮想環境をアクティブ化し、次のコマンドを実行してアプリケーションを起動します。
上記のコマンドを実行すると、次のような表示になります。
https
ngrokのURLをクリップボードにコピーします。次に、Twilioアカウントのコンソール>[Voice](音声)>[TwiML]>[TwiML Apps](TwiMLアプリ)ダッシュボードに移動し、このチュートリアル用に作成したTwiMLアプリを選択します。
TwiML アプリ設定の[Voice](音声)セクションを見つけ、ngrok
から提供されたhttps://
URLの後ろに/handle_calls
を付加して「Request URL」(リクエストURL)フィールドに貼り付け、[Save](保存)ボタンをクリックします。これにより、アプリケーションをTwiML Appに接続するWebhookが作成されます。
この例では、ngrok URLはhttps://48dcc810632b.ngrok.io/handle_calls
です。URLの最初の部分は、ngrokが起動されるたびに変わります。
次に、マイク付きヘッドセットをコンピューターに接続してからブラウザーを開き、「http://localhost:3000/
」をアドレスバーに入力します。次のように表示されます。
Twilio.Device Ready!
というメッセージが表示された場合、Twilioデバイスは正常に動作しています。緑色の電話アイコンのあるボタンをクリックすると、ダイヤルモーダルが表示されます。
パッドの数字を使用して発信したい番号を入力するか、キーボードからパッド上部の入力フィールドに入力し、入力できたら緑色の電話マークをクリックして発信します。
このボタンをクリックすると、ブラウザーからマイク使用の許可を求められます。その場合は許可します。相手先の番号が着信に応答すると、通話中のモーダルが表示されます。
Flaskアプリケーションを実行しているターミナルに移動すると、Twilioが/handle_calls
エンドポイントに送信するリクエストデータが次のように表示されます。
プロパティのTo
の値(発信先の番号)がTwilio番号と一致していないため、handle_calls
エンドポイントのif
ステートメント内のコードが実行されました。
着信通話への応答
前のセクションでは、アプリケーションを使用して通話を発信しましたが、着信はまだ確認していません。通話の着信を可能にするには、main.py
、main.js
、home.html
にコードを追加し、このチュートリアル用に購入した番号をTwilio Consoleに設定して着信に対応できるようにする必要があります。
main.py
ファイルに戻り、/handle_calls
エンドポイントのコードを次のように置き換えます。
ここでは、else
ステートメントを/handle_calls
エンドポイントに追加しました。この部分のコードは、着信を受けた番号がこのチュートリアル用に購入した番号である場合、つまり着信コールが発生した場合に実行されます。
TwiML dialオブジェクトのcallerId
をrequest.form
のCaller
プロパティの値に設定しています。名前が示すように、Caller
はTwilio番号を呼び出している番号です。これは、アプリケーションUIで誰が呼び出しているかを確認できるようにするためです。また、dialオブジェクトのclient
には、/token
エンドポイントにアクセストークンを作成した際に使用したidentity
の値を設定します。
着信コールのフローを完了するには、dialオブジェクトをTwiML応答オブジェクトに追加し、この応答オブジェクトを文字列として返します。
main.js
ファイルに戻り、device.on(‘disconnect')
リスナーの下に次のコードを追加します。
ここでは、Twilioデバイスが着信コールを監視し、着信を検出するとコール着信中モーダルを表示できるイベントリスナーを追加しました。
Twilio Console >[Phone Numbers](電話番号)>[Manage Numbers](番号の管理)>[Active Numbers](アクティブな番号) ダッシュボードに移動し、このチュートリアル用に購入した番号を選択します。
電話番号設定の[Voice & Fax](音声とFAX)セクションを見つけ、[Configure With](設定)フィールドで[TwiML App](TwiMLアプリ)を選択します。続いて、[TwiML App]フィールドでこのチュートリアル用に作成したTwiMLアプリの名前を選択します。これにより、このチュートリアル用に購入したTwilio番号が、作成したTwiMLアプリにバインドされます。以降は、この番号が着信を受けるたびに、TwiMLアプリのWebhook URLとその他の設定を取得し、それを使用して通話に応答します。 この例では、https://48dcc810632b.ngrok.io/handle_calls
にPOSTリクエストを送信し、発信者番号やその他の有用な情報も含めています。
ブラウザーに戻り、http://localhost:3000/
に移動し、表示されたページにTwilio.Device Ready!
メッセージが表示されるまで待機します。次に、通話の発信ができるデバイスを使用し、このチュートリアル用に購入したTwilio番号に電話をかけます。着信音が鳴り始めると、コール着信中モーダルが表示されます。
通話に応答する場合は緑色の電話アイコンの付いたボタンを押し、通話を拒否する場合は赤色のアイコンのボタンを押します。
Flaskアプリケーションを実行しているターミナルに移動すると、Twilioが/handle_calls
エンドポイントに送信するリクエストデータが次のように表示されます。
まとめ
このチュートリアルでは、Twilio Voice APIを使用してブラウザーで通話を発信または受信する方法を学習しました。また、Flaskフレームワークを使用してアプリケーションクライアントを構築し、Twilio Client JS SDKで作成したTwilioデバイスとの対話を可能にする方法も学びました。
アプリケーション全体のコードは、こちらのリポジトリ(https://github.com/CSFM93/twilio-in-browser-calls)にあります。
Carlos Mucuho氏は、モザンビークの地質学者から転身した開発者であり、プログラミングを使用してアイデアを現実に変えることを楽しんでいます。https://github.com/CSFM93