Twilio Flexの始め方（部品を知ろう編）

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

# はじめに

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

[Twilio Flex Advent Calendar 2021](https://qiita.com/advent-calendar/2021/twilio-flex) 二日目の記事となります。
[前回](https://qiita.com/mobilebiz/private/bbc45ddae7b224fb9bcc)は、Twilio Flexってそもそもどんなサービスといった説明を行いましたが、今回はその内部を少しだけ見ていきたいと思います。

# Twilio Flex の部品

![エンジンルーム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/e46f9f71-aabe-85c8-6e5e-871db8374aa6.png)

前回の記事にも書いたように、Twilio Flex は、もともと Twilio が提供してきた以下のAPIから構成されています。

- [Programmable Voice](https://jp.twilio.com/docs/voice/api)
- [Programmable Messaging](https://jp.twilio.com/docs/sms)
- [Programmable Conversation](https://jp.twilio.com/docs/conversations)
- [Phone Numbers](https://jp.twilio.com/docs/phone-numbers/api)
- [TaskRouter](https://jp.twilio.com/docs/taskrouter)
- [Proxy](https://jp.twilio.com/docs/proxy)
- [Studio](https://jp.twilio.com/docs/studio/user-guide)
- [Sync](https://jp.twilio.com/docs/sync)

これに加えて、Flexだけに提供される[Flex UI](https://www.twilio.com/docs/flex/developer/ui)という外観をカスタマイズするしくみが用意されています。Flex UIはいうならば、車の外装になります。

それぞれのAPI（部品）については、それぞれのドキュメントに詳しく書かれていますが、Flex全体として、これらの部品がどのように連携して動作しているかを理解することが大切です。

# シナリオベースで理解する

それぞれの部品を理解するためには、具体的なシナリオに沿ってイメージしていただくのが早いかと思いますので、今回は以下のシナリオを使って、それぞれの部品がどのように連携しているかを説明していきます。

## 音声ベースのコンタクトセンター

1. エンドユーザーが電話をかけてきます。
1. IVRを使って要件（営業への問い合わせ or サポートへの問い合わせ）を確認します。
1. 要件ごとに対応するオペレーターに対して電話をつなぎます。
1. オペレーターが電話にでます。

では、このシナリオに沿って、実際にFlex内部ではどのようなフローになっているのかを説明します。

### 1. エンドユーザーからの着信

Flexで電話の着信するためには、Twilio上で購入した電話番号が必要になります。
現在日本では、050、0800、0120の３種類の電話番号を購入することができます。残念ながら、すでに皆さんがお持ちの電話番号を使うことはできません。ただし、0800と0120についてはナンバーポータビリティを使うことで、KDDIウェブコミュニケーションズに名義変更すれば番号を持ち込むことができます。
詳しくは以下のFAQを御覧ください。
[現在利用している電話番号をそのままTwilioで利用できますか?](https://cloudapi.zendesk.com/hc/ja/articles/206420821)

実際に電話番号を購入したら、その番号に着信したときの動作を指定する必要があります。
Flexでは通常、Twilio Studioのフローを呼び出すようにします。
![スクリーンショット 2021-11-29 16.51.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/c8b2434f-8f1b-09e3-d86e-378dfc320d4f.png)

この例では、「Voice IVR」という名前のフローに制御を渡していることがわかります。

### 2. IVRによる要件分類

電話口で数字の１などを押すことで、対話型でやり取りをすることをIVR（Interactive Voice Response）と呼びます。
Twilioでは、このIVRをコーディングをせずに設計するために、Twilio Studioという機能を用意しています。先程の1.で指定した「Voice IVR」は、このStudioを使って実装されています。

![スクリーンショット 2021-11-29 17.13.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/f80aadbc-b216-c582-7593-1968cf22e05d.png)

これが先程指定した「Voice IVR」という名前がつけられたフローになります。
電話番号に紐付けられたフローは、一番上部にある赤い箱の「Incoming Call」というところから、線をたどって降りてきます。
最初につながっている箱には「GatherCall」という名前がついていますが、この箱は電話をかけてきた人と対話形式でやり取りをするための機能を持っています。

[GatherCallの設定画面]
![スクリーンショット 2021-11-29 17.16.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/5881212d-8822-791e-0872-585a68c8afb2.png)

**TEXT TO SAY**の中に書かれた日本語が自動音声として読み上げられます。
日本語以外にも各種言語に対応していますし、話者も選択できます。この例ではMizukiという女性の声が選択されています。
この箱を通るときに、音声の読み上げと同時にテンキーの受付も行われます。受け付けたキーを判定するのが、その次の「CheckValue」と書かれた箱になります。

[CheckValueの設定画面]
![スクリーンショット 2021-11-29 17.50.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/0cb0507d-ef38-49cb-a08e-f67162b84064.png)

この箱では、実際にユーザーが入力してきたテンキーの値を判定して、処理を分岐させることができます。
今回は、１か２を受け付けますので、それ以外が入力されたとき、もしくは時間内に入力がなかったときは、一つ前の「Gather Call」に制御を戻しています。

テンキーの値によって分岐された線は、それぞれ１が押されたときは「SetValueToSales」、２が押されたときは「SetValueToSupport」と名前がつけられた箱につながっています。

[SetValueToSalesの設定画面]
![スクリーンショット 2021-11-29 17.57.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/2360781b-d21d-d863-c392-c7b4cf1df6a4.png)

[SetValueToSupportの設定画面]
![スクリーンショット 2021-11-29 17.57.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/dd794ae0-a148-a459-0281-981282a7a414.png)

それぞれの箱では、変数「skill」に対して「Sales」もしくは「Support」という値をセットしています。

そして、それぞれの箱からつながっている最後の箱が「SendCallToAgent」と書かれた箱になります。

[SendCallToAgentの設定画面]
![スクリーンショット 2021-11-29 17.59.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/6e0e08b1-753c-a904-3d3c-4bdd747370e4.png)

この箱によって、電話はTaskRouterに渡ります。
TaskRouterの詳細はこの後説明するので、ここでは設定画面を中心に簡単に説明します。
まずひとつ目が、**WORKFLOW**の指定です。このワークフローにコールをつなぐという設定になります。ワークフローの詳細はともかく、渡す際にパラメータ（**TASK ATTRIBUTES**）を指定することができ、その中には以下のように記載されています。

```json
{
 "type": "inbound",
 "skill": "{{flow.variables.skill}}",
 "name": "{{trigger.call.From}}" 
}
```

`type`は、このタスクがどのようなものなのかを指定するもので、`inbound`になっているので、着信を表しています。
`skill`は、先程「SetValueToSales」もしくは「SetValueToSupport」で指定した変数です。
`name`は、発信者の名前を指定します。今回は発信者番号を入れていますが、たとえばStudio内で外部のCRMを検索してユーザー名が取得できたのであれば、そちらを指定しても構いません。
重要なことは、Studio内でTaskRouterにコールを引き継ぐ際にパラメーターを渡すことができるということです。そして、このパラメーターをTaskRouter内で判定することで、実際のオペレーターのアサインに活かしたり、オペレーターの画面にパラメーターを表示させたりできるのです。

### 3. オペレーターのアサイン

オペレーターをアサインする作業を、ACD（Automatic Call Distribution）と呼びます。ACDの主な役割は、着信したコールを自動的に最適なオペレーターに割り当てることです。たとえば、オペレーターが複数人いた場合に、どのオペレーターにコールを渡せばよいかを判断する役目がACDの仕事になります。
割り当て方法はコンタクトセンターによって異なりますが、オペレーターのスキルや、問い合わせの種別によって予め対応するオペレーターを割り当てておくケースが多いです。
そのような割り当てを実装するためには、以下の２つの条件が必要になります。

- オペレーターをスキル別にグルーピングしておく
- 着信したコールの内容や、発信者の情報を事前に把握しておく

後者については、前述のStudioを使って判定することが多いです。たとえば、今回の例ではIVRを使って取り合わせの種別（営業かサポート）をTaskRouterに渡しています。

前者についてですが、TaskRouterではオペレーターをワーカーと呼び、それぞれのワーカーにスキルを付与することで実現しています。

[ワーカーの設定画面]
![スクリーンショット 2021-11-30 8.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/79357fd5-1198-19bc-29e3-3a6ee6a95a9a.png)

この中の**ATTRIBUTES**を見やすくしたのが次のJSONです。

```json
{
  "routing":{
    "skills":["Sales"],
    "levels":{}
  },
  "full_name":"katsumi takahashi",
  "image_url":"https:\/\/www.gravatar.com\/avatar\/acb69cfef89e268ee34cd6dedf260241?d=mp",
  "roles": ["admin","wfo.full_access"],
  "contact_uri":"client:katsumi_2Etakahashi",
  "disabled_skills":{
    "skills":[],
    "levels":{}
  },
  "email":"katsumi.takahashi@kddi-web.com"
}
```

いろいろなパラメーターがありますが、ここで確認するべきポイントは、`routing.skills`パラーメーターです。
このようにオペレーターのスキルを指定する（この例では`Sales`）ことで、オペレーターのグルーピングを可能にしています。

次にキューの説明をします。
キューというのは、コールを一時的にためておく場所です。キューがあることで、たとえばオペレーターが全員対応中だったとしても、発信してきた人を待たせておくことができます。
TaskRouterにもキューのしくみが用意されており、たとえば次のような内容でキューを定義しておけます。

[Task Queuesの設定画面]
![スクリーンショット 2021-11-30 8.37.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/3384dea1-0206-b06e-3a04-ba965678cb33.png)

詳細については次回以降の記事に回しますが、この設定画面で重要なのが**QUEUE EXPRESSION**です。
ここでは、`routing.skills HAS "Sales"`と指定されていますが、これがワーカーのスキルを一致させるための指定です。すなわち、このキューは、`Sales`のスキルをもったワーカーがグルーピングされたキューということになります。

つぎに、このキューに対してコールを割り当てる仕組みについても見ていきます。キューへのアサインを行うのが、ワークフローになります（Studioの説明で出てきたワークフローです）。

[Workflowsの設定画面]
![スクリーンショット 2021-11-30 8.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/7bcf81c6-fd84-cf7b-b52c-83bd3cc5a908.png)

こちらも詳しい説明は次回以降に回すとして、概要だけを説明します。
**MATCHING TASK**で、`skill == 'Sales'`と指定しているため、タスクの属性に`skill`が存在し、かつその値が`Sales`だった場合の処理が記載されています。
この画面では、もしタスクが一致した場合は、`Sales`というキューにコールを入れるという指定になっています。その時のタスクの並び順（この例では、待ち時間が一番長い人から優先的に）や、対応できない場合の最大待ち時間の指定（この例では、30秒）がされています。

このようにして、コールはTaskRouterを通じてワーカーに対して割当されていきます。
この後、割当されたコール（タスク）は「予約」状態となってワーカーの呼び出しに遷移します。ワーカーの設定画面に、`contact_uri`パラメーターがありましたが、その指定に従ってワーカーが呼び出されます。

### 4. 電話応答

先程のワーカーの設定にある、`contact_uri`には、`client:katsumi_2Etakahashi`と記載がありました（`_2E`は、`.`を意味します）。
`client:`から始まる宛先は、Programmable VoiceのVoIPクライアントを意味します。わかりやすくいうと、ブラウザベースで起動されている電話機能（ブラウザ以外にも、iOSやAndroidもあります）ということです。
着信するためには、ワーカーは事前にFlexにログインしておき、かつ待受状態にしておく必要があります。

[待受中のワーカー]
![スクリーンショット 2021-11-30 9.12.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/cc31c840-da8f-f04a-7571-ca2db0def099.png)

ワーカーはUI上で、自分自身の状態を変更することができ、上の図のように`Idle`状態になっているワーカーは待受中であることを意味します。
この状態になっていれば、ワーカーの呼び出しがされると以下の図のように着信が通知されます。

[着信中のワーカー]
![スクリーンショット 2021-11-30 9.16.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/b26cd43d-81c6-e113-9641-23b860728863.png)

緑色のアイコンをクリックすることで着信が完了し、発信者と繋がります。

以上が電話を使ったFlexの一連の動作となります。
これらをまとめたのが下の図になります。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/bd73653c-2b0f-db96-ff64-c5a96be476c6.png)

コール（音声）によるフローは比較的単純ですが、チャットのフローはもう少し複雑になります。チャットフローについては別の機会で説明したいと思います。

# まとめ

いかがでしょうか。全体の相関関係は伝わりましたか。
相関関係がわかると、たとえばどこをチューニングするのであれば、どのAPIをカスタマイズすればよいかがわかり、カスタマイズの工数が短くすみます。
この後の記事では、それぞれの部品をさらに詳細に開設することで、具体的なカスタマイズのイメージを持ってもらえるようにしたいと思います。

★次の記事
[Twilio Flexの始め方（セットアップ編）](https://qiita.com/mobilebiz/items/d06a29214b437339d226)

---
### 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