はじめに
Twilio Studioは簡単に電話応答フローを作ることができます。
今回は想定されるシナリオに対して、いくつかのTipsを紹介します。
今回の想定シナリオ
- 営業時間内に電話がかかってくると、自動応答で接続する部署のメンバーに転送する。
- エンジニア部門には、担当者全員のケータイに一斉コール。
- リサーチ部門には、担当者間で予め決めておいた順番でコール。
- 営業時間外に電話がかかってきたら、留守番電話に録音して、担当者に通知。
今回の必要となる処理
- 複数の担当者のケータイ電話を同時に鳴らす
- 複数の担当者のケータイ電話を順番に鳴らす
- アナウンス後、ボタンをプッシュして部署を切り分け
- 営業時間外判定をする
- 留守番電話録音して通知する
各処理を作っていく
複数の担当者のケータイ電話を同時に鳴らす
Connect Call Toウィジェットを利用します。

ウィジェットの設定でCONNECT CALL TOをMultiple Numbers (Simulring)に設定します。
PHONE NUMBERS OR CLIENTSには、カンマ(,)区切りで転送先電話番号を複数指定します。ちなみに電話番号は+81で始まるいわゆる国際電話番号のフォーマット(E.164)で指定する必要があります。
複数の担当者のケータイ電話を順番に鳴らす
TwiML Binsを使いTwiMLを作成し、ADD TWIML REDIRECTウィジェットを使ってTwiML BinsをStudioから呼び出すようにします。TwiML Binsは管理コンソール左から選択できます。

TWIMLには以下を記載します。
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial callerId="+8150********" timeout="20" sequential="true">
<Number>+819000000001</Number>
<Number>+819000000002</Number>
</Dial>
</Response>
callerIdには受付電話番号をE.164フォーマットで記載、Numberには、転送したい番号をE.164フォーマットで<Number></Number>で囲い記載します。記載した電話番号の順番に架電をします。
Saveをクリックすると、PropertiesのURLにURLが記載されますので、そちらをコピーしておきます。
StudioのADD TWIML REDIRECTウィジェットを使って、さきほどのTwiML Binsを呼び出します。

URLには、さきほどのTwiML BinsのURLを入力します。
アナウンス後、ボタンをプッシュして部署を切り分け
アナウンスとボタンのプッシュを取得するためにGather Input on Callウィジェット、押されたボタンの切り分けのためにSplit Based On...ウィジェットを使います。

Gather Input on CallのTEXT TO SAYには、アナウンスする内容を記入します。LANGUAGEはJapaneseにすることをお忘れなく。ちなみにSAY OR PLAY MESSAGEでPlay a Messageを選択すると、mp3ファイルを再生させることもできます。

Split Based On...ウィジェットの設定では、VARIABLE TO TESTにGather Input on CallウィジェットのDigitsを指定します。これはGather Input on Callウィジェットでプッシュされた番号が格納されています。その値に対してCONDITIONを作成し、分岐させます。
Gather Input on CallのUser Pressed KeysとSplit Based On...をつなぎます。とりあえず今は分岐がわかるようにSay/Playウィジェットを接続しておきました。
営業時間外判定をする
Twilio Functionsを使い営業時間判定を行い、Studioから呼び出すようにします。
Functionsからの返答を取得し、フローを切り分けるためにSplit Based On...ウィジェットを使います。
Twilio Functionsは管理コンソール左から選択できます。2種類あるので今回はFunctions(Classic)を使います。

CODEには以下を記載します。FUNCTION NAMEやPATHにはわかりやすい名前を入れておきます。
exports.handler = function(context, event, callback) {
let is_business_times = true;
let date = new Date(Date.now() + (9 * 60 * 60 * 1000)); // UTC → JST
let hour = date.getHours();
let week = date.getDay();
// 平日(月〜金)の9時から17時までを営業時間とする
if(hour < 9 || hour >= 17 || week === 0 || week == 6){
is_business_times = false;
}
callback(null, {"is_business_times" : is_business_times} );
};
callbackの第2引数にStudioに返却するデータを入れておくと良いです。
作ったFunctionをStudioで呼び出します。

RUN FUNCTIONウィジェットを使います。SERVICEはDefaultを指定します。これはFunctions(Classic)のことになります。FUNCTION URLには、プルダウンで上記で作成したFunctionの名前を指定します。

Split Based On...ウィジェットでは、VARIABLE TO TESTに以下を記述します。
widgets.IsBusinessTimes.parsed.is_business_times
これは、widgets.{RUN FUNCTIONウィジェットの名前}.parsed.{プロバティ名}となっています。
これで、Functionが返した値を取得することができます。
とりあえず今は分岐がわかるようにSay/Playウィジェットを接続しておきました。trueなら営業時間、その他は営業時間外というようなアナウンスをSayするようにしています。
留守番電話録音して通知する
留守番電話録音するためにrecord_voicemailウィジェットを使います。
また、録音データをSMSで担当者に通知するための処理をTwilioFunctionsを使って作ります。
まずはTwilio FunctionsでSMSで担当者に通知する処理を作ります。
Twilio Functionsは管理コンソール左から選択できます。2種類あるので今回はFunctions(Classic)を使います。

CODEには以下を記載します。FUNCTION NAMEやPATHにはわかりやすい名前を入れておきます。
exports.handler = async function (context, event, callback) {
if (event.RecordingDuration !== 0 && event.RecordingStatus == 'completed') {
let client = context.getTwilioClient();
let body = '留守番電話にメッセージが届いています。' + event.RecordingUrl;
await client.messages
.create({
body: body,
from: '{送信元の電話番号}',
to: '{SMS送信先の電話番号}'
});
}
callback(null, {});
}
fromには、送信元となるTwilioで購入したSMS送信可能な電話番号を記載します。toには通知を受けたいケータイ電話番号をE.164フォーマットで記載します。
Twilio StudioではRECORD VOICEMAILウィジェットを使います。

RECORDING STATUS CALLBACKに、録音データ通知用に作成したFunctionのURLを記入します。
留守番電話に録音がされると、以下のようなSMSが指定した電話番号に届きます。メッセージの末尾に記載されているURLにアクセスすると録音された内容を聞くことができます。
留守番電話にメッセージが届いています。https://api.twilio.com/2010-04-01/Accounts/AC**************************/Recordings/RE************************
各処理をつなぎ合わせる
シナリオに沿って、各処理をつなぎ合わせると、以下のような感じのフローになります。

※エラー時フローはぐちゃぐちゃするので記載してません。任意に追加してくださいませ。
補足
この記事はQiita Engineer Festa 2022「Twilioを使うためのコツ、Tipsやおもしろ実装など、Twilioのことなら何でも共有しよう!」への参加記事になります。
最近、リリースされたDev Phoneがテストをするときなどにかなり便利です。オススメ。