AmazonConnectとGoogleSTTでオウム返し音声ボットを作ってみた(1)

#1. はじめに

　こんにちは, ノベルワークスでインターンをしているユウガです。
　音声ボットシステムの開発に携わってきました。
　この時に使用した技術をふんだんに盛り込んで, オウム返し音声ボットを作りました。
　特に, AmazonConnectとGoogleSTTを組み合わせて, リアルタイムに文字起こしをしたい方
　に有益になると思います。

　今回の記事では, Connectをメインに説明します。
　次の記事は[こちら](https://qiita.com/yuga-t/items/f42fdd006df3fca1a1c1)

>リアルタイムに日本語を文字起こしできるサービスとして, AmazonTranscribeもあります
https://aws.amazon.com/jp/blogs/news/amazon-transcribe-streaming-adds-support-for-japanese-korean-and-brazilian-portuguese/


**目次**
[1.はじめに](#1-はじめに)
[2.デモ](#2-デモ)
[3.アーキテクチャ](#3-アーキテクチャ)
[4.問い合わせフローの作成](#4-問い合わせフローの作成)
[5.次回](#5-次回)

#2. デモ

　作る物のイメージが無いと理解しにくいと思うので, デモを公開します↓
　https://drive.google.com/file/d/1OsolNuuSxA6zbFeaM-fIVdolntdGaLqo/view?usp=sharing

#3. アーキテクチャ

　このシステムのアーキテクチャは, 大体こんな感じになります↓

![connect_bot_diagram (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/4f71c612-9b46-ae5f-9076-e264153b4eaf.png)

#4. 問い合わせフローの作成

　音声ボットの流れを決めるために, Connectで問い合わせフローを作ります。

　では, 早速作っていきましょう！

- **音声の設定**を作り, 日本語を設定します。**エントリーポイント**から繋げて下さい。


- **問い合わせ属性の設定**を作り, 以下のように設定します。**音声の設定**から繋げて下さい。<br>これは, Connect内の変数を設定できます。ConnectからLambdaを呼び出す時に, この変数を渡すことができます。<br>replyCountは, 何回目の返答かを表す変数です。DynamoDBに書き込まれた文字起こしを取得する際に使います。<br>saveCallRecordingは, 音声をs3に保存するかどうかのフラグです。

![contactFlow1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/7a866c25-cd4b-86dc-12db-057f4568b64c.png)<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/5906225b-0ee7-2906-1267-572118fd0a6f.png" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/ad80b270-b507-5216-5f7d-8e4ec268266f.png" width=50%>

- **メディアストリーミングの開始**を作り, [顧客から]にチェックを付けます。<br>**問い合わせ属性**の設定から繋げて下さい。<br>[顧客から]にチェックを付けると, 電話をかけてきた人が喋る音声がKVSに保存されます。さらに, そのデータにアクセスするための変数がConnect内に作られます。

>メディアストリーミングの有効化についてはこちら
https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/enable-live-media-streams.html

- **Lambda関数を呼び出す**を作ります。**メディアストリーミングの開始**から繋げて下さい。<br>ここで設定するLambdaは, Connect内の変数を使って, 別のLambdaをinvokeします。<br>Lambdaは次回作ります。


- **プロンプトの再生**を作り, テキストの入力で「何か話して下さい」と設定します。<br>**Lambda関数を呼び出す**から繋げて下さい。


- **Lambda関数を呼び出す**を作ります。**プロンプトの再生**から繋げて下さい。<br>ここで設定するLambdaは, DynamoDBから文字起こし結果を取得します。<br>このLambdaで, reply, isKeyError, replyCount をreturnします。<br>そうする事で、Lambdaの変数をConnectで扱う事ができます。<br>Lambdaは次回作ります。


- **問い合わせ属性**の設定を作り, 以下のように設定します。**Lambda関数を呼び出す**から繋げて下さい。<br>前のLambdaでreturnした変数をConnectで保持するための設定です。<br>replyは, ボットの返答文。<br>isKeyErrorは, DynamoDBに文字起こし結果があるかどうかのフラグ。<br>replyCountは, 何回目の返答かを表す変数です。

![contactFlow2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/0e770239-d5d2-3c96-5904-4e8c73dacd99.png)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/0cb9a004-8344-9f36-bd75-4db98f9464fb.png" width=33%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/d0555448-44ab-2878-916f-ac5a4bf6fabe.png" width=33%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/be505d0d-719f-a959-d6d0-c42ed397aec8.png" width=33%>


- **問い合わせ属性を確認する**を作り, 以下のように設定します。<br>**問い合わせ属性の設定**から繋げて下さい。<br>if文の役割を担います。isKeyError=Falseなら, DynamoDBから文字起こし結果を取得できた事を表し, Trueであれば, 取得できなかった事を表します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/99673710-8a28-3dd9-a473-7251e03f9ed3.png" width=30%>


- **プロンプトの再生**を作り, 以下のように設定します。**問い合わせ属性を確認する**のFalseから繋げて下さい。<br>ここでは, DynamoDBから取得した文字起こし(reply)を喋らせています。<br>終わったら, **プロンプトの再生**に繋げます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/61d955eb-1048-60da-f647-592a830123b7.png" width=30%>
![contactFlow3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/1d941b1e-179e-7adb-4f5c-b5094360728f.png)


- **プロンプトの再生**を作り, 以下のように設定します。**問い合わせ属性を確認する**のTrueから繋げて下さい。<br>ここでは, DynamoDBから文字起こし結果が取得できなかったので, 1秒間のブレイクタイムを設けています。<br>ブレイクタイムを設けないと, 文字起こし結果がDynamoDBに書き込まれていない間に, Lambda関数が頻繁に呼び出されてしまいます。なので, 1秒だけ時間を空けています。<br>終わったら、**Lambda関数を呼び出す**に繋げます。

>SSMLについてはこちら
https://qiita.com/novelworks/items/8b5cd9e0dae9a472c966

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/9fae9fe0-f123-7120-4ad5-cefeae146586.png" width=30%>
![contactFlow4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599936/11efff25-ce77-8a35-60c4-2613981a6c51.png)


　終わりです！

**補足**

- エラーになった時は**切断**に繋げていますが, **プロンプトの再生**でエラー内容を喋らせた後に,**切断**に繋げると良いでしょう。デバッグしやすくなります。
- 問い合わせフローはjsonファイルでimport/exportできます。私の完成問い合わせフローはこちら↓

>完成問い合わせフロー
https://drive.google.com/file/d/1rxNnbWM--u3VTU-xyEAZr_58jF2HIzlt/view?usp=sharing

#5. 次回

 次回は, Lambdaの作成をメインに説明します。お楽しみに〜
 次の記事は[こちら](https://qiita.com/yuga-t/items/f42fdd006df3fca1a1c1)