Twilio Voice TwiMLの機能拡張について

:::note alert
2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
:::

# はじめに

みなさん、こんにちは。
KDDIウェブコミュニケーションズの Twilio事業部エバンジェリストの高橋です。

今回は、2021年1月14日（日本時間）にアナウンスされた、Twilio Programmable Voice の TwiML の機能拡張について解説します。
今回のアップデートは色々と要素が絡んでいるので、メールでの説明では今ひとつ分かりづらく、ぜひこの記事で理解を深めてください。

<font color='red'>~~なお、今回の修正は **SIP Interface を利用した Dial 動詞に関するもの** なので、それ以外での利用には影響はありません。~~
（2021/4/28追記）
SIP以外でも今回の機能拡張の影響を受けるようです。とくに、Dial 動詞の中で Number や Client 名詞を列挙するような使い方をしている方は挙動が変わりますので注意が必要です。</font>

具体的には、`<Dial>sip:xxxxxx@ドメイン.sip.twilio.com</Dial>`のような使い方をしている方が対象です。
余談ですが、SIP Interface は[先日のアップデート](https://qiita.com/mobilebiz/items/e7ca636cdf35a02da062)で東京リージョンで使えるようになったり、同時発信、順次発信に対応したり、かなり使いやすくなりました。

## 今回の変更が適用される条件

今回の変更は、以下の設定を行うことですぐに利用が可能です。設定を変更しない場合は従来の動作をしますが、**2021/7/31には設定を変更していないアカウントでも一斉に有効になります。**ほとんどのユーザは、この変更に伴ってコードの修正は必要ないはずですが、仕組みを理解する上でも参考になるので、ぜひ知っておくと良いと思います。

7月31日を待たずに今回の変更を有効にするには、管理コンソール上の [Programmable Voice の設定画面](https://jp.twilio.com/console/voice/settings)で **Enhanced Programmable SIP Features** を**ENABLED**にしてください。

![スクリーンショット 2020-12-30 6.34.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/0f3e04a1-b386-ebce-db9d-b3922673d514.png)

# アップデート項目一覧

今回のアップデートで修正・追加された項目は以下の通りです。

- GLL（Global Low Latency）に対応
- ringTone パラメータに対応
- StatusCallback で子コールの地域データが返却
- 同時発信、順次発信時のコールログの扱い
- answerOnBridge パラメータ利用時の挙動

## GLL（Global Low Latency）に対応

前回のアップデートで、SIP Interface が東京リージョンでも使えるようになったのですが、SIP Interface を利用した \<Dial>動詞でリージョンを指定するには、`<Sip>sip:alice@example.com;region=jp1</Sip>`のようなパラメータを付与する必要がありました。指定しない場合は、SIP Interface がホストされているリージョンからの発信になります。
東京リージョンで利用している場合は、東京からの発信になるので問題はないですが、海外への転送などでは常に東京リージョンを経由してしまうため、遅延が予想されます。
しかし今回のアップデートにより、`hangupOnStar="true"`パラメータを付与することで、`region`パラメータを指定しなくても GLL（Global Low Latency）を利用して、最も近いリージョンから発信が可能になります。日本宛の転送しかない場合は気にしなくても良いですが、海外への転送がある場合は、こちらのパラメータを利用しましょう。

## ringTone パラメータに対応

従来、\<Number>や\<Client>ではサポートされていた`ringTone`パラメータが、SIP Interface でも使えるようになりました。`rintTone`パラメータは、呼び出し音を強制的に変更するためのオプションで、このパラメータがないときは、常にアメリカの呼び出し音がなっていました。
日本の呼び出し音を使いたい場合は`ringTone="jp"`と指定します。

## StatusCallback で子コールの地域データが返却

従来から、\<SIP>名詞で`statusCallback`パラメータを利用することで、コールの状態が変化したときに、Twilio から WebHook を受け取ることができました。ただし、\<SIP>名詞の場合は、親コール（通常は Inbound）に設定される`FromCountry`と`ToCountry`がパラメータとして設定されてしまいましたが、今回の変更によって、子コール（Outbound）のパラメータが渡されるように改善されました。

## 同時発信、順次発信時のコールログの扱い

前回のアップデートで、SIP Interface でも同時発信と順次発信がサポートされました。具体的には次のような TwiML になります。

```xml:同時発信
<Dial>
  <Sip>sip:2001@example.sip.twilio.com</Sip>
  <Sip>sip:2002@example.sip.twilio.com</Sip>
  <Sip>sip:2003@example.sip.twilio.com</Sip>
</Dial>
```

```xml:順次発信
<Dial timeout="15" sequential="true">
  <Sip>sip:2001@example.sip.twilio.com</Sip>
  <Sip>sip:2002@example.sip.twilio.com</Sip>
  <Sip>sip:2003@example.sip.twilio.com</Sip>
</Dial>
```

従来このような使い方をした場合、実際に繋がったコールにしかログが残りませんでしたが、今回のアップデートによって、呼び出しが発生したすべてのコールログが生成されるようになりました。応答しなかったコールのステータスは`No Answer`になります。

## answerOnBridge パラメータ利用時の挙動
 
転送を使ったソリューションでよく聞かれる質問に、「呼び出し音が途中で変わるのをなんとかできませんか？」というものがあります。先程の`ringTone`パラメータを使ってもこの問題は解決できません。

そこで必要になるのが、`answerOnBridge="true"`パラメータです。
このパラメータの本来の意味は、**子コールが応答するまで親コールで生成された呼び出し音を流し続ける**というものです。ですので、上記質問については、このパラメータを指定することで解決できます。

しかし、このパラメータにはもう一つ重要な意味があります。

まず、このパラメータを付与しなかった場合に、SIP 宛の転送途中で発信者が切断した場合のコールステータスの変化を載せます。シナリオとしては、転送先が応答しなかったので、発信者が切断した場合と考えてください。

```
2021-01-13 23:54:35  call[in]     ringing      FROM: 発信者番号, TO: Twilio番号
2021-01-13 23:54:36  call[in]     in-progress  FROM: 発信者番号, TO: Twilio番号
2021-01-13 23:54:37  call[out]    queued       FROM: 発信者番号, TO: sip:xxxx@XXXX.sip.twilio.com
2021-01-13 23:54:40  call[in]     completed    FROM: 発信者番号, TO: Twilio番号
2021-01-13 23:54:40  call[out]    no-answer    FROM: 発信者番号, TO: sip:xxxx@xxxx.sip.twilio.com
```

まず Twilio 番号に着信が来た瞬間に、親コール（inbound）が `ringing`ステータスとなり（１行目）、その後すぐに `in-progress` に変化しています（２行目）。
その後、\<Dial>動詞が実行されて SIP 宛の発信が発生します（子コール、Outbound）。この時点で、子コールのステータスは `queued` です（3行目）。
その後、相手側が応答しない状態で発信者側が切断をします。これによって、親コールは`Complete`になります（４行目）。また、子コールについては、`no-answer`になり、一連のコールはすべて完了します。

ここで注意が必要なのは、親コールは`in-progress`→`completed`になりますので、その間の4秒間は**課金対象**ということです。
これは、転送先が SIP であろうと、PSTN であろうと同じです。

では次に、`answerOnBridge="true"`を指定した場合の **PSTN 宛**のコールステータスを載せます。

```
2021-01-13 23:46:40  call[in]     ringing      FROM: 発信者番号, TO: Twilio番号
2021-01-13 23:46:42  call[out]    ringing      FROM: Twilio番号, TO: 宛先番号（PSTN）
2021-01-13 23:46:45  call[in]     no-answer    FROM: 発信者番号, TO: Twilio番号
2021-01-13 23:46:45  call[out]    no-answer    FROM: Twilio番号, TO: 宛先番号（PSTN）
```

このケースでは、着信（1行目）のあとに親コールは`in-progress`にはなりません。その状態で、宛先に対して呼び出しがかかり、相手先が応答しない状態で発信者が切断をしたタイミングで、親コールも子コールも `no-answer` になります（３行目と４行目）。
この状態であれば、親コールは最終的に`no-answer` で完了しますので、**コストはかかりません**。
ですので、`answerOnBridge`パラメータはつけたほうがお得です（もちろん、相手が応答した場合はそこからは親コールも着信料が発生します）。

ところが、SIP 宛の\<Dial>動詞では、このパラメータを付与したとしてもコールのステータスはパラメータを付与しなかったときと同じとなり、親コールには着信コストがかかります（呼び出し音については、最初の呼び出し音が継続します）。

今回のアップデートでは、この部分も PSTN 宛と同様、`answerOnBridge`パラメータを付与することで、ステータスの遷移が以下のようになります。

```
2021-01-13 23:50:43  call[in]     ringing      FROM: 発信者番号, TO: Twilio番号
2021-01-13 23:50:46  call[out]    ringing      FROM: 発信者番号, TO: sip:xxxx@xxxx.sip.twilio.com
2021-01-13 23:50:48  call[in]     no-answer    FROM: 発信者番号, TO: Twilio番号
2021-01-13 23:50:48  call[out]    no-answer    FROM: 発信者番号, TO: sip:xxxx@xxxx.sip.twilio.com
```

相手が応答する前に切断されたので、親コールの着信料も無料です。

### answerOnBridge での注意

転送に関しては、`answerOnBridge`パラメータは非常に有効ですが、一点注意があります。
それは、このパラメータを付与することで、本来子コールの呼び出しで流れるはずだった呼び出し音がならず、親コールの呼び出し音が継続するということです。たとえば、携帯電話の圏外アナウンスなどは、呼び出し音としてキャリアが送出しているのですが、このメッセージが流れなくなり、呼び出し中の音だけが流れるようになります。
このように、キャリアが呼び出し音の代わりに流すメッセージは他にも存在するので注意が必要です。

# まとめ

今回のアップデートでは、SIP Interface に関する\<Dial>動詞の機能拡張が行われましたが、最後の内容については、あまり外部では説明されてないところなので参考にしていただだけると幸いです。

---
### Twilio（トゥイリオ）とは

https://cloudapi.kddi-web.com
Twilio は音声通話、メッセージング（SMS /チャット）、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウド API サービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。

自己紹介|　
:--|:--
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/b51a8b88-abd5-ce5e-195a-de3564ba2ae6.png" height='200' width='150'/>|高橋克己（Katsumi Takahashi） 自称「<font color='red'>赤い芸人</font>」<br />グローバル・インターネット・ジャパン株式会社　代表取締役<br />株式会社KDDIウェブコミュニケーションズ　Twilio事業部エバンジェリスト<br /><br />2001年より大手通信事業者の法人サービスの教育に携わり、企業における電話のしくみや重要性を研究。2016年よりTwilio事業部にジョインし、Twilioを使ったスマートコミュニケーションの普及活動を精力的に行っている。<br />2015 Hall of Doers<br />2019 Twilio Champions