2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
はじめに
みなさん、こんにちは。
KDDIウェブコミュニケーションズ、Twilioエバンジェリストの高橋です。
この記事は、Twilio Advent Calendar 2022の6日目の記事となります(空いていたので書いてみた②)。
今回の記事は、以下のようなシナリオで役に立つ記事です。
- Twilioの番号に着信
- 担当者に電話を転送
- 転送する際に担当者の優先順位をつけたい
- 一斉呼び出しで後続する着信が話中になるのを避けたい
Twilio Voiceの動詞には、名詞を列挙する書き方があるので、そちらを使うことで比較的簡単に実現ができます。
しかし、この方法には以下の欠点があります。
- 列挙できる電話番号は最大10個まで
- 一斉呼び出しをしている間に次の着信が入ると話中になってかからない
- シーケンシャル呼び出しにすると、常にリストの先頭からになってしまうので不公平
このようなときは、TaskRouterを使って転送を実装しましょう。
ただ、TaskRouterに関してはあまり詳しい記事がなかったり、ドキュメントが膨大でどこから読めばよいかがわからないという声をよく耳にします。
そこで、今回は非常に簡単なデモを準備しましたので、デモの手順に従って作業していくことでTaskRouterの仕組みが少しわかるかと思います。
プログラムの準備
以下のGitHubに準備しましたので、適宜Cloneするか、ZIPダウンロード&展開してください。
ハンズオン
タスクルーターを使って、着信したコールを複数の PSTN 宛に転送します。
この手順では単純な転送のみを想定していますので、ワークフローの設計などは含まれません。
シナリオ
Twilio で購入した番号に着信したコールを、予め設定しておいた複数の電話番号に転送します。
ワークフローは初期状態で作成しますので、単純にラウンドロビン(待ち時間の長い転送先を順番にアサイン)で転送されます。
準備
本手順を実施するためには、以下の項目を予め用意しておく必要があります。
- 転送先となる電話番号
- Twilio アカウント(アカウントをお持ちでない方は、こちらから作成してください。
- Twilio の API Key / API Secret
- 転送元に使う電話番号の購入(日本の番号を購入するには、Bundles の作成も必要です)
- Twilio CLI のセットアップ
- CLI Serverless プラグインのセットアップ
タスクルーターの初期設定
- 管理コンソールにログインし、TaskRouter > Workspaces メニューに移動します。
-
Create new Workspaceボタンを押して新しいワークスペースを作成します。
- WORKSPACE NAME欄に何か名前をつけて、Saveボタンを押します。
- 作成されたワークスペースの SID(WS から始まる文字列)は後ほど作成しますので、どこかに控えておいてください。
ワーカーを作成する
ワーカーとは、タスクルーターにおけるオペレーターになります。今回は電話を転送するために転送先番号ごとにワーカーを作成していきます。
- 先ほど作成したワークスペースの Workers を選択します。
-
Create new Workerボタンを押します。
- Worker Name欄に、何かわかり易い名前をつけます。
- Attributes欄に、以下の JSON を記述します。
{ "name": "Agent_1", "contact_uri": "+8190XXXXXXXX" }
- ※contact_uri には、転送させたい先の電話番号を記載してください(E.164 形式)。
- Saveボタンを押して、ワーカーを作成します。
転送先を複数設定する場合は、上記を繰り返して複数のワーカーを作成してください。
Functions / Assets のデプロイ
ではここからは、転送に必要なプログラムなどを Twilio にデプロイしていきましょう。
.env
.env.sample
をコピーします。
cp .env.sample .env
コピーした.env
を編集します。
設定項目 | 値 |
---|---|
ACCOUNT_SID | Twilio の AccountSid(AC から始まる文字列) |
API_KEY | Twilio の API Key(SK から始まる文字列) |
API_SECRET | API Key とペアで作成される API Secret |
WORKSPACE_SID | 先程作成したワークスペースの SID(WS から始まる文字列) |
TRANSFER_FROM | Twilio 上で購入した電話番号(E.164 形式) |
デプロイ
以下のコマンドを使って、Functions などを Twilio にデプロイしていきます。
npm run deploy
デプロイが成功すると、Domain(taskrouter-demo-XXXX-dev.twil.io)
が払い出されますので、メモ帳などに控えておいてください。
Assignment Callback の設定
タスクルーターがワーカーを選択すると、タスクがワーカーに割り当てられます。その際に Twilio から Webhook が飛んでくるので、それを処理することで転送を実現します。
この Webhook のことを、Assignment Callback
と呼び、設定はワークフロー設定で行います。
- ワークスペース内の Workflows を選択します。
- すでに作成されている
Default Fifo Workflow
を選択します。
-
Assignment Callbackを展開し、ASSIGNMENT URL欄に、
https://taskrouter-demo-XXXX-dev.twil.io/assignment-callback
(XXXX は先程デプロイしたときに払い出された Domain 環境に合わせてください) - Saveボタンを押して設定を保存します。
ちなみに、Webhook 先となるassignment-callback
は以下のようなコードになっています。
exports.handler = function (context, event, callback) {
console.log(`🐞 assignment-callback called.`);
const { DOMAIN_NAME, TRANSFER_FROM } = context;
let res = {
instruction: 'dequeue',
from: TRANSFER_FROM,
status_callback_url: `https://${DOMAIN_NAME}/status-callback`,
};
callback(null, res);
};
こちらのドキュメントに記載があるように、Assignment Callback では色々な処理が用意されています。
今回は、着信してキューに入っているコールを転送したいため、dequeueを使っていくことになります。
instruction
パラメータに、dequeue
を指定することで、キューに入っているコールを取り出し、更に電話を転送してくれます。
転送先は、to
パラメータで指定しても良いのですが、Workers の Attributes にcontact_uri
パラメータがある場合は、そちらがデフォルトで使われます。
from
パラメータは、日本国内で PSTN 経由の発信をする場合は必ず Twilio の番号を発信元番号に指定する必要があるので必須となります。
status_callback_url
パラメータについては、後ほど解説をします。
着信を TaskRouter に接続
最後に、着信したコールを TaskRouter にわたす部分を作成します。具体的には、Enqueue
動詞を使って渡すことができますが、Studio フローでも実現が可能なため、今回は Studio フローを使っていきましょう。
- 管理コンソールから Studio を選択します。
- スクラッチで新しいフローを作成しましょう。名前は何でも OK です。
- Enqueue Callウィジェットをキャンバスにドラッグし、Incoming Callとつなぎます。
-
Enqueue Callウィジェットには以下のようにパラメータを設定していきます。
パラメータ | 値 |
---|---|
WIDGET NAME | なんでもよいです |
QUEUE OR TASKROUTER TASK |
TaskRouter Task を選択 |
TASK ROUTER WORKSPACE | 今回作成したワークスペースを選択 |
TASK ROUTER WORKFLOW | 先程 Webhook を設定したDefault Fifo Workflow を選択 |
HOLD MUSIC TWIML URL |
https://taskrouter-demo-XXXX-dev.twil.io/wait-url (XXXX はご自分の環境に合わせてください) |
TWIML REQUEST METHOD |
GET を選択 |
- Saveボタンを押して設定を保存した後、忘れずにPublishをしておいてください。
着信番号にフローを割り当て
では今作成した Studio フローを、着信番号に割り当てましょう。
- 管理コンソール内の Phone Numbers > Manage > Active numbers を選択し、着信させたい番号のプロパティを開きます。
-
A CALL COME INで
Studio Flow
と、先程作成したフローを選択します。
動作確認
上記の設定で、HOLD MUSIC TWIML URLを指定しているため、着信した際に「ただいま、オペレーターにお繋ぎしておりますので、このまましばらくお待ち下さい。」というガイダンスが流れ、電話が転送されます。
何回かテストをして、ラウンドロビンで振り分けられていることを確認しておきましょう。
動作説明
では最後に、一連の流れの解説をしていきます。
- 着信したコールは、Studio 経由で TaskRouter に渡ります。このときのワークフローは Enqueue ウィジェットで指定しています。
- ワークフローの中では、本来はスキルルーティングなどが設定できますが、今回設定した
Default Fifo Workflow
は、直接Sample Queue
にコールを入れています。また、キューに入れる順番も指定をしていませんので、最後の対応してからの時間がもっとも長い Worker からアサインされるようになります。 -
Sample Queue
には、このキューで通話をアサインされる Worker が紐付けられますが、今回は特別な条件は指定されていないので、すべての Worker がアサイン対象となります。 - ここでワーカーがアサインされると、
Reservation
が作成され、Worker は予約済みとなります。と同時に、ワークフローで設定したAssignment Callback
が発火します。 - Webhook の通知先である、
assignment-callback.js
では、単純にキューからコールを取り出して、転送先に転送することを目的としたdequeue
応答を返します。これにより、Twilio はコールをキューから取り出して、転送先に発信します。 - 通話中のときのタスクの状態(Assignment Status)は、
assigned
になり、この状態では Worker は他のコールを受けられませんし、タスクルーターもアサインはしません。 - 通話が終了すると、タスクの状態は
wrapped
(後処理中)になります。後処理中のタスクを持っている Worker は、次のコールがアサインされないので、今回の例だと全員が一度通話をしてしまうと、後続の着信を誰も取らなくなってしまいます。 - そこで、
dequeue
応答した際に、status_callback_url
を指定し、通話が終了した時に、Twilio から Webhook を取得するようにしておきます。そして、Webhook の受取先(status-callback.js
)でタスクの状態を強制的にcompleted
に書き換える処理を入れています。具体的には以下のようなコードとなります。
exports.handler = async function (context, event, callback) {
console.log(`🐞 status-callback called.`);
const { TaskSid, CallStatus, ReservationSid } = event;
const { API_KEY, API_SECRET, ACCOUNT_SID, WORKSPACE_SID } = context;
const client = require('twilio')(API_KEY, API_SECRET, {
accountSid: ACCOUNT_SID,
});
try {
if (CallStatus === 'completed') {
// 通話が正常に終了したらタスクを完了させる
await client.taskrouter.v1
.workspaces(WORKSPACE_SID)
.tasks(TaskSid)
.update({
assignmentStatus: 'completed',
});
} else {
// 通話が失敗したら、Reservationをリジェクトする
await client.taskrouter.v1
.workspaces(WORKSPACE_SID)
.tasks(TaskSid)
.reservations(ReservationSid)
.update({
reservationStatus: 'rejected',
});
}
callback(null, {});
} catch (err) {
console.error(`👺 ERROR: ${err.message ? err.message : err}`);
callback(err);
}
};
Assignment Callback
から転送したときのStatus Callback
には、標準でTaskId
が含まれています。なので、この値を使ってタスクを更新しています。
イレギュラーな処理
もし転送先が応答しなかった場合など、正常に通話が終了しない場合は、別の Worker にアサインし直す必要があります。
その場合は、Status Callback
で、CallStatus
を判定し、completed
以外が入っている場合は、Reservation のステータスをreject
に更新することで対応が可能です。
上記のstatus-callback.js
にその処理が記載されています。
応用
上記の手順(デフォルトのTaskRouterの動作)では、呼び出しは一人ずつになります。場合によっては、同時に複数の電話番号に架電をして、最初に応答した人にだけつなぎたい時があります(一斉同報と呼びます)。
TaskRouterを使って一斉同報を実装するには、TaskQueueの設定を一部変更します。
具体的には、MAX RESERVED WORKERSに、同時に呼び出したい数を入れます。
設定値の最大値は50です。
まとめ
以上が、今回のデモの一連の流れとなります。
タスクルーターは基本的にタスクをワーカーにアサインするところが主な役割になりますので、アサインされたあとの処理はプログラムで対応する必要があります。
今回の実装により、転送先が10件よりも多い場合の対応や、ラウンドロビンにより特定の人に通話が集中しない仕組みが実装されました。
本来はワークフローの設計を行うことで、より高度なルーティングが可能になりますので、以下の記事を参考にするなどして、ぜひそちらにもチャレンジしてみてください。
Twilio(トゥイリオ)とは
https://cloudapi.kddi-web.com
Twilio は音声通話、メッセージング(SMS /チャット)、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウド API サービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。
Twilioに関するご相談などがございましたら、ぜひ相談会をご利用ください。
Twilio相談会