[Amazon Lex] HTML+JavaScriptで作成したLexクライアントでカード情報の表示に対応してみました。

2019.04.02

この記事は公開されてから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のフォーマットのバージョン

参考: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文字

参考:GenericAttachment

(3) Button

GenericAttachmentのbuttons配列に設定されるオブジェクトで、表示されるテキスト及び、それを押されたときに返す値です。

Name Type Required Detail
text String Yes 1〜15文字
value String Yes 1〜1000文字

参考:Button

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ハンズオンセミナー」を開催致します。導入を検討されておられる方は、是非、お申し込み下さい。

また音声を中心とした各種ソリューションの開発支援も行なっております。