備忘録のため,内容の正当性については責任を持ちません。

ふと思い立って、”たった4行で電話が作れる API” の Twilio で遊んでみることにした。まずは電話を受けて、発信者情報を取得してみよう。


Twilio とは?

Twilio とは、Web アプリケーションに対して電話の発着信や SMS の送受信機能を実装できるクラウド電話 API で、「トゥイリオ」と読むらしい。日本では KDDI なんちゃらかんちゃらって会社が提供しているようだ。

登録すると自分専用の電話番号 (050-XXXX-XXXX) が発行される。色んなとこに紹介記事があがってるので、詳細はググって欲しい。

TwiML

Twilio に着信があったときの挙動は、TwiML (トぅぃむる) で定義する。TwiML とは「通話や SMS を受信した時の動作を Twilio に指示するための命令のセット」とのことだが、実体はただの XML なので何も難しくない。

Twilio に着信があると、あらかじめ指定した URL (Voice Request URL) に対して、Twilio のサーバが http(s) 通信で TwiML を読みに来る。その際、アプリ側では各種メタデータ (発信者の電話番号など) を POST 値として取得できる。そしてアプリは Twilio に TwiML を返し、Twilio はその記述 (TwiML 動詞) に従って電話の発信者に応答する。シーケンス図にすると以下のような感じ。

着信時のシーケンス図

着信時のシーケンス図

あとから気づいたが、公式のブログでわかりやすくまとめられていた。

それで今回は TwiML 動詞の “Reject” を使って、着信を拒否してみる (なぜなら課金されないらしいから)。ちなみに Reject 以外の挙動だと、発信者には通常の通話料が、着信者 (つまり Web アプリ側) には1円/回が課金される模様。

話がそれるが web sequence diagrams 便利だな。以下のような記述で、簡単にシーケンス図を作成できる。

title Twilio's Incoming Flow

発信者->Twilio: 電話を発信
Twilio->Web アプリ: メタデータを添えて、\nTwiML を http(s) で要求
note right of "Web アプリ": TwiML を生成
Web アプリ->Twilio: TwiML を出力
Twilio->発信者: TwiML に従って応答

サンプルアプリケーション

Twilio に対して TwiML を返すプログラムを作成する。言語は何でも良くて、極端な話 static な XML ファイルでも OK だが、今回は POST 値を手軽に取得したいので PHP を使う。

で、作成したのが以下のコード。日時と POST 値をログに残しつつ、TwiML を出力するプログラムだ。なお、xml の宣言が PHP のショートタグとコンフリクトするので echo で出力している。

<?php

$log = "./reject.log";
error_log(date("Y-m-d H:i:s") . "\n", 3, $log);
error_log(print_r($_POST, true), 3, $log);

header("Content-Type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>';

?>
<Response>
    <Reject reason="busy" />
</Response>

これを reject.php と言う名前で Web サーバに置き、同じディレクトリに reject.log を作成して Web サーバからの書込み権限を与える。

試しにブラウザでアクセスしてみると、以下のように表示される。同時に reject.log にログが出力されていれば成功だ。

reject.php の実行結果

reject.php の実行結果

なお、このままの状態だと Twilio のサーバから以外でも、URL を知ってさえいれば TwiML を取得できてしまう (実際ブラウザで表示できてるし)。対策としては、下記のページを見ると BASIC 認証を施すのが簡単そう。あと SSL のオレオレ証明書には現時点では非対応とのこと。

Voice Request URL の登録

作成したプログラムの URL を Twilio に登録する。

Twilio のサインアップはあらかじめ済ませておく。Twilio にログインし、[電話番号] をクリックしたあと表示されるページで、設定したい電話番号 (050-XXXX-XXXX) をクリックする。

Manage Numbers

Manage Numbers

次に表示されるページで、Voice Request URL を入力して [変更を保存する] をクリックすれば完了だ。

Voice Request URL の登録

Voice Request URL の登録

電話をかけてみる

以上でアプリケーション側の準備ができたので、いよいよ Twilio の番号に電話をかけてみる。今回は発信に 050 plus を使う。ピッポッパッ。

050 plus で発信

050 plus で発信

すると、トライアルアカウントである旨アナウンスが流れたあと、電話が切れる。通話料を見てみると……。

050 plus の通話情報

050 plus の通話情報

無料だと思ってたのに課金され奴ww なんでだろう。トライアルアカウントのアナウンスが流れる分の通話料か?まぁいいや今度聞いてみよう (誰に)。

そして Web サーバ側の reject.log を確認すると、以下のようにメタデータを取得できている。

2013-10-19 14:05:13
Array
(
    [AccountSid] => xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    [CalledVia] => 0503154xxxx
    [FromState] =>
    [ToZip] =>
    [Called] => +81503154xxxx
    [FromCountry] => JP
    [CallerCountry] => JP
    [CalledZip] =>
    [Direction] => inbound
    [FromCity] =>
    [ForwardedFrom] => 0503154xxxx
    [CalledCountry] => JP
    [CallerState] =>
    [CallSid] => xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    [CalledState] =>
    [From] => +8150yyyyyyyy
    [CallerZip] =>
    [FromZip] =>
    [CallStatus] => ringing
    [ToCity] =>
    [ToState] =>
    [To] => +81503154xxxx
    [ToCountry] => JP
    [CallerCity] =>
    [ApiVersion] => 2010-04-01
    [Caller] => +8150yyyyyyyy
    [CalledCity] =>
)

ちなみに Web サーバのログには次のように残っていた。ご多分に漏れず AWS を使っているらしい。

23.22.14.xxx - - [19/Oct/2013:14:05:13 +0900] "POST /path/to/reject.php HTTP/1.1" 200 52 "-" "TwilioProxy/1.1"

まとめ

以上のように、Twilio を使って、発信者の電話番号などを Web アプリケーションで簡単に取得することができた。POST で送られてくるメタデータに応じて TwiML を動的に生成するプログラムを作成すれば、もっと色んなことができそうだ。


コメント

コメントする




CAPTCHA