Programmable Voice クイックスタート for Node.js

Twilio Programmable Voiceを使用すればたった数行のコードで、Node.jsアプリケーションで通話の発着信ができるようになります。

本Node.jsクイックスタートでは開発を容易にするために、TwilioのREST APITwilio Node.jsヘルパーライブラリーを使用してこれを行う方法を説明していきます。 

このクイックスタートでは、下記のことを学んでいきます:

  1. Twilioにサインアップして、音声通話機能を持ったはじめてのTwilio電話番号を入手する
  2. 通話の発着信を行えるように開発環境をセットアップする
  3. MP3ファイルを再生する通話を発信する
  4. 通話を着信させ、テキストtoスピーチを使用して発信者にメッセージを読み上げる応答を返す

ビデオを見ながらの入門がお好みですか? Node.jsで通話の発着信を行う方法 YouTubeビデオ (英語) をご覧ください。

すでにTwilioアカウントと音声通話機能を持ったTwilio電話番号をお持ちなら、すでに準備万端です! ログインして次のステップまで読み飛ばしてください。

Node.jsで通話を発信できるようになる前に、Twilioアカウントにサインアップするか、すでにアカウントをお持ちの場合はログインが必要になります。 

続いて必要になるのは、音声通話機能を持つTwilio電話番号です。 音声通話機能を持つTwilio電話番号を現在お持ちでない場合は、購入する必要があります。 番号を購入ページに移動後、「音声通話 (Voice)」チェックボックスをオンにして、「検索 (Search)」をクリックします。

音声通話の利用可能な電話番号の検索

すると、利用可能な電話番号と、その機能の一覧が表示されます。 お好みに合った番号が見つかったら「購入」をクリックすると、それがアカウントに追加されます。

これでTwilioアカウントとプログラマブルな電話番号が手に入ったので、通話の発信に必要な基本ツールが揃ったことになります。

TwilioのHTTP APIを使用して通話を発信できますが、Node.js用のTwilioモジュールを使用してこれをより容易にします。 ここでこれをインストールしましょう。 

すでに他のNode.jsクイックスタートを終えていて、Twilio Node.jsモジュールがインストールされている場合は、このステップを読み飛ばしてすぐに最初の通話を発信できます。

ターミナルを開いて下記のコマンドを入力することで、すでにNode.jsがすでにPCにインストール済みかどうか確認できます:

$ node --version

下記のように表示されます:

$ node --version
v8.9.1

If you're on version 2.11 or earlier, we recommend you upgrade with the most recent version.

Node.jsがインストールされていない場合は、ターミナルで下記のコマンドをインストールすることで別のパッケージマネージャーであるhomebrewでインストールを行えます:

brew install node

Windows PCをお使いの場合は、nvm-windowsをインストールして、Node.jsとそのパッケージマネージャーであるnpmをインストールしてください。 Windowsユーザーはこちらの素晴らしいチュートリアルの手順にしたがってインストールできます。

Twilio Node.jsモジュールをインストールする

ライブラリーをインストールするもっとも簡単な方法は、必要なライブラリーのインストールに使用できるNode.jsのパッケージマネージャーであるnpmを使用することです。 Nodeおよびnpmがすでにインストールされたマシン上でターミナル、またはコマンドライン・インターフェイスを開き、新規のディレクトリーで下記のコマンドを実行します。

npm install twilio

Node.jsで通話を発信する

 ここで新Twilio Node.jsライブラリーを活用しましょう。 

単一ののAPIリクエストで、先ほど購入したTwilio電話番号から通話を発信できます。 "make_call.js" という名前の新規ファイルを開き、下記コードをペーストします。

コードサンプルを読み込んでいます...
Language
SDKバージョン:
  • 2.x
  • 3.x
形式:
  • JSON
  • XML
// Download the Node helper library from twilio.com/docs/node/install
// These vars are your accountSid and authToken from twilio.com/user/account
const accountSid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);

client.calls.create(
  {
    url: 'http://demo.twilio.com/docs/voice.xml',
    to: '+14155551212',
    from: '+15017122661',
  },
  (err, call) => {
    console.log(call.sid);
  }
);
// Download the helper library from https://www.twilio.com/docs/node/install
// Your Account Sid and Auth Token from twilio.com/console
const accountSid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);

client.calls
      .create({
         url: 'http://demo.twilio.com/docs/voice.xml',
         to: '+123456789',
         from: '+987654321'
       })
      .then(call => console.log(call.sid))
      .done();
{
  "account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "annotation": null,
  "answered_by": null,
  "api_version": "2010-04-01",
  "caller_name": null,
  "date_created": "Tue, 31 Aug 2010 20:36:28 +0000",
  "date_updated": "Tue, 31 Aug 2010 20:36:44 +0000",
  "direction": "inbound",
  "duration": "15",
  "end_time": "Tue, 31 Aug 2010 20:36:44 +0000",
  "forwarded_from": "+141586753093",
  "from": "+987654321",
  "from_formatted": "+987654321",
  "group_sid": "GPXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "parent_call_sid": "CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "phone_number_sid": "PNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "price": "-0.03000",
  "price_unit": "USD",
  "sid": "CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "start_time": "Tue, 31 Aug 2010 20:36:29 +0000",
  "status": "completed",
  "subresource_uris": {
    "notifications": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Notifications.json",
    "recordings": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Recordings.json",
    "feedback": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Feedback.json",
    "feedback_summaries": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/FeedbackSummary.json"
  },
  "to": "+123456789",
  "to_formatted": "+123456789",
  "uri": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.json",
  "url": "http://demo.twilio.com/docs/voice.xml"
}
<TwilioResponse>
	<Call>
		<Sid>CAa346467ca321c71dbd5e12f627deb854</Sid>
		<DateCreated>Thu, 19 Aug 2010 00:25:48 +0000</DateCreated>
		<DateUpdated>Thu, 19 Aug 2010 00:25:48 +0000</DateUpdated>
		<ParentCallSid/>
		<AccountSid>ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</AccountSid>
		<To>+14155551212</To>
		<FormattedTo>(415) 555-1212</FormattedTo>
		<From>+14158675310</From>
		<FormattedFrom>(415) 867-5310</FormattedFrom>
		<PhoneNumberSid></PhoneNumberSid>
		<Status>queued</Status>
		<StartTime/>
		<EndTime/>
		<Duration/>
		<Price/>
		<Direction>outbound-api</Direction>
		<AnsweredBy/>
		<ApiVersion>2010-04-01</ApiVersion>
		<ForwardedFrom/>
		<CallerName/>
		<Uri>/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAa346467ca321c71dbd5e12f627deb854</Uri>
		<SubresourceUris>
			<Notifications>/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAa346467ca321c71dbd5e12f627deb854/Notifications</Notifications>
			<Recordings>/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAa346467ca321c71dbd5e12f627deb854/Recordings</Recordings>
		</SubresourceUris>
	</Call>
</TwilioResponse>
通話の発信

このコードは引数として渡された2つの電話番号間の通話を開始します。 「from」番号は皆さんのTwilio番号で、「to」番号は通話の発信先です。 

URL」引数は、着信側が電話に応答した際にTwilioが次に何を行うべきかを指示するTwiML (=Twilio Markup Language, Twilioマークアップ言語) を指します。 このTwiMLはTwilioに対してテキストToスピーチを使用してメッセージを読み上げ、それからMP3ファイルを再生するよう指示します。

しかしコードが動作するようになる前に、皆さんのTwilioアカウントで機能するように少々編集が必要です。

プレースホルダーのクレデンシャル値を置き換える

accountSidおよびauthTokenに対応するプレースホルダー値を、お使いのTwilioの認証情報に置き換えます。

https://jp.twilio.com/console にアクセスしてログインします。 このページ上で、今回のようなTwilio Client経由でメッセージを送信する際に常に必要になる一意のアカウントSIDおよび認証トークンが見つかります。 認証トークンは、目玉アイコンをクリックすると表示されます:

make_call.jsを開き、accountSidおよびauthTokenに対応する値をご使用のアカウントの一意な値に置き換えます。 

ご注意ください: 初めのうちは認証情報をハードコーディングしても構いませんが、本番環境にデプロイするにあたっては、環境変数を使用してこれらが漏洩しないようにしてください。 追加情報については、環境変数の設定方法を参照してください。

toおよびfrom電話番号を置き換える

数分前に購入した、音声通話機能対応の電話番号を覚えていますか? どうぞ、既存のfrom番号をご自身の番号に置き換えてください。 また、E.164形式が使用されていることも確認します。

[+][country code][phone number including area code]

to電話番号を、ご自身の携帯電話番号に置き換えます。 通話の着信が行える電話番号であればどれでも使用できますが、ご自身の電話機を使用すれば魔法のような出来事を目の当たりにできる点で良いアイディアです。 上記同様、この値にはE.164形式を使用してください。

変更を保存し、ターミナルから下記のコマンドを実行してコードを実行します:

node make_call.js

これにて以上です! Twilio番号からの通話が着信し、短いメッセージが読み上げられます。😉 

トライアルアカウントをご使用の場合、Twilioで検証済みの電話番号に発信先が制限されます。 電話番号はTwilioコンソール内の検証済み発信者番号にて検証できます。 その他のトライアルアカウントの制限については、無料のTwilioトライアルアカウントの仕組みについてのガイドを参照してください。

続いて、Twilio電話番号にかかってきた通話に応答する方法を学習しましょう。 まずはExpressサーバーを用意して起動しておく必要があります。

Node.jsとExpressで着信通話に応答する

Twilio電話番号に通話が着信すると、ご用意いただいたサーバーにHTTPリクエストが送信されます。 このコールバックの仕組みをWebhookと呼んでいます。 Twilioが開発中のアプリケーションにリクエストを送信すると、着信への応答方法を指示するTwiML XML形式でレスポンスすることが想定されます。 

着信通話を処理するには、TwilioからのHTTPリクエストを受け付ける軽量なWebアプリケーションが必要です。 アプリケーションから通話の発着信を行うのに使用できるWebフレームワークは多数ありますが、このクイックスタートではNode.jsと一緒にExpressを使用することにします。

コマンドラインで下記のコマンドを実行します

npm install express --save

「server.js」という名前のファイルを作成して下記のコードを使用し、受信メッセージを処理できるサーバーを作成します。

コードサンプルを読み込んでいます...
Language
SDKバージョン:
  • 2.x
  • 3.x
const http = require('http');
const twilio = require('twilio');

http
  .createServer((req, res) => {
    // Create TwiML response
    const twiml = new twilio.TwimlResponse();
    twiml.say('Hello from your pals at Twilio! Have fun.');

    res.writeHead(200, { 'Content-Type': 'text/xml' });
    res.end(twiml.toString());
  })
  .listen(1337, '127.0.0.1');

console.log("TwiML servin' server running at http://127.0.0.1:1337/");
const http = require('http');
const VoiceResponse = require('twilio').twiml.VoiceResponse;

http
  .createServer((req, res) => {
    // Create TwiML response
    const twiml = new VoiceResponse();

    twiml.say('Hello from your pals at Twilio! Have fun.');

    res.writeHead(200, { 'Content-Type': 'text/xml' });
    res.end(twiml.toString());
  })
  .listen(1337, '127.0.0.1');

console.log('TwiML server running at http://127.0.0.1:1337/');
メッセージを読み上げるTwiMLを生成する

下記コマンドでサーバーを実行します:

node server.js

http://127.0.0.1:1337/でローカルポートを解放すると、Webブラウザーに着信通話で読み上げて欲しいメッセージを伴うXMLを返すポート1337で実行されているサーバーが確認できるはずです。

これで、あとやっておくべきことはこのエンドポイントをTwilioからアクセスできるようにすることです。

Twilioがアプリケーションと通信できるようにする

着信通話に対する応答の中でTwilioに行なって欲しいことを指示できるようになる前に、まず皆さんのサーバーをインターネット上に公開することです。 ローカルの開発サーバーの実行時は、それがローカルネットワーク上からしかアクセスできない見込みが非常に高くなっています。 でもご心配なく。 サーバーをテストする簡単な方法をお見せします。

多くのTwilio製品やサービスは皆さんのアプリケーションとの通信にWebhookを使用します。 たとえばTwilioに通話が着信したとき、皆さんがあらかじめ指定しておいた特定のURLにTwilioからアクセスを行い、それに対して皆さんのサーバーは応答を処理する方法の指示を供給します。

server.js内のコードの一部は、発信者に対して「スピーチ」を返すために使用できる指示の一例になります。 とにかくこのサーバーを外部に公開する方法を探さなければなりません。

(外部のホスティングサービスにデプロイするなど)このコードを公開する方法はたくさんありますが、弊社ではngrok(エングロック)と呼ばれるツールの使用を推奨します。 ngrokを開始すると、このツールはngrok.ioドメイン上の一意なURLを提供し、受信リクエストをお使いのローカル開発環境に転送します。

アーキテクチャーは下記のようになります:

Twilioがローカルサーバーにアクセスできるようにするために、ngrokがどのように役に立つのか

まだNgrokを使用していない場合はダウンロードページにアクセスし、お使いのオペレーティングシステム用の適切なバイナリーをダウンロードしてください。 ダウンロードが済んだらパッケージを展開します。

MacまたはLinuxをお使いの場合は、以上で作業はおしまいです。 Windowsをお使いの場合は、Windows上でngrokをインストールおよび構成するガイドに従ってください。 いくつかの素晴らしいヒントや裏技を含むngrokの追加情報については、こちらの詳しいブログ投稿(英語)をご参照ください。

ローカルサーバーをngrokで公開する

ダウンロードが済んだら、先ほど作成したサーバーファイルを実行してみましょう:

node server.js

ローカルアプリケーション ローカルで実行してください。 そうしなければngrokが正常に動作しません。

続いて新規のターミナルタブまたはウィンドウを開いて、下記のコマンドでngrokを実行します:

ngrok http 1337

ローカルサーバーが異なるポート番号で実行されている場合は、1337を正しいポート番号に置き換えてください。

下記のような出力がご覧いただけるでしょう。

ngrok-node-voice-1337port

この出力から公開URLをコピーしブラウザーにペーストします。 Expressアプリケーションの「Hello from your pals at Twilio!」メッセージが表示されます。

Twilio Webhookを構成する

ここでこの公開URLを使用して、これをConsole内で電話番号のいずれかに対してWebhookとして構成することが必要です。 Consoleに戻って電話番号を選択し、「通話着信時 (A CALL COMES IN) 」のポップアップを「Webhook」に変更、続いて外部URLの項目をご自身のサービスのもの、たとえば 「https://069a61b7.ngrok.io/voice」 に変更します。

where-to-put-ngrok-url-configure-number-nodejs-voice-qs

「保存 (Save) 」をクリックしていることを確認して、ターミナルに戻ります。 ngrokがターミナルのタブでまだ実行されていることを確認し、別のタブでまだnode server.js が実行されていない場合はこれを実行します。  

Twilio電話番号に通話を発信しましょう。 数秒後にngrokコンソールでHTTPリクエストが確認でき、通話が接続されると短いメッセージが聞こえてきます。

簡単でしょう? Node.jsで通話の発着信ができましたね。 

関連トピック

これで、Node.jsによる通話の発信と着信通話への応答についての基本が理解できました。

このアプリケーションではテキストtoスピーチを使用して発信者にメッセージを読み上げるTwiML動詞の<Say>のみを使用しました。 他のTwiML動詞で他の強力な仕組みや通話フローを作成できます。 <Record><Gather>、それから<Conference>など少し試してみましょう。

以下のページをご覧いただき、さらに理解を深めてください:

皆さまが何を開発されるのか、目にするのが待ちきれません!

ヘルプが必要ですか?

誰しもが一度は考える「コーディングって難しい」。そんな時は、お問い合わせフォームから質問してください。 または、Stack Overflow でTwilioタグのついた情報から欲しいものを探してみましょう。

コードサンプルを読み込んでいます...
SDKバージョン:
  • 2.x
  • 3.x
形式:
  • JSON
  • XML
// Download the Node helper library from twilio.com/docs/node/install
// These vars are your accountSid and authToken from twilio.com/user/account
const accountSid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);

client.calls.create(
  {
    url: 'http://demo.twilio.com/docs/voice.xml',
    to: '+14155551212',
    from: '+15017122661',
  },
  (err, call) => {
    console.log(call.sid);
  }
);
// Download the helper library from https://www.twilio.com/docs/node/install
// Your Account Sid and Auth Token from twilio.com/console
const accountSid = 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);

client.calls
      .create({
         url: 'http://demo.twilio.com/docs/voice.xml',
         to: '+123456789',
         from: '+987654321'
       })
      .then(call => console.log(call.sid))
      .done();
{
  "account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "annotation": null,
  "answered_by": null,
  "api_version": "2010-04-01",
  "caller_name": null,
  "date_created": "Tue, 31 Aug 2010 20:36:28 +0000",
  "date_updated": "Tue, 31 Aug 2010 20:36:44 +0000",
  "direction": "inbound",
  "duration": "15",
  "end_time": "Tue, 31 Aug 2010 20:36:44 +0000",
  "forwarded_from": "+141586753093",
  "from": "+987654321",
  "from_formatted": "+987654321",
  "group_sid": "GPXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "parent_call_sid": "CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "phone_number_sid": "PNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "price": "-0.03000",
  "price_unit": "USD",
  "sid": "CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "start_time": "Tue, 31 Aug 2010 20:36:29 +0000",
  "status": "completed",
  "subresource_uris": {
    "notifications": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Notifications.json",
    "recordings": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Recordings.json",
    "feedback": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Feedback.json",
    "feedback_summaries": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/FeedbackSummary.json"
  },
  "to": "+123456789",
  "to_formatted": "+123456789",
  "uri": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.json",
  "url": "http://demo.twilio.com/docs/voice.xml"
}
<TwilioResponse>
	<Call>
		<Sid>CAa346467ca321c71dbd5e12f627deb854</Sid>
		<DateCreated>Thu, 19 Aug 2010 00:25:48 +0000</DateCreated>
		<DateUpdated>Thu, 19 Aug 2010 00:25:48 +0000</DateUpdated>
		<ParentCallSid/>
		<AccountSid>ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</AccountSid>
		<To>+14155551212</To>
		<FormattedTo>(415) 555-1212</FormattedTo>
		<From>+14158675310</From>
		<FormattedFrom>(415) 867-5310</FormattedFrom>
		<PhoneNumberSid></PhoneNumberSid>
		<Status>queued</Status>
		<StartTime/>
		<EndTime/>
		<Duration/>
		<Price/>
		<Direction>outbound-api</Direction>
		<AnsweredBy/>
		<ApiVersion>2010-04-01</ApiVersion>
		<ForwardedFrom/>
		<CallerName/>
		<Uri>/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAa346467ca321c71dbd5e12f627deb854</Uri>
		<SubresourceUris>
			<Notifications>/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAa346467ca321c71dbd5e12f627deb854/Notifications</Notifications>
			<Recordings>/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls/CAa346467ca321c71dbd5e12f627deb854/Recordings</Recordings>
		</SubresourceUris>
	</Call>
</TwilioResponse>
SDKバージョン:
  • 2.x
  • 3.x
const http = require('http');
const twilio = require('twilio');

http
  .createServer((req, res) => {
    // Create TwiML response
    const twiml = new twilio.TwimlResponse();
    twiml.say('Hello from your pals at Twilio! Have fun.');

    res.writeHead(200, { 'Content-Type': 'text/xml' });
    res.end(twiml.toString());
  })
  .listen(1337, '127.0.0.1');

console.log("TwiML servin' server running at http://127.0.0.1:1337/");
const http = require('http');
const VoiceResponse = require('twilio').twiml.VoiceResponse;

http
  .createServer((req, res) => {
    // Create TwiML response
    const twiml = new VoiceResponse();

    twiml.say('Hello from your pals at Twilio! Have fun.');

    res.writeHead(200, { 'Content-Type': 'text/xml' });
    res.end(twiml.toString());
  })
  .listen(1337, '127.0.0.1');

console.log('TwiML server running at http://127.0.0.1:1337/');