Twilio Studioで作ったIVRフローでサーバーのレスポンスを使って流してみた

Twilio Studioでサーバーのレスポンスを元にIVRを流すフローをチョチョっと作ってみたので
作り方を記載します。

# 今回使用する環境
- サーバー:PHP
- Twilio:Twilio Studio

# 手順
1. メッセージを返却するサーバーを作成する
2. Twilio Studioのフローを作成する

## 1. メッセージを返却するサーバーを作成する
以下レスポンスを返すサーバーを用意します。

```json
{
  "message":"text message"
}
```

サンプルコード(PHP)

```php
<?php
    # タイムゾーンをセット
    date_default_timezone_set('Asia/Tokyo');

    # レスポンスメッセージ作成
    $json_array = array(
        "message" => "test message"
    );

    # JSONで送りますよというヘッダーを追加
    # これを追加しないとTwilio Studio側でjsonを識別と識別出来ない
    header("Content-Type: application/json; charset=utf-8");

    # JSON 形式にエンコードしてechoでPOST送信
    echo json_encode($json_array);
?>
```

## 2.Twilio Studioでフローを作成する
### 新規Twilio Studioフローを作成する
左側のメニューの中からStudioを選択します。
<img width="221" alt="スクリーンショット 2019-02-14 17.54.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/cc93160c-7955-8d52-546c-2a67d249af80.png">

<img width="341" alt="スクリーンショット 2019-02-12 15.33.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/9261347c-54e2-a4d4-2a6c-5f28a99ba3f8.png">

Studioの画面を開いたら「Create a flow」をクリックして新規フローを作成します。
<img width="833" alt="スクリーンショット 2019-02-14 17.50.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/957b3919-e92a-4160-1eb5-3bd60f74b1bb.png">

「FLOW NAME」を入力して「Next」ボタンをクリックします。
<img width="602" alt="スクリーンショット 2019-02-12 15.49.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/1e2d3baa-7f01-c687-f0bb-93905935fcd2.png">

続いて「Start from scratch」を選択し、「Next」をクリックします。
※いくつかテンプレートが用意されているので、この記事が終わったら、ぜひ試してみてください。
<img width="601" alt="スクリーンショット 2019-02-12 15.54.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/2ecb7db5-1784-5971-0b37-554ea0c532da.png">

これで、空のflowが出来ました。
続いて、IVRフローを作成していきます。

### IVRフロー作成

以下手順にてIVRのフローを作成していきます。
1. 電話を受けた時に音声を流し、ユーザーの入力を待つ
2. 入力を受け取って、その後の処理を振り分ける
3. 振り分けられた後の挙動を作る

#### 1. 電話を受けた時に音声を流し、ユーザーの入力を待つ
まず、右側の「WIDGET LIBRARY」の中から「Gather Input on Call」を選びキャンバスに配置します。
[Gather Input on Callの公式ドキュメント](https://jp.twilio.com/docs/studio/widget-library#gather-input-on-call)
<img width="304" alt="スクリーンショット 2019-02-14 18.13.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/5c8b2e86-5d3c-a456-75ee-9907ee482f0a.png">

キャンバスに配置した、「Gather Input on Call」を選択すると、右側の「WIDGET LIBRARY」が「GATHER INPUT ON CALL」に変化し、設定値を入力できるようになります。
以下設定値を入力します。
・TEXT TO SAY
・LANGUAGE(日本語を喋らせたい場合は、日本語に設定する)
・MESSAGE VOICE(好きな音声を選んで)

設定したら「Save」をクリックします。

各種設定が終わったら「Trigger」と書かれたWidgetの「Incoming Call」を作成した「Gather Input on Call」のWidgetと紐付けます。
<img width="679" alt="スクリーンショット 2019-02-15 11.53.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/4d60e2ad-c4b2-c14d-97c5-5461b6f34263.png">

#### 2. 入力を受け取って、その後の処理を振り分ける

次に「Gather Input on Call」からユーザーの入力を受け取って処理を分割させます。
処理を分割するには「Split Based On...」を使用します。

<img width="305" alt="スクリーンショット 2019-02-15 11.57.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/eda0680f-a933-37d2-6760-43cfe4e830cf.png">

「Split Based On...」をキャンバス上に配置し、選択します。
※今回はユーザーのダイアル入力を受け取る前提とします。
設定部分を以下内容で設定します。
この設定は、どの値を使って分岐させるかを設定します。
VARIABLE TO TEST:widgets.gather_1.Digits
<img width="302" alt="スクリーンショット 2019-02-15 13.46.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/3a839fb9-376e-e312-522a-98985fb22f93.png">

<a name="second"></a> 続いて分岐内容を追加していきます。
「Split Based On...」Widgetの「NEW」ボタンをクリックし、「Condition Matches」を選択します。
<img width="436" alt="スクリーンショット 2019-02-15 12.15.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/f78e391c-0467-c4af-72df-ae12997575fd.png">

するとWidgetの設定欄が分岐条件の設定内容に変化します。
設定内容を以下内容(ユーザーが1を押した時)に変更します。
predicate:Equal To
Value:1

設定が終わったら、「Set condition」をクリックして設定を保存します。
さらにその後「Save」をクリックします。

<img width="304" alt="スクリーンショット 2019-02-15 12.21.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/c21fa3c4-9c8c-56a2-64f4-03f73ff9abe5.png">

[Split Based On...の公式ドキュメント](https://jp.twilio.com/docs/studio/widget-library#split-based-on)

#### 3. 振り分けられた後の挙動を作る

ここで、一旦振り分けられた後に流す音声Twilio Studioで設定します。
Widgetの中から「Say/Play」を選択してキャンバスに配置します。
以下内容を設定します
・TEXT TO SAY(喋らせたい内容):任意
・LANGUAGE(日本語を喋らせたい場合は、日本語に設定する)
・MESSAGE VOICE(日本語を喋らせたい場合は、日本語の音声を設定する)

これを先ほど作った「Split Based On...」Widgetの条件と紐付けます。

<img width="526" alt="スクリーンショット 2019-02-15 14.11.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/df707eb4-3aa8-78eb-a0a8-fff1c7bb778f.png">

[Say/Playの公式ドキュメント](https://jp.twilio.com/docs/studio/widget-library#sayplay)

本題のサーバーからのレスポンスを喋らせるフローを作成します。
まず、Widgetの中から「http request」を選択し、キャンバスに配置します。
<img width="305" alt="スクリーンショット 2019-02-15 15.08.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/78cf4173-afd4-1e63-4d08-551272f3c8ea.png">

http requestに以下設定をします。
・REQUEST URL: 本記事の最初の方に作成した、サーバーのURLを記載(ex:http://sample.com/message.php)

設定したら「Save」をクリックします。

<img width="302" alt="スクリーンショット 2019-02-15 15.15.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/09ee57a5-4ff4-0b4a-35f1-71a4386a9740.png">

次にレスポンスを喋らせるための「Say/Play」をWidgetの中からを選択してキャンバスに配置します。
以下内容を設定します
・TEXT TO SAY(喋らせたい内容):{{widgets.HTTP Requestのwidget名.parsed.message}}
  ※widgets.HTTP Requestのwidget名.parsedにレスポンスのjson部分がパースされた状態で格納されている。
  ※パースされた変数にアクセスするには.変数名で繋ぎます。
・LANGUAGE(日本語を喋らせたい場合は、日本語に設定する)
・MESSAGE VOICE(好きな音声を選んで)

設定したら「Save」をクリックします。

<img width="304" alt="スクリーンショット 2019-02-15 15.29.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/e0b105f3-4f0a-fb3b-f038-62153dcfb4f3.png">

これを「HTTP Request」widgetとつなぐ
<img width="316" alt="スクリーンショット 2019-02-15 15.26.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/4989c687-cb1f-509d-45a9-75d2f21803c2.png">

[2. 入力を受け取って、その後の処理を振り分ける](#second)と同じ手順で条件を作成作成します。
作成後、「Http Request」Widgetと繋ぎます。

#### 最終的に作成したフロー
<img width="487" alt="スクリーンショット 2019-02-14 17.16.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/3ff49ac8-a733-1c85-37c2-a6f230e36ca9.png">

全ての作業が終わったら、最後に画面上部の「Publish」をクリックして、フローを公開しましょう！
<img width="1198" alt="スクリーンショット 2019-02-15 15.49.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/da5c1807-b8d6-5d5c-7b16-e1b5fc0faf5a.png">


### 作成したフローを電話番号に紐づける
最後に作成したフローと電話番号を紐付けます。

まず電話番号の設定画面を開きます。
<img width="340" alt="スクリーンショット 2019-02-13 10.29.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/1c2be751-ed78-4028-35fc-256f9e69be81.png">

次に対象の電話番号を選択します。
<img width="488" alt="スクリーンショット 2019-02-13 10.29.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/e98da07a-4f90-eecd-87d9-f17e15c818f5.png">

対象の電話に電話がかかってきたときにどの処理に流すか選択します。
<img width="411" alt="スクリーンショット 2019-02-13 10.30.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/54230473-32a6-4fb7-11e1-24b22096f80a.png">

最後に先ほど作成したFlowを選択します。
<img width="1016" alt="スクリーンショット 2019-02-15 15.46.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/5c875708-fee1-f9bb-6e27-6d72c88f3fe4.png">

設定ができたら「保存」を押して、対象の電話番号に電話をかけてみましょう！

サーバーからの音声が流れたら成功です！

### 音声がうまく流れなかったときの確認項目
- サーバーからのレスポンスヘッダーが`application/json`になっていますか。
- widgetのLanguageの設定が日本語になっていますか。