# Example Documentation: How to Create an Amazon Lex Chat Bot This document does not replace the [official documentation](https://docs.aws.amazon.com/lexv2/latest/dg/building-bots.html). It's intended just to help you understand the steps needed to build a chat bot that you can use with this example code. Use of Amazon Lex is subject to the AWS Service Terms, including the terms specific to the AWS Machine Learning and Artificial Intelligence Services. Since you will be building this bot manually, you also must destroy it manually. The automation provided as part of the demo code will not create, modify or destroy the Amazon Lex bot. ## Preparation: Building the Bot You can build a complete conversational voice bot using Amazon Lex. In this example, you will use the Lex console to build a bot. We will skip the steps where you build the lambda function that Lex calls. This example is specifically how to connect Amazon Chime PSTN Audio to Lex. Please see the [Lex documentation](https://docs.aws.amazon.com/lex/latest/dg/how-it-works.html) for details on how to build custom Lex bots. In this example, we will leverage the built-in "book trip" example. Log into the Amazon Lex console in the same region that you deployed the Amazon Chime SDK resources in. This must be in either [us-east-1](https://us-east-1.console.aws.amazon.com/lexv2/home) or [us-west-2](https://us-west-2.console.aws.amazon.com/lexv2/home). Select "Bots" from the left menu. ### Create a Bot Click "Create Bot" on the right of the Bots panel. In the new page select "Start with an Example." Scroll down to "Bot Configuration" and enter a name for your bot ("BookTrip" for example). The name does not matter, it's just for you to track the bot. You can include an optional description. Under IAM permissions, select "Create a role with basic Amazon Lex permissions." Below that, in the section labeled "Children’s Online Privacy Protection Act (COPPA)" select "no" (this example will not need this protection, but for your own bot creation you should select that appropriately). Scroll down to to "Idle session timeout" and reduce the Session Timeout to 1 minute. For this demo program we don't need long timeouts. Skip the Advanced Settings. Click Next to advance to the next screen. On the "Add language to bot" page select the language you desire. This example assumes English (US). Under "Voice Interaction" select the voice that you would like. You can click "Play" to play the test phrase to see if the voice is to your liking. Leave the rest of the defaults and click Done. You will now move to the "Intents" section. Scroll down to "Fulfillment" and add the following text to "On successful fulfillment": ```bash Thank you! We'll see you on {CheckInDate}. ``` Scroll down to "Closing responses" and add the following text to "Message": ```bash Goodbye! ``` Skip down to the bottom and click the orange "Save Intent" button. Then click on the "Build" button. It will take a few moments to build the bot. When it completes you can test the bot using the console, if you desire. ### Create a Version You have now built the bot, but you need to publish it as a version. Navigate to the "Bot Versions" page (under your bot name). Click the orange "Create version" button on the upper right. You can accept all the default values and click the orange "Create" button in the lower right of the page. ### Create an Alias Navigate to the "Aliases" page using the left panel. Click the orange "Create alias" button. Enter a name for the alias into the "Alias name" block ("production" or "test" for example). In the "Associate with a version" block select "Version 1" from the dropdown box. If you had more versions of your bot, they would appear here. Click the orange "Create" button in the lower right corner. You will return the Aliases screen. Select the alias name you just entered ("production" for example). This will expand into a page about that Alias. Scroll down to "Resource-based policy" and click "Edit" to add a policy that will allow Chime SDK PSTN Audio to invoke Lex for you. In the text box, paste the following. You must then edit the JSON. ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "SMALexAccess", "Effect": "Allow", "Principal": { "Service": "voiceconnector.chime.amazonaws.com" }, "Action": "lex:StartConversation", "Resource": "", "Condition": { "StringEquals": { "AWS:SourceAccount": "" }, "ArnEquals": { "AWS:SourceArn": "arn:aws:voiceconnector:::*" } } } ] } ``` Replace the """ with the Resource ARN directly above the text box. This is the ARN for the bot alias. Replace "" with your account number and "" with the region you are deploying into (either us-east-1 or us-west-2). That defines the ARN of the PSTN Audio control plane in your account. Click "Save" to store the policy. ## IMPORTANT: Getting the Lex Bot Alias ARN Click on the copy button for the "Resource ARN" again to copy it to your clipboard. ### Actual Production use of a Bot In a real chat-bot application, you would almost certainly implement a lambda function to process the intents. This demo program is focussed on explaining how to connect to Amazon Chime SDK PSTN Audio, so we don't go into that level of detail. The [documentation](https://docs.aws.amazon.com/lex/latest/dg/ex-book-trip-create-integrate.html) for implementing that kind of functionality explains how to do that. ### Configuring Your Lambda to use the Lex Bot ARN. Open the src/index.ts source code file for the lambda and edit the variable "botAlias" near the top of the file: ```typescript const botAlias = ""; ``` Again, replace "" with the ARN you copied to the clipboard. You can now deploy the bot with a "yarn deploy" and swap the new lambda into PSTN Audio with "yarn swap." You will also notice the welcome text in the startBotConversationAction object: ```typescript const startBotConversationAction = { Type: "StartBotConversation", Parameters: { BotAliasArn: "none", LocaleId: "en_US", Configuration: { SessionState: { DialogAction: { Type: "ElicitIntent" } }, WelcomeMessages: [ { ContentType: "PlainText", Content: "Welcome to AWS Chime SDK Voice Service. Please say what you would like to do. For example: I'd like to book a room, or, I'd like to rent a car." }, ] } } } ``` After doing a 'yarn deploy;yarn swap' calls to that number will cause Lex will start the bot and use Polly to read that text. This gives the caller a greeting, and tells them what they should do next. ## Operation This example adds more actions to what we learned in the ["Call and Bridge Call" lesson](../lambdas/call-and-bridge/README.md). The NEW_INBOUND_CALL event arrives and is processed the same way. We enable Voice Focus (which will enhance the ability of Lex to understand words) and then immediately hand the incoming call off to the bot you send a "StartBotConversation" action. An example of that action looks like this: ```json { "SchemaVersion": "1.0", "Actions": [ { "Type": "Pause", "Parameters": { "DurationInMilliseconds": "1000" } }, { "Type": "VoiceFocus", "Parameters": { "Enable": true, "CallId": "2947dfba-0748-46fc-abc5-a2c21c7569eb" } }, { "Type": "StartBotConversation", "Parameters": { "BotAliasArn": "arn:aws:lex:us-east-1::bot-alias/RQXM74UXC7/ZYXLOINIJL", "LocaleId": "en_US", "Configuration": { "SessionState": { "DialogAction": { "Type": "ElicitIntent" } }, "WelcomeMessages": [ { "ContentType": "PlainText", "Content": "Welcome to AWS Chime SDK Voice Service. Please say what you would like to do. For example: I'd like to order flowers." } ] } } } ] } ``` When the bot returns an ACTION_SUCCESSFUL event, the data collected by the Lex bot is included in the event. You will note that the collected data from the bot is included, and your lambda could use that data if needed. An example might look like this: ```javascript { "SchemaVersion": "1.0", "Sequence": 2, "InvocationEventType": "ACTION_SUCCESSFUL", "ActionData": { "IntentResult": { "SessionId": "2947dfba-0748-46fc-abc5-a2c21c7569eb", "SessionState": { "SessionAttributes": {}, "Intent": { "Name": "BookHotel", "Slots": { "RoomType": { "Value": { "OriginalValue": "deluxe", "InterpretedValue": "deluxe", "ResolvedValues": [ "deluxe" ] }, "Values": [] }, "CheckInDate": { "Value": { "OriginalValue": "june first", "InterpretedValue": "2022-06-01", "ResolvedValues": [ "2022-06-01" ] }, "Values": [] }, "Nights": { "Value": { "OriginalValue": "five", "InterpretedValue": "5", "ResolvedValues": [ "5" ] }, "Values": [] }, "Location": { "Value": { "OriginalValue": "san francisco", "InterpretedValue": "san francisco", "ResolvedValues": [ "san francisco" ] }, "Values": [] } }, "State": "Fulfilled", "ConfirmationState": "Confirmed" } }, "Interpretations": [ { "NluConfidence": { "Score": 1 }, "Intent": { "Name": "BookHotel", "Slots": { "RoomType": { "Value": { "OriginalValue": "deluxe", "InterpretedValue": "deluxe", "ResolvedValues": [ "deluxe" ] }, "Values": [] }, "CheckInDate": { "Value": { "OriginalValue": "june first", "InterpretedValue": "2022-06-01", "ResolvedValues": [ "2022-06-01" ] }, "Values": [] }, "Nights": { "Value": { "OriginalValue": "five", "InterpretedValue": "5", "ResolvedValues": [ "5" ] }, "Values": [] }, "Location": { "Value": { "OriginalValue": "san francisco", "InterpretedValue": "san francisco", "ResolvedValues": [ "san francisco" ] }, "Values": [] } }, "State": "Fulfilled", "ConfirmationState": "Confirmed" } }, { "Intent": { "Name": "FallbackIntent", "Slots": {} } }, { "NluConfidence": { "Score": 0.21 }, "Intent": { "Name": "BookCar", "Slots": {} } } ] }, "Type": "StartBotConversation", "Parameters": { "BotAliasArn": "arn:aws:lex:us-east-1::bot-alias/RQXM74UXC7/ZYXLOINIJL", "LocaleId": "en_US", "Configuration": { "SessionState": { "DialogAction": { "Type": "ElicitIntent" } }, "WelcomeMessages": [ { "Content": "Welcome to AWS Chime SDK Voice Service. Please say what you would like to do. For example: I'd like to order flowers.", "ContentType": "PlainText" } ] }, "CallId": "2947dfba-0748-46fc-abc5-a2c21c7569eb" } }, "CallDetails": { "TransactionId": "685af72e-fd74-4ea9-b1bd-9715099ae9e9", "AwsAccountId": "", "AwsRegion": "us-east-1", "SipRuleId": "2e19ff5c-6298-4549-9a1b-2648272b6643", "SipMediaApplicationId": "d7439ce4-4f78-4f34-9d5e-f6cf6d850da6", "Participants": [ { "CallId": "2947dfba-0748-46fc-abc5-a2c21c7569eb", "ParticipantTag": "LEG-A", "To": "+15626663539", "From": "+14155551212", "Direction": "Inbound", "StartTimeInMilliseconds": "1646881785536", "Status": "Connected" } ] } } ```