クラウドPBX、twilio で内線通話
クラウド PBX、twilio をセットアップし、2つの SIPクライアントを SIP REGISTER し、SIPクライアントから外線(PSTN網)へ発信、外線(PSTN網)から SIPクライアントへの着信までやってきました。
今回はいよいよ、PBX の主たる機能と言える内線通話です。
本来、内線はとてもカンタンです。社内のルールで動かして良いものなのでちょっと設定ミスがあったところでお客様に迷惑を掛けるわけではないからです。(外線の場合、電話がつながらない、というトラブルがあります)
SIPクライアント同士における内線は、本来はとてもシンプルです。SIPクライアント同士で通話する場合、通話相手は SIP URI で指定します。復習になりますが、下のような形式でしたね。
sip:3001@fugafuga.sip.twilio.com
これを便宜上、内線番号3001 と呼びます。同様に、
sip:3002@fugafuga.sip.twilio.com
は内線番号3002 と呼びます。いま、内線番号3001 はスマホアプリGS Waveに、内線番号3002 は VoIPソフト MicroSIP に使っています。
内線番号3001 が、内線番号3002 と通話したいとき、GS Wave(内線番号3001 が使ってる)の相手先の欄に上記の SIP URI を入れれば、通話することができます。
このときの動作としては、GS Wave は SIP URI の @以降(適宜上、後半部、と呼びます)を見て、これを DNS で正引きして IPアドレスを知り、この IPアドレスの 5060ポート宛に UDP で SIPパケット(SIP INVITE)を送りつけます。
fugafuga.sip.twilio.com はこの SIP INVITE に対して、3001 の本来の IPアドレスなどを返答したり、自身が間に入ってブリッヂしたりすることで、2つの SIP URI同士を取り持ってくれます。
しかし、内線をかけるたびに、SIP URI をすべて入れるというのは操作性の点で現実的ではありません。電話は、「番号」だけで相手とつながるから便利なのです。
そこで、多くの VoIPクライアントでは、ユーザが番号だけを入れても動作するように設計されています。
もう一度、内線3001 が内線3002 に内線通話を掛けたいとして、「現実的な」動作から内部でどのような処理が動いているかを説明します。
内線3002 に通話したいわけですから、GS Wave の画面には「3002」と番号だけを入れて通話を開始します。
GS Wave はユーザが数字だけを入れた場合、これを以下のように変換します。
1. 頭に sip: を付けて、SIP URI 形式にする
2. 後ろに、自身が SIP REGISTER している SIP Domain を付ける
3. 以下、SIP URI が入力された際と同じ動作に移る
つまり、ユーザが入れた「3002」は、「sip:3002@fugafuga.sip.tokyo.twilio.com」であると内部的に理解され、通話が開始されます。
ここで作成された SIP URI、sip:3002@fugafuga.sip.tokyo.twilio.com は SIP URI としては問題ないフォーマットなのですが、twilio の仕様により、通話先としては使えないようになっています。
具体的には、SIP URI の後半部が .tokyo と付くエッヂロケーションサーバ形式になっています。これは SIP REGISTER に使う際に入れる形式として使うだけで、SIP URI の宛先としては使えないことになっています。
このまま通話しようとしても、間を取り持ってくれるはずの fugafuga.sip.tokyo.twilio.com (の中身である twilio)はエラー(32220, Specifying an edge is not allowed when dialing SIP registered endpoints)を返して通話を開始してくれません。
ユーザにつないで欲しいときは、エッヂロケーションサーバ形式ではなく、生の SIP Domain、この場合だと fugafuga.sip.twilio.com 宛にSIP INVITE を送る必要があります。
この動作は掛ける側に求められる実装なので、twilio の仕様をよく知っているアプリケーション作者が、エッヂロケーションサーバ形式を自動的に生SIP Domain に変換するルーチンを入れていれば問題ないのですが、アプリがこのような実装を行うことはまずありません。(自前で開発するなら実装してしまってもいいかもしれません)
そこで、twilio の SIP Domain の A CALL IN COMING に紐付けてある Studio、前回まで作っていた Outgoing に手を加えて、エッヂロケーションサーバに送られてくる SIP INVITE を、正常なルートにルーティングしてやろうと思います。
twilio console、Studios、Outgoing と開いていきます。(そろそろ操作にも慣れましたね?)
もともとは Trigger の Incoming Call が connect_call_1 につながっていました。
ここに、条件分岐で処理を分けるために SPLIT BASED ON を挟み込んでやります。
SPLIT BASED ON は変数をテストして、その結果としてフローを分岐するという処理ができます。
今回は、「宛先が 3から始まる 4ケタの数字なら内線番号である」という条件を書いていきます。テストするのは宛先です。これは trigger.call.To に入っています。(変数を展開するわけではないので、二重括弧は使いません)
これをテスト対象の設定である、VARIABLE TO TEST に入力します。
次に、分岐条件を書きます。
Transitions のタブへ行き、NEW CONDITION をクリックします。
「3から始まる 4ケタの数字」かどうかは正規表現で判別します。正規表現は、Regex です。
注意としては、これは変数の全体にマッチする条件を書く必要があります。(一部だけマッチは機能しません)
sip:3[0-9]{3}@.+
という正規表現で、
1. sip:3 から始まり、
2. 0~9 が 3回続き、(=000~999)
3. @ のあとに何らかの文字列が入っている
という意味になります。3ケタにも 4ケタにもマッチさせたいなら、
sip:3[0-9]{2,3}@.+
になります。3から始まるだけでなく、2~8 で始まる、3~4ケタの数字なら、
sip:[2-8][0-9]{2,3}@.+
になります。
条件にマッチしたときは、TwiML Bin を呼び出したいので、ADD TWIML REDIRECT を配置します。URL は、
https:// [TwiML Bin の URL]?Exten={{trigger.call.To | replace: '.sip.tokyo', '.sip' | split: ';' | first}}
とします。
Exten というのは内線番号を表す英語、Extension の略です。ネイティブの人は Ex. と言ったりします。
フィルターの中身としては、エッヂロケーションサーバ名だった後半部を生SIP Domain に書き換える、そして SIP URI の最後部に付いているオプション類、例えば ;transport=tls といった指定を消してしまいます。
このフィルタを通すことで、宛先がもともと、
sip:3002@fugafuga.sip.tokyo.twilio.com;transport=tls
だったものが、
sip:3002@fugafuga.sip.twilio.com
に変わります。
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial answerOnBridge="true">
<Sip>{{Exten}}</Sip>
</Dial>
</Response>
呼び出す TwiML Bin の中身です。
answerOnBridge="true" を付けると通話を twilio でブリッヂしてくれます。直接、転送してしまっても良いのですがそうすると通話を開始後に通話に介入できなくなってしまう(会議室に参加させる、通話内容を録音する、など)のでわざとブリッヂとしています。
単に転送先を教えるだけであれば、SIP REFER という方法があります。これはまた別の機会にご紹介します。
次回は、物理的な電話機、VoIPフォンをつないでみる予定です。
目次
クラウドPBX、twilio で内線通話 (この記事)
twilio に SIPクライアントを追加するときの注意(特にスマホ)
クラウドPBX、twilio を VoIPフォンで使う(Panasonic KX-UT248)