予約システムに名前を認識してもらえなかったのでAmazon Connectで作ってみた

# はじめに
[アイレット株式会社アドベントカレンダー](https://qiita.com/advent-calendar/2024/iret)10日目です！

タイトルの通り、とあるお店の電話予約のシステムに名前を認識してもらえなかったのでAmazon Connect+Amazon Lexで自分の名前を正しく認識してくれるものを作ってみようという記事です！

(大木で予約しようとしたところ何度も「大きい様でよろしかったでしょうか。」と聞き返され、結局店員さんに直接つないでもらう羽目になりました......)

# 利用サービス
今回はAWSのコンタクトセンター構築サービスのAmazon Connectと対話型bot作成サービスのAmazon Lexを組み合わせて自動応答してくれる予約システムを作ります。

Amazon Connect
https://docs.aws.amazon.com/connect/

Amazon Lex
https://docs.aws.amazon.com/lex/

# 利用料金
Amazon Connectの利用料金は以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/e0a30427-ed47-8a81-5a7e-0ead0ca2d4ea.png)
受信、発信共に0.018USD/分(1USD 150円換算で2.7円)で利用することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/e1556ee3-e6e1-f62d-7bac-87307f84aad6.png)
また通話を受けるため1日当たり電話番号1つにつきDID番号だと0.1USD、通話無料電話番号だと0.48USDかかります。

また、無料枠としてAmazon Connectのコンタクトセンターを最初にデプロイしてから12か月間以下を無料利用できるようです。

・ 1 か月あたり 90 分の Amazon Connect サービス使用量
・ AWS リージョンがある国からの直通ダイヤルイン (DID) 番号
・ 1 か月あたり 30 分のインバウンド DID コール
・ 1 か月あたり 30 分の AWS リージョンがある国の番号へのアウトバウンドコール

Amazon Lexは音声リクエストかテキストリクエストかで料金が変わるのですが、今回は音声のため以下になります。
1リクエストあたり 0.004 USD

# 作成

## Amazon Connectインスタンス立ち上げ
Amazon Connectのサービスコンソールに接続し「インスタンスを追加する」から作成していきます。
![FireShot Capture 039 - Instances - Amazon Connect - ap-northeast-1_ - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/4b43f621-6132-2c84-e6d1-a12d1b1c484d.png)


IDの管理方法とAmazon Connect用のURLを設定します。　フローの登録や細かい設定はこちらのURLから行います。
![FireShot Capture 040 - Create Instance - Amazon Connect - ap-northeast-1_ - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/affedda1-4dd6-f918-6459-3c4852e2564c.png)

管理者の情報を入力します。
ここで入力したユーザ名、パスワードで後からログインするのでメモしておいてください。
![FireShot Capture 041 - Create Instance - Amazon Connect - ap-northeast-1_ - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/5923611b-f52b-aed8-0208-8a8f762ffabd.png)

今回は予約システムで電話を受けるだけなので着信のみ許可します。
![FireShot Capture 042 - Create Instance - Amazon Connect - ap-northeast-1_ - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/2d2f697c-242c-781f-4941-104a9daa7424.png)

この辺はお好みで設定して問題ないと思います。
![FireShot Capture 043 - Create Instance - Amazon Connect - ap-northeast-1_ - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/8e8af711-f56e-765e-18de-8e0bd04806f9.png)

設定を確認しインスタンスを作成します。

# Amazon Connect管理者コンソール接続
先ほどのURLにアクセスし設定したID、パスワードでログインします。
![FireShot Capture 046 - surai-test - AWS Apps Authentication - surai-test.awsapps.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/2ed7bfdb-a05d-6977-0b6b-3393308da151.png)

Amazon Connect管理者ワークスペース内は初期設定英語になっていますが、右上から言語を変更することができます。
![FireShot Capture 047 - Amazon Connect - Dashboard - surai-test.my.connect.aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/957ad857-4034-0428-a861-aea86e27e3f7.png)

ここまで確認出来たら、まず先に自動応答で使うAmazon Lexのbot作成を行います。

## Amazon Lex
LexのサービスコンソールにアクセスしてCreate botを選択します。
![FireShot Capture 049 - Amazon Lex - ap-northeast-1 - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/9641ebca-fedb-0071-e6a2-6f01c999e83c.png)

Botの設定は以下のようにしました。
![FireShot Capture 050 - Amazon Lex - ap-northeast-1 - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/7941d6f8-da5b-6390-d132-955c68a08b22.png)

音声はMizukiに今回は設定しました。
![FireShot Capture 051 - Amazon Lex - ap-northeast-1 - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/d8a100bb-335a-e2a0-475b-bdbe421087e2.png)

Lexの設定の仕方をすべて書いていたら恐ろしいほど長くなってしまうので作成した最終的なフローを紹介します。
![スクリーンショット 2024-12-10 061717.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/e78902d1-9023-5808-406e-4ee5d6ff46c5.png)

今回は以下のようなフローで顧客から情報を取得するものを作成しました。
1. 予約したい等のワードを検知する
1. 日付を確認する
1. 時間を確認する
1. 人数を確認する
1. 名前を確認する
1. 予約内容の確認を行う
1. 予約完了

今回の目標は正しく名前を認識してもらえる予約システムなので予約機能やエラーハンドリングは適当です。

実際に作成する場合は予約日時に空きがあるかを照会したり、予約内容の登録を行うLambdaを間に挟み込む形となります。


作成したものをビルドし、テストを行います。
![スクリーンショット 2024-12-10 030652.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/cc86510b-6e5f-9704-ae77-124d7cb4e508.png)
![スクリーンショット 2024-12-10 030711.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/fd24cca7-3058-3e37-c5d7-e85c076c2627.png)

時間の表示が怪しいですが概ねOKです。
後は電話でも名前をしっかり聞き取ってくれることを祈るだけです。

## Amazon Connectとの紐づけ

Amazon Connectで実際に利用するために現在のテストバージョンから分離したバージョンを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/9d7ad240-5937-9f20-e657-eea60a33ee74.png)
![スクリーンショット 2024-12-10 063018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/06f68bdd-6b14-0964-481d-476fdad2bd14.png)

さらにそのバージョンを新規で作成したエイリアスに紐づけます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/2ba8f69d-d727-a36d-8571-d9cb0f714b31.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/e40215a7-0960-8141-7ceb-de726698b73b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/817bbc5d-ae30-94c5-b86d-21ffdb3a575c.png)

ここまで来たらAmazon Connectの管理者ワークスペースに戻り、電話フローの設定を行います。

左メニューのルーティング>フローからフローを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/c1c8f308-0f15-cf1e-486e-176d4508f366.png)

今回Connect側のフローとしては以下のようにしました。
顧客の入力を取得するの部分で先ほどのLex側のフローが走ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/524fa31a-712c-41ea-55df-c279d8288e89.png)

Lexの紐づけはARNにて行っています。ARNは以下のような形式になります。
``` arn:aws:lex:{リージョン名}:{アカウントID}:bot-alias/{ボットID}/{エイリアスID} ```

また、Lex接続前に要件を確認する旨のテキストを読み上げるように設定しています。
![スクリーンショット 2024-12-10 063851.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/c6a90168-df85-7a36-f810-c611a1fe9ba6.png)

完成したら保存を行い、その後公開を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/55f8b1b0-5cc0-7111-76f1-7a063ff7ab0a.png)

最後に電話番号とフローの紐づけを行って設定完了です。(日本の番号はサポートケースを作成しないと取得できなかったため今回はUSの電話番号で代用しています)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/8acb3f8f-4ddc-5b02-c83b-0f135472d69c.png)


電話をかけたときの音声が以下になります。(めちゃめちゃ尺余りしてますが気にしないでください)

<iframe width="1195" height="896" src="https://www.youtube.com/embed/4x-HQfkYOjQ" title="自動音声テスト" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

ちょっと時間の読み上げがおかしいのと25人で予約されていますが、しっかり大木と認識して予約してくれているので **不問とします**。

# 最後に
最後少し適当な感じになってしまいましたが、この後何度か試したところ、結構認識精度も高く名前を正常に読み取ってくれていることが確認できました。

今回は本当に側の側だけ作成しましたが、また機会があれば予約用のLambdaやDynamoDBなどの設定も行って本格的なものを作成しようと思います。

お時間があれば[アイレット株式会社アドベントカレンダー](https://qiita.com/advent-calendar/2024/iret)の他の記事も読んでみてください！