Twilio PROGRAMMABLE VOICE クイックスタート FOR NODE.JS 写経

Twilioの勉強のため、[PROGRAMMABLE VOICE クイックスタート FOR NODE.JS](https://jp.twilio.com/docs/voice/quickstart/node)の写経(という名のコピペ)をやってみました。

## 始める前にまずはアカウント作成
Twilioをするには、当然ですがまずはアカウントを作成しなければなりません。
### [Twilioトップページ](https://twilio.kddi-web.com/)にアクセスし右上の「サインアップ」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17554/22af31fa-4eae-bdd8-a29c-8d578a215fc1.png)


### 「トライアルサインアップ」動画を視聴
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17554/ec8525de-50fe-e45b-f526-73d4bc87c91e.png)

「サインアップ」ボタンをクリックすると、ページ内ポップアップで利用規約およびプライバシーポリシーへの同意チェックボックスとともに「トライアルサインアップ」という動画が表示されますので、その動画を視聴すればトライアルサインアップの流れは把握できます。
動画の説明に従い、アカウントの作成およびtiwilioの電話番号の取得を行います。
動画内においてTwilioの電話番号を「購入」するという説明がされますが、電話番号１つまではトライアルの範囲となり無料となります。
また、動画内で説明があるように、アカウント作成の際にSMS認証を行った(スマホ等一般の)外部の電話番号がトライアル(無料)で利用できる(電話が掛けられる)唯一の外部の電話番号となります(「検証済電話番号」と呼ぶようです)。
アカウントの作成及び、Twilioの電話番号を取得が済みましたら、クイックスタートの開始です。

## [PROGRAMMABLE VOICE クイックスタート FOR NODE.JS](https://jp.twilio.com/docs/voice/quickstart/node)
クイックスタートを始めるにあたり、Twilio Node.jsモジュールのインストールを行います。
```
$ npm i -S twilio
```
## クイックスタート その１「[Node.jsで通話を発信する](https://jp.twilio.com/docs/voice/quickstart/node#make-an-outgoing-phone-call-with-nodejs)」
### コードをコピペ

```js
// Download the Node helper library from twilio.com/docs/node/install
// These consts are your accountSid and authToken from twilio.com/user/account
const accountSid = 'ACxxxxxxxxxxxxxxxxx';
const authToken = 'your_auth_token';
const Twilio = require('twilio');
const client = new Twilio(accountSid, authToken);

client.api.calls
  .create({
    url: 'http://demo.twilio.com/docs/voice.xml',
    to: '+14155551212',
    from: '+15017122661',
  })
  .then(call => console.log(call.sid));
```
コピペ元のコードのaccountSidには、自動で自分のaccountSidが既に設定されていますが、authTokenは自動で設定されていませんので、この部分を自分のAUTHTOKENに変更します。

### AUTHTOKENの確認
AUTHTOKENは[Twilioコンソール](https://jp.twilio.com/console)のダッシュボードのページで確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17554/92625781-5345-8814-9df1-6f15654b2852.png)
デフォルトではマスクされていますので、左の眼のアイコンをクリックするとマスクが解除されAUTHTOKENが表示されますので、これをコピーし先ほどコピペしたコードのauthTokenの'your_auth_token'の部分にペーストします。

### to,fromの編集
Twilioでの電話番号のフォーマットは、[E.164形式](https://jp.twilio.com/docs/glossary/what-e164)と呼ばれるフォーマットが使用されます。
海外の商品をネットショッピングで購入するなど、海外のサイトで電話番号を入力する場面があると思いますが、その際+81で始まり、頭の0を外した市外局番＋電話番号を入力したかと思いますがあれと(ほぼ)同じです。
E.164形式で、toの番号をかけたい電話番号(検証済電話番号)に、fromをTwilioの電話番号に変更します。
以上でコードの編集は終了です。

### 実行
コードの編集が終わりましたら、実行します。
すると、数秒後にtoに設定した電話に電話がかかります。
電話を受けると、トライアルアカウントの場合、**最初にトライアルの自動音声が流れます**。
トライアルの自動音声の指示に従い、キーパッドのいずれかのボタンをタップすると、実際のコードの処理が行われます。
具体的には、トライアルの自動音声とは別の自動音声が流れた後に、有名な曲が流れます。
この自動音声と有名な曲を流すというのは、コードのurlに設定されている http://demo.twilio.com/docs/voice.xml で処理が行われています。
このXMLファイルは[TwiML](https://jp.twilio.com/docs/voice/twiml)と呼ばれるもので、着信(受信)したときどのようにTwilio側で処理を行うかを記述したXMLファイルです。

```xml:voice.xml
<Response>
  <Say voice="alice">Thanks for trying our documentation. Enjoy!</Say>
  <Play>http://demo.twilio.com/docs/classic.mp3</Play>
</Response>
```
以上で、クイックスタートその１は終了です。

## クイックスタート その２「[Node.jsとExpressで着信通話に応答する](https://jp.twilio.com/docs/voice/quickstart/node#receive-and-respond-to-inbound-voice-calls-with-nodejs-and-express)」
タイトルにもExpressと書かれており、Twilioのクイックスタートの説明においてもExpressをインストールすることになっていますが、Expressは必要ありません。
クイックスタートその２はWebHookを使用したサンプルとなっています。
Twilioの電話番号に電話をかけると、WebHookに設定したURLにリクエストが飛び、リクエストに対してTwiMLを返すとTwiMLに従いその発信が処理されるというものです。


### コードをコピペ

```js:コード
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/');
```
Webサーバーのコードとなっております。
今回は、コードを編集する箇所はありませんのでコピペしたらそのまま実行し、Webサーバーを起動させておきます。

### ngrokのダウンロードおよび実行
さて、本来であれば、Webサーバーはグローバルにアクセスできる環境に配置すべきですが、今回はローカル環境でWebサーバーを立ち上げたので、これを外からアクセスできるようにしなければなりません。
ルーターのポート開放やポートフォワーディングなどの設定を行い、外部からのアクセスを可能にさせるというのもありますが、Twilioのクイックスタートの説明において、[ngrok](https://ngrok.com)というツール(サービス)が紹介されています。
このツールは、ローカルで立ち上げたWebサーバーを簡単に公開できるというものです。
私の環境はWindowsですので、Windowsで説明すると、ngrokの[downloadページ](https://ngrok.com/download)にアクセスし、ツールをダウンロードします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17554/39c74b06-10b2-516d-64ab-3e6e6cd1842d.png)
ダウンロードした圧縮ファイルを適当なフォルダに展開し、そのフォルダにパスを通します。
コマンドプロンプトを起動し、

```js
> ngrok http 1337
```
と、コマンドを入力して実行します。
すると、ngrokでフォワーディングが行われるURLが表示されますので、このURLをコピーしておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17554/d9c3a85f-3125-8e0f-2898-86c1de242871.png)

### Twilioの電話番号にWebHookの設定を行います。
[Twilioコンソール](https://jp.twilio.com/console)にアクセスし、一番左のタブから「Programmable Voice」タブ(受話器のアイコン)をクリックし、サブメニューの「電話番号」をクリック、「電話番号」のコンテンツが表示されるので、「Manage Numbers」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17554/850c4c2f-7ab7-9d51-00ab-a16659596a58.png)
取得したTwilioの電話番号のリストが表示されますので、WebHookを設定するTwilioの電話番号をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17554/5252ce2d-11ec-bd58-f50e-af470aa2f2c9.png)
クリックしたTwilioの電話番号に対する設定フォームが表示されますので、「通話着信時」の項目で最初のドロップダウンリストで"WebHook"を選択(デフォルトで"WebHook"になっていると思います)、入力欄にngrok実行時にコピーしたngrokのURLをペースト、最後のドロップダウンリストで"HTTP POST"(デフォルトで"HTTP POST"になっていると思います)を選択したら、最後に「保存」ボタンをクリックして、設定を反映します。
以上で着信応答の環境が整いました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17554/760d1035-0d23-a863-2f86-de1bcd1e481b.png)

### Twilioの電話番号に電話をかけてみる
着信応答の環境が整いましたら、外部の電話(検証済電話番号)から電話をかけてみます。
すると、クイックスタートその１と同様に、最初に**トライアルの自動音声が流れます**。
音声に従いキーパッドのいずれかのボタンをタップしたら、実際のコードの処理が行われ、
"Hello from your pals at Twilio! Have fun"
という自動音声が流れます。

## WebHookについて
WebHookの設定において、"HTTP POST"を設定しましたが、"HTTP GET"でも問題はありません。
"HTTP GET"の場合はURLのクエリーパラメーターに、"HTTP POST"の場合はリクエストボディーに以下の情報が付与されリクエストが飛んできました。

|キー|値 |
|:---:|---|
|Called|"Twilioの電話番号(E.164形式)"|
|ToState|""|
|CallerCountry| "JP"|
|Direction|"inbound"|
|CalledVia|"Twilioの電話番号(E.164形式ではなく050で始まる普通のフォーマットでの電話番号)"|
|CallerState|""|
|ToZip|""|
|CallSid|"CA1595d8aae71db71549bd64b0ad0e0152"|
|To|"Twilioの電話番号(E.164形式)"|
|CallerZip|""|
|ToCountry|"JP"|
|ApiVersion|"2010-04-01"|
|CalledZip|""|
|CalledCity|""|
|CallStatus|"ringing"|
|From|"かけた側の外部の電話番号(E.164形式)"|
|AccountSid|"ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"|
|CalledCountry|"JP"|
|CallerCity|""|
|Caller|"かけた側の外部の電話番号(E.164形式)"|
|FromCountry|"JP"|
|ToCity|""|
|FromCity|""|
|CalledState|""|
|ForwardedFrom|"Twilioの電話番号(E.164形式ではなく050で始まる普通のフォーマットでの電話番号)"|
|FromZip|""|
|FromState|""|

この情報をもとに、発信者別にTwiMLのDialで別々の担当者に転送するといったことができると思います。

## 最後に
長々と事細かく書きましたが、２つのプログラムを実行するだけで実際は5分もかからずに終わってしまうと思います。