この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
こんにちは、Alソリューション部の平内(SIN)です。
Amazon Lex(以下、Lex)のAPIであるPostText()のレスポンスには、カード情報を追加することが出来ます。
今回は、前回作成したLexクライアントで、このカード情報を表示できるようにして見ました。
[Amazon Lex] HTML+JavaScriptでLexクライアントを作ってみました)
最初に、動作しているようすです。花の種類を聞き取る段階で、送られてきたカードを表示しています。選択は、ボタンで行うことも出来ます。
2 Prompt response cards
カードの情報は、コンソールでもLambdaからでも設定可能です、今回は、コンソールで以下のように設定しました。
3 ResponseCardオブジェクト
ResponseCardにセットされるオブジェクトの内容は以下のとおりです。
(1) ResponseCard
ResponseCardの各アイテムは、以下のとおりです。
Name | Type | Required | Detail |
---|---|---|---|
contentType | String | No | application/vnd.amazonaws.card.generic |
genericAttachments | Array of GenericAttachment | No | 0〜10個のアイテム |
version | String | No | ResponseCardのフォーマットのバージョン |
(2) GenericAttachment
ResponseCardのgenericAttachments配列に設定されるオブジェクトで、表示されるオプションを表します。 画像、ボタン、リンク、又はテキストです。
Name | Type | Required | Detail |
---|---|---|---|
attachmentLinkUrl | String | No | 1〜2048文字 |
buttons | Array of Button | No | 0〜5個のアイテム |
imageUrl | String | No | 1〜2048文字 |
subTitle | String | No | 1〜80文字 |
title | String | No | 1〜80文字 |
(3) Button
GenericAttachmentのbuttons配列に設定されるオブジェクトで、表示されるテキスト及び、それを押されたときに返す値です。
Name | Type | Required | Detail |
---|---|---|---|
text | String | Yes | 1〜15文字 |
value | String | Yes | 1〜1000文字 |
4 クライントの実装
実装したコードは、以下のとおりです。 Lexからの戻り値にresponseCardがあった時に、それを表示しています。
<br />
<center>Order Flowers</center><script src="https://sdk.amazonaws.com/js/aws-sdk-2.283.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style language="text/css">
<p> div#logView {<br />
background-color:darkturquoise;<br />
border: 1px solid #ccc;<br />
padding: 4px;<br />
width: 400px;<br />
height: 500px;<br />
overflow: scroll;<br />
}</p>
<p> div#logView2 {<br />
background-color:darkturquoise;<br />
border: 1px solid #ccc;<br />
padding: 4px;<br />
width: 400px;<br />
height: 500px;<br />
overflow: scroll;<br />
}</p>
<p> .card {<br />
float: left;<br />
padding: 4px;<br />
background-color:white;<br />
text-align:center;<br />
}<br />
.card img {<br />
width: 100%;<br />
}<br />
.card button {<br />
margin: 2px;<br />
width: 60%;<br />
height:30px;<br />
border-radius:10px;<br />
background-color:royalblue;<br />
color:white;<br />
font-weight:bolder;<br />
}<br />
.card .title {<br />
font-weight:bolder;<br />
}</p>
<p> input#message {<br />
padding: 4px;<br />
font-size: 1em;<br />
width: 400px<br />
}</p>
<p> log {<br />
margin: 4px;<br />
padding: 4px;<br />
border-radius: 4px;<br />
min-width: 50%;<br />
max-width: 85%;<br />
}</p>
<p> log.req {<br />
float: left;<br />
background-color:white;<br />
}</p>
<p> log.res {<br />
text-align: right;<br />
float: right;<br />
background-color:beige;<br />
}<br />
log.err {<br />
text-align: right;<br />
float: right;<br />
color: #f77;<br />
}<br />
</style>
<script>
$('#message').focus();
AWS.config.region = 'us-east-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId:
'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx',
});
const lexruntime = new AWS.LexRuntime();
let sessionAttributes = {};
const botAlias = '$LATEST';
const botName = 'OrderFlowers';
const userId = 'id-' + Date.now();
function pushChat() {
const message = $('#message').val().trim();
if(message.length > 0) {
$('#message').val('');
const params = {
botAlias: botAlias,
botName: botName,
inputText: message,
userId: userId,
sessionAttributes: sessionAttributes
};
appendLog(message, 'req');
lexruntime.postText(params, function(err, data) {
if (err) {
console.log(err, err.stack);
appendLog(err.message, 'err');
}
if (data) {
console.log(JSON.stringify(data));
sessionAttributes = data.sessionAttributes;
appendLog(data.message, 'res');
if(data.responseCard) {
appendCard(data.responseCard);
}
}
});
}
return false;
}
function appendLog(message, className) {
$('<log>', { class:className, text:message }).appendTo('#logView');
$('#logView').scrollTop(self.innerHeight);
}
function appendCard(responseCard) {
const genericAttachments = responseCard.genericAttachments;
genericAttachments.forEach(genericAttachment => {
const card = $('</p>
<div class="card"></div>
<p>');
const imageUrl = genericAttachment.imageUrl;
const title = genericAttachment.title;
const subTitle = genericAttachment.subTitle;
$('<img src=' + imageUrl + '>').appendTo(card);
$('</p>
<div class="title">' + title + '</div>
<p>').appendTo(card);
$('</p>
<div>' + subTitle + '</div>
<p>').appendTo(card);
const buttons = genericAttachment.buttons;
buttons.forEach(button => {
const b = $('<button>' + button.text + '</button>');
b.click(function(){
$('#message').val(button.value);
pushChat();
});
b.appendTo(card);
})
card.appendTo('#logView');
});
$('#logView').scrollTop(self.innerHeight);
}
</script>
<div id="logView"></div>
<form><input id="message" size="80" type="text" value="" /></form>
5 最後に
今回は、HTML+JavaScriptのLexクライアントでカード情報に対応してみました。
何故(当然)か、オーディオ対応のPostContent()では、ResponseCardを返すことが出来ません。
ってことは、音声対応のLexクライアントでは、音声でもボタンでも応答可能なリッチなクライアントは、ResponseCardでは、対応できないことになります。
Lambda側の実装で、SessionAttributesに、ResponseCardと同じ内容を返すなどの工夫が必要のようです。次回は、この辺の仕様を検討して、音声対応のLexクライアントでもカード表示に対応させて見たいと思います。
6 参考リンク
Amazon Lex Runtime Service » PostText
[Amazon Lex] HTML+JavaScriptでLexクライアントを作ってみました)
[Amazon Lex] HTML+JavaScriptでLexクライアントを作ってみました(音声対応)
弊社ではAmazon Connectのキャンペーンを行なっております。
3月に引き続き、4月も「無料Amazon Connectハンズオンセミナー」を開催致します。導入を検討されておられる方は、是非、お申し込み下さい。
また音声を中心とした各種ソリューションの開発支援も行なっております。