Twilio Client ハンズオン勉強会資料

[【Twilio-UG 東京】Twilio Client ハンズオン勉強会](https://twiliojp-ug.doorkeeper.jp/events/55307) のハンズオン資料です。

発表資料はこちら
https://speakerdeck.com/honkimi/twilio-client-mian-qiang-hui

## 第1部: Twilio Client を動かす
ひとまずは本ハンズオンで「動く」というところまで持っていくことを目標にします。

ハンズオンの途中で、余裕のある方向けにソースコードの解説を行います。


### 環境のセットアップ
Ruby, Node.js, PHP, Python のいずれかの実行環境

ngrok (ローカルサーバーを外部に一時的に公開できるツール)
https://ngrok.com/download


### アカウント情報の取得

- TWILIO_ACCOUNT_SID
- TWILIO_AUTH_TOKEN
- TWILIO_TWIML_APP_SID
- TWILIO_CALLER_ID:

QuickStart で Client 環境をセットアップ

https://jp.twilio.com/docs/quickstart/client/javascript#download-configure-and-run-the-starter-app

それぞれの Github の README を読みながら、セットアップに挑戦しましょう！

上記ドキュメント内にある `ngrok` を使って、 Twilio Client から携帯電話への番号発信までできたら、大成功です。

## 着信の設定
QuickStart で番号発信ができたら、着信の設定もトライしましょう。

### プログラムコードの修正
まず、着信の設定を簡単にするために各プログラムのソースコードのうち、`identity`を生成している部分を修正します。

```ruby
  identity = Faker::Internet.user_name.gsub(/[^0-9a-z_]/i, '')
```

👇

```ruby
  identity = "twilio_user"
```

### TwiML Bins のセットアップ
TwiML Bins は TwiML を簡単にセットアップできる開発ツールです。
https://jp.twilio.com/console/dev-tools/twiml-bins

Dual Channel Recording の録音モードに指定します。(New)

```
<Response>
  <Dial callerId="＋８１..購入した番号" record="record-from-answer-dual">
    <Client>twilio_user</Client>
  </Dial>
</Response>
```

そして、電話番号の設定へ行き、番号詳細ページの `A CALL COMES IN` を、セットした TwiML Bins に指定してあげます。
https://jp.twilio.com/console/phone-numbers/incoming
![スクリーンショット 2016-12-17 21.56.58.png](https://qiita-image-store.s3.amazonaws.com/0/11103/3db09cec-b4fc-9237-c745-12157f551ed0.png)

一度修正を加えたので Node.js を再起動します。

これだけで 購入した番号に電話をかけると、Client で着信ができるようになります。

おめでとうございます! Twilio で電話の受発信ができるようになりました。本格的にサービスとして公開するには、 ngrok ではなく、URL が固定の Web サーバーを用意し、TwiML の指定先を変える必要があります。

### ソースコードの解説

- 全体像
- ケイパビリティトークンの生成
- JavaScript SDK の各種イベント

それでは、いよいよ Twilio Client 1.4 の最新機能を見ていきましょう。

## 第2部: 最新の Twilio Client を覗いてみよう
### Twilio の Insgihts をオンにする
https://jp.twilio.com/console/voice/insights/settings
にて、Twilio の Insights をオンにします。これで、電話ごとに情報の詳細を出力してくれるようになります。

### Twilio Client のアップデート
`public/index.html`の Twilio Client の読み込み先を編集

`<script type="text/javascript" src="//media.twiliocdn.com/sdk/js/client/v1.3/twilio.min.js"></script>`
👇
`<script type="text/javascript" src="//media.twiliocdn.com/sdk/js/client/v1.4/twilio.min.js"></script>`

ひとまずこれで通話してみましょう。

その後、Twilio の 電話のログへ行き、Twilio <-> Client の通話ログを開きます。
https://jp.twilio.com/console/voice/logs/calls

![スクリーンショット 2016-12-17 22.33.04.png](https://qiita-image-store.s3.amazonaws.com/0/11103/d2de2bc0-d898-5bb8-3572-0981d719973b.png)

このように、Client と通話したログには、新しく Insights Summary, Events, Metrics の3つのタブが出現します。

#### Insights Summary
通信状況の概要を示します。専門のネットワーク用語をいくつか解説します。

#### Events
ブラウザと Twilio の接続開始から終了までの各種イベントを表示します。

Twilio Client で使われている WebRTC という技術の詳細です。専門的な内容となるため、今回の勉強会では割愛します。

#### Metrics
通話状況の詳細のグラフを表示します。通話のどの時間帯にどれだけネットワーク状況が低下したのか、などをより具体的に閲覧することができます。

### 通話中の通話状況の取得

Twilio Client 1.4 はこれだけではありません。通話中に、その通話の状況をイベントとしてキャッチすることができます。

quickstart.js を編集していきます。

```
Twilio.Device.connect(function (conn) {
  log('Successfully established call!');
  document.getElementById('button-call').style.display = 'none';
  document.getElementById('button-hangup').style.display = 'inline';

  // 以下を追加  
  connection.on('warning', function(name) {
    log(name + " is occurred.");
  });
  connection.on('warning-cleared'', function(name) {
    log(name + " is cleared.");
  });
});
```

これで、通話中に何かネットワークに問題が起きた際に、ログに情報を追記されるようになりました。実際に試してみてください。うまく警告が出せれば、通話中にログが表示されるでしょう。それぞれの詳細の意味を以下にまとめます。

- high-jitter: High jitter は貧弱なネットワーク環境と強い相関関係にある。ジッタ: ネットワーク通信で、データ伝送にかかる時間が一定せずに到着するデータの順番が乱れる現象
- low-mos: 低いMOS は 通話品質の低下を示す。 MOS: 圧縮による音質の評価基準
- constant-audio-input(output)-level: 10秒以上オーディオ入出力レベルが一定のまま通話されている状況。
- high-packet-loss:  最近の5サンプルのうち3つで受け取ったパケットの1%以上が失われた。多くのパケット損失は貧弱なネットワーク環境と強い相関がある。
- high-rtt: 最近の5サンプルのうち3つでパケットの周回時間が 400ms を超えた

### Twilio Client の最新情報
2016/12/20 リリースの最新 Twilio Client(1.4.9) 情報

#### デバイス入出力の切り替え
Twilio Client では、音声の入出力デバイスを JavaScript で指定できるようになります。(現状は Chrome のみサポート)

`Twilio.Device.audio.availableInputDevices` で利用可能な入力デバイス一覧を配列で取得でき、 `Twilio.Device.audio.speakerDevices.set(id)` で通話中の入力デバイスを指定できます。(複数可)
`Twilio.Device.audio.ringtoneDevices.set(id)` で着信音の入力デバイスを指定できます。(複数可)

今までパソコンのOSの設定でしか切り替えることができませんでしたが、 JavaScript で動的に切り替えられるようになります。例えば着信音だけPCとヘッドセットから鳴らし、通話中の音声はヘッドセットのみ流すということが可能になります。

#### デバイスのボリュームの取得/設定
現在のボリューム音量の値を取得/設定することもできます。これにより、例えば音が聞こえづらかった場合には、Web　ページ内で音量を上げるような操作をすることも可能になります。

#### Client の発着信音のカスタマイズ
着信音などの Twilio のデフォルト音声をカスタマイズすることも可能になりました。着信音、発信音、DTMF送信などの時の音を指定できます。

```javascript
Twilio.Device.setup(token, {
  sounds: {
    incoming: 'http://mysite.com/incoming.mp3',
    outgoing: 'http://mysite.com/outgoing.mp3',
    dtmf8: 'http://mysite.com/funny_noise.mp3'
  }
}
```

#### Twilio Interconnect for Twilio Client
これは現在 US リージョン限定ですが、Twilio Client での通話を専用回線で繋げられるような設定が可能になりました。インターネット回線を使うことでどうしても問題になっていた音質劣化の改善が見込めます。