twilio

Twilio Functionsを使って、サーバーレスで連続架電を行う

はじめに

電話APIであるTwilioには、非常に多くの利用方法がありますが、その中でも代表的な使い方に「異常を電話で通報する」というものがあります。その名の通り、例えばサーバーに異常が発生したり、夜間にドアが空いたことを検知したりした場合に、自動的に電話をかけるソリューションです。

自動で電話をかけるにはどうするか

Twilioが用意しているRestAPIを利用します。
例えば、以下のコードを実行するとTwilio経由で電話がかけられます(予めNode.jsヘルパーライブラリをインストールしておく必要があります)。

Node.js
const accountSid = 'TwilioのAccountSID';
const authToken = 'TwilioのAuthToken';
const client = require('twilio')(accountSid, authToken);

client.calls.create({
  url: 'http://demo.twilio.com/docs/voice.xml',
  to: '発信先電話電話番号',
  from: 'Twilioで購入した発信元電話番号',
})
.then((call) => process.stdout.write(call.sid));

本記事で紹介すること

上記コードのように、Twilioを使うとプログラムから簡単に電話をかけることができます。
しかし、異常通報では次のような要件が課せられることがあります。

  • 通報先が一人ではない
  • 誰かが出るまで電話をし続けたい

このようなニーズには、上記のような単純なしくみでは上手く行きません。
一般的には、上記のようなコードをループさせるプログラムを作り、自前のサーバー上で実行する必要があります。
これは正しいアプローチであり、Twilioとしても推奨する手法です。
一方で、通報のためだけに自前のサーバーを立てるのは難しいとか、自前のサーバーに異常が発生した場合にどうするかという問題もあります。
そこで本記事では、自前でサーバーを建てずに、しかも複数人に対して、誰かが電話にでるまで架電するしくみを紹介します。そのために、Twilioの管理コンソール内に用意されている「Twilio Functions」を利用します。

注意事項

  • 本記事で紹介する方法は、あくまでサンプルです。
  • この記事に記載した方法で想定されない動作をした場合に、その責任は一切負いませんので、予めご了承ください。

準備

本記事を実行するために必要なものは以下の通りです。

  • Twilioのアップグレードアカウント(トライアルアカウントでは、発信先には認証済み電話番号しか指定できません)
  • Twilioで購入した050番号を1つ
  • RestAPIを呼び出すためのしくみ(上記で紹介したコードなどが実行できるパソコンなど)

ソースコードの取得

今回の記事で使用するコードは、以下のGitHubにて公開されています。
https://github.com/twilioforkwc/serialCall

$ git clone git@github.com:twilioforkwc/serialCall.git
で取得するか、
https://github.com/twilioforkwc/serialCall/archive/master.zip
をダウンロードして解凍してください。

しくみを理解する

ダウンロードしたフォルダ内に、functions.jsがあるので、こちらを見ながら今回のコードを説明します。

通知先の電話番号は、架電先リストに登録していきます。

// 架電先リスト
const callList = {
  "携帯1": "+8190xxxxxxxx",
  "携帯2": "+8180xxxxxxxx",
  "携帯3": "+8180xxxxxxxx",
};

Twilioでは、電話番号をE.164形式で指定する必要がありますので、先頭に国番号を付けるのを忘れないようしてください(日本の国番号は+81です)。

架電する発信元番号は、発信元番号として設定します。発信元番号はTwilioで購入した番号のみが利用できます。

// 発信元番号
const callFrom = '+8150xxxxxxxx';

その後に動作を指示するパラメータが続きます。

// ループ回数(1以上の整数、1ならループしない)
const maxLoop = 2;
// 留守電チェック(する: true、しない: false)
const AMD = false;
// 呼び出し秒数
const timeout = 10;
// メッセージ
const message = "異常が発生いたしました。至急確認が必要です。";
  • ループ回数は1以上を指定してください。0を指定した場合は、誰にも架電はしません。
  • AMD(Answering Machine Detection:機械応答検知)は、最近Twilioで実装された機能で、留守番電話やFAXなど人間以外が応答した場合に、それをチェックすることができる機能です。この機能は、まだ正式に日本ではサポートされていないのと、1コール毎に1.125円がかかりますので、有効(true)にする場合は注意が必要です。
  • 呼び出し秒数は、相手が出るまでのタイムアウト秒数です。この時間内に相手が応答しなかった場合、次の架電先にコールが移動します。
  • メッセージは、相手が応答した場合に通知したい内容を記載します。この文章はTwilioのSay動詞のパラメータとして45〜49行目付近で利用されます。日本語以外にしたい場合などはこの部分を変更してください。

このFunctionでは、Twilioが標準で送ってくるパラメータ以外に、idxとloopという2つのパラメータを取ります。
idxパラメータは、発信先リストの何番目に架電するかを指します(0が先頭)。loopパラメータは何回目のループかを判定します(0が最初のループ)。
Functionsの中からRestAPIで発信を行い、相手が応答した場合、もしくは応答しなかった場合に、自分自身を再度呼び出すしくみになっています。

架電するかどうかのチェック条件は以下のとおりです。
- 応答があったが、人間以外が応答した場合(AMDを有効時のみ)
- 話中であった場合
- 発信が何らかの理由により失敗した場合
- 相手が応答しなかった場合
- 相手側からキャンセル応答(通話拒否)がきた場合
- 初回の呼び出し時

構築

Functionsの作成

  1. Twilioの管理コンソールにログインします。
  2. ランタイムメニューを開き、Overviewを選択します。
    Fuctions連続架電01.png

  3. YOUR DOMAINの部分のドメイン名をコピーしておきます。

  4. ランタイムメニューのFunctionsを選択し、新しいFunctionsを作成します。

  5. 雛形のダイアログが表示されたら、「Blank」を選択して、「Create」ボタンを押します。
    スクリーンショット 2017-07-21 10.07.59.png

  6. FUNCTION NAMEは「連続架電」とします(なんでも良いです)。

  7. PATHの部分に「/serialCall」と入力します。

  8. ACCESS CONTROLにチェックを外します。

  9. CODE欄をすべて削除し、先程ダウンロードしたfunctions.jsの内容を貼り付けます。
    Functions連続架電02 (1).png

  10. 架電先リスト、発信元番号をそれぞれご自分の環境に併せて変更します。

  11. 「SAVE」ボタンを押して保存します。

テスト

作成したFunctionsをCurlを使って実行してみます。

  1. Curlが実行できる環境で、以下のコマンドを入力します。
Curl
curl -X GET https://xxxxxxx-xxxxxxx-xxxx.twil.io/serialCall

ドメイン名の部分は、先程控えておいたご自分のドメイン名に変更してください。
これで連続架電が開始されます。

万が一、コールが止まらずに何度もループしてしまうような場合には、Functionsを一度削除してください。