How to Implement AWS Cloud ChatBot User Interface

Posted By : Ravindra Singh | 09-Mar-2021

Introduction :

Here i am going to explain you the charming concept called AWS Cloud ChatBot.The chatbot Web User Interface (UI) is an elegent concept and it is developed by using  Amazon Lex, AWS SDK for JavaScript in the Browser, and Amazon Cognito for interacting with AWS Lex chatbots, we can create a conversational experience on our Website. We will use JavaScript and AWS services to create and build an interactive experience for visitors to our Web site, that seems like a lot to take on. The chatbot web UI support for different devices and browsers, authentication, voice recording, and much more. 

By using web UI chatbot we are connecting with AWS Lex and Lex is connected with AWS Lambda to process the business logic, So the flow is when the user is given the voice input on to web UI and then web UI sends request to lex, Lex recognizes voice input and sent to Lambda and then lambda process the result and sent back to browser.

 

Look into how to run as a full-webpage aws OrderFlowerchatbot UI :

Source: https://madewithvuejs.com/aws-lex-web-ui

 


Or we can Embed it into a site as a chatbot widget :

Source: https://aws.amazon.com/blogs/machine-learning/deploy-a-web-ui-for-your-chatbot/

 

 

Here is the web UI code :


<html> 

<head> 
    <meta charset="UTF-8"> 
    <title>AmazonLex</title> 
    <meta name="author" content="lafranch"> 
    <meta name="description" content="Lex Runtime example from the browser."> 
    <meta name="keywords" content="Amazon Lex, SDK, Runtime, Browser, JavaScript"> 
    <link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" /> 
    <link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" /> 
    <link rel="stylesheet" href="style.css"> 
</head> 

<body class="wrapper"> 
     
    <div class="container"> 
     
<header> 
   
    <left> 
      <h1>VirginLexPOC</h1>        
   </left>     
         
    <left> 
          
    </left> 
</header> 
    <div id="conversationHeader" style="width: 400px; height: 70px; border: 1px solid #ccc; background-color: #00BFFF; padding: 4px; margin-left:10px; text-clor:white"> 
    <h3 style="color: white;">Hi! I am your chat bot assistant. I can help you search for movies and their synopsis.</h3> 
    </div> 
    <div id="conversation" style="width: 400px; height: 400px; border: 1px solid #ccc; background-color: #eee; padding: 4px; margin-left:10px; overflow: scroll"></div> 
    <form id="chatform" style="margin-top: 1px" onsubmit="return pushChat();"> 


        <div id=id="input_container" style="margin-left:10px;"> 
            <input type="text" id="wisdom" size="80" value="" placeholder="Book a flowers"> 
               <div class="audio-control" id="input_img"> 
            <p id="audio-control" class="white-circle" style="right"> 
                <img src="https://google.com/intl/en/chrome/assets/common/images/content/mic.gif"> 
        </p> 
            <p><span id="message"></span></p> 
                 
                 
        </div> 
        </div> 
    </form> 
         
        <!--<p> 
        <input type="password" id="ACCESS_ID" name="ACCESS ID" placeholder="ACCESS ID" value=""/> 
    </p> 
    <p> 
        <input type="password" id="SECRET_KEY" name="SECRET KEY" placeholder="SECRET KEY" value=""/> 
    </p> 
    <p> 
        <input type="text" id="BOT" name="BOT" placeholder="BOT" value=""/> 
    </p>--> 
<footer>Copyright © Vision360</footer> 
    </div>     
</body> 

</html>

 

 

Here is the web JS code :


<script src="https://sdk.amazonaws.com/js/aws-sdk-2.48.0.min.js"></script> 
    <script src="../dist/aws-lex-audio.js" type="text/javascript"></script> 
    <script src="renderer.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
        //var waveform = window.Waveform(); 
        var message = document.getElementById('message'); 
        var config, conversation; 
        message.textContent = 'Passive'; 

        document.getElementById('audio-control').onclick = function() { 

            AWS.config.credentials = new AWS.Credentials('Access Key ID', 'Secret access key', null);
            AWS.config.region = 'eu-west-1'; 
              
                   
            config = { 
                    silenceDetection: true,  
                    silenceDetectionConfig: { 
                        time: 14000, 
                        amplitude: 0.2 
                    }, 
                    lexConfig:{ 
                        botName: 'AWSLexApp', 
                        botAlias: '$LATEST', 
                        contentType: 'audio/x-l16; sample-rate=16000', 
                        userId: 'chatbot-demo' + Date.now(), 
                        accept: 'audio/mpeg' 
                    } 
                }; 

            conversation = new LexAudio.conversation(config, function(state) { 
                message.textContent = state + '...'; 
                if (state === 'Listening') { 
        config.silenceDetection='false'; 
                    //waveform.prepCanvas(); 
                } 
                if (state === 'Sending') { 
                    //waveform.clearCanvas(); 
                } 

        if (config.silenceDetectionConfig.time == '14000') { 
        config.silenceDetection='true'; 
                    //state='Passive'; 
                } 

            }, function(data) { 
                console.log('Transcript: ', data.inputTranscript, ", Response: ", data.message); 
                if(data.inputTranscript!=undefined && data.inputTranscript.trim()!=''){ 
        showRequest(data.inputTranscript); 
        } 
                     
                if(data.message!=undefined && data.message!='') 
                    showResponse(data); 
            }, function(error) { 
                message.textContent = error; 
            }, function(timeDomain, bufferLength) { 
                //waveform.visualizeAudioBuffer(timeDomain, bufferLength); 
            }); 
            conversation.advanceConversation(); 
        }; 
         
        //Chat conversation 
        // Initialize the Amazon Cognito credentials provider 
        AWS.config.region = 'eu-west-1'; // Region 
        AWS.config.credentials = new AWS.CognitoIdentityCredentials({ 
        // Provide your Pool Id here 
            IdentityPoolId: 'pool id', 
        }); 
             
         
        var lexruntime = new AWS.LexRuntime(); 
        var lexUserId = 'chatbot-demo' + Date.now(); 
        var sessionAttributes = {}; 

        function pushChat() {     
         
             
            // if there is text to be sent... 
            var wisdomText = document.getElementById('wisdom'); 
            if (wisdomText && wisdomText.value && wisdomText.value.trim().length > 0) { 

                // disable input to show we're sending it 
                var wisdom = wisdomText.value.trim(); 
                wisdomText.value = '...'; 
                wisdomText.locked = true; 

                // send it to the Lex runtime 
                var params = { 
                    botAlias: '$LATEST', 
                    botName: 'VirginLexPoc', 
                    inputText: wisdom, 
                    userId: lexUserId, 
                    sessionAttributes: sessionAttributes 
                }; 
                showRequest(wisdom); 
                lexruntime.postText(params, function(err, data) { 
                    if (err) { 
                        console.log(err, err.stack); 
                        showError('Error:  ' + err.message + ' (see console for details)') 
                    } 
                    if (data) { 
                        // capture the sessionAttributes for the next cycle 
                        sessionAttributes = data.sessionAttributes; 
                        // show response and/or error/dialog status 
                        showResponse(data); 
                    } 
                    // re-enable input 
                    wisdomText.value = ''; 
                    wisdomText.locked = false; 
                }); 
            } 
            // we always cancel form submission 
            return false; 
        } 

        function showRequest(daText) { 

            var conversationDiv = document.getElementById('conversation'); 
            var requestPara = document.createElement("P"); 
            requestPara.className = 'userRequest'; 
            requestPara.appendChild(document.createTextNode(daText)); 
            conversationDiv.appendChild(requestPara); 
            conversationDiv.scrollTop = conversationDiv.scrollHeight; 
        } 

        function showError(daText) { 

            var conversationDiv = document.getElementById('conversation'); 
            var errorPara = document.createElement("P"); 
            errorPara.className = 'lexError'; 
            errorPara.appendChild(document.createTextNode(daText)); 
            conversationDiv.appendChild(errorPara); 
            conversationDiv.scrollTop = conversationDiv.scrollHeight; 
        } 

        function showResponse(lexResponse) { 

            var conversationDiv = document.getElementById('conversation'); 
            var responsePara = document.createElement("P"); 
            responsePara.className = 'lexResponse'; 
            if (lexResponse.message) { 
                responsePara.appendChild(document.createTextNode(lexResponse.message)); 
        //responsePara.appendChild(document.createTextNode(lexResponse.dialogState.responseCard)); 

                responsePara.appendChild(document.createElement('br')); 
            } 
           /* if (lexResponse.dialogState === 'ReadyForFulfillment') { 
                responsePara.appendChild(document.createTextNode( 
                    'Ready for fulfillment')); 
                // TODO:  show slot values 
            } else { 
                responsePara.appendChild(document.createTextNode( 
                    '(' + lexResponse.dialogState + ')')); 
            }*/ 
            conversationDiv.appendChild(responsePara); 
            conversationDiv.scrollTop = conversationDiv.scrollHeight; 
        } 
    </script>

 

 

The following features are supported by AWS Lex chatbot UI :

1-> Mobile-ready responsive UI with full screen or we can say embedded widget model.
2-> Full support for voice and text, with the ability to toggle between them.
3-> Support voice with following features automatic silence detection, transcriptions, audio record, and replay are the main features. 
4-> Response cards support for both text and voice
5-> AWS Lex have the Ability to programmatically interact with the chatbot UI from the hosting website.
6-> Multiple deployment options
7-> Deployment and integration options

 

There are four options for deploying and integrating the chatbot Web UI:

1-> Using AWS CloudFormation.
2-> Using AWS Mobile Hub.
3-> Using a prebuilt distribution library.
4-> Using a prepackaged Vue component.

 

 


Deploying with AWS CloudFormation is very easy, so we’ll show you how we deploy with it:

These are the steps to deploy the chatbot UI :

  1. Press the Launch Stack button:
  2. And Next to accept all default parameters.
    This deploys a demonstration environment in your account and installs the OrderFlowerBot.
  3.  When AWS CloudFormation launches the stack will do then the status is shown CREATE_COMPLETE. Then open the Outputs tab. And choose WebAppUrl or ParentPageUrl to experiment or test with your aws web chatbot UI:

Source: https://aws.amazon.com/blogs/machine-learning/deploy-a-web-ui-for-your-chatbot/

 

 

The stack deployment architecture is as given below. It is completely serverless? charges are only paid as you go with using services.

Source: https://aws.amazon.com/blogs/machine-learning/deploy-a-web-ui-for-your-chatbot/

 

 

Thanks

About Author

Author Image
Ravindra Singh

Ravindra is Sr. Associate Consultant Development- Java (Backend Developer). And Familiar with AWS Cloud Machine Learning Programming (AWS Lex, Lambda, Polly, Elasticsearch ), And also having good experience in Spring Boot Microservice Architecture Applica

Request for Proposal

Name is required

Comment is required

Sending message..