ゼロからはじめるぜ! Twilio – シーズン2 第7回

20140219-04.jpgこんにちわ。ネットワークエンジニアのまさです。
シーズン 2 もいよいよ佳境、今回が最終回です。前回は MySQL のデータベースを操作する Perl スクリプトを作成しましたので、今回はメインメニューと連携、Perl スクリプトに命令を渡す部分を作ります。

 

20140219-05.jpg図でいうと真ん中の小さい青枠「トイレ番号を指定」の部分です。

メインメニューで 2 を押すと、噴水を発射するトイレのモードを Armed にしたり解除したりできるメニューになりますので、ここでトイレ番号を 2 桁入力させ、もし既にその番号のトイレが Armed モードであれば解除、もし Armed モードでなければオンにする、ということを実現します。
またこのフロー図の通り、メインメニューから 1 階層進んだ部分になりますので、元のメインメニューに戻ったり、終了したりできるようにもしておきます。

 

では、早速コードを追っていきましょう。

おおむね シーズン 2 第 3 回 でつくった GATHER によるプッシュ操作収集と同じ作りをしています。

このパートは、メインメニュー部で GATHER 動詞を使い、2 桁のプッシュ操作を受け、switch 文で条件分岐をします。switch の default がトイレ番号を受け付ける部分で、2 桁を受け取ったら、その番号のトイレの噴水発射モード (Armed) の ON / OFF を切り替えるのが主な役割です。
が、トイレ番号選択の後、通話が終わると非常に不親切なので、この 2 桁が 98 ならメインメニューに戻り、99 なら終了するという機能も加えます。

 

98 の場合は、「メインメニューに戻る」ことを実現したいのですが、TwiML では action URL で次々に命令を渡す先を指定する方式を取りますので、そもそも「戻る」という概念がありません。
なので、GATHER 動詞を使って 1 桁待ち受ける、すなわち、メインメニューと同じことをやる命令をココに書いてあげればメインメニューに戻ったことになります。

 

if 文内の else では、前回と同じように 「$input が空のままこの PHP にアクセスされたら」です。通常、前のメニューから遷移してるはずなので、$input が空になることは、不正アクセス以外にはないです。よって、この場合は威嚇して追い返します。

トイレ番号 2 桁を受け付ける default 部分をもう少し詳しく追ってみます。

この GATHER 部は、トイレ番号の 2 桁を受け付けた後に、前回までに作成した twimllet_db.pl に STANO=2 桁、を引数として渡しつつ、ACTION=MODIFY を同時に引数として渡して実行します。

twimllet_db.pl では、この 2 桁のトイレ番号を selectし、トイレの Armed モードが ON なのか OFF なのか調べた上で、ON なら OFF に、OFF なら ON にという挙動をするものを作りましたね。
そしてその結果は、twimllet_db.pl が文章で print して返してきますので、これをそのままセリフとして読み上げます。それが $result の部分です。$input でトイレ番号を読み上げ、そのトイレのモードをどっちにしたのかを $result でしゃべります。
そして「さらに他のトイレのモードを替えるならトイレ番号 2 桁を、メインメニューに戻るなら 98 を、終わるなら 99 を押せ」としゃべります。

 

ここで少し SAY 動詞の TIPS を。

$gather->say("Station $input$result, push 2 digits for modifying another station mode,
push 9 8 to go back previous menu, push 9 9 to exit.",
array('voice' => 'alice', 'language' => 'en-US'));

 

よく見て欲しいのですが「push 9 8 to go back」のように「9」と「8」の間にスペースをいれています。
ここを続けて「98」としてしまいますと「ninety eight」と、九十八として認識して読み上げるので、ここはスペースを入れて区切ります。

ではこのファイルを modify.php という名前で保存し、アップロードしましょう。この位置です。

 

20140219-06.jpgさて、ではいよいよメインメニューを作ります。コードを見てみましょう。合わせて冒頭にあるフロー図も確認してください。

 

 

メニュー番号となる 1 桁の数字、もしくは、先ほど作成したトイレモード変更メニューで 98 のどちらかが $input に入っているはずです。
まずはこの $input が定義されているか否かを if 文で調べ、定義されていれば、番号別の条件分岐です。定義されていない場合は else 文です。
そして、もう分かりますね? 順当にアクセスしていれば、定義されていないでこの PHP が呼ばれることはありませんので、これは不正アクセスとして威嚇して追い返します。

 

それではメニュー部です。default は、98 が入っている、もしくはメニュー番号にない数字が押されたことを想定しています。この GATHER 文では numDigits=1 を与えて 1 桁の待ち受けにしています。このメニューからの処理は 1 桁待ち受ければ十分だからです。SAY 動詞でどの番号が何の処理をするのか説明し、プッシュ操作を待ちます。

case 文の「1」は、各トイレのサマリーを読み上げる処理です。前回までに作成した twimllet_db.pl に ACTION=SUMMARY を引数に与え実行します。
その結果は twimllet_db.pl が print 文で返してきて $on_stations に読み上げるテキストのまま入っていますので、これを SAY 動詞で読み上げるだけです。

case 文の「2」は、さっき作った modify.php への処理渡しです。

case 文の「3」は、Armed モードのトイレがどれかの確認を行う処理です。twimllet_db.pl に ACTION=ARMED を引数に与え実行します。
case 文の「1」と同じように結果はそのまま $armed_stations に入っていますので、これを読み上げるだけです。

case 文「4」と「5」は実際に、噴水を発射したり止めたりする部分です。
このサンプルでは実際に噴水を発射すべき物理デバイスが存在していないので、コメント部分に「もしそんなデバイスを開発したら噴水発射の命令をココに書いてね」と示してあります。
是非、そんなデバイスを開発して私にお披露目してください。

case 文「9」は終了です。きちんと挨拶をして終わります。

 

では、このファイルを menu.php という名前で保存し、先ほど貼り付けた WinSCP の画像の場所へアップロードしましょう。

さて。これで完成なのですが、せっかくなのでもう一工夫してみます。Twimllet Commander Z は遠隔でトイレの噴水を発射するという、いわば敵を精神的に追い詰める兵器となりうる危険なアプリケーションです。誰でもかれでも不正にこの PHP にアクセスされたら非常に困る。

 

これまでコード内で不正アクセスを追い返す仕組みを盛り込んではいますが、念には念をいれておきましょう。この twimllet 領域にアクセスするために、BASIC 認証を必須とし、ブラウザやその他の方法で HTTP アクセスしようとしても、認証が掛かるようにしてみます。

以下、Web サーバには Apache を使っていることを前提に、BASIC 認証を掛ける方法を説明します。

まず、TeraTerm 等のターミナルソフトウェアで、ご自身のサーバにログインし、twimllet のファイル一式がある領域に移動してください。このシリーズと全く同じようにファイルを配置していれば、この領域でファイルのリストを取ると、以下のようになっているはずです。

 

kwc:root[/data/html/twimllet]# ls -l
合計 20
drwxr-xr-x 3 apache apache 4096 3 月 7 2013 Services/
-rw-r--r-- 1 apache apache 879 1 月 10 16:25 auth.php
-rw-r--r-- 1 apache apache 328 1 月 10 16:26 commander.php
-rw-r--r-- 1 apache apache 2822 1 月 10 16:26 menu.php
-rw-r--r-- 1 apache apache 1703 1 月 10 16:27 modify.php

この領域全体に BASIC 認証を掛けます。まずは .htaccess ファイルを作成しましょう。vi コマンドで直接書きます。

$ vi .htaccess

 

そして、以下の内容をそのままペーストしましょう。

AuthUserFile /data/html/twimllet/.passwd
AuthGroupFile /dev/null
AuthName "Enter Twimllet code"
AuthType Basic
require valid-user

 

保存したら、次にパスワードファイルです。以下のコマンドを実行してください。

$ htpasswd -c .passwd masa

masa の部分は自分の名前とか好きな文字列にしてください。ここは認証時の「ユーザ名」になります。実行すると、パスワード入力を 2 回求められます。これがユーザ名に対するパスワードです。

 

これでパスワードファイルができました。リストを取るとこのようになっているはずです。

kwc:root[/data/html/twimllet]# ls -la
合計 36
drwxr-xr-x 3 apache apache 4096 1 月 9 18:45 ./
drwxr-xr-x 5 apache apache 4096 12 月 26 18:02 ../
-rw-r--r-- 1 apache apache 130 11 月 29 18:23 .htaccess
-rw-r--r-- 1 apache apache 19 11 月 29 18:23 .passwd
drwxr-xr-x 3 apache apache 4096 3 月 7 2013 Services/
-rw-r--r-- 1 apache apache 879 1 月 10 16:25 auth.php
-rw-r--r-- 1 apache apache 328 1 月 10 16:26 commander.php
-rw-r--r-- 1 apache apache 2822 1 月 10 16:26 menu.php
-rw-r--r-- 1 apache apache 1703 1 月 10 16:27 modify.php

 

これでブラウザから、この領域のどのファイルでもいいのでアクセスしてみてください。認証のポップアップが現れ、先ほどのユーザ名とパスワードを入力しないとアクセスできないようになったはずです。

さぁ、これで準備完了! Twilio の管理画面で電話番号と URL を紐付けます。
このシリーズも長くなったので、実際に Twilio 電話番号にかけて最初にアクセスされるべきファイルがどれか忘れてしまったかもしれませんが、最初は暗証番号 4 桁の入力を求める PHP ですので、commander.php になります。

Twilio の管理画面にログインし、電話番号メニューを開いたら、紐付けたい電話番号をクリックし、Voice URL に commander.php までの URL を入力して保存します。
私の場合は、アメリカでデモをしたのでアメリカの電話番号に紐づけてあります。

 

20140219-07.jpgそしてこの時の注意。先ほどこの領域は BASIC 認証を掛けたので、BASIC 認証のユーザ名とパスワードをURL の中で指定します。書式は、

http:// ユーザ名 : パスワード@実際の URL

です。使っているドメインが example.com でアップロード領域がドキュメントルート以下 /twimllet で、ユーザ名 hoge、パスワードが puyo だとすれば、URL はこのようになります。

http://hoge:puyo@example.com/twimllet/commander.php

 

保存したら、さぁいよいよです! 実際に電話をかけてみましょう。

どうですか? 最初に 4 桁のプッシュ操作を促され、auth.php で定義してない 4 桁なら追い返されたはずです。正しい 4 桁だとメインメニューに移ります。
トイレモードの確認をしたり、Armed モードの ON / OFF も試して下さい。電話で切り替えると、きちんと MySQL 上のテーブルも更新されていますよ。

 

さて、これにてシーズン 2 は終了です。だいぶ長丁場になりましたが、ひと通り Twilio の主要機能を使って簡単、かつ本格的な IVR が構築できたと思います。安全対策もバッチリですね。
Twilio を使うと、これまで専門装置を使って大掛かりな投資と開発をしなければ実現できなかった電話ソリューションが簡単に作れます。このシリーズではハードウェアの連携まではやりませんでしたが、これを読んだみなさんなら、ハードウェアに命令を出すコードだけ挟み込めば簡単にできちゃうことがお分かりになったかと思います。

 

是非、新しいアイデアで楽しいソリューションを作ってみてください。
できれば、この Twimllet Commander Z の噴水付実機を作って見せてくれたら嬉しいです。
楽しみにお待ちしております!

 

最後に

これだけ大々的に尻洗浄便座を取り上げてますが、私は TOTO からも INAX からも 1 銭たりとも貰っていませんし、彼らが是非 CM に出てくれ! とか、是非、ウチの新商品として Twilio 機能付きの便座を開発させてくれ! と声を掛けてくれたりもしていません。

私としては一切拒むつもりはありません、両方歓迎します。

この記事をシェア


最新記事

すべての記事へ