

End of support notice: On September 15, 2025, AWS will discontinue support for Amazon Lex V1. After September 15, 2025, you will no longer be able to access the Amazon Lex V1 console or Amazon Lex V1 resources. If you are using Amazon Lex V2, refer to the [Amazon Lex V2 guide](https://docs.aws.amazon.com/lexv2/latest/dg/what-is.html) instead. . 

# Step 3: Getting Started (Console)
<a name="gs-console"></a>

The easiest way to learn how to use Amazon Lex is by using the console. To get you started, we created the following exercises, all of which use the console:
+ Exercise 1 — Create an Amazon Lex bot using a blueprint, a predefined bot that provides all of the necessary bot configuration. You do only a minimum of work to test the end-to-end setup.

  In addition, you use the Lambda function blueprint, provided by AWS Lambda, to create a Lambda function. The function is a code hook that uses predefined code that is compatible with your bot.
+ Exercise 2 — Create a custom bot by manually creating and configuring a bot. You also create a Lambda function as a code hook. Sample code is provided.
+ Exercise 3 — Publish a bot, and then create a new version of it. As part of this exercise you create an alias that points to the bot version.

**Topics**
+ [Exercise 1: Create an Amazon Lex Bot Using a Blueprint (Console)](gs-bp.md)
+ [Exercise 2: Create a Custom Amazon Lex Bot](getting-started-ex2.md)
+ [Exercise 3: Publish a Version and Create an Alias](gettingstarted-ex3.md)

# Exercise 1: Create an Amazon Lex Bot Using a Blueprint (Console)
<a name="gs-bp"></a>

In this exercise, you do the following:
+ Create your first Amazon Lex bot, and test it in the Amazon Lex console. 

  For this exercise, you use the **OrderFlowers** blueprint. For information about blueprints, see [Amazon Lex and AWS Lambda Blueprints](lex-lambda-blueprints.md). 

   
+ Create an AWS Lambda function and test it in the Lambda console. While processing a request, your bot calls this Lambda function. For this exercise, you use a Lambda blueprint (**lex-order-flowers-python**) provided in the AWS Lambda console to create your Lambda function. The blueprint code illustrates how you can use the same Lambda function to perform initialization and validation, and to fulfill the `OrderFlowers` intent. 

   
+ Update the bot to add the Lambda function as the code hook to fulfill the intent. Test the end-to-end experience.

The following sections explain what the blueprints do. 

## Amazon Lex Bot: Blueprint Overview
<a name="gs-bp-summary-bot"></a>

You use the **OrderFlowers** blueprint to create an Amazon Lex bot.For more information about the structure of a bot, see [Amazon Lex: How It Works](how-it-works.md). The bot is preconfigured as follows:
+ **Intent** – OrderFlowers
+ **Slot types** – One custom slot type called `FlowerTypes` with enumeration values: `roses`, `lilies`, and `tulips`.
+ **Slots** – The intent requires the following information (that is, slots) before the bot can fulfill the intent.
  + `PickupTime` (AMAZON.TIME built-in type)
  + `FlowerType` (FlowerTypes custom type)
  + `PickupDate` (AMAZON.DATE built-in type)
+ **Utterance** – The following sample utterances indicate the user's intent:
  + "I would like to pick up flowers."
  + "I would like to order some flowers."
+ **Prompts** – After the bot identifies the intent, it uses the following prompts to fill the slots:
  + Prompt for the `FlowerType` slot – "What type of flowers would you like to order?"
  + Prompt for the `PickupDate` slot – "What day do you want the \$1FlowerType\$1 to be picked up?"
  + Prompt for the `PickupTime` slot – "At what time do you want the \$1FlowerType\$1 to be picked up?"
  + Confirmation statement – "Okay, your \$1FlowerType\$1 will be ready for pickup by \$1PickupTime\$1 on \$1PickupDate\$1. Does this sound okay?" 



## AWS Lambda Function: Blueprint Summary
<a name="gs-bp-summary-lambda"></a>

The Lambda function in this exercise performs both initialization and validation and fulfillment tasks. Therefore, after creating the Lambda function, you update the intent configuration by specifying the same Lambda function as a code hook to handle both the initialization and validation and fulfillment tasks. 
+ As an initialization and validation code hook, the Lambda function performs basic validation. For example, if the user provides a time for pickup that is outside of normal business hours, the Lambda function directs Amazon Lex to re-prompt the user for the time.
+ As part of the fulfillment code hook, the Lambda function returns a summary message indicating that the flower order has been placed (that is, the intent is fulfilled).

**Next Step**  
[Step 1: Create an Amazon Lex Bot (Console)](gs-bp-create-bot.md)

# Step 1: Create an Amazon Lex Bot (Console)
<a name="gs-bp-create-bot"></a>

For this exercise, create a bot for ordering flowers, called OrderFlowersBot.

To create an Amazon Lex bot (console)

1. Sign in to the AWS Management Console and open the Amazon Lex console at [https://console.aws.amazon.com/lex/](https://console.aws.amazon.com/lex/).

1. If this is your first bot, choose **Get Started**; otherwise, on the **Bots** page, choose **Create**. 

1. On the **Create your Lex bot** page, provide the following information, and then choose **Create**.
   + Choose the **OrderFlowers** blueprint.
   + Leave the default bot name (OrderFlowers).
   + For **COPPA**, choose **No**.
   + For **User utterance storage**, choose the appropriate response.

1. Choose **Create**. The console makes the necessary requests to Amazon Lex to save the configuration. The console then displays the bot editor window.

1. Wait for confirmation that your bot was built.

1. Test the bot.
**Note**  
You can test the bot by typing text into the test window, or, for compatible browsers, by choosing the microphone button in the test window and speaking. 

   Use the following example text to engage in conversation with the bot to order flowers:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/OrderFlowers-NoLambda.png)

   From this input, the bot infers the `OrderFlowers` intent and prompts for slot data. When you provide all of the required slot data, the bot fulfills the intent (`OrderFlowers`) by returning all of the information to the client application (in this case, the console). The console shows the information in the test window.

   Specifically:
   + In the statement "What day do you want the roses to be picked up?,"the term "roses" appears because the prompt for the `pickupDate` slot is configured using substitutions, `{FlowerType}`. Verify this in the console.
   + The "Okay, your roses will be ready..." statement is the confirmation prompt that you configured. 
   + The last statement ("`FlowerType:roses...`") is just the slot data that is returned to the client, in this case, in the test window. In the next exercise, you use a Lambda function to fulfill the intent, in which case you get a message indicating that the order is fulfilled.

**Next Step**  
[Step 2 (Optional): Review the Details of Information Flow (Console)](gs-bp-details-two-runtime-apis.md)

# Step 2 (Optional): Review the Details of Information Flow (Console)
<a name="gs-bp-details-two-runtime-apis"></a>

This section explains the flow of information between a client and Amazon Lex for each user input in our example conversation. 

The example uses the console test window for the conversation with the bot.

**To open the Amazon Lex test window**

1. Sign in to the AWS Management Console and open the Amazon Lex console at [https://console.aws.amazon.com/lex/](https://console.aws.amazon.com/lex/).

1. Choose the bot to test.

1. From the right side of the console, choose **Test chatbot**.

To see the flow of information for spoken or typed content, choose the appropriate topic. 

**Topics**
+ [Step 2a (Optional): Review the Details of the Spoken Information Flow (Console)](gs-bp-details-postcontent-flow.md)
+ [Step 2b (Optional): Review the Details of the Typed Information Flow (Console)](gs-bp-details-part1.md)

# Step 2a (Optional): Review the Details of the Spoken Information Flow (Console)
<a name="gs-bp-details-postcontent-flow"></a>

This section explains the flow of information between the client and Amazon Lex when the client uses speech to send requests. For more information, see [PostContent](API_runtime_PostContent.md). 

1. The user says: I would like to order some flowers.

   1. The client (console) sends the following [PostContent](API_runtime_PostContent.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/content HTTP/1.1
      x-amz-lex-session-attributes: "e30=" 
      Content-Type: "audio/x-l16; sample-rate=16000; channel-count=1"
      Accept: "audio/mpeg"
      
      
      Request body
      input stream
      ```

      Both the request URI and the body provide information to Amazon Lex:
      + Request URI – Provides the bot name (`OrderFlowers`), bot alias (`$LATEST`), and the user name (a random string that identifies the user). `content` indicates that this is a `PostContent` API request (not a `PostText` request).
      + Request headers
        + `x-amz-lex-session-attributes` – The base64-encoded value represents "\$1\$1". When the client makes the first request, there are no session attributes. 
        + `Content-Type` – Reflects the audio format.
      + Request body – The user input audio stream ("I would like to order some flowers.").
**Note**  
If the user chooses to send text ("I would like to order some flowers") to the `PostContent` API instead of speaking, the request body is the user input. The `Content-Type` header is set accordingly:  

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/content HTTP/1.1
      x-amz-lex-session-attributes: "e30="
      Content-Type: "text/plain; charset=utf-8"
      Accept: accept
      
      Request body
      input stream
      ```

   1. From the input stream, Amazon Lex detects the intent (`OrderFlowers`). It then chooses one of the intent's slots (in this case, the `FlowerType`) and one of its value elicitation prompts, and then sends a response with the following headers: 

      ```
      x-amz-lex-dialog-state:ElicitSlot
      x-amz-lex-input-transcript:I would like to order some flowers.
      x-amz-lex-intent-name:OrderFlowers
      x-amz-lex-message:What type of flowers would you like to order?
      x-amz-lex-session-attributes:e30=
      x-amz-lex-slot-to-elicit:FlowerType
      x-amz-lex-slots:eyJQaWNrdXBUaW1lIjpudWxsLCJGbG93ZXJUeXBlIjpudWxsLCJQaWNrdXBEYXRlIjpudWxsfQ==
      ```

      The header values provide the following information:
      + `x-amz-lex-input-transcript` – Provides the transcript of the audio (user input) from the request
      + `x-amz-lex-message` – Provides the transcript of the audio Amazon Lex returned in the response
      + `x-amz-lex-slots` – The base64 encoded version of the slots and values:

        ```
        {"PickupTime":null,"FlowerType":null,"PickupDate":null}
        ```
      + `x-amz-lex-session-attributes` – The base64-encoded version of the session attributes (\$1\$1)

      The client plays the audio in the response body.

1. The user says: roses

   1. The client (console) sends the following [PostContent](API_runtime_PostContent.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/content HTTP/1.1
      x-amz-lex-session-attributes: "e30="
      Content-Type: "audio/x-l16; sample-rate=16000; channel-count=1" 
      Accept: "audio/mpeg"
      
      
      Request body
      input stream ("roses")
      ```

      The request body is the user input audio stream (roses). The `sessionAttributes` remains empty.

   1. Amazon Lex interprets the input stream in the context of the current intent (it remembers that it had asked this user for information pertaining to the `FlowerType` slot). Amazon Lex first updates the slot value for the current intent. It then chooses another slot (`PickupDate`), along with one of its prompt messages (When do you want to pick up the roses?), and returns a response with the following headers:

      ```
      x-amz-lex-dialog-state:ElicitSlot
      x-amz-lex-input-transcript:roses
      x-amz-lex-intent-name:OrderFlowers
      x-amz-lex-message:When do you want to pick up the roses?
      x-amz-lex-session-attributes:e30=
      x-amz-lex-slot-to-elicit:PickupDate
      x-amz-lex-slots:eyJQaWNrdXBUaW1lIjpudWxsLCJGbG93ZXJUeXBlIjoicm9zaSdzIiwiUGlja3VwRGF0ZSI6bnVsbH0=
      ```

      The header values provide the following information:
      + `x-amz-lex-slots` – The base64-encoded version of the slots and values:

        ```
        {"PickupTime":null,"FlowerType":"roses","PickupDate":null}
        ```
      + `x-amz-lex-session-attributes` – The base64-encoded version of the session attributes (\$1\$1)

      The client plays the audio in the response body.

1. The user says: tomorrow

   1. The client (console) sends the following [PostContent](API_runtime_PostContent.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/content HTTP/1.1
      x-amz-lex-session-attributes: "e30="
      Content-Type: "audio/x-l16; sample-rate=16000; channel-count=1"
      Accept: "audio/mpeg"
      
      
      Request body
      input stream ("tomorrow")
      ```

      The request body is the user input audio stream ("tomorrow").The `sessionAttributes` remains empty.

   1. Amazon Lex interprets the input stream in the context of the current intent (it remembers that it had asked this user for information pertaining to the `PickupDate` slot). Amazon Lex updates the slot (`PickupDate`) value for the current intent. It then chooses another slot to elicit value for (`PickupTime`) and one of the value elicitation prompts (When do you want to pick up the roses on 2017-03-18?), and returns a response with the following headers:

      ```
      x-amz-lex-dialog-state:ElicitSlot
      x-amz-lex-input-transcript:tomorrow
      x-amz-lex-intent-name:OrderFlowers
      x-amz-lex-message:When do you want to pick up the roses on 2017-03-18?
      x-amz-lex-session-attributes:e30=
      x-amz-lex-slot-to-elicit:PickupTime
      x-amz-lex-slots:eyJQaWNrdXBUaW1lIjpudWxsLCJGbG93ZXJUeXBlIjoicm9zaSdzIiwiUGlja3VwRGF0ZSI6IjIwMTctMDMtMTgifQ==
      x-amzn-RequestId:3a205b70-0b69-11e7-b447-eb69face3e6f
      ```

      The header values provide the following information:
      + `x-amz-lex-slots` – The base64-encoded version of the slots and values:

        ```
        {"PickupTime":null,"FlowerType":"roses","PickupDate":"2017-03-18"}
        ```
      + `x-amz-lex-session-attributes` – The base64-encoded version of the session attributes (\$1\$1)

      The client plays the audio in the response body.

1. The user says: 6 pm

   1. The client (console) sends the following [PostContent](API_runtime_PostContent.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/content HTTP/1.1
      x-amz-lex-session-attributes: "e30="
      Content-Type: "text/plain; charset=utf-8"
      Accept: "audio/mpeg"
      
      
      Request body
      input stream ("6 pm")
      ```

      The request body is the user input audio stream ("6 pm"). The `sessionAttributes` remains empty.

   1. Amazon Lex interprets the input stream in the context of the current intent (it remembers that it had asked this user for information pertaining to the `PickupTime` slot). It first updates the slot value for the current intent. 

      Now Amazon Lex detects that it has information for all of the slots. However, the `OrderFlowers` intent is configured with a confirmation message. Therefore, Amazon Lex needs an explicit confirmation from the user before it can proceed to fulfill the intent. It sends a response with the following headers requesting confirmation before ordering the flowers:

      ```
      x-amz-lex-dialog-state:ConfirmIntent
      x-amz-lex-input-transcript:six p. m.
      x-amz-lex-intent-name:OrderFlowers
      x-amz-lex-message:Okay, your roses will be ready for pickup by 18:00 on 2017-03-18.  Does this sound okay?
      x-amz-lex-session-attributes:e30=
      x-amz-lex-slots:eyJQaWNrdXBUaW1lIjoiMTg6MDAiLCJGbG93ZXJUeXBlIjoicm9zaSdzIiwiUGlja3VwRGF0ZSI6IjIwMTctMDMtMTgifQ==
      x-amzn-RequestId:083ca360-0b6a-11e7-b447-eb69face3e6f
      ```

      The header values provide the following information:
      + `x-amz-lex-slots` – The base64-encoded version of the slots and values:

        ```
        {"PickupTime":"18:00","FlowerType":"roses","PickupDate":"2017-03-18"}
        ```
      + `x-amz-lex-session-attributes` – The base64-encoded version of the session attributes (\$1\$1)

      The client plays the audio in the response body.

1. The user says: Yes

   1. The client (console) sends the following [PostContent](API_runtime_PostContent.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/content HTTP/1.1
      x-amz-lex-session-attributes: "e30="
      Content-Type: "audio/x-l16; sample-rate=16000; channel-count=1"
      Accept: "audio/mpeg"
      
      
      Request body
      input stream ("Yes")
      ```

      The request body is the user input audio stream ("Yes"). The `sessionAttributes` remains empty.

   1. Amazon Lex interprets the input stream and understands that the user want to proceed with the order. The `OrderFlowers` intent is configured with `ReturnIntent` as the fulfillment activity. This directs Amazon Lex to return all of the intent data to the client. Amazon Lex returns a response with following: 

      

      ```
      x-amz-lex-dialog-state:ReadyForFulfillment
      x-amz-lex-input-transcript:yes
      x-amz-lex-intent-name:OrderFlowers
      x-amz-lex-session-attributes:e30=
      x-amz-lex-slots:eyJQaWNrdXBUaW1lIjoiMTg6MDAiLCJGbG93ZXJUeXBlIjoicm9zaSdzIiwiUGlja3VwRGF0ZSI6IjIwMTctMDMtMTgifQ==
      ```

      The`x-amz-lex-dialog-state` response header is set to `ReadyForFulfillment`. The client can then fulfill the intent.

1. Now, retest the bot. To establish a new (user) context, choose the **Clear** link in the console. Provide data for the `OrderFlowers` intent, and include some invalid data. For example: 
   + Jasmine as the flower type (it is not one of the supported flower types)
   + Yesterday as the day when you want to pick up the flowers

   Notice that the bot accepts these values because you don't have any code to initialize and validate the user data. In the next section, you add a Lambda function to do this. Note the following about the Lambda function:
   + It validates slot data after every user input. It fulfills the intent at the end. That is, the bot processes the flower order and returns a message to the user instead of simply returning slot data to the client. For more information, see [Using Lambda Functions](using-lambda.md).
   + It also sets the session attributes. For more information about session attributes, see [PostText](API_runtime_PostText.md). 

      After you complete the Getting Started section, you can do the additional exercises ([Additional Examples: Creating Amazon Lex Bots](additional-exercises.md) ). [Book Trip](ex-book-trip.md) uses session attributes to share cross-intent information to engage in a dynamic conversation with the user.

**Next Step**  
[Step 3: Create a Lambda Function (Console)](gs-bp-create-lambda-function.md)

# Step 2b (Optional): Review the Details of the Typed Information Flow (Console)
<a name="gs-bp-details-part1"></a>

This section explains flow of information between client and Amazon Lex in which the client uses the `PostText` API to send requests. For more information, see [PostText](API_runtime_PostText.md). 

1. User types: I would like to order some flowers

   1. The client (console) sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "I would like to order some flowers",
          "sessionAttributes": {}
      }
      ```

      Both the request URI and the body provide information to Amazon Lex:
      + Request URI – Provides bot name (`OrderFlowers`), bot alias (`$LATEST`), and user name (a random string identifying the user). The trailing `text` indicates that it is a `PostText` API request (and not `PostContent`).

         
      + Request body – Includes the user input (`inputText`) and empty `sessionAttributes`. When the client makes the first request, there are no session attributes. The Lambda function initiates them later.

   1. From the `inputText`, Amazon Lex detects the intent (`OrderFlowers`). This intent does not have any code hooks (that is, the Lambda functions) for initialization and validation of user input or fulfillment. 

      Amazon Lex chooses one of the intent's slots (`FlowerType`) to elicit the value. It also selects one of the value-elicitation prompts for the slot (all part of the intent configuration), and then sends the following response back to the client. The console displays the message in the response to the user.  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-10.png)

      The client displays the message in the response.

1. User types: roses

   1. The client (console) sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "roses",
          "sessionAttributes": {}
      }
      ```

      The `inputText` in the request body provides user input. The `sessionAttributes` remains empty.

   1. Amazon Lex first interprets the `inputText` in the context of the current intent—the service remembers that it had asked the specific user for information about the `FlowerType` slot. Amazon Lex first updates the slot value for the current intent and chooses another slot (`PickupDate`) along with one of its prompt messages—What day do you want the roses to be picked up?—`` for the slot.

      Then, Amazon Lex returns the following response:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-20.png)

      The client displays the message in the response.

1. User types: tomorrow

   1. The client (console) sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "tomorrow",
          "sessionAttributes": {}
      }
      ```

      The `inputText` in the request body provides user input. The `sessionAttributes` remains empty.

   1. Amazon Lex first interprets the `inputText` in the context of the current intent—the service remembers that it had asked the specific user for information about the `PickupDate` slot. Amazon Lex updates the slot (`PickupDate`) value for the current intent. It chooses another slot to elicit value for (`PickupTime`). It returns one of the value-elicitation prompts—Deliver the roses at what time on 2017-01-05?—``to the client.

      Amazon Lex then returns the following response:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-30.png)

      The client displays the message in the response.

1. User types: 6 pm

   1. The client (console) sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "6 pm",
          "sessionAttributes": {}
      }
      ```

      The `inputText` in the request body provides user input. The `sessionAttributes` remains empty.

   1. Amazon Lex first interprets the `inputText` in the context of the current intent—the service remembers that it had asked the specific user for information about the `PickupTime` slot. Amazon Lex first updates the slot value for the current intent. Now Amazon Lex detects that it has information for all the slots. 

      The `OrderFlowers` intent is configured with a confirmation message. Therefore, Amazon Lex needs an explicit confirmation from the user before it can proceed to fulfill the intent. Amazon Lex sends the following message to the client requesting confirmation before ordering the flowers:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-40.png)

      The client displays the message in the response.

1. User types: Yes

   1. The client (console) sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/4o9wwdhx6nlheferh6a73fujd3118f5w/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "Yes",
          "sessionAttributes": {}
      }
      ```

      The `inputText` in the request body provides user input. The `sessionAttributes` remains empty.

   1. Amazon Lex interprets the `inputText` in the context of confirming the current intent. It understands that the user want to proceed with the order. The `OrderFlowers` intent is configured with `ReturnIntent` as the fulfillment activity (there is no Lambda function to fulfill the intent). Therefore, Amazon Lex returns the following slot data to the client.   
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-50.png)

      Amazon Lex set the `dialogState` to `ReadyForFulfillment`. The client can then fulfill the intent.

1. Now test the bot again. To do that, you must choose the **Clear** link in the console to establish a new (user) context. Now as you provide data for the order flowers intent, try to provide invalid data. For example: 
   + Jasmine as the flower type (it is not one of the supported flower types).
   + Yesterday as the day when you want to pick up the flowers.

   Notice that the bot accepts these values because you don't have any code to initialize/validate user data. In the next section, you add a Lambda function to do this. Note the following about the Lambda function:
   + The Lambda function validates slot data after every user input. It fulfills the intent at the end. That is, the bot processes the flowers order and returns a message to the user instead of simply returning slot data to the client. For more information, see [Using Lambda Functions](using-lambda.md).
   + The Lambda function also sets the session attributes. For more information about session attributes, see [PostText](API_runtime_PostText.md). 

      After you complete the Getting Started section, you can do the additional exercises ([Additional Examples: Creating Amazon Lex Bots](additional-exercises.md) ). [Book Trip](ex-book-trip.md) uses session attributes to share cross-intent information to engage in a dynamic conversation with the user.

**Next Step**  
[Step 3: Create a Lambda Function (Console)](gs-bp-create-lambda-function.md)

# Step 3: Create a Lambda Function (Console)
<a name="gs-bp-create-lambda-function"></a>

Create a Lambda function (using the **lex-order-flowers-python** blueprint) and perform test invocation using sample event data in the AWS Lambda console. 

You return to the Amazon Lex console and add the Lambda function as the code hook to fulfill the `OrderFlowers` intent in the `OrderFlowersBot` that you created in the preceding section.

**To create the Lambda function (console)**

1. Sign in to the AWS Management Console and open the AWS Lambda console at [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Choose **Create function**.

1. On the **Create function** page, choose **Use a blueprint**. Type **lex-** in the filter text box and then press `Enter` to find the blueprint, choose the `lex-order-flowers-python` blueprint. 

   Lambda function blueprints are provided in both Node.js and Python. For this exercise, use the Python-based blueprint.

1. On the **Basic information** page, do the following. 
   + Type a Lambda function name (`OrderFlowersCodeHook`).
   + For the execution role, choose **Create a new role with basic Lambda permissions**.
   + Leave the other default values.

1. Choose **Create function**.

1. If you are using a locale other than English (US) (en-US), update the intent names as described in [Updating a Blueprint for a Specific Locale](lex-lambda-blueprints.md#blueprint-update-locale).

1. Test the Lambda function.

   1. Choose **Select a test event**, **Configure test events**.

   1. Choose **Amazon Lex Order Flowers** from the **Event template** list. This sample event matches the Amazon Lex request/response model (see [Using Lambda Functions](using-lambda.md)). Give the test event a name (`LexOrderFlowersTest`).

   1. Choose **Create**.

   1. Choose **Test** to test the code hook.

   1. Verify that the Lambda function ran successfully. The response in this case matches the Amazon Lex response model.

**Next Step**  
[Step 4: Add the Lambda Function as Code Hook (Console)](gs-bp-create-integrate.md)

# Step 4: Add the Lambda Function as Code Hook (Console)
<a name="gs-bp-create-integrate"></a>

In this section, you update the configuration of the OrderFlowers intent to use the Lambda function as follows:
+ First use the Lambda function as a code hook to perform fulfillment of the `OrderFlowers` intent. You test the bot and verify that you received a fulfillment message from the Lambda function. Amazon Lex invokes the Lambda function only after you provide data for all the required slots for ordering flowers.
+ Configure the same Lambda function as a code hook to perform initialization and validation. You test and verify that the Lambda function performs validation (as you provide slot data).

**To add a Lambda function as a code hook (console)**

1. In the Amazon Lex console, select the **OrderFlowers** bot. The console shows the **OrderFlowers** intent. Make sure that the intent version is set to `$LATEST` because this is the only version that we can modify.

1. Add the Lambda function as the fulfillment code hook and test it.

   

   1. In the Editor, choose **AWS Lambda function** as **Fulfillment**, and select the Lambda function that you created in the preceding step (`OrderFlowersCodeHook`). Choose **OK** to give Amazon Lex permission to invoke the Lambda function.

      You are configuring this Lambda function as a code hook to fulfill the intent. Amazon Lex invokes this function only after it has all the necessary slot data from the user to fulfill the intent.

   1. Specify a **Goodbye message**.

   1. Choose **Build**.

   1. Test the bot using the previous conversation.

   The last statement "Thanks, your order for roses....." is a response from the Lambda function that you configured as a code hook. In the preceding section, there was no Lambda function. Now you are using a Lambda function to actually fulfill the `OrderFlowers` intent.

1. Add the Lambda function as an initialization and validation code hook, and test.

   The sample Lambda function code that you are using can both perform user input validation and fulfillment. The input event the Lambda function receives has a field (`invocationSource`) that the code uses to determine what portion of the code to run. For more information, see [Lambda Function Input Event and Response Format](lambda-input-response-format.md).

   1. Select the \$1LATEST version of the `OrderFlowers` intent. That's is the only version that you can update. 

   1. In the Editor, choose **Initialization and validation** in **Options**. 

   1. Again, select the same Lambda function. 

   1. Choose **Build**.

   1. Test the bot. 

      You are now ready to converse with Amazon Lex as in the following image. To test the validation portion, choose time 6 PM, and your Lambda function returns a response ("Our business hours are from 10 AM to 5 PM."), and prompts you again. After you provide all the valid slot data, the Lambda function fulfills the order.   
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/OrderFlowers-FullLambda.png)

**Next Step**  
[Step 5 (Optional): Review the Details of the Information Flow (Console)](gs-bp-details-after-lambda.md)

# Step 5 (Optional): Review the Details of the Information Flow (Console)
<a name="gs-bp-details-after-lambda"></a>

This section explains the flow of information between the client and Amazon Lex for each user input, including the integration of the Lambda function.

**Note**  
The section assumes that the client sends requests to Amazon Lex using the `PostText` runtime API and shows request and response details accordingly. For an example of the information flow between the client and Amazon Lex in which client uses the `PostContent` API, see [Step 2a (Optional): Review the Details of the Spoken Information Flow (Console)](gs-bp-details-postcontent-flow.md).

For more information about the `PostText` runtime API and additional details on the requests and responses shown in the following steps, see [PostText](API_runtime_PostText.md). 

1. User: I would like to order some flowers.

   1. The client (console) sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/ignw84y6seypre4xly5rimopuri2xwnd/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "I would like to order some flowers",
          "sessionAttributes": {}
      }
      ```

      Both the request URI and the body provide information to Amazon Lex:
      + Request URI – Provides bot name (`OrderFlowers`), bot alias (`$LATEST`), and user name (a random string identifying the user). The trailing `text` indicates that it is a `PostText` API request (and not `PostContent`).
      + Request body – Includes the user input (`inputText`) and empty `sessionAttributes`. When the client makes the first request, there are no session attributes. The Lambda function initiates them later.

   1. From the `inputText`, Amazon Lex detects the intent (`OrderFlowers`). This intent is configured with a Lambda function as a code hook for user data initialization and validation. Therefore, Amazon Lex invokes that Lambda function by passing the following information as event data:

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "DialogCodeHook",
          "userId": "ignw84y6seypre4xly5rimopuri2xwnd",
          "sessionAttributes": {},
          "bot": {
              "name": "OrderFlowers",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "OrderFlowers",
              "slots": {
                  "PickupTime": null,
                  "FlowerType": null,
                  "PickupDate": null
              },
              "confirmationStatus": "None"
          }
      }
      ```

      For more information, see [Input Event Format](lambda-input-response-format.md#using-lambda-input-event-format).

      In addition to the information that the client sent, Amazon Lex also includes the following additional data:
      + `messageVersion` – Currently Amazon Lex supports only the 1.0 version.
      + `invocationSource` – Indicates the purpose of Lambda function invocation. In this case, it is to perform user data initialization and validation. At this time, Amazon Lex knows that the user has not provided all the slot data to fulfill the intent.
      + `currentIntent` information with all of the slot values set to null.

   1. At this time, all the slot values are null. There is nothing for the Lambda function to validate. The Lambda function returns the following response to Amazon Lex:

      ```
      {
          "sessionAttributes": {},
          "dialogAction": {
              "type": "Delegate",
              "slots": {
                  "PickupTime": null,
                  "FlowerType": null,
                  "PickupDate": null
              }
          }
      }
      ```

      For information about the response format, see [Response Format](lambda-input-response-format.md#using-lambda-response-format).

      Note the following:
      + `dialogAction.type` – By setting this value to `Delegate`, Lambda function delegates the responsibility of deciding the next course of action to Amazon Lex. 
**Note**  
If Lambda function detects anything in the user data validation, it instructs Amazon Lex what to do next, as shown in the next few steps.

   1. According to the `dialogAction.type`, Amazon Lex decides the next course of action. Because none of the slots are filled, it decides to elicit the value for the `FlowerType` slot. It selects one of the value elicitation prompts ("What type of flowers would you like to order?") for this slot and sends the following response back to the client:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-10.png)

      The client displays the message in the response.

1. User: roses

   1. The client sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/ignw84y6seypre4xly5rimopuri2xwnd/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "roses",
          "sessionAttributes": {}
      }
      ```

      In the request body, the `inputText` provides user input. The `sessionAttributes` remains empty.

   1. Amazon Lex first interprets the `inputText` in the context of the current intent. The service remembers that it had asked the specific user for information about the `FlowerType` slot. It updates the slot value in the current intent and invokes the Lambda function with the following event data:

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "DialogCodeHook",
          "userId": "ignw84y6seypre4xly5rimopuri2xwnd",
          "sessionAttributes": {},
          "bot": {
              "name": "OrderFlowers",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "OrderFlowers",
              "slots": {
                  "PickupTime": null,
                  "FlowerType": "roses",
                  "PickupDate": null
              },
              "confirmationStatus": "None"
          }
      }
      ```

      Note the following:
      + `invocationSource` – continues to be `DialogCodeHook` (we are simply validating user data). 
      + `currentIntent.slots` – Amazon Lex has updated the `FlowerType` slot to roses.

   1. According to the `invocationSource` value of `DialogCodeHook`, the Lambda function performs user data validation. It recognizes `roses` as a valid slot value (and sets `Price` as a session attribute) and returns the following response to Amazon Lex. 

      ```
      {
          "sessionAttributes": {
              "Price": 25
          },
          "dialogAction": {
              "type": "Delegate",
              "slots": {
                  "PickupTime": null,
                  "FlowerType": "roses",
                  "PickupDate": null
              }
          }
      }
      ```

      Note the following:
      + `sessionAttributes` – Lambda function has added `Price` (of the roses) as a session attribute.
      + `dialogAction.type` – is set to `Delegate`. The user data was valid so the Lambda function directs Amazon Lex to choose the next course of action.

       

   1. According to the `dialogAction.type`, Amazon Lex chooses the next course of action. Amazon Lex knows it needs more slot data so it picks the next unfilled slot (`PickupDate`) with the highest priority according to the intent configuration. Amazon Lex selects one of the value-elicitation prompt messages—"What day do you want the roses to be picked up?"—for this slot according to the intent configuration, and then sends the following response back to the client:   
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-20.png)

      The client simply displays the message in the response – "What day do you want the roses to be picked up?."

1. User: tomorrow

   1. The client sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/ignw84y6seypre4xly5rimopuri2xwnd/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "tomorrow",
          "sessionAttributes": {
              "Price": "25"
          }
      }
      ```

      In the request body, `inputText` provides user input and the client passes the session attributes back to the service.

   1. Amazon Lex remembers the context—that it was eliciting data for the `PickupDate` slot. In this context, it knows the `inputText` value is for the `PickupDate` slot. Amazon Lex then invokes the Lambda function by sending the following event: 

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "DialogCodeHook",
          "userId": "ignw84y6seypre4xly5rimopuri2xwnd",
          "sessionAttributes": {
              "Price": "25"
          },
          "bot": {
              "name": "OrderFlowersCustomWithRespCard",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "OrderFlowers",
              "slots": {
                  "PickupTime": null,
                  "FlowerType": "roses",
                  "PickupDate": "2017-01-05"
              },
              "confirmationStatus": "None"
          }
      }
      ```

      Amazon Lex has updated the `currentIntent.slots` by setting the `PickupDate` value. Also note that the service passes the `sessionAttributes` as it is to the Lambda function.

   1. As per `invocationSource` value of `DialogCodeHook`, the Lambda function performs user data validation. It recognizes `PickupDate` slot value is valid and returns the following response to Amazon Lex: 

      ```
      {
          "sessionAttributes": {
              "Price": 25
          },
          "dialogAction": {
              "type": "Delegate",
              "slots": {
                  "PickupTime": null,
                  "FlowerType": "roses",
                  "PickupDate": "2017-01-05"
              }
          }
      }
      ```

      Note the following:
      + `sessionAttributes` – No change.
      + `dialogAction.type` – is set to `Delegate`. The user data was valid, and the Lambda function directs Amazon Lex to choose the next course of action.

   1. According to the `dialogAction.type`, Amazon Lex chooses the next course of action. Amazon Lex knows it needs more slot data so it picks the next unfilled slot (`PickupTime`) with the highest priority according to the intent configuration. Amazon Lex selects one of the prompt messages ("Deliver the roses at what time on 2017-01-05?") for this slot according to the intent configuration and sends the following response back to the client:   
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-30.png)

      The client displays the message in the response – "Deliver the roses at what time on 2017-01-05?"

1. User: 4 pm

   1. The client sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/ignw84y6seypre4xly5rimopuri2xwnd/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "4 pm",
          "sessionAttributes": {
              "Price": "25"
          }
      }
      ```

      In the request body, `inputText` provides user input. The client passes the `sessionAttributes` in the request.

   1. Amazon Lex understands context. It understands that it was eliciting data for the `PickupTime` slot. In this context, it knows that the `inputText` value is for the `PickupTime` slot. Amazon Lex then invokes the Lambda function by sending the following event: 

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "DialogCodeHook",
          "userId": "ignw84y6seypre4xly5rimopuri2xwnd",
          "sessionAttributes": {
              "Price": "25"
          },
          "bot": {
              "name": "OrderFlowersCustomWithRespCard",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "OrderFlowers",
              "slots": {
                  "PickupTime": "16:00",
                  "FlowerType": "roses",
                  "PickupDate": "2017-01-05"
              },
              "confirmationStatus": "None"
          }
      }
      ```

      Amazon Lex has updated the `currentIntent.slots` by setting the `PickupTime` value.

   1. According to the `invocationSource` value of `DialogCodeHook`, the Lambda function performs user data validation. It recognizes `PickupDate` slot value is valid and returns the following response to Amazon Lex. 

      ```
      {
          "sessionAttributes": {
              "Price": 25
          },
          "dialogAction": {
              "type": "Delegate",
              "slots": {
                  "PickupTime": "16:00",
                  "FlowerType": "roses",
                  "PickupDate": "2017-01-05"
              }
          }
      }
      ```

      Note the following:
      + `sessionAttributes` – No change in session attribute.
      + `dialogAction.type` – is set to `Delegate`. The user data was valid so the Lambda function directs Amazon Lex to choose the next course of action.

   1. At this time Amazon Lex knows it has all the slot data. This intent is configured with a confirmation prompt. Therefore, Amazon Lex sends the following response to the user asking for confirmation before fulfilling the intent:   
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-45.png)

      The client simply displays the message in the response and waits for the user response.

1. User: Yes

   1. The client sends the following [PostText](API_runtime_PostText.md) request to Amazon Lex: 

      ```
      POST /bot/OrderFlowers/alias/$LATEST/user/ignw84y6seypre4xly5rimopuri2xwnd/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
          "inputText": "yes",
          "sessionAttributes": {
              "Price": "25"
          }
      }
      ```

   1. Amazon Lex interprets the `inputText` in the context of confirming the current intent. Amazon Lex understands that the user wants to proceed with the order. This time Amazon Lex invokes the Lambda function to fulfill the intent by sending the following event, which sets the `invocationSource` to `FulfillmentCodeHook` in the event it sends to the Lambda function. Amazon Lex also sets the `confirmationStatus` to `Confirmed`.

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "FulfillmentCodeHook",
          "userId": "ignw84y6seypre4xly5rimopuri2xwnd",
          "sessionAttributes": {
              "Price": "25"
          },
          "bot": {
              "name": "OrderFlowersCustomWithRespCard",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "OrderFlowers",
              "slots": {
                  "PickupTime": "16:00",
                  "FlowerType": "roses",
                  "PickupDate": "2017-01-05"
              },
              "confirmationStatus": "Confirmed"
          }
      }
      ```

      Note the following:
      + `invocationSource` – This time Amazon Lex set this value to `FulfillmentCodeHook`, directing the Lambda function to fulfill the intent.
      + `confirmationStatus` – is set to `Confirmed`.

   1. This time, the Lambda function fulfills the `OrderFlowers` intent, and returns the following response:

      ```
      {
          "sessionAttributes": {
              "Price": "25"
          },
          "dialogAction": {
              "type": "Close",
              "fulfillmentState": "Fulfilled",
              "message": {
                  "contentType": "PlainText",
                  "content": "Thanks, your order for roses has been placed and will be ready for pickup by 16:00 on 2017-01-05"
              }
          }
      }
      ```

      Note the following: 
      + Sets the `dialogAction.type` – The Lambda function sets this value to `Close`, directing Amazon Lex to not expect a user response. 
      + `dialogAction.fulfillmentState` – is set to Fulfilled and includes an appropriate `message` to convey to the user.

   1. Amazon Lex reviews the `fulfillmentState` and sends the following response back to the client. 

      Amazon Lex then returns the following to the client:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs-1-details-48.png)

      Note that:
      + `dialogState` – Amazon Lex sets this value to `fulfilled`.
      + `message` – is the same message that the Lambda function provided.

      The client displays the message.

1. Now test the bot again. To establish a new (user) context, choose the **Clear** link in the test window. Now provide invalid slot data for the `OrderFlowers` intent. This time the Lambda function performs the data validation, resets invalid slot data value to null, and asks Amazon Lex to prompt the user for valid data. For example, try the following:
   + Jasmine as the flower type (it is not one of the supported flower types).
   + Yesterday as the day when you want to pick up the flowers.
   + After placing your order, enter another flower type instead of replying "yes" to confirm the order. In response, the Lambda function updates the `Price` in the session attribute, keeping a running total of flower orders.

   The Lambda function also performs the fulfillment activity. 

**Next Step**  
[Step 6: Update the Intent Configuration to Add an Utterance (Console)](gs-bp-utterance.md)

# Step 6: Update the Intent Configuration to Add an Utterance (Console)
<a name="gs-bp-utterance"></a>

 The `OrderFlowers` bot is configured with only two utterances. This provides limited information for Amazon Lex to build a machine learning model that recognizes and responds to the user's intent. Try typing "I want to order flowers", as in the following test window. Amazon Lex doesn’t recognize the text, and responds with "I didn't understand you, what would you like to do?" You can improve the machine learning model by adding more utterances.

![\[Test window shows missed utterance.\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-120.png)


Each utterance that you add provides Amazon Lex with more information about how to respond to your users. You don't need to add an exact utterance, Amazon Lex generalizes from the samples that you provide to recognize both exact matches and similar input.

**To add an utterance (console)**

1. Add the utterance "I want flowers" to the intent by typing it in the **Sample utterances** section of the intent editor, as in the following image, and then clicking the plus icon next to the new utterance.  
![\[Intent editor with the new utterance.\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-130.png)

1.  Build your bot to pick up the change. Choose **Build**, and then choose **Build** again. 

1. Test your bot to confirm that it recognized the new utterance. In the test window, as in the following image, type "I want to order flowers." Amazon Lex recognizes the phrase and responds with "What type of flowers would you like to order?".  
![\[The intent editor recognizes the new utterance.\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-140.png)

**Next Step**  
[Step 7 (Optional): Clean Up (Console)](gs-bp-cleaning-up.md)

# Step 7 (Optional): Clean Up (Console)
<a name="gs-bp-cleaning-up"></a>

Now, delete the resources that you created and clean up your account.

You can delete only resources that are not in use. In general, you should delete resources in the following order:
+ Delete bots to free up intent resources.
+ Delete intents to free up slot type resources.
+ Delete slot types last.

**To clean up your account (console)**

1. Sign in to the AWS Management Console and open the Amazon Lex console at [https://console.aws.amazon.com/lex/](https://console.aws.amazon.com/lex/).

1. From the list of bots, choose the check box next to **OrderFlowers**.

1. To delete the bot, choose **Delete**, and then choose **Continue** in the confirmation dialog box.

1. In the left pane, choose **Intents**.

1. In the list of intents, choose **OrderFlowersIntent**.

1. To delete the intent, choose **Delete**, and then choose **Continue** in the confirmation dialog box.

1. In the left pane, choose **Slot types**.

1. In the list of slot types, choose **Flowers**.

1. To delete the slot type, choose **Delete**, and then choose **Continue** in the confirmation dialog box.

You have removed all of the Amazon Lex resources that you created and cleaned up your account. If desired, you can use the [Lambda console](https://console.aws.amazon.com/lambda) to delete the Lambda function used in this exercise.

# Exercise 2: Create a Custom Amazon Lex Bot
<a name="getting-started-ex2"></a>

In this exercise, you use the Amazon Lex console to create a custom bot that orders pizza (`OrderPizzaBot`). You configure the bot by adding a custom intent (`OrderPizza`), defining custom slot types, and defining the slots required to fulfill a pizza order (pizza crust, size, and so on). For more information about slot types and slots, see [Amazon Lex: How It Works](how-it-works.md).

**Topics**
+ [Step 1: Create a Lambda Function](gs2-prepare.md)
+ [Step 2: Create a Bot](gs2-create-bot.md)
+ [Step 3: Build and Test the Bot](gs2-build-and-test.md)
+ [Step 4 (Optional): Clean up](gs2-clean-up.md)

# Step 1: Create a Lambda Function
<a name="gs2-prepare"></a>

First, create a Lambda function which fulfills a pizza order. You specify this function in your Amazon Lex bot, which you create in the next section.

**To create a Lambda function**



1. Sign in to the AWS Management Console and open the AWS Lambda console at [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Choose **Create function**.

1. On the **Create function** page, choose **Author from scratch**. 

   Because you are using custom code provided to you in this exercise to create a Lambda function, you choose author the function from scratch.

   Do the following:

   1. Type the name (`PizzaOrderProcessor`).

   1. For the **Runtime**, choose the latest version of Node.js.

   1. For the **Role**, choose **Create new role from template(s)**.

   1. Enter a new role name (`PizzaOrderProcessorRole`).

   1. Choose **Create function**.

1. On the function page, do the following: 

   In the **Function code** section, choose **Edit code inline**, and then copy the following Node.js function code and paste it in the window. 

   ```
   'use strict';
        
   // Close dialog with the customer, reporting fulfillmentState of Failed or Fulfilled ("Thanks, your pizza will arrive in 20 minutes")
   function close(sessionAttributes, fulfillmentState, message) {
       return {
           sessionAttributes,
           dialogAction: {
               type: 'Close',
               fulfillmentState,
               message,
           },
       };
   }
    
   // --------------- Events -----------------------
    
   function dispatch(intentRequest, callback) {
       console.log(`request received for userId=${intentRequest.userId}, intentName=${intentRequest.currentIntent.name}`);
       const sessionAttributes = intentRequest.sessionAttributes;
       const slots = intentRequest.currentIntent.slots;
       const crust = slots.crust;
       const size = slots.size;
       const pizzaKind = slots.pizzaKind;
       
       callback(close(sessionAttributes, 'Fulfilled',
       {'contentType': 'PlainText', 'content': `Okay, I have ordered your ${size} ${pizzaKind} pizza on ${crust} crust`}));
       
   }
    
   // --------------- Main handler -----------------------
    
   // Route the incoming request based on intent.
   // The JSON body of the request is provided in the event slot.
   export const handler = (event, context, callback) => {
       try {
           dispatch(event,
               (response) => {
                   callback(null, response);
               });
       } catch (err) {
           callback(err);
       }
   };
   ```

1. Choose **Save**.

## Test the Lambda Function Using Sample Event Data
<a name="gs2-lambdafunction-test"></a>

In the console, test the Lambda function by using sample event data to manually invoke it. 

**To test the Lambda function:**

1. Sign in to the AWS Management Console and open the AWS Lambda console at [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. On the **Lambda function** page, choose the Lambda function (`PizzaOrderProcessor).`

1. On the function page, in the list of test events, choose **Configure test events**.

1. On the **Configure test event** page, do the following: 

   1. Choose **Create new test event**.

   1. In the **Event name** field, enter a name for the event (`PizzaOrderProcessorTest`).

   1. Copy the following Amazon Lex event into the window. 

      ```
      {
        "messageVersion": "1.0",
        "invocationSource": "FulfillmentCodeHook",
        "userId": "user-1",
        "sessionAttributes": {},
        "bot": {
          "name": "PizzaOrderingApp",
          "alias": "$LATEST",
          "version": "$LATEST"
        },
        "outputDialogMode": "Text",
        "currentIntent": {
          "name": "OrderPizza",
          "slots": {
            "size": "large",
            "pizzaKind": "meat",
            "crust": "thin"
          },
          "confirmationStatus": "None"
        }
      }
      ```

1. Choose **Create**.

AWS Lambda creates the test and you go back to the function page. Choose **Test** and Lambda runs your Lambda function.

In the result box, choose **Details**. The console displays the following output in the **Execution result** pane. 

```
{
  "sessionAttributes": {},
  "dialogAction": {
    "type": "Close",
    "fulfillmentState": "Fulfilled",
    "message": {
      "contentType": "PlainText",
      "content": "Okay, I have ordered your large meat pizza on thin crust."
    }
}
```

## Next Step
<a name="gs2-next-step-create-bot"></a>

[Step 2: Create a Bot](gs2-create-bot.md)

# Step 2: Create a Bot
<a name="gs2-create-bot"></a>

In this step, you create a bot to handle pizza orders. 

**Topics**
+ [Create the Bot](gs2-create-bot-create.md)
+ [Create an Intent](gs2-create-bot-intent.md)
+ [Create Slot Types](gs2-create-bot-slot-types.md)
+ [Configure the Intent](gs2-create-bot-configure-intent.md)
+ [Configure the Bot](gs2-create-bot-configure-bot.md)

# Create the Bot
<a name="gs2-create-bot-create"></a>

Create the `PizzaOrderingBot` bot with the minimum information needed. You add an intent, an action that the user wants to perform, for the bot later.

**To create the bot**

1. Sign in to the AWS Management Console and open the Amazon Lex console at [https://console.aws.amazon.com/lex/](https://console.aws.amazon.com/lex/).

1. Create a bot.

   1. If you are creating your first bot, choose **Get Started**. Otherwise, choose **Bots**, and then choose **Create**. 

   1. On the **Create your Lex bot** page, choose **Custom bot** and provide the following information:
      + **Bot name**: PizzaOrderingBot 
      + **Language**: Choose the language and locale for your bot.
      + **Output voice**: Salli 
      + **Session timeout **: 5 minutes.
      + **COPPA**: Choose the appropriate response.
      + **User utterance storage: Choose the appropriate response.**

   1. Choose **Create**. 

      The console sends Amazon Lex a request to create a new bot. Amazon Lex sets the bot version to `$LATEST`. After creating the bot, Amazon Lex shows the bot **Editor** tab, as in the following image:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-20.png)
      + The bot version, **Latest**, appears next to the bot name in the console. New Amazon Lex resources have `$LATEST` as the version. For more information, see [Versioning and Aliases](versioning-aliases.md).
      + Because you haven't created any intents or slots types, none are listed. 
      + **Build** and **Publish** are bot-level activities. After you configure the entire bot, you'll learn more about these activities.

## Next Step
<a name="gs2-next-step-intent"></a>

[Create an Intent](gs2-create-bot-intent.md)

# Create an Intent
<a name="gs2-create-bot-intent"></a>

Now, create the `OrderPizza` intent , an action that the user wants to perform, with the minimum information needed. You add slot types for the intent and then configure the intent later.

**To create an intent**

1. In the Amazon Lex console, choose the plus sign (\$1) next to **Intents**, and then choose **Create new intent**.

1. In the **Create intent** dialog box, type the name of the intent (`OrderPizza`), and then choose **Add**.

The console sends a request to Amazon Lex to create the `OrderPizza` intent. In this example you create slots for the intent after you create slot types.

## Next Step
<a name="gs2-next-step-slot-types"></a>

[Create Slot Types](gs2-create-bot-slot-types.md)

# Create Slot Types
<a name="gs2-create-bot-slot-types"></a>

Create the slot types, or parameter values, that the `OrderPizza` intent uses.

**To create slot types**

1. <a name="slotTypeStart"></a>In the left menu, choose the plus sign (\$1) next to **Slot types**.

1. In the **Add slot type** dialog box, add the following: 
   + **Slot type name** – Crusts
   + **Description** – Available crusts
   + Choose **Restrict to Slot values and Synonyms**
   + **Value** – Type **thick**. Press tab and in the **Synonym** field type **stuffed**. Choose the plus sign (\$1). Type **thin** and then choose the plus sign (\$1) again.

   The dialog should look like the following image:  
![\[The edit slot type dialog box.\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-25a.png)

1. Choose **Add slot to intent**.

1. <a name="slotTypeFinish"></a>On the **Intent** page, choose **Required**. Change the name of the slot from **slotOne** to **crust**. Change the prompt to **What kind of crust would you like?**

1. Repeat [Step 1](#slotTypeStart) through [Step 4](#slotTypeFinish) using the values in the following table:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lex/latest/dg/gs2-create-bot-slot-types.html)

## Next Step
<a name="gs2-next-step-configure-intent"></a>

[Configure the Intent](gs2-create-bot-configure-intent.md)

# Configure the Intent
<a name="gs2-create-bot-configure-intent"></a>

Configure the `OrderPizza` intent to fulfill a user's request to order a pizza.

**To configure an intent**
+ On the **OrderPizza** configuration page, configure the intent as follows:
  + **Sample utterances** – Type the following strings. The curly braces \$1\$1 enclose slot names.
    + I want to order pizza please 
    + I want to order a pizza
    + I want to order a \$1pizzaKind\$1 pizza
    + I want to order a \$1size\$1 \$1pizzaKind\$1 pizza 
    + I want a \$1size\$1 \$1crust\$1 crust \$1pizzaKind\$1 pizza
    + Can I get a pizza please
    + Can I get a \$1pizzaKind\$1 pizza
    + Can I get a \$1size\$1 \$1pizzaKind\$1 pizza
  + **Lambda initialization and validation** – Leave the default setting.
  + **Confirmation prompt** – Leave the default setting.
  + **Fulfillment** – Perform the following tasks:
    + Choose **AWS Lambda function**.
    + Choose **PizzaOrderProcessor**. 
    + If the **Add permission to Lambda function** dialog box is shown, choose **OK** to give the `OrderPizza` intent permission to call the `PizzaOrderProcessor` Lambda function.
    +  Leave **None** selected.

  The intent should look like the following:  
![\[The intent editor.\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-70c.png)

## Next Step
<a name="gs2-next-step-configure-bot"></a>

[Configure the Bot](gs2-create-bot-configure-bot.md)

# Configure the Bot
<a name="gs2-create-bot-configure-bot"></a>

Configure error handling for the `PizzaOrderingBot` bot.

1. Navigate to the `PizzaOrderingBot` bot. Choose **Editor**. and then choose **Error Handling**, as in the following image:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-80.png)

1. Use the **Editor** tab to configure bot error handling.
   + Information you provide in **Clarification Prompts** maps to the bot's [clarificationPrompt](https://docs.aws.amazon.com/lex/latest/dg/API_PutBot.html#lex-PutBot-request-clarificationPrompt) configuration. 

     When Amazon Lex can't determine the user intent, the service returns a response with this message. 
   + Information that you provide in the **Hang-up** phrase maps to the bot's [abortStatement](https://docs.aws.amazon.com/lex/latest/dg/API_PutBot.html#lex-PutBot-request-abortStatement) configuration. 

     If the service can't determine the user's intent after a set number of consecutive requests, Amazon Lex returns a response with this message.

   Leave the defaults.

## Next Step
<a name="gs2-next-step-build-and-test"></a>

[Step 3: Build and Test the Bot](gs2-build-and-test.md)

# Step 3: Build and Test the Bot
<a name="gs2-build-and-test"></a>

Make sure the bot works, by building and testing it. 

**To build and test the bot**

1. To build the `PizzaOrderingBot` bot, choose **Build**. 

   Amazon Lex builds a machine learning model for the bot. When you test the bot, the console uses the runtime API to send the user input back to Amazon Lex. Amazon Lex then uses the machine learning model to interpret the user input. 

   It can take some time to complete the build. 

1. To test the bot, in the **Test Bot** window, start communicating with your Amazon Lex bot. 
   + For example, you might say or type the following:  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-110.png)
   + Use the sample utterances that you configured in the `OrderPizza` intent to test the bot. For example, the following is one of the sample utterances that you configured for the `PizzaOrder` intent: 

     ```
     I want a {size} {crust} crust {pizzaKind} pizza
     ```

     To test it, type the following:

     ```
     I want a large thin crust cheese pizza
     ```

   When you type "I want to order a pizza," Amazon Lex detects the intent (`OrderPizza`). Then, Amazon Lex asks for slot information.

   After you provide all of the slot information, Amazon Lex invokes the Lambda function that you configured for the intent.

   The Lambda function returns a message ("Okay, I have ordered your ...") to Amazon Lex, which Amazon Lex returns to you..

## Inspecting the Response
<a name="gs2-inspect-pane"></a>

Underneath the chat window is a pane that enables you to inspect the response from Amazon Lex. The pane provides comprehensive information about the state of your bot that changes as you interact with your bot. The contents of the panes show you the current state of the operation.
+ **Dialog State** – The current state of the conversation with the user. It can be `ElicitIntent`, `ElicitSlot`, `ConfirmIntent` or `Fulfilled`. 

   
+ **Summary** – Shows a simplified view of the dialog that shows the slot values for the intent being fulfilled so that you can keep track of the information flow. It shows the intent name, the number of slots and the number of slots filled, and a list of all of the slots and their associated values. See the following image:  
![\[The Amazon Lex console's response summary inspection pane.\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-115.png)
+ **Detail** – Shows the raw JSON response from the chatbot to give you a deeper view into the bot interaction and the current state of the dialog as you test and debug your chatbot. If you type in the chat window, the inspection pane shows the JSON response from the [PostText](API_runtime_PostText.md) operation. If you speak to the chat window, the inspection pane shows the response headers from the [PostContent](API_runtime_PostContent.md) operation. See the following image:  
![\[The console's response inspection pane.\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs1-116.png)

## Next Step
<a name="gs2-next-step-clean-up"></a>

[Step 4 (Optional): Clean up](gs2-clean-up.md)

# Step 4 (Optional): Clean up
<a name="gs2-clean-up"></a>

Delete the resources that you created and clean up your account to avoid incurring more charges for the resources you created.

You can delete only resources that are not in use. For example, you cannot delete a slot type that is referenced by an intent. You cannot delete an intent that is referenced by a bot.

Delete resources in the following order:
+ Delete bots to free up intent resources.
+ Delete intents to free up slot type resources.
+ Delete slot types last.



**To clean up your account**

1. Sign in to the AWS Management Console and open the Amazon Lex console at [https://console.aws.amazon.com/lex/](https://console.aws.amazon.com/lex/).

1. From the list of bots, choose **PizzaOrderingBot**.

1. To delete the bot, choose **Delete**, and then choose **Continue**.

1. In the left pane, choose **Intents**.

1. In the list of intents, choose **OrderPizza**.

1. To delete the intent, choose **Delete**, and then choose **Continue**.

1. In the left menu, choose **Slot types**.

1. <a name="chooseSlots"></a>In the list of slot types, choose **Crusts**.

1. <a name="deleteSlots"></a>To delete the slot type, choose **Delete**, and then choose **Continue**.

1. Repeat [Step 8](#chooseSlots) and [Step 9](#deleteSlots) for the `Sizes` and `PizzaKind` slot types.

You have removed all of the resources that you created and cleaned up your account.

## Next Steps
<a name="gs-ex2-more-info"></a>
+ [Publish a Version and Create an Alias](https://docs.aws.amazon.com/lex/latest/dg/gettingstarted-ex3.html)
+ [Create an Amazon Lex bot with the AWS Command Line Interface](https://docs.aws.amazon.com/lex/latest/dg/gs-cli.html)

# Exercise 3: Publish a Version and Create an Alias
<a name="gettingstarted-ex3"></a>

In Getting Started Exercises 1 and 2, you created a bot and tested it. In this exercise, you do the following:
+ Publish a new version of the bot. Amazon Lex takes a snapshot copy of the `$LATEST` version to publish a new version. 
+ Create an alias that points to the new version. 

For more information about versioning and aliases, see [Versioning and Aliases](versioning-aliases.md).

Do the following to publish a version of a bot you created for this exercise:

1. In the Amazon Lex console, choose one of the bots you created. 

   Verify that the console shows the `$LATEST` as the bot version next to the bot name.

1. Choose **Publish**.

1. On the **Publish *botname*** wizard, specify the alias **BETA**, and then choose **Publish**.

1. Verify that the Amazon Lex console shows the new version next to the bot name, as in the following image.  
![\[\]](http://docs.aws.amazon.com/lex/latest/dg/images/gs2-final.png)

Now that you have a working bot with published version and an alias, you can deploy the bot (in your mobile application or integrate the bot with Facebook Messenger). For an example, see [Integrating an Amazon Lex Bot with Facebook Messenger](fb-bot-association.md).