ボクココ

個人開発に関するテックブログ

Twilio で 03 番号を利用する方法

ども、@kimihom です。

この記事は、Twilio Advent Calendar 2018 の3日目の記事です。まだ空きがあるので、Twilio ユーザーな方はぜひご登録を。

qiita.com

Twilio 03 番号実現に向けて

今回のテーマは Twilio における長年の課題の一つであった「Twilio は 050/0800/0120 の3タイプしか使えない」問題を解決する方法だ。確かに今までも 03 番号を 050 などへボイスワープ(転送)を使って Twilio で着信することはできた。しかし、この方法は転送に余計なコストがかかったり、Twilio から 03番号通知で発信ができないという問題を抱えていて現実的な解決ではなかった。

そこで、本記事では 03番号を転送せず直接 Twilio で扱えて、かつ発信も03番号で通知できる Twilio SIP の利用方法について案内する。

実現の概要

今まで Twilio 03 番号の利用が困難だったのは、Twilio と連携した SIP ゲートウェイが存在しないからだった。Twlio の SIP の仕組みを使えば他の電話回線と接続することは前からできたんだけど、その接続先がどこにもなかったというわけだ。そして満を時して先日、フォースネット株式会社さんがFC-GW という Twilio の SIP 接続に対応した SIP ゲートウェイをリリースされた。 この FC-GW を使えば、新規03番号か今まで利用していた固定電話番号を、Twilio で利用することができるようになる。

ひかりIP電話 クラウドPBX接続サービス FC-GW | FC-GW(エフ・シー・ゲートウェイ)は全国の地域電話(0ABJ)番号を各社クラウドPBXサービスで利用できます。

執筆時点で Twilio と接続できるゲートウェイのサービスは FC-GW しかないが、SIP 接続を Twilio でやるのは他でも同じ方法である。ゲートウェイ側が Twilio に合わせた実装をする必要があるので、実際に電話の受発信を実装する私たちはどんなゲートウェイサービスと提携したとしても、Twilio の実装方法にのっとって開発ができる。

f:id:cevid_cpp:20181201142724p:plain
構成概要

実装方法

ではいよいよ Twilio 03番号の実装方法について案内していく。

Twilio の SIP では、SIP Domain, Credential, Credential List, Credential Mapping という4つのモデルが登場する。それぞれのリレーションを雑に書くと以下のような形だ。

f:id:cevid_cpp:20180408012823j:plain

FC-GW から得た情報を Twilio へ登録し、Twilio と接続できるようにする必要がある。FC-GW で実際に電話回線や電話番号が用意されると、FC-GW から以下のような情報が提供される。() の中にある記載は、後のサンプルコードで使われる変数名である。

  • 電話番号(phone_number)
  • Twilio SIP ドメイン(twilio_sip_domain)
  • ゲートウェイドメイン(gw-domain)
  • ゲートウェイユーザー名(gw-user)
  • ゲートウェイパスワード(gw-password)

これらの情報を Twilio SIP に登録していこう。これらは Twilio の管理画面からぽちぽち入力して登録することもできるが、Twilio Developer なら全部 API で登録するよねってことで、Ruby のサンプルコードで一括で登録する方法を案内する。

なお、下記サンプルコードはあくまで Twilio へ登録しに行くだけのコードだ。実際は後述する03発信を可能にするために各値を DB へデータ保存する必要もあるので注意してほしい。

def create_sip_phone phone_number, twilio_sip_domain, gw_domain, gw_user, gw_password
  credential_list_sid = self.create_sip_credential_list
  credential_sid = self.create_sip_credential(credential_list_sid, gw_user, gw_password)
  domain_sid = self.create_sip_domain("sample_url", twilio_sip_domain)
  mapping_sid = self.mapping_sip_credential_domain(domain_sid, credential_list_sid)
end

def create_sip_credential_list
  credential_list = twilio_client.sip.credential_lists.create(friendly_name: "SIP-Credential-List-Name")
  credential_list.sid
end

def create_sip_credential credential_list_sid, user, pass
  credential = twilio_client.api.account.sip.credential_lists(credential_list_sid).credentials.create(
     username: user,
     password: pass
   )
  credential.sid
end

def create_sip_domain action_url, domain_name
  domain = twilio_client.sip.domains.create(
    friendly_name: "SIP-Domain-Name",
    voice_url: action_url,
    auth_type: 'CREDENTIAL_LIST',
    domain_name: domain_name,
    sip_registration: true
  )
  domain.sid
end

def mapping_sip_credential_domain domain_sid, credential_list_sid
  sip_mapping = twilio_client.sip.domains(domain_sid)
                       .credential_list_mappings
                       .create(credential_list_sid: credential_list_sid)
  sip_mapping.sid
end

実行してうまく動作したら、実際に Twilio コンソールにログインして電話の "SIPドメイン" のメニューで確認してみよう。

着信

着信の実装は、最初の定義と指定した TwiML でほぼ完了だ。

create_sip_domain のメソッド内で、着信時の Twilio アクションを定義することができる。着信を受けたら <Say> で IVR を流したり、<Dial>で電話をかけたりすることだろう。これだけで FC-GW で用意された 03から着信を受けたら、指定された TwiML が呼び出されて動作するようになる。

着信時における実装で注意したいポイントを列挙する。

  • Twilio から渡ってくる from は電話番号ではなく sip:090111122222@55.66.6.10 のような形式で渡ってくる。誰からかかってきたかを取得するには sip:@ の間の文字列を取り出す必要がある。
  • 着信を受けたときに返す TwiML を <Number> にしたい場合、<Sip password="pass" username="user">sip:番号@hoge.fcgw.jp</Sip> のようにすることで 03 通知の着信として受け取ることが可能。
  • <Dial> で複数の <SIP><Client> を組み合わせることはできない。<SIP>オンリーか、<Client>オンリーである必要がある。(Twilio の仕様っぽい)
  • FC-GW のチャネルの概念が出てくる。同時に何回線通話するかによってFC-GWへチャネル登録が必要。

発信

Twilio Client で発信する場合、取得したケイパビリティトークンで事前に指定した TwiML App から発信の動作を定義する形となる。ここで返す TwiML に注意が必要だ。以下のような TwiML を通じて、Twilio からではなく FC-GW を通じて発信する必要がある。

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial action="action_url" callerId="0311112222" record="record-from-answer-dual">
    <Sip password="password" username="user">sip:09011112222@hoge.fcgw.jp</Sip>
  </Dial>
</Response>

このような TwiML を返すことで、ついに 03番号通知で発信することが実現できる。発信するときは GWのドメインやユーザー名/パスワードが必要になるので、これらはDBに保存してアクセスした際に適切に表示できるような実装が必要になる。

終わりに

一部特殊な実装が必要になるけど、逆を言えばこれだけで Twilio で 03 番号が使えるようになる。裏側のサーバーサイドやフロントエンドの Twilio Client 等の実装をほとんど今まで通りのコードで実現できるのはTwilio の提供する API の素晴らしさだと言えるだろう。

本記事で、より多くの方が Twilio で素晴らしいアプリケーションを作り、使われるようになる一助になれば幸いである。

電話はなぜつながるのか 知っておきたいNTT電話、IP電話、携帯電話の基礎知識

電話はなぜつながるのか 知っておきたいNTT電話、IP電話、携帯電話の基礎知識