Twilio Flexの始め方（ACD編）

:::note alert
2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
:::

# はじめに

みなさん、こんにちは。
KDDIウェブコミュニケーションズの Twilioエバンジェリストの高橋です。

[Twilio Flex Advent Calendar 2021](https://qiita.com/advent-calendar/2021/twilio-flex) 8日目の記事となります。
[前回](https://qiita.com/mobilebiz/items/3c2f2582b7437f63dc14)までの記事で、ワーカーの管理方法まで解説をしたので、今回は着信した電話をどのように振り分けるかについて説明していきます。

# ACDとは

コンタクトセンターにおける着信の振り分けは、ACD（Automatic Call Distributor: 着信呼自動分配）と呼ばれます。
ACDの目的は、**最適なオペレーターにコールを割り当てる**ことにあります。

そのためには、実際にオペレーターに割り当てる前に発信者が誰なのか、どのような目的で電話をしてきたのかを知る必要があるかもしれません。
発信者が誰かを知るために、電話番号を使って判定することができます。具体的なやり方については、以下の記事を参考にしてください。
[Twilio Flexの始め方（GoogleSpreadsheet連携編）](https://qiita.com/mobilebiz/items/916b416af155bdab988b)

また、着信時にIVRを使って要件を確認することもできます。具体的なやり方については、以下の記事が参考になります。
[Twilio Flexの始め方（IVR編）](https://qiita.com/mobilebiz/items/4906a2d37607e1082808)

Twilio Flexには、スキルベースのタスクルーティングが可能なTaskRouterが用意されていますので、スキルの有無やレベルに合わせたACDなども実装することができます。

# 具体的なACDの実装

今回は、以下のシナリオを沿ってTwilio　Flex上でACDの設定をしていきたいと思います。

- オペレーターは4名。
- 営業案件に対応する営業グループのオペレーターが2名、既存ユーザーのサポートに対応するサポートグループのオペレーターが2名。
- 営業グループの担当者のスキルレベルはそれぞれ異なるが、着信は均等に行いたい。
- サポートグループの担当者もそれぞれスキルレベルが異なり、レベルの低い担当者を優先的に対応させたい。
- それぞれのグループの担当者がすべて埋まっている場合は、別の担当グループでも対応できるようにしたい。

要件を図にすると以下のようになります。
![ACD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/cd3b4ac8-f561-93d0-c5d3-dab32b7de98c.png)


## スキルの設定

まずは、上記シナリオにあるグループ分けをするため、営業（Sales）とサポート（Support）の2つのスキルを作りましょう。

- Twilio管理コンソール経由でFlexを起動します。管理者としてログインした状態になります。

![スクリーンショット 2021-12-17 10.20.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/27988b86-c166-a152-f8ba-e31a3dac3c85.png)

- マネージメントパネルの**ASSIGNMENT**の中にある**SKILLS**ボタンを押します。
- 以下の図のように、2つのスキルを作成してください。

![スクリーンショット 2021-12-17 10.22.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/4f2afa3d-73ff-9b99-2c35-7ab2169615f1.png)

ポイントは、それぞれのスキルにレベル（MIN:1、MAX:10）を設定するところです。
これによって、それぞれのワーカーにスキルレベルを与えることができるようになります。

## ワーカーの設定

次に、それぞれの担当者（ワーカー）にスキルを設定していきます。

![スクリーンショット 2021-12-17 10.25.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/31c263b4-9ee2-6c44-a614-2045cadd3793.png)

- ワーカーパネルを開いて、一人づつスキルを割り当てます。
- サポート担当者には、それぞれスキルとして「Support」、一人はスキルレベルを「1」、もうひとりには、スキルレベルを「6」で割り当てを行います。
- 営業担当者には、それぞれスキルとして「Sales」、スキルレベルもそれぞれ「1」と「６」に割り当てておきます。
- それぞれの設定時に**Save**ボタンを押すのを忘れないようにしてください。

## IVRの設定

次に、着信時に要件を聞き出すIVRを構築しましょう。
完成フローはこんな感じです。

![スクリーンショット 2021-12-17 11.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/51d442c7-aafe-dfb6-39c5-a153cf12a740.png)

ポイントとなるところだけ説明していきます。

### 要件を聞き出す

**Gather Input On Call**ウィジェットを使います。今回は「GetQuestion」という名前をつけました。
![スクリーンショット 2021-12-17 11.46.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/1a7caaa5-fcc0-3fbd-6ed6-0859acf48726.png)

特に難しいことはしていません。営業系の問い合わせは１を押させて、サポートは２を押させるようにしています。

### 変数でスキルを管理

今回は、入力された値（１か２）を判定して、**Set Variables**ウィジェット（「SetSkills」という名前をつけました）内で、文字列（`Sales`もしくは`Support`）に変換して、変数に格納しています。

![スクリーンショット 2022-02-26 9.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/4acf352f-ef37-7b6e-3642-1e8a95cb6126.png)

Liquid Template Languageを使って、条件式を指定しています。

```
{% if widgets.GetQuestion.Digits == '1' %}Sales{% else %}Support{% endif %}
```

### TaskのAttributeを設定

最後に、**Send To Flex**ウィジェット（「SendCallToAgent」という名前にしてあります）内で、タスクの属性として変数の値を指定しています。

![スクリーンショット 2021-12-17 11.51.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/55f62f91-0c8c-4b92-e655-bd2e9f08b60a.png)

Keyは、`skill`とし、Valueは変数の値（`{{flow.variables.skill}}`）を指定しています。

このフローを電話番号にアサインする作業をすれば、とりあえずIVRの部分は完成です。

## TaskRouterの設定

この後いよいよACDを設定していきますが、その前に先程のIVRを経由して作成されたタスクのAttributesを確認してみましょう。

- Twilio管理コンソールの左側のスライドメニューから、TaskRouterを選択します。
- **WORKSPACE**から「Flex Task Assignment」のリンクを選択します。
- **Tasks**メニューを選択します。

![スクリーンショット 2021-12-17 12.53.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/7ba80b4d-b78b-0252-0096-66d24681340d.png)

- 着信直後はタスクの一覧が表示されるので、そちらを選択します（しばらくするとタスクは削除されます）。

![スクリーンショット 2021-12-17 12.56.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/41227a6f-d62a-695e-f52e-89778cfaf550.png)

タスクの詳細画面上に、**属性**が表示されます。以下はサンプルです（一部マスクしています）。

```json
{
  "from_country":"JP",
  "called":"+1276xxxxxxxx",
  "to_country":"US",
  "to_city":"DAVENPORT",
  "type":"inbound",
  "to_state":"VA",
  "caller_country":"JP",
  "call_sid":"CAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "skill":"Support",
  "account_sid":"ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "from_zip":"",
  "from":"+8180xxxxxxxx",
  "direction":"inbound",
  "called_zip":"24217",
  "caller_state":"",
  "to_zip":"24217",
  "called_country":"US",
  "from_city":"",
  "called_city":"DAVENPORT",
  "caller_zip":"",
  "api_version":"2010-04-01",
  "called_state":"VA",
  "from_state":"",
  "caller":"+8180xxxxxxxx",
  "caller_city":"",
  "name":"+8180xxxxxxxx",
  "to":"+1276xxxxxxxx"
}
```

`skill`というパラメータと、`Sales`もしくは`Support`という値が入っていることを確認しておきます。
また、このタスクが「Assign to Anyone」というワークフローに割り当てられていることも合わせて確認しておきましょう。

## タスクキューの設定

では次に、ワーカーをグルーピングしてタスクを処理するためのキューの設定をしていきましょう。

- TaskRouterのサブメニューにある**タスクキュー**を選択します。

![スクリーンショット 2021-12-17 14.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/fc4d1c10-d8be-4728-767c-34d1ccc7ed10.png)

- 青い＋アイコンを押します。

![スクリーンショット 2021-12-17 14.46.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/dc576547-11ea-e59c-e9a7-619a297f4e9d.png)

- **TASK QUEUE NAME**には、「Sales」と入力します。
- **MAX RESERVED WORKERS**には「1」と入力します。これは、タスクを同時に何人に予約するかの指定です。デフォルトは１です。
- **QUEUE EXPRESSION**には、`routing.skills HAS "Sales"`と入力します。これは、ワーカーの属性として`routing.skills`という配列に、`Sales`が入っている人を抽出するための条件文です。先程、スキルの指定をした際に自動的に表示されていたものと同じです。
![スクリーンショット 2021-12-17 14.50.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/899e25cf-67fe-a119-ff48-76b967b48ff2.png)

- **Save**ボタンを押します。画面上に、条件に一致するワーカーの一覧が表示されます。

![スクリーンショット 2021-12-17 14.53.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/2e717967-fdcf-1843-c5e0-ec7c6da64df4.png)

上記と同じように、今度は`Support`というタスクキューを作成してみてください。

![スクリーンショット 2021-12-17 14.58.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/c7b992e3-169a-f38e-be42-09daa45c819b.png)

## ワークフローの設定

ACDの中心となるのが、ワークフローです。
今回は、先程のシナリオに沿ったACDを構築するために、新たにワークフローを作っていきましょう。

- TaskRouterのサブメニューにある**Workflow**を選択します。
![スクリーンショット 2021-12-17 14.35.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/d777d7ee-3942-c59c-e6e0-ce17d812ff75.png)

- 青い＋アイコンを押します。

![スクリーンショット 2021-12-17 15.10.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/3ed90b19-8625-9389-e033-7a41f2adacc4.png)

- **WORKFLOW NAME**に「Sales and Support」と入力します。
- **TASK RESERVATION TIMEOUT**は「120」のままにします。これは、ワーカーが待受中にも関わらず、割り当てられたタスクを処理しないときのタイムアウト値です。デフォルトは120秒（２分）です。
- **Add Filter**ボタンを押します。

![スクリーンショット 2021-12-18 9.49.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/f0e13e2d-4c69-df30-f243-ac6b5a01c2c3.png)

- Unnamed Filterと書かれた場所をクリックして、フィルターに「Sales」という名前をつけます。
- **MATCHING TASK**には、`skill == 'Sales'`と入力します。これでタスクのskill属性が`Sales`のものが対象になります。
- **TASK QUEUE**のプルダウンから、先程作成した「Sales」タスクキューを選択します。
- **SKIP TIMEOUT**には、「`1==1`」を入力します。

☝️タイムアウトについて
フィルター内には、**SKIP TIMEOUT**と**TIMEOUT**の２つのタイムアウト値が存在します。
**SKIP TIMEOUT**は、このステップ内でワーカーの割り当てができなかった場合に参照される条件です。今回は、`1==1`と指定しているので、「対応できるワーカーが不在のときは、このステップをスキップする」という条件になります。シナリオに該当するグループが対応できない場合は、別のグループにエスカレーションする要件があるため、このように設定しておくことで、ワーカーが空くの待たずに、すぐに別グループにエスカレーションされます。
一方、**TIMEOUT**は、タスクが予約されてからのタイムアウト値です。待受中のワーカーがタスクを処理しなかった場合のケースで、`None`にしておくとワークフローのデフォルト値（120秒）がタイムアウト値になります。

- **Add a Step**のリンクを押します。

![スクリーンショット 2021-12-18 9.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/8df19603-e37c-35dd-ce79-5341619a761b.png)

- **TASK QUEUE**に「Everyone」をアサインしておきます。

このように設定することで、営業グループが全員埋まっている場合は、全員のタスクキューにタスクが割り当てられるようになります。

- **Add a Filter**ボタンを押して、同様にサポート用のフィルターも作成しましょう。

![スクリーンショット 2021-12-18 9.53.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/350ed7d8-fd26-fefe-1961-6cd54cfa9dd6.png)

サポートのシナリオについては、レベルの低い担当者を優先するというシナリオになっているため、ステップは３つ必要です。
前の２つのステップは、どちらもタスクキューに「Support」を割り当てますが、１つ目のステップの**EXPRESSION**に`worker.routing.levels.Support < 6`と入力しています。**EXPRESSION**は、タスクキューにタスクを入れる際の条件を指定します。今回は、「サポートレベルが６より小さいワーカーをアサイン」という条件を指定しているため、このステップには、レベルの低いワーカーのみが選択されます。
もし、レベルの低いワーカーが不在の場合は、先程説明した**SKIP TIMEOUT**が参照され、条件が「1==1」なので、次のステップに遷移します。
次のステップでは、**EXPRESSION**がデフォルトの`Any available worker in queue`になっているため、レベルに関係なくサポート担当者がアサインされるようになります。

- **Create**ボタンを押して、作成したワークフローを保存します。

### Studioフローの修正

では最後に、IVR側の設定を修正しましょう。

![スクリーンショット 2021-12-17 16.43.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/f6bc5a96-8bc9-392c-93ec-ebce11ebd2af.png)

- **SendCallToAgent**ウィジェットの**WORKFLOW**のプルダウンから、今作成した「Sales and Support」を選択します。
- **Save**ボタンを押します。
- **Publish**ボタンを押して、フローをパブリッシュします。

# テスト

今回のシナリオをテストするためには、同時に４名でFlexにログインしておく必要があります。
Chromeブラウザと、Chromeブラウザ（シークレットモード）、BraveブラウザとBraveブラウザ（シークレットモード）の４つでテストすることにします。

![スクリーンショット 2021-12-17 16.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/afe57dc2-95de-597a-96af-19f2d468a4f0.png)

全員を「Available」にしておくことを忘れないようにしましょう。

## テスト① 営業とサポートの振り分け

- 発信後のIVRで１を押すことで営業担当者に着信することを確認します。
- 応答後終話し、再び待受（Available）に戻します。
- 発信後のIVRで2を押すことでサポート担当者に着信することを確認します。
- 応答後終話し、再び待受（Available）に戻します。

## テスト② グループ内着信優先度

営業担当者にはデフォルトの優先度である「待ち時間の長いワーカー」が設定されています。

- 発信後のIVRで１を押すことで営業担当者に着信することを確認します。
- 応答後終話し、再び待受（Available）に戻します。
- 再度発信し、IVRで１を押すことで、先程とは別の営業担当者に着信することを確認します。
- 応答後終話し、再び待受（Available）に戻します。

サポート担当者には、レベルの低いワーカーを優先させるという条件になっています。

- 発信後のIVRで2を押すことでレベルを低く設定したサポート担当者に着信することを確認します。
- 応答後終話し、再び待受（Available）に戻します。
- 発信後のIVRで再び2を押すと、再びレベルを低く設定したサポート担当者に着信することを確認します。
- 応答後終話し、Offlineにしておきます。
- 発信後のIVRで再び2を押すと、レベルを高く設定したサポート担当者に着信することを確認します。
- 応答後、それぞれの担当者を待ち受け（Available）に戻します。

## テスト③　異なるグループへのエスカレーション

- 営業担当者をすべてOfflineにしておきます。
- 発信後のIVRで１を押すことでサポート担当者にエスカレーションして着信することを確認します。

# まとめ

今回は、コンタクトセンターの基本機能であるACDについて、Flex上でどのように実装するのかを解説しました。
ワーカーの属性をうまく生かしたタスクキューを作成し、ワークフローでフローを調整するのが基本的なACDの設計になります。ワークフローのパラメータにも重要な意味がありますので、ぜひそちらもうまく利用してください。

★次の記事
[Twilio Flexで特定の担当者に直接繋ぐ方法](https://qiita.com/mobilebiz/items/971683edee076b3a5686)

---
### Twilio（トゥイリオ）とは

https://cloudapi.kddi-web.com
Twilio は音声通話、メッセージング（SMS /チャット）、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウド API サービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。

自己紹介|　
:--|:--
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/b51a8b88-abd5-ce5e-195a-de3564ba2ae6.png" height='200' width='150'/>|高橋克己（Katsumi Takahashi） 自称「<font color='red'>赤い芸人</font>」<br />グローバル・インターネット・ジャパン株式会社　代表取締役<br />株式会社KDDIウェブコミュニケーションズ　Twilio事業部エバンジェリスト<br /><br />2001年より大手通信事業者の法人サービスの教育に携わり、企業における電話のしくみや重要性を研究。2016年よりTwilio事業部にジョインし、Twilioを使ったスマートコミュニケーションの普及活動を精力的に行っている。<br />2015 Hall of Doers<br />2019 Twilio Champions