def yasuharu519(self):

日々の妄想

Twilio で会話中に Twilio に好きな言葉を話させる

これは、Twilio Advent Calendar 2015 の 12月4日の記事です。
12月3日は、@uturist さんの 【Twilio】作品&小ネタ3連発! でした。

今回は、TechCrunch Tokyo Hackathon 2015 にて、 出んわという Twilio を使ったアプリを作成し、そこで得た知見の紹介をしたいと思います。 出んわ は、相手からかかってきた電話にチャットを打つ感覚で音声で応答ができるというアプリです。 通話状態を続けながら音声で返答するといったことが必要で、それについて結構苦労もあったのですがそれについて書きます。

Twilio とは

Twilio はクラウド電話APIを提供する会社/サービスで、 電話番号を取得して、その番号からHTTPリクエストで電話を発信したり、 着信を受けて電話案内を行うといったようなことができます。 今回の出んわでは、特定の電話番号にかかってきた電話は、 クライアントアプリに転送するようにして、電話を受けれるようにしていました。

TwiML について

TwiML文書 は、通話や SMS を受信した時の動作を Twilio に指示するための、命令のセットです。

Twilio で取得した電話番号に電話がかかってくると、その後の動作については TwiML という XML のような言語で指示します。 リクエストに応じて適切な TwiML を返すサーバを作成することで、電話をリダイレクトしたり、ボタン入力を待って動作を変えたりと好きな様に動作させることができます。

f:id:yasuharu519:20151204204212p:plain

上の図は Twilio に電話をかけた場合の一般的な例で、Twilio になにかさせるためには TwiML を読ませる必要があります。

上は TwiML の例ですが、たとえばこの例では女性の声でメッセージが流れた後、20秒音声が録音されます。

通話を切らずに好きな音声を流す方法

Twilio の一般的な使い方は、電話がかかってきた時に録音したり転送したりといったものです。 そのため、かかってきた電話を保持しながら音声を流すのには苦労しました... というのも、 Twilio になにかさせるためには TwiMLを読ませる 必要があるので、通話中の任意のタイミングで Twilio に TwiML をどう読ませるようにできるのかがなかなかわからなかったためです。

電話がかかってきた後、音声で返答するためには、電話を受けた端末から音声を流す方法もあるかもしれませんが、今回は Conference という Twilio の三者間通話機能を使うようにしました。 Conference を使うことで、40人近くの人が入るルームなども作成することが可能なようです。

通話を受けながら音声を流すものとして、実現に際しては、以下のページなどを参考にしました。

stackoverflow.com

この構成では、電話を受ける側は、音声を聞くだけのモードでカンファレンスに参加し、発声のリクエストを送ると一瞬だけカンファレンスに Twilio が参加し、音声を発して退出するようになります。 こうすると「出んわ」でやったように好きな音声を流すことや、カンファレンスに誰かが入ってきた時に自動アナウンスを流したりすることが可能となります。 ただし、自動音声が発されるたびに電話をかけてるのと同じで、まあまあ料金がかかるのに注意!

flask で実装したのがこちらの例。

まず Twilio から提供された番号に電話をかけると、index が呼び出されたあと、呼び出し先として指定された電話番号に電話がかけられた後、電話をかけた側/電話をかけられた側からconference_joined が呼び出される。これが呼び出されると、カンファレンス名として指定したルームにお互い参加することとなる。また、かけられた側はミュートで参加することとなる。

このカンファレンスルームで音声を再生するためには、message_req, message_res の両方を使用する。message_req に対してPOSTでmessageを送ると、一旦そのメッセージを redis に保存し、その後 Twilio が 自身の電話番号に対して電話をかける。その後、再度 index が呼び出され、Twilio が自分に電話をかけた場合(発信先と発信元の電話番号が同じ場合)には、指定していたカンファレンスに参加し、最後に message_res が呼ばれます。 message_res では、メッセージを Redis から取り出し、 Say コマンドの twiml を吐き出すことで、音声を流します。 Say コマンドの代わりに Play コマンドを使用することで、 指定したタイミングで音楽を流すことも可能です。

まとめ

  • Redis にメッセージを保存し、取り出すようにしてメッセージを流している
  • メッセージを流すたびに発信料金がかかる

など、あまり実用的ではありません。 ただ、大規模なカンファレンスコールを行うときなどに、 参加してきた人の名前を読み上げる、好きな音楽を流すなど、 使い方はいろいろあるのかなーとも思っています。 でも電話とネットが繋がるのはすごい楽しかったし、いろいろ可能性を感じました。

テストでかけまくってたら電話代めっちゃかかるのまじ注意な