Amazon Connectで問い合わせフローを作る

AWS初心者 Advent Calendar 2018 15日目の記事です。

#遂に東京に上陸!!

2018/12/11。Amazon Connectが東京リージョンにやってきました!!
[Amazon Connect が東京リージョンに対応しました。](https://aws.amazon.com/jp/blogs/news/amazon-connect-tokyo-region/)

企業で使われるにはフリーダイヤルの対応が必須の場合が多いと思いますし、なんとなく海外の番号経由で電話するのは心象的にもあまり良くないですよね・・・
かなり破壊的なサービスだと思います。

##気になる料金

以下2つの観点で料金が発生することを抑えておく必要があります。

1. Amazon Connectを利用する事によって発生する料金
2. 電話をする事により発生する料金
    3. 電話番号利用料(1日単位)
    4. 受信通話料金(1分単位)
    5. 発信通話料金(1分単位)

1のAmazon Connect利用料金は分かりやすく、1分あたり0.018USDです。
2の項目は少々複雑であり、直通ダイヤルかフリーダイヤルかで料金が分かれてきます。

|        |       直通ダイヤル |    フリーダイヤル    |
|:-----------------|------------------:|:------------------:|
| 電話番号利用料    |            0.10USD|        0.48USD     |
| 受信通話料金|            0.003USD|       0.1482USD|
※発信通話料金は0.1USDです。
※2018/12/15時点の料金です。

サービス全体の料金を厳密に出すには、通話データをS3に記録する場合S3の利用料金とLambdaを利用する場合Lambdaの料金も計算する必要があります。

##問い合わせフローを作ってみる

作ったフロー
・非会員向け問い合わせフロー
・会員向け問い合わせフロー

非会員向け問い合わせフローでやること
1. 各種設定(ログ・通話記録、音声の設定など)
2. 自動応答メッセージをながし、オペレーターに繋ぐ または 会員向け問い合わせフローに飛ばす。

会員向け問い合わせフローでやること
1. 各種設定(ログ・通話記録、音声の設定など)
2. 顧客の電話番号を変数に詰める
3. 2で設定した電話番号でDynamoDBを検索するLambdaを呼び出す。
4. 3のLambdaで、DynamoDBに電話番号が見つかったらパスワードを求める処理へ、見つからなければオペレータに繋ぐ処理へ。

画面はこんな感じです。
オンプレのコールセンターサービスを組んだ事がないため比較は出来ませんが、作ってて楽しいです。
※画面右上でpublishボタンで定義Fileをexportする事も出来ます。良い。

非会員向け問い合わせフロー
![非会員向け.png](https://qiita-image-store.s3.amazonaws.com/0/36448/8f66b37b-96dc-290b-b9ca-98096a672f93.png)

会員向け問い合わせフロー(一部)
![会員向け.png](https://qiita-image-store.s3.amazonaws.com/0/36448/c44f83fa-48da-40c4-f95b-33cec7c3d8dc.png)

次の項目で、フローを構成する要素について書きます。

##問い合わせフローを作る上で理解すること

メニュー項目として、操作・設定・ブランチ・統合・終了/転送の5つの項目があります。

###操作

![操作.PNG](https://qiita-image-store.s3.amazonaws.com/0/36448/b97a6655-3e30-7502-ecf0-9aa8fba39505.png)


プロンプトの再生：Amazon Connectから音声を流す事が出来ます。予め固定の文言を設定する事も可能ですし、$.External.変数名でLambdaから取得した値を読み上げる事が出来ます。

顧客の入力を取得する：「～の場合は1を、～の場合は2を」のような、お客様に操作を選択させる操作が可能です。
※増やした選択肢それぞれに、後続のフローを設定する必要があります。
![選択肢.PNG](https://qiita-image-store.s3.amazonaws.com/0/36448/78e51a48-daa5-3d50-ca18-404fcdf092bb.png)


###設定

![設定.PNG](https://qiita-image-store.s3.amazonaws.com/0/36448/2535c478-b80c-bfac-549c-1ebfd19706fe.png)


キューの設定：ダッシュボードメニューで作成したキューを設定します。後続の転送で利用します。
※queueごとに最大待機数を設定できますが、最大99件しか対応出来ません。

ログの記録動作の設定：ログを記録する設定を有効化出来ます。

通話記録動作の設定：通話を記録する設定を有効化出来ます。

音声の設定：言語の設定が出来ます。日本語にした場合、タクミさん・ミズキさんどちらかの音声を設定出来ます。

###ブランチ

![ブランチ.PNG](https://qiita-image-store.s3.amazonaws.com/0/36448/2e6afad9-14f6-32e0-6bdd-7bb922d40984.png)


※例で作った問い合わせフローでは利用していませんが、キューの状態を確認できたり割合に基づいてお客様を振り分けたりできる、しっかり作りこむには必須の機能があります。
日を改めて確認したいです。

###統合

![統合.PNG](https://qiita-image-store.s3.amazonaws.com/0/36448/c3b426da-ec83-d93f-980f-a40b9052e925.png)


AWS Lambdaを呼び出すことが出来ます。引数も渡せます。

**Lambdaを呼ぶ上での注意点**
・LambdaのARNを設定すれば呼べることが出来ますが、別途Amazon ConnectからLambdaを許可するadd-permissionをCLIから行う必要があります。

参考
[Amazon Connect で AWS Lambda 関数を使用する](https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/connect-lambda-functions.html)
aws lambda add-permission --function-name function:my-lambda-function --statement-id 1 \ 
     --principal connect.amazonaws.com --action lambda:InvokeFunction --source-account 123456789012 \ 
     --source-arn arn:aws:connect:us-east-1:123456789012:instance/def1a4fc-ac9d-11e6-b582-06a0be38cccf

・Amazon Connect側からLambdaを呼ぶ場合、タイムアウト時間は最大8秒までしか呼べません。
→API Gatewayより厳しい制約ですが、電話なので時間のかかるLambdaは使わない方が良いですよね。

###終了/転送

![終了_転送.PNG](https://qiita-image-store.s3.amazonaws.com/0/36448/38863e37-cbd8-6704-9826-df5b01610a4c.png)


切断/ハングアップ：電話を切ります。
キューへ転送：設定項目で指定したキューに転送します。
電話番号への転送：電話番号に転送します。
フローへの転送：別の問い合わせフローに転送します。

##問い合わせフローからLambdaを呼ばれた場合

event.Detailsの中にAmazon Connectから渡されるデータが格納されています。
今のところ頼れる資料はアドミニストレーターガイドしかなさそうです・・・
[Amazon Connect Administrator Guide](https://docs.aws.amazon.com/connect/latest/adminguide/connect-ag.pdf)


```js:amazon_connect_event.json
{
 "Details": {
 "ContactData": {
 "Attributes": {},
 "Channel": "VOICE",
 "ContactId": "4a573372-1f28-4e26-b97b-XXXXXXXXXXX",
 "CustomerEndpoint": {
 "Address": "+1234567890",
 "Type": "TELEPHONE_NUMBER"
 },
 "InitialContactId": "4a573372-1f28-4e26-b97b-XXXXXXXXXXX",
 "InitiationMethod": "INBOUND | OUTBOUND | TRANSFER | CALLBACK",
 "InstanceARN": "arn:aws:connect:aws-region:1234567890:instance/
c8c0e68d-2200-4265-82c0-XXXXXXXXXX",
 "PreviousContactId": "4a573372-1f28-4e26-b97b-XXXXXXXXXX",
 "Queue": "QueueName",
 "SystemEndpoint": {
 "Address": "+1234567890",
 "Type": "TELEPHONE_NUMBER"
 }
 },
 "Parameters": {
 "sentAttributeKey": "sentAttributeValue"
 }
 },
 "Name": "ContactFlowEvent"
}
```

例えばお客様の電話番号をevent.Details(デフォルト引数で)取得するには、下記コードで取得出来ます。他にもInstanceARNが取れるので、複数リージョン構成にした場合もLambda側での判定は容易そうです。
※デフォルトで渡される値以外にも、ユーザ定義で指定した値をとる事も出来ます。

```js:amazon_connect.js
// デフォルトの引数を利用する場合
const callerID = event.Details.ContactData.CustomerEndpoint.Address
// ユーザ定義の引数を利用する場合
const callerID = event.Details.Parameters.TellNo

```

##まとめ

・デモレベルなら簡単に作れる。
・既存サービスの完全置き換えを検討するのであれば、考慮事項はそれなりに必要。
・DRまで厳密に作るとなると、もう一リージョンの選定が必要。
※海外の場合、キャリア側でAmazon Connectの電話番号が生きているか確認してくれるサービスがあるとか。日本で同様の対応出来るんでしょうか・・・電話番号を素直に二つ用意するしかない？

素晴らしいサービスだと思いますので、業務内外問わず追っていきます。