この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、洲崎です。
Amazon Connect アドベントカレンダー 2022、24日目の記事です!
クラスメソッドとギークフィードさんの有志が募ってチャレンジしている企画になります。
(アドベントカレンダーのカレンダー一覧はこちら↓)
今日はクリスマスイブということで、サンタさんのプレゼント受付窓口のボットを作ってみました。
実装画面
Amazon Connect Chatを埋め込んだシンプルなWebページです。
チャットで「配達希望日」と「欲しいもの」を伝えます。
チャットが終了したら、Amazon SNSで登録したサンタさんのプレゼント受付窓口宛に「配達希望日」と「欲しいもの」をEメールで連絡する仕組みです。
構成図
Amazon CloudFront × Amazon S3でチャットページを用意します。
裏側はAmazon Lex→AWS Lambda→Amazon SNSでプレゼント受付窓口にEメールで連絡します。
Amazon LexはAWS Lambdaからのreturn値も必要になるため、Lex↔︎Lambda間は交互に指してます。
やってみる
Amazon Lex
Amazon Lexのボットを作成します。
ボットは分かる名前と説明を入力し、IAMロールは自動作成、他はデフォルトです。
インテントでプレゼント窓口のフローを作成します。
インテントは、”サンプル発話”、”スロット”、”Confirmation”、”フルフィルメント”、”応答を閉じる”の箇所を設定します。
サンプル発話
サンプル発話にはトリガーとなる発話をいれます。「プレゼントが欲しい」や「サンタさんにお願いしたい」を入れました。
スロット
チャットで連絡してきた情報をスロットとして保存します。
今回はdelivery
(スロットタイプ:AMAZON.Date)で「いつお届けしますか?」に対する回答と、iwant
(カスタムスロットタイプ:want)で「何が欲しいですか?」の2つを設定しました。
スロットタイプのAMAZON.Dateは組み込みで用意されているのでそのまま利用できます。
AMAZON.Dateは「today」、「now」、または「12月24日」等の連絡を、2022-12-24
として変換する機能です。
今日だけでなく、「来週」や「先週」等も変換可能です。詳しくは下記ドキュメントを参照ください。
カスタムスロットタイプは、組み込みスロットにない情報を保存したい時に使う機能です。別で作成する必要があります。
ボットの”スロットタイプ”から、”スロットタイプを追加”→”空のスロットタイプを追加”でスロットタイプを追加で作成します。
スロットタイプ値のところで、「入力されそうなワード」をいくつか入力します。
今回は「スイッチ」、「カービィのゲーム」、「マリオのゲーム」、「くまのぬいぐるみ」を登録しました。
これ以外の発話だとLexが認識しない為、事前にリサーチして入力しそうな単語を入れるようにします。
(Lexはフリーワードをスロットとして登録する手法がないと思ってますが、もっと良い方法があるよ!という方はブログのコメント欄か、Twitter等で連絡いただけると嬉しいです。)
Confirmation
Confirmationでスロットの内容の確認を簡単に行うことができます。
スロットを指定したい場合はスロットのプロンプトを{}
で囲みます。
「{delivery}
に{iwant}
を希望でよろしいですか?」と入力します。
フルフィルメント
Lambda関数を設定する項目は、Lambdaを作成する前に設定してテストを行うとエラーが起きてしまうので、テスト後に設定します。
フルフィルメントが成功した場合は「サンタさんにお伝えします」、失敗した場合は「エラーが発生しました」と入力します。
応答を閉じる
チャットを終了する時のメッセージを入力します。
設定が終わったら、右下の”インテントを保存”をクリックし、右上のBuildをクリックします。
Lexのテスト
ここで一旦、Lexの流れをテストします。
右上のTestボタンをクリックし、一連の流れを通して確認します。
”検査”ボタンをクリックすることで、JSONの入力/出力の内容を確認できます。
(マネジメントコンソールがダークモードだとちょっと見づらいですね。。)
最後の”応答”のところのJSONをコピーします。(あとでLambda関数を作成する時に参考にします)
私の場合は、こんな形で出力されていました。
{
"messages": [
{
"content": "サンタさんにお伝えします。",
"contentType": "PlainText"
},
{
"content": "いい子にして待っててね。",
"contentType": "PlainText"
}
],
"sessionState": {
"dialogAction": {
"type": "Close"
},
"intent": {
"name": "present",
"slots": {
"delivery": {
"value": {
"originalValue": "12/25",
"interpretedValue": "2022-12-25",
"resolvedValues": [
"2022-12-25"
]
}
},
"iwant": {
"value": {
"originalValue": "くまのぬいぐるみ",
"interpretedValue": "くまのぬいぐるみ",
"resolvedValues": [
"くまのぬいぐるみ"
]
}
}
},
"state": "Fulfilled",
"confirmationState": "Confirmed"
},
"sessionAttributes": {},
"originatingRequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
},
"interpretations": [
{
"nluConfidence": {
"score": 1
},
"intent": {
"name": "present",
"slots": {
"delivery": {
"value": {
"originalValue": "12/25",
"interpretedValue": "2022-12-25",
"resolvedValues": [
"2022-12-25"
]
}
},
"iwant": {
"value": {
"originalValue": "くまのぬいぐるみ",
"interpretedValue": "くまのぬいぐるみ",
"resolvedValues": [
"くまのぬいぐるみ"
]
}
}
},
"state": "Fulfilled",
"confirmationState": "Confirmed"
}
},
{
"intent": {
"name": "FallbackIntent",
"slots": {}
}
}
],
"requestAttributes": {},
"sessionId": "xxxxxxxxxxxxxxx"
}
この中でresolvedValues
の2022-12-25
とくまのぬいぐるみ
をLambdaで取り出してSNSに連携できれば、メールで内容を送れそうだなということがわかります。
フルフィルメントのLambda設定
テストが終わったら詳細オプションを開き、”フルフィルメントにLambda関数を使用”にチェックを入れます。
最後に右上のBuildをもう1度クリックします。
Amazon SNS
Amazon SNSのトピック作成方法は下記ブログをご確認ください。(数クリックで終了します)
作成できたらSNSのARNを控えておきます。
AWS Lambda
LexからSNSに情報を渡してメールを飛ばすLambdaを作成します。
Python3.9で作成しました。
import boto3
def lambda_handler(event, context):
topic_arn = "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxxx:lex-to-email"
subject = "【サンタさんのプレゼント受付窓口】申し込みのお知らせ"
sns = boto3.resource('sns')
date = event.get('interpretations',{})[0].get('intent',{}).get('slots',{}).get('delivery',{}).get('value',{}).get('resolvedValues',{})[0]
iwant = event.get('interpretations',{})[0].get('intent',{}).get('slots',{}).get('iwant',{}).get('value',{}).get('resolvedValues',{})[0]
platform_endpoint = sns.PlatformEndpoint(topic_arn)
msg = """
チャットからプレゼントを受け付けました。\n
配達希望日: {date}\n
欲しいもの: {iwant}\n
""".format(date=date, iwant=iwant)
response = platform_endpoint.publish(
Message = msg,
Subject = subject
)
return {
'sessionState': {
'dialogAction': {
'type': 'Close'
},
'intent': {
'name': 'present',
'state': 'Fulfilled'
}
}
}
topic_arn
のところに、控えたSNSのトピックARNを貼り付けます。
date
とwant
はテスト時にJSONで吐き出した値を抽出しています。
dateの場合は今回でいうと2022-12-25
、wantはくまのぬいぐるみ
です。
最後にreturn
でLambdaからLexに値を返しています。
今回はAmazon Lex V2のドキュメントに書いてある必須項目のsessionState
,dialogAction
,intent
をreturnで返しました。
LexにLambdaを設定
Lambda関数をデプロイできたら、Lexに対象のLambdaを設定します。
場所はボットのサイドメニューから、エイリアス→言語のJapanese(Japan)→エイリアス言語のサポートです。
ソースとバージョンまたはエイリアスを指定して、保存をクリックします。
Amazon Connect
Amazon Lex、AWS Lambda、Amazon SNSと設定できたので、最後はAmazon Connectを設定します。
マネジメントコンソールの問い合わせフローに飛んで、Amazon Lexの部分で作成したボットとエイリアスを指定して、”Amazon Lex ボットを追加”をクリックします。
Amazon Connectコンソールに入り、フローを作成します。(ほぼLexに任せてるのでかなりシンプルです)
”顧客の入力を取得する”ブロックでLexを設定します。
アナウンスはテキスト読み上げで「サンタさんのプレゼント受付窓口です。プレゼントが欲しいと送信してください。」と入力し、追加したLexボットを指定します。
これで、Amazon Connect、Amazon Lex、AWS Lambda、Amazon SNSを連携することができました!
Amazon Connect Chat
こちらは、下の記事で構築手順を載せてますので割愛します。
作成したAmazon Connectのフローを紐づけてもらえれば、チャットで一連の動作の確認が可能です。
最後に
クリスマスイブということで、サンタさんのプレゼント受付のボットを作ってみました!
実際作ってみようと思うと、Lambdaはどう書くのだろうとか、Lexはどう設定したらいいのだろう等、色々考えることがあり勉強になりました。
これからも”何か作ってみよう”の気持ちを忘れずに、色々試していきたいと思います。
いよいよ、明日はAmazon Connect Advent Calendar 2022の最終日です!(あっという間ですね)
ギークフィード 西山さんが執筆予定です。ぜひ楽しみにしてください!
ではまた!コンサルティング部の洲崎でした。