Twilioの人気動詞Gather、電話器のプッシュ音を認識し、いろんな処理を簡単に実現させます。

Twilioのプッシュ音認識機能、<Gather>をご紹介します。
プッシュ音とは、スマホや固定電話など電話器の数字ボタンを押した際に発生する「音」のことを言います。

Twilioはこの「音」を数字に変換し、呼ばれた処理に値（データ）をPSOTやGETで渡します。
このプッシュ音認識機能はTwilioの機能の中で良く使われる動詞の一つです。
例えば、受信電話番号の振り分け、IVR（自動音声応答）などの開発で良く使われています。

Twilioの「Gather」を使えば単なる電話処理だけではなく、PHPやRubyなどプログラミング言語による開発も可能です。 

<h3>プッシュ音認識 Gather</h3>
 Gather動詞は短いコードで、ユーザーから入力されたプッシュ音を認識します。
まず、下のコードをTwilioのRequest URLに設定し、電話をかけてみてください。

そうすると、4行目のメッセージが再生された後、無言状態になります。
そこで、電話器の数字ボタンをプッシュしてみてください。
プッシュされたボタン（キー）の値を取得できるのが<Gather>です。

なお、Twilioの動詞にはそれぞれいろんな属性を持っていますので、Gatherの属性も試してみてください。
今回のコードでには「timeoutとfinishOnKey」が設定されています。
属性に関する情報やサンプルコード、概要などは下の公式ドキュメントから確認できます。
TwiML 音声通話：[Gather](https://jp.twilio.com/docs/api/twiml/gather)

※ Request URLの設定はブログの「[◎ 電話番号管理画面](http://blog.twilio.kddi-web.com/2014/06/25/%E6%96%B0%E8%A6%8F%E7%99%BB%E9%8C%B2%E3%81%A7%E3%81%99%E3%81%90%E4%BD%BF%E3%81%88%E3%82%8B-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E9%9B%BB%E8%A9%B1-sms-api-twilio%E3%81%AE%E6%96%B0%E8%A6%8F%E7%99%BB%E9%8C%B2/)」を参考してください。

```xml:twilio-gather.xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Gather timeout="10" finishOnKey="*">
    <Say language="ja-jp">こんにちは、ボタンを入力してください。</Say>
  </Gather>
</Response>
```

<h3>ネスト動詞</h3>
 下記の二つのサンプルコードみればお分かりかと思いますが、二つのサンプルコードは動きが違います。

・上のサンプルコードはメッセージの再生の途中でもキーの入力可能です。
・下のサンプルコードはメッセージの再生の途中にはキーの入力不可能です。

つまり、<Gather>動詞は[Say](https://jp.twilio.com/docs/api/twiml/say)と[Play](https://jp.twilio.com/docs/api/twiml/play)動詞のネストが可能です。 

```xml:twiml-gather-say.xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Gather timeout="10">
    <Say language="ja-jp">Gatherの処理を遷移させます。</Say>
  </Gather>
</Response>
```

```xml:twiml-gather-say-se.xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Gather timeout="10" />
  <Say language="ja-jp">Gatherの処理を遷移させます。</Say>
</Response>
```

<h3>通話の分岐</h3>
ここでは通話の処理を分岐させてみたいと思います。
このソースコードは電話をかけたユーザーから好きな果物を電話の数字ボタンで選択してもらいます。
① ユーザーが050に電話をかけます。
② 6行目のアナウンスに従って好きな番号をプッシュします。
③ ユーザーがプッシュした数字がTwilio経由でこのファイルに戻って来ます。
戻って来る値はPOSTまたはGETに設定されます。（選択可）

■ Request URL
下記のソースコードURLをTwilioの電話番号（050）のRequest URLに設定すると、そのRequest URLに値を渡します。
<Gather>によるデータはリアルタイムで渡されますので、動的なアプリケーションの開発が可能です。

なお、7行目の<Gather>動詞を他の分岐処理の中に入れますと、処理を入れた箇所で新しい入力を受けることになります。 

```php:twilio-gather-ivr.php
<?php
  header("content-type: text/xml");
?>
  <Response>
<?PHP if (empty($_POST["Digits"])) { ?>
  <Say language="ja-jp">リンゴは1を、オレンジは2を、バナナは3を押してください。</Say>
  <Gather numDigits="1" timeout="30" />
<?PHP } elseif ($_POST["Digits"] == "1") { ?>
  <Say language="ja-jp">リンゴを選択しました。</Say>
<?PHP } elseif ($_POST["Digits"] == "2") { ?>
  <Say language="ja-jp">オレンジを選択しました。</Say>
<?PHP } elseif ($_POST["Digits"] == "3") {?>
  <Say language="ja-jp">オレンジを選択しました。</Say>
<?PHP } else { ?>
  <Say language="ja-jp">入力は1から3までです。</Say>
<?PHP } ?>
</Response>
```

<h3>Twilioのライブラリを使いますと。</h3>
Twilioは様々なプログラミング言語のライブラリを提供しています。
今回はPHPのライブラリを使いましたが、他のライブラリも是非ご覧ください。

```php:twiML-ivr-test.php
<?php
  require("../Services/Twilio.php");
 
  $response = new Services_Twilio_Twiml();
 
  if (empty($_POST["Digits"])) {
    $gather = $response->gather(array('numDigits' => 1, 'timeout' => 30));
    $gather->say("許可するには1を拒否は2を押してください。", array('language' => 'ja-jp'));
  } elseif ($_POST["Digits"] == "1") {
    $response->say("許可を選びました。", array('language' => 'ja-jp'));
  } elseif ($_POST["Digits"] == "2") {
    $gather->say("拒否を選びました。", array('language' => 'ja-jp'));
    $gather = $response->gather(array('numDigits' => 1, 'timeout' => 30));
  }
  print $response;
?>
```

<h3>入力後の処理を遷移させる</h3>
こちらの処理は<Gather>による処理終了後その処理を遷移させることが可能です。
使い方は簡単、Gather動詞に actionに遷移先のURLを記述します。
サンプルコードではパラメータ変数を「POST」になっていますが、GETにすることも可能です。
このように書けば、$_GET["userId"]から値の取得が可能になります。 

```xml:twiml-gather.xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Gather action="twiml-gather-action.php" method="POST">
    <Say language="ja-jp">Gatherの処理を遷移させます。</Say>
  </Gather>
</Response>
```

```php:twiml-gather-action.php
<?php
  header("content-type: text/xml");
 
  $tel_from = $_POST['From'];
  $tel_to = $_POST['To'];
  $call_status = $_POST['CallStatus'];
  $gather = $_POST['Digits'];
?>
<Response>
  <Say language="ja-jp">入力された値は<?php echo $gather; ?>です。</Say>
</Response>
```