DEV Community

Cover image for How to build an AI Chatbot using Amazon Lex and Lambda, and Integration with ReactJS
The ERIN
The ERIN

Posted on • Updated on

How to build an AI Chatbot using Amazon Lex and Lambda, and Integration with ReactJS

Introduction

Chatbots have emerged as one of the latest trends in modern-day technology, and they're making a huge impact on our day-to-day activities. From scheduling appointments and medical advice to booking flights, providing real-time informations.Chatbots are simplifying our lives and making everything easier and more efficient, as they can provide instant responses and personalised interactions.

Amazon Lex is one of the most popular platforms for creating fast and scalable chatbots. In this article, I’ll walk you through the process of creating a chatbot with Amazon Lex and Lambda and how you can integrate it into your React.js project.

In this article, you’ll learn how to build a COVID Tracker chat bot using

  1. Amazon Lex UI console to build and test the chatbot
  2. AWS Lambda Function to enhance the capabilities of the chatbot, allowing it to provide more accurate and up-to-date information to users.
  3. AWS CloudFormation to automate the deployment and management of the applications in simple steps.

At the end of this article, you’ll have a deeper understanding of how to build, enhance and deploy your chatbots with the help of AWS Lex, Lambda Functions and Cloud Formation and finally how you can include them in your React.js projects.

 

Prerequisites

  • An AWS account

  • Some basic understanding of Node.js is required.

  • A working computer with any type of operating system

  • Any code editor you’re comfortable using

 

What is AWS Lex

AWS Lex is a cloud-based service provided by Amazon Web Services that enables developers to build conversational interfaces using voice and text. It uses natural language understanding (NLU) technology to understand and interpret user input, allowing developers to create chatbots, voice bots, and virtual assistants that can interact with users in a human-like way. AWS Lex is like a brain that can understand what people say or type, and then respond back like a human.

For example, Capital One, a large financial institution, used AWS Lex to create Eno, a virtual assistant that helps customers manage their accounts through a chat interface. Eno can answer questions about account balances, transactions, and payments, and can even proactively alert customers to potential fraud.

Another example is the healthcare company, HealthTap, which used AWS Lex to create a chatbot that helps patients find answers to their health-related questions. The chatbot uses natural language understanding to interpret the user's question, and then provides relevant information and resources based on the user's needs.

AWS Lex enables developers to build powerful conversational interfaces that can improve customer engagement and automate common tasks.

 

How to Build an AWS Lex Chatbot

  • To get started, log in to your AWS management console via this link.

     

  • Search for Amazon Lex in the top navigation bar and select to open the Amazon Lex dashboard. We’ll be doing most of our operations on the dashboard, like creating, managing, and testing our chatbot.

 

Amazon Lex Navigation

 

We’ll be using the Version 1 console, from the sidebar, click on “Return to the V1 console” to switch to the V1 user interface console.

 

Switching to lex v1 console

 

  • To create a new chatbot, click the "Create" button. First, we’ll be prompted to select if you want to create our own custom bot or use one of the sample bots. Since we’re creating a custom chat bot, we’ll continue with the first option.

 

a custom chatbot

 

  • For our custom bot, we must set up a few basic options. The following fields need to be specified:

Bot name: In our example, let's call our bot "CovidChatBot." This field includes the name of our bot. It must be between 2 and 50 characters long and only allow letters—no spaces.

Language: This is the language that our chatbot will use to communicate. Let's choose “English (US)”.

Output voice: The Lex Service provides us with different voice outputs we can use for our chatbot. We’re building a text-based chat bot, so let’s go with the "None" option.

Session timeout: This option specifies how long we want Amazon Lex to retain the context; it can be set between zero and 1440 (24 hours). Let's go with 5 minutes.

COPPA: This stands for the Children’s Online Privacy Protection Act. This indicates if our bot is subjected to COPPA. Select no, as our bot does not apply to COPPA.

We'll leave the other fields at their default values.

 

Defining Intents, Utterances and Slots

Excellent work!, We've successfully created our custom covid chatbot, but before we move on, let's go over the key fundamental components of the Lex service, which are Intents, Utterances and Slots.

Intents

"Intents," as the name suggests, are a fundamental concept used to represent the purpose or goal of a user's input. Intents can be viewed as a verb, detecting what a user's intention is. For example, if you go to a pizza shop and order a pizza, your main intention is to order pizza, your purpose for going to the store is to get pizza. This works the same way for lex-powered chatbots. We have to define intents so the bot can easily track or identify our goals during a conversation.

Utterances

Utterances are examples of phrases or sentences that we might use to convey a specific meaning or request. For example, when we walk into the pizza store to order a box of pizza, a possible request we could make is "I want to order a box of pizza." These utterances are used to teach the chatbot how to understand and respond to what we are saying. The more utterance we give, the better the chatbot will be at understanding what we’re trying to say.

Slots and Slot Types

Slots are a collection of information that you prompt chatbot users to provide during a conversation with your bot. In the COVID chatbot we're building in this article, for example, we can define slots by country and prompt the user to enter a value for each slot. The bot will prompt the user to provide information for each slot, and once all of the required slots have been filled, the bot will be able to process the order and respond appropriately.

Amazon Lex includes a variety of built-in slot types, including numbers, dates, countries, and many more. We can also define what sets of values are acceptable by creating our own custom slot types.

 

Developing our Covid Chat Bot

Okay, so that was a bit of a theoretical explanation; now let's get back to building our chat bot. Remember, we've already set up our own chat bot. We need to create our intents, then add possible utterances and slots as needed.

 

Creating Intents

Let's make four intents for our Covid chatbot: the Welcome intent, the About intent, the CovidTracker intent, and the Goodbye intent.

  • Navigate to the Lex console to create the four different intents. Click the "Create Intent" button to open a modal window with three options; select the "Create Intent" option. We must give each intent a distinct name so that we can distinguish them when writing our lambda function.

 

Creating Utterances

Just as we understood what utterances are, we need to add possible utterances that a user could ask our chatbot. Ideally, it’s best to add as many possible utterances as possible to make the chatbot efficient.

To create an utterance, on the sidebar, select the intent you want to create possible utterances for. Under the "Sample Utterances," we can go ahead and add as many possible utterances as a user can ask our chatbot.

 

CovidTracker Utterances

This is the fundamental part of our chatbot, as our chatbot is tasked with providing current covid information. For this intent, we’ll add possible utterances, and I’ll also show you how to add slots and how they work in action.

To add slots, we need the bot to identify them, so we have to wrap the words in curly braces when defining an utterance.

 

covid utterance

 

We've added a slot called "country," because our CovidTracker Intent requires the name of the country where a user wants to learn more about the COVID situation.

When we add slots, we must also include the slot type. This could be any value, but we'll use "Amazon.Country" in this case. We also have the option of adding prompts. " Prompts are messages or questions that are used to obtain user input for a specific slot. They can be customized, and multiple prompts for a single slot can be created to provide variety.

 

Goodbye and About Utterances

screenshot for Goodbye Intent

 

screenshot here for About Intents.

 

The goodbye and about intents, as the name implies, will include possible utterances that tell users more about our Chatbot and also send personalized goodbye messages to our users. I've added a list of possible utterances as shown in the screenshots above, but feel free to add as many as you like.

 

Integrating the chatbot with AWS Lambda

AWS Lambda is a way to write and run code without worrying about setting up and maintaining the underlying server or computing resources. We can focus on writing our code, and Lambda takes care of executing it and scaling it as needed based on demand. It’s a popular choice for building serverless applications.

Why do we need a Lambda Function attached to our chatbot?

Then you're probably wondering why we need a Lambda function associated with our chatbot.

Our COVID Tracker chatbot relies on lambda functions to perform various tasks based on user input or the state of a conversation. This is why we require a lambda function for our project:

  1. Retrieving COVID data: Based on what our users request for a specific country, our Lambda function will retrieve the most recent COVID data from a third-party API. It provides our users with real-time information.

  2. Processing user input: Before returning a response to the user, our lambda function will process and validate their input. If a user requests data for a country that does not exist, the lambda function will respond with an appropriate error message.

  3. Provide additional resources: Based on the user's request, it will provide additional resources. If a user requests more information about COVID symptoms, for example, the Lambda function can return links to relevant articles or resources.

Overall, introducing a Lambda function into our COVID tracker chatbot will improve its capabilities, allowing it to provide more accurate and up-to-date information to our users while also providing a more engaging conversational experience.

 

Writing lambda functions using Node.js

  • To begin, go to the management console and search for and select the Lambda service.

     

Screenshot of lambda being searched in the management console.

 

  • To create a new Lambda function, click the "Create Function" button. Lambda offers three different options, but the "Author from scratch" option is the best fit for us.

 

Screenshot of the new lambda function being filled out.

 

  • We need to name our lambda function. I recommend choosing a name that is simple and descriptive. Let's call it "chatBotFunction" in accordance with the camel naming convention.

     

  • Because we're writing our function in Node.js, we'll use the Node.js 18 runtime environment.

     

  • Click the "Create function" button to finish creating an environment for our "chatBotFunction" Lambda Function.

     

  • The following page is a function editor. This is a sandbox where we can write code, test it, deploy it, and monitor its performance.

 

Writing Our Lambda Function

  • Open your preferred code editor to begin writing the lambda function. We're using a text editor because it allows us to install dependencies needed for our lambda function to function properly.

     

  • Launch a new terminal and run the following commands. I'm using "npm" as my package manager, you can use commands specific to your preferred package manager:

     

// this creates a new package.json file
> npm init -y 

// installing dependencies to make requests to the API
> npm install request request-promise --save

// this creates an index.js file ( the name of the file should be the same as below, since it will be referred as default handler in lambda function as "index.handler")
> touch index.js
Enter fullscreen mode Exit fullscreen mode
  • Open the newly created index.js file and copy the code below there. I’ll explain what each line of code does.

     

const Request = require("request-promise");
const numeral = require("numeral");
const dispatcher = async (event) => {
  let response = {
    sessionAttributes: event.sessionAttributes,
    dialogAction: {
      type: "Close",
      fulfillmentState: "",
      message: {
        contentType: "PlainText",
        content: "",
      },
    },
  };
  switch (event.currentIntent.name) {
    case "CovidTracker":
      try {
        let url =
          "https://disease.sh/v3/covid-19/countries/" +
          event.currentIntent.slots.country;
        console.log("endpoint: " + url);
        let result = await Request(url, { json: true });

        console.log(result.todayCases);
        response.dialogAction.fulfillmentState = "Fulfilled";
        response.dialogAction.message.content =
          "Today (" +
          new Date().toISOString().slice(0, 10) +
          ") Cases: " +
          numeral(result.todayCases).format("0.0a") +
          ",\n" +
          "Recovered: " +
          numeral(result.todayRecovered).format("0.0a") +
          ",\n" +
          "Deaths: " +
          numeral(result.todayDeaths).format("0.0a") +
          "\n" +
          "Total Cases (till date): " +
          numeral(result.cases).format("0.0a") +
          ",\n" +
          "Recovered: " +
          numeral(result.recovered).format("0.0a") +
          ",\n" +
          "Deaths: " +
          numeral(result.deaths).format("0.0a");
      } catch {
        response.dialogAction.fulfillmentState = "Failed";
        response.dialogAction.message.content =
          "Sorry, no data found for provided country. Please try again with correct country name!";
      }
      break;
    case "Goodbye":
      response.dialogAction.fulfilmentState = "Failed";
      response.dialogAction.message.content =
        "Goodbye, Stay Updated! Stay Protected!";
      break;
    case "AboutBot":
      response.dialogAction.fulfilmentState = "Failed";
      response.dialogAction.message.content =
        "This bot helps to stay updated on the latest covid-19 informations.";
      break;
    case "Welcome":
      response.dialogAction.fulfillmentState = "Fulfilled";
      response.dialogAction.message.content =
        "Hello, I'm Dexa, How can I help you today?";
      break;
    default:
      response.dialogAction.fulfillmentState = "Failed";
      response.dialogAction.message.content = "No data found for this country";
      break;
  }
  return response;
};
exports.handler = async (event) => {
  return dispatcher(event);
};
Enter fullscreen mode Exit fullscreen mode

 

This is a Node.js module that exports a function called handler. This function takes an input event object and returns a response object.

The handler function first imports two Node.js packages: request-promise and numeral. request-promise is a library that allows the code to make HTTP requests to external APIs. numeral is a library that helps with formatting numbers.

The dispatcher function is defined next. This function takes an event object and returns a response object. It starts by creating a default response object with a Close dialog action type and an empty message.

The function then switches on the name property of the currentIntent object in the event input to determine what action to take. The code has cases for the following intents:

CovidTracker: This case retrieves COVID-19 statistics for a country and formats them into a response message. It uses the request-promise library to make a GET request to an external API, retrieves the relevant statistics, and formats them into a response message using the numeral library. The response message is then added to the message property of the default response object.

Goodbye: This case simply returns a farewell message as the response.

AboutBot: This case returns a message describing the purpose of the bot.

Welcome: This case returns a greeting message as the response.

Default: This case handles any other intent not covered by the other cases. It simply returns a generic message saying that no data was found for the requested country.

Finally, the dispatcher function returns the response object.

The handler function simply calls the dispatcher function with the event input and returns the result. This makes the dispatcher function the main logic for handling the input and generating the output of the AWS Lambda function that is using this code.

  • AWS Lambda provides us with the options to upload our file, which contains our code, to the playground. Since we have used npm modules for this lambda function, we have to zip the function, and we can do this by running this command in the terminal.
// create zip file
> zip -r handler.zip *
Enter fullscreen mode Exit fullscreen mode

Click the "Upload from button" on the right side of the page, opposite the "Code Source" heading, from the playground, and select the ".zip file" option.

After the file upload is complete, the directory structure should look like this.

 

Screenshot of the folder directory

 

  • We must test the lambda function before deploying it, which requires some basic configuration.

     

  • Click the arrow next to the Test button to open a dropdown menu with the "Configure test event" option. When you do, a modal window with a few basic configuration options will appear.

     

  • As your test event action, choose "Create new event" and give it a descriptive name, such as "CovidTracker" in my case.

     

  • Copy and paste the code below into the "Event JSON" field. Change the slots.country value to the name of your country, then click the Save button.

     

{
  "messageVersion": "1.0",
  "invocationSource": "DialogCodeHook",
  "userId": "John",
  "sessionAttributes": {},
  "bot": {
    "name": "MakeAppointment",
    "alias": "$LATEST",
    "version": "$LATEST"
  },
  "outputDialogMode": "Text",
  "currentIntent": {
    "name": "CovidTracker",
    "slots": {
      "country": "Nigeria"
    },
    "confirmationStatus": "None"
  }
}
Enter fullscreen mode Exit fullscreen mode

 

When you press the Test button, you should get the response shown in the screenshot below.

 

screenshot of test successful

 

Attaching our Lambda function to our Lex bot.

Congratulations! Now that we've successfully created our lambda function, we need to connect it to our chatbot in order to improve its capabilities.

  • Choose one of the four previous intents. Under "Fulfillment," choose the AWS Lambda Function option and the chatBotFunction, making sure it's the most recent version. Do this for the remaining three intents.

     

screenshot of fulfillment

 

  • To save all changes, click the "Save Intent" button. When making changes to any of your created intents, always click the save button.

     

    Putting our Chatbot to Test

  • Let's put our bot to the test. Select the "Build" option. This button is located on the right side of the page. This button allows us to build our chatbot and use the test playground.

     

  • This only takes a few seconds, and we can put it to the test.

     

 

  • You can use all of the utterances specified in each intent to have a conversation and test the bot's efficiency.

Good job! Our bot is now ready for deployment.

 

Deploying the Bot Using AWS CloudFormation

Our bot is complete, but we must consider hosting and deploying the user interface. AWS already offers a simple method via one of its services, AWS CloudFormation.

AWS CloudFormation is an AWS tool that allows us to create and manage cloud resources. It enables us to automate application deployment and management in simple steps.

More information can be found here.

  • To begin, go to the management console, search for and select the Cloud Formation Service.

 

screenshot of a cloud formation search in the management console

Make certain that the region you select is the same as where you created your bot.

Northern Virginia

Oregon

Ireland

Sydney

Singapore

London

Tokyo

Frankfurt

  • You should see a page with various configuration options, but the ones we're most concerned about are:

Stack name: Provide a descriptive stack name that may include alphabets, numbers, or dashes.

CodeBuildName: This is the name of the CodeBuild project that will be created. It is used to upload the web application to S3. You could call it the same name as your stack name.

BotName: This applies to us under the Lex V1 Configuration parameters because we created our bot using the V1 console. You must use the same name you used when creating your bot in the Lex console. "CovidChatBot". Ignore the form field Lex V2 Bot Configuration Parameters.

WebAppParentOrigin: In the Web Application Parameters form section, we must enter the WebAppParentOrigin, which is the URL to which we want our bot's user interface to be integrated. Enter the URL where your React.js project is hosted.

WebAppPath: Under "Web Application Parameter," you must specify a path to the page (or pages) under WebAppParentOrigin that will host the chatbot UI. A comma-separated list of paths can be specified.

WebAppConfBotInitialText: This is the first bot message displayed to users in the chatbot UI.

WebAppConfToolbarTitle: The title that appears in the chatbot UI toolbar.

Once you've finished filling out the form fields, confirm the two acknowledgments at the bottom of the form, and click the "Create Stack" button.

Once your stack has been successfully created and deployed, you should see the following entries in the screenshot below.

 

stacks created successfully

 

Integrating With React.Js Project

Our stacks have been built and launched, and the status is now "CREATE COMPLETE". Our chatbot can now be integrated into a ReactJS project.

  • To begin, select the "stack name" that contains your chatbot in the CloudFormation console.

     

  • Scroll down the page and look for "SnippetUrl." Click on the "Outputs" tab. Clicking on the URL should take you to a page with a code snippet that you can paste into your web application.

     

  • Because we're integrating it with a React JS application, copy the snippet code and open your project's index.html file in the public folder.

     

  • Paste the snippet code just before the closing tag of the html file's body element.

When you visit your page, your chatbot should be visible on the right bottom side of the screen.

Amazing! You now have a Covid Tracker Lex-powered chatbot that is fully operational. Test the chatbot now, and you'll see how quick and effective it is.

 

Conclusion

To summarize, building chatbots with AWS Lex, Lambda, and CloudFormation and integrating them with a ReactJS web app is a powerful and efficient way to increase user engagement and customer satisfaction.

You can easily create chatbots with natural language understanding, integrate them with your web apps, and automate various workflows using these AWS Services. You can easily build and deploy chatbots by following the steps outlined in this article without having to worry about the underlying infrastructure.

You can provide an end-to-end solution for building sophisticated chatbots that can improve user experience and streamline business operations by leveraging the power of AWS Lex, Lambda, CloudFormation, and Reactjs.

So, as you move forward with building chatbots with AWS Lex, Lambda, and CloudFormation, I encourage you to fully explore the capabilities of these tools. With the right approach and tools, you can create chatbots that meet the needs and demands of your users.

If you liked my article and found it useful, please leave a tip. Your contribution would enable me to continue producing high-quality articles for you.

Image description

Thank you for your continued support, and I look forward to providing you with more useful content in the future.

Top comments (0)