Serverless technology is here to stay, In this tutorial, we will deploy a small chatbot with AWS Lex to help users set various kinds of budgets, and to check in on their budget. We will explore the combination of AWS services here and how they can be stitched together to create a powerful, scalable and secure application. To complete this tutorial, you will need: An AWS Account, basic knowledge of the AWS UI, and some basic understanding of node/express. and the benefits of a serverless architecture for your app or product are huge. Step 1: Deploy a Lex bot In your AWS console, find Amazon Lex and click on it. Click on the blue button and then on the next screen, click Note there are other examples here if you’d like to explore them! Get Started Custom Bot. On the next screen you will see an opportunity to An is a goal or action the user wants to achieve. Think of an intent as the specific reason a user would want to send a message to your bot. Lets create an intent and call it SetBudget. Once we’ve done that, we’re greeted with another screen with a whole bunch of input options. Lets focus on first. Create Intent. Intent Slots Slots are the of Lex. If someone was ordering a pizza, the Slots to include would be things like {SIZE}, {PIZZA_TYPE} and {DELIVERY_ADDRESS}. For our chatbot, we will have two slots. {AMOUNT} and {BUDGET_CATEGORY}. variables There is a lot to discuss regarding slots and different slot types, so I encourage you to see what amazon already provides before defining your own. Create a slot called AMOUNT. Set the slot type to AMAZON.NUMBER, check the required checkbox and for prompt, type in “What is the maximum budget you would like to set?”. If this slot is present in a sample utterance for an intent, then the prompt will come up if they have not provided a value for AMOUNT. In our case, we will need this value so including a prompt and making sure this is required is an important step! 2. On the left side of the dashboard, you will see an option to create a . Click on that, and fill out the values to create a slot variable with values that we will set. slot type new Note that you can add synonyms for values, and the option. Expand Values lets Lex use machine learning to add similar words to your slot list, letting it grow beyond your list of associated words. expand values Set a few budgets that you would like to include in the Slot. I have included Family, Vacation, Savings and Car. Notice the and checkboxes. Expand Values allows you to let Lex use its natural language processing and amazons machine learning to fill in your slot with words that it thinks should be included. For our purposes we wont need it, but it is an important feature that can come in handy as your application grows. Expand Values Restrict to Slot Values and Synonyms Create another slot called BUDGET_CATEGORY, and set the slot type to our new budgetCategory slot type. Note the difference between Slots and Slot Types. The trick is that the NLP needs to recognize that a value is a Slot, as well as parse the actual value of that slot. Pretty amazing that it gets it right most of the time! Now that we have our slots defined, lets go back up and create an intent. Add the following for your intent: Set a budget of {AMOUNT} for {BUDGET_CATEGORY}Create budget {AMOUNT} for {BUDGET_CATEGORY}make a budget for {AMOUNT} Add in any other variations of that utterance you can think of, but keep it relatively short to 2–3 different variations. Notice I didn’t include BUDGET_CATEGORY in the last utterance. If this variable is not included, we will create a budget under the “general” category. 3. Add a if you wish. I did not include one, but depending on the nature of your intent this could be important. Confirmation Prompt 4. Notice for you have the option to either send the intent to a lambda function or return parameters to client. For now, lets click and click save. We’re going to check on our bot before moving over to and creating the business logic of our chatbot. Scroll down and save your intent. Fulfillment, Return Parameters to Client Amazon Lambda 5. And now for a bit of fun! On the top right of the dashboard, click This will initialize your chatbot and allow you to begin testing it. A chat widget should pop up on the right side of the screen. Try it out! Build. As you can see, Amount for 50 and Category of Family is successfully captured by the chatbot. Wow! Make sure to try with the required prompts as well to validate they are being requested. Awesome, our Lex chatbot is almost ready to go. Our next step is to attach a function to it. For the rest of this tutorial, we will simply receive the slots and their values in lambda and return them in a way that Lex understands. of this tutorial will cover the inclusion of a Serverless Amazon Aurora Database to store the data and an event alarm to trigger another lambda function if they set a budget thats very high. This second lambda function will add the user to a list of High Rollers we can presumably pester to sell things to. For our purposes though, it will demonstrate chaining of Lambda functions and one of many patterns in serverless. Lambda Part II Step 2: Deploy a Lambda Function In your AWS console, go to and select In the next screen, you will have the option of building your custom function or selecting a blueprint. The blueprints are great examples and I highly recommend checking them out to enhance your knowledge. Amazon Lambda Build a Function from Scratch. Choose a name for your function, a runtime (we will be using Node.js 8.10) and select “New role” when specifying the role. For our purposes, Select and fill out the form with your function name, runtime environment (Node.js 8.10 for this tutorial), and This is a good time to mention that Lambda functions are born into this world with no permissions. To allow your lambda function to interact with other AWS services, you will need to choose a role for that function. For our setBudget function, you will need a custom role that can read/write to RDS so we’re going to take a quick detour to create that role! Author From Scratch Role. Follow the instructions for creating a role, and assign it to this function. When thats done, open a new tab and head over to services and look for IAM. in IAM, find the roles dashboard and you should see the new role you created. Attach a policy to this role which allows for full RDS access. Lambda Functions take on an IAM Role during execution. This role can have specific policies attached outlining exactly which AWS services it can interact with and how. Don’t forget Roles and IAM users always start off with zero permissions. Once your role is created and the policy is attached, check back on your Lambda function. You should now be able to select that role from the dropdown to create your function! On this next Screen you will be treated to your lambda function, the designer tool, and some dashboard items for testing and monitoring your function. The first time you hit , you will be asked to supply a JSON snippet describing what the test input should be. Test For our purposes, lets focus on the function in the top right corner which allows us to invoke our function. We can also edit the index.js document which contains the entirety of the function and modify it as we need. Note the function appears very similar to a standard express endpoint, returning a JSON response with a status code (200) and a stringified JSON body. Test For now, all we will do is add the following: console.log(event) as the first line in our function. The variable includes the data we receive from lex, so we’re going to log it and see what it looks like! event So now our function is created, it has the required roles, it can return a response, we’re looking good! Lets check back on our Lex dashboard, and revisit our setBudget intent. If we scroll down our to fulfillment, we can now select AWS Lambda Function and choose our setBudget function. Make sure your version/Alias is set to latest or you may not see updates! (This is a terrible bug which I wish upon nobody). Build the bot, and lets test out our integration! setBudget Intent Type in an intent, and lets see what we get. Oh no! Our Lambda has returned an invalid response! Oh no! As you can see, an error has ocurred and we have not received a proper response from Lambda that Lex can interpret. We are going to rectify that! But first, lets also check in on cloudwatch to see just what our , with its (hopefully) populated , actually looks like in lambda. Intent Slots Go to cloudwatch and click on Logs. You should see a log group for the setBudget Lambda function. 2. Clicking on that log group, and then clicking on the latest log will show you the latest output from our lambda function. and is a very powerful tool to ensure you are optimizing your lambda and serverless architecture appropriately. We will be doing more with Cloudwatch integrations in the next tutorial. Cloudwatch captures everything 3. Notice that we have lines which read something like and . These represent the beginning and ending of your Lambda invocation, and all logging per invocation is sandwiched between those lines. Start Request ID: End Request ID: 4. Since we logged the value to console, we can now see it in cloudwatch. It should look like this: event { messageVersion: '1.0',invocationSource: 'FulfillmentCodeHook',userId: 'bn0r1odqm2ce0ayze5n5xrlfo6lkeno1',sessionAttributes: {},requestAttributes: null,bot: { name: 'BudgetBud', alias: '$LATEST', version: '$LATEST' },outputDialogMode: 'Text',currentIntent:{ name: 'setBudget',slots: { AMOUNT: '40', BUDGET_CATEGORY: 'Family' },slotDetails: { AMOUNT: [Object], BUDGET_CATEGORY: [Object] },confirmationStatus: 'None' },inputTranscript: 'set budget of 40 for family' } Aha! Thats our Lex Intent, along with some beautiful supplemental data including which intent version we’re on, userId (more on that later), botname and currentIntent. As you can see, current intent parses our slots and slot types so we have a defined amount key and value, as well as a budget_category key/value. Our data is in a friendly JSON format and we can now do more with it. Lets finish off by returning a meaningful response to Lex, we’ll save all the database stuff for Part II. , the response needs to be in the following format: According to the AWS docs {"sessionAttributes": {"key1": "value1","key2": "value2"},"dialogAction": {"type": "Close","fulfillmentState": " ","message": {"contentType": " ","content": " "},}} _Fulfilled_ _PlainText_ _Your budget has been confirmed._ Lets try pop this into our lambda function as the response object and see what happens. For reference, your lambda function should now look like this: exports.handler = async (event) => {console.log(event);let lambda_response = {"sessionAttributes": {"amount": event.currentIntent.slots.AMOUNT,"current_budget": event.currentIntent.slots.BUDGET_CATEGORY},"dialogAction": {"type": "Close","fulfillmentState": "Fulfilled","message": {"contentType": "PlainText","content": "Your budget of " + event.currentIntent.slots.AMOUNT + " has been confirmed for category " + event.currentIntent.slots.BUDGET_CATEGORY},}}return lambda_response;}; As you can see, our response has which return context to lex, and a DialogAction can be used to elicit further prompts and responses from a user, so be sure to check out its many option types. For our purposes, we’re simply going to return a plainText message to the user letting them know their budget has been set for the correct amount. Once you’ve saved that version of the lambda function, check back on lex and run a query. If everything worked you should see the following: sessionAttributes, dialogAction. Beautiful. To review, we set up an Amazon Lex bot with an (set budget) and (amount, category). This intent was handed off to a function which could then parse the value of those slots in JSON, and return a response object to Lambda. IAM was used to create an execution role for the lambda function, and Cloudwatch was used for logging. Intent Slots Lambda In of this tutorial, we will add a serverless Amazon Aurora database to store and query this data, another intent+lambda function to see our budgets, as well as a couple more pieces of interesting architecture. Time permitting, I may include a React Native tutorial to show how to directly integrate this into an app as well, so stay tuned! Part II Part III If you are interested in building a chatbot or any other kind of application, please reach out to me at simon@apricotstudios.ca or at www.apricotstudios.ca