

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. . 

# Book Trip


This example illustrates creating a bot that is configured to support multiple intents. The example also illustrates how you can use session attributes for cross-intent information sharing. After creating the bot, you use a test client in the Amazon Lex console to test the bot (BookTrip). The client uses the [PostText](API_runtime_PostText.md) runtime API operation to send requests to Amazon Lex for each user input. 

The BookTrip bot in this example is configured with two intents (BookHotel and BookCar). For example, suppose a user first books a hotel. During the interaction, the user provides information such as check-in dates, location, and number of nights. After the intent is fulfilled, the client can persist this information using session attributes. For more information about session attributes, see [PostText](API_runtime_PostText.md). 

Now suppose that the user continues to book a car. Using information that the user provided in the previous BookHotel intent (that is, destination city, and check-in and check-out dates), the code hook (Lambda function) you configured to initialize and validate the BookCar intent, initializes slot data for the BookCar intent (that is, destination, pick-up city, pick-up date, and return date). This illustrates how cross-intent information sharing enables you to build bots that can engage in dynamic conversation with the user. 

In this example, we use the following session attributes. Only the client and the Lambda function can set and update session attributes. Amazon Lex only passes these between the client and the Lambda function. Amazon Lex doesn't maintain or modify any session attributes.
+ `currentReservation` – Contains slot data for an in-progress reservation and other relevant information. For example, the following is a sample request from the client to Amazon Lex. It shows the `currentReservation` session attribute in the request body.

  ```
  POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text
  "Content-Type":"application/json"
  "Content-Encoding":"amz-1.0"
  
  {
     "inputText":"Chicago",
     "sessionAttributes":{
         "currentReservation":"{\"ReservationType\":\"Hotel\",
                                \"Location\":\"Moscow\",
                                \"RoomType\":null,
                                \"CheckInDate\":null,
                                \"Nights\":null}"
     }
  }
  ```

   
+ `lastConfirmedReservation` – Contains similar information for a previous intent, if any. For example, if the user booked a hotel and then is in process of booking a car, this session attribute stores slot data for the previous BookHotel intent.

   
+ `confirmationContext` – The Lambda function sets this to `AutoPopulate` when it prepopulates some of the slot data based on slot data from the previous reservation (if there is one). This enables cross-intent information sharing. For example, if the user previously booked a hotel and now wants to book a car, Amazon Lex can prompt the user to confirm (or deny) that the car is being booked for the same city and dates as their hotel reservation





In this exercise you use blueprints to create an Amazon Lex bot and a Lambda function. For more information about blueprints, see [Amazon Lex and AWS Lambda Blueprints](lex-lambda-blueprints.md).





**Next Step**  
[Step 1: Review the Blueprints Used in this Exercise](ex-book-trip-blueprints.md)

# Step 1: Review the Blueprints Used in this Exercise
Step 1: Blueprint Review

**Topics**
+ [

## Overview of the Bot Blueprint (BookTrip)
](#ex-book-trip-bp-summary-bot)
+ [

## Overview of the Lambda Function Blueprint (lex-book-trip-python)
](#ex-book-trip-summary-lambda)

## Overview of the Bot Blueprint (BookTrip)


The blueprint (**BookTrip**) you use to create a bot provides the following preconfiguration:
+ **Slot types** – Two custom slot types:
  +  `RoomTypes` with enumeration values: `king`, `queen`, and `deluxe`, for use in the `BookHotel` intent.
  +  `CarTypes` with enumeration values: `economy`, `standard`, `midsize`, `full size`, `luxury`, and `minivan`, for use in the `BookCar` intent.

     
+ **Intent 1 (BookHotel)** – It is preconfigured as follows:
  + **Preconfigured slots** 
    + `RoomType`, of the `RoomTypes` custom slot type
    + `Location`, of the `AMAZON.US_CITY` built-in slot type
    + `CheckInDate`, of the `AMAZON.DATE` built-in slot type
    + `Nights`, of the `AMAZON.NUMBER` built-in slot type
  + **Preconfigured utterances** 
    + "Book a hotel"
    + "I want to make hotel reservations" 
    + "Book a \$1Nights\$1 stay in \$1Location\$1"

    If the user utters any of these, Amazon Lex determines that `BookHotel` is the intent and then prompts the user for slot data.
  + **Preconfigured prompts** 
    + Prompt for the `Location` slot – "What city will you be staying in?"
    + Prompt for the `CheckInDate` slot – "What day do you want to check in?"
    + Prompt for the `Nights` slot – "How many nights will you be staying?" 
    + Prompt for the `RoomType` slot – "What type of room would you like, queen, king, or deluxe?" 
    + Confirmation statement – "Okay, I have you down for a \$1Nights\$1 night stay in \$1Location\$1 starting \$1CheckInDate\$1. Shall I book the reservation?" 
    + Denial – "Okay, I have cancelled your reservation in progress."

       
+ **Intent 2 (BookCar)** – It is preconfigured as follows:
  + **Preconfigured slots** 
    + `PickUpCity`, of the `AMAZON.US_CITY` built-in type
    + `PickUpDate`, of the `AMAZON.DATE` built-in type
    + `ReturnDate`, of the `AMAZON.DATE` built-in type
    + `DriverAge`, of the `AMAZON.NUMBER` built-in type
    + `CarType`, of the `CarTypes` custom type
  + **Preconfigured utterances** 
    + "Book a car"
    + "Reserve a car" 
    + "Make a car reservation"

    If the user utters any of these, Amazon Lex determines BookCar is the intent and then prompts the user for slot data.
  + **Preconfigured prompts**
    + Prompt for the `PickUpCity` slot – "In what city do you need to rent a car?"
    + Prompt for the `PickUpDate` slot – "What day do you want to start your rental?""
    + Prompt for the `ReturnDate` slot – "What day do you want to return this car?"
    + Prompt for the `DriverAge` slot – "How old is the driver for this rental?"
    + Prompt for the `CarType` slot – "What type of car would you like to rent? Our most popular options are economy, midsize, and luxury"
    + Confirmation statement – "Okay, I have you down for a \$1CarType\$1 rental in \$1PickUpCity\$1 from \$1PickUpDate\$1 to \$1ReturnDate\$1. Should I book the reservation?" 
    + Denial – "Okay, I have cancelled your reservation in progress."

## Overview of the Lambda Function Blueprint (lex-book-trip-python)


In addition to the bot blueprint, AWS Lambda provides a blueprint (**lex-book-trip-python**) that you can use as a code hook with the bot blueprint. For a list of bot blueprints and corresponding Lambda function blueprints, see [Amazon Lex and AWS Lambda Blueprints](lex-lambda-blueprints.md).

When you create a bot using the BookTrip blueprint, you update configuration of both the intents (BookCar and BookHotel) by adding this Lambda function as a code hook for both initialization/validation of user data input and fulfillment of the intents.



This Lambda function code provided showcases dynamic conversation using previously known information (persisted in session attributes) about a user to initialize slot values for an intent. For more information, see [Managing Conversation Context](context-mgmt.md).

**Next Step**  
[Step 2: Create an Amazon Lex Bot](ex-book-trip-create-bot.md)

# Step 2: Create an Amazon Lex Bot


In this section, you create an Amazon Lex bot (BookTrip). 

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. On the **Bots** page, choose **Create**.

1. On the **Create your Lex bot** page, 
   + Choose **BookTrip** blueprint.
   + Leave the default bot name (BookTrip).

1. Choose **Create**. The console sends a series of requests to Amazon Lex to create the bot. Note the following:

1. The console shows the BookTrip bot. On the **Editor** tab, review the details of the preconfigured intents (BookCar and BookHotel).

1. Test the bot in the test window. Use the following to engage in a test conversation with your bot:   
![\[Conversation with an agent, in which the agent elicits the city, day, number of nights, and type of room for the customer's trip. The agent then confirms the reservation.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-trip-no-lambda-10.png)

   From the initial user input ("Book a hotel"), Amazon Lex infers the intent (BookHotel). The bot then uses the prompts preconfigured in this intent to elicit slot data from the user. After user provide all of the slot data, Amazon Lex returns a response back to the client with a message that includes all the user input as a message. The client displays the message in the response as shown. 

   ```
   CheckInDate:2016-12-18 Location:Chicago Nights:5 RoomType:queen
   ```

   Now you continue the conversation and try to book a car in the following conversation.  
![\[Conversation with an agent, in which the agent elicits the city, start day, return day, driver age, and type of car, for the customer's car rental. The agent then confirms the reservation.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-trip-no-lambda-20.png)

   Note that, 
   + There is no user data validation at this time. For example, you can provide any city to book a hotel.
   + You are providing some of the same information again (destination, pick-up city, pick-up date, and return date) to book a car. In a dynamic conversation, your bot should initialize some of this information based on prior input user provided for booking hotel. 

   In this next section, you create a Lambda function to do some of the user data validation, and initialization using cross-intent information sharing via session attributes. Then you update the intent configuration by adding the Lambda function as code hook to perform initialization/validation of user input and fulfill intent.

**Next Step**  
[Step 3: Create a Lambda function](ex-book-trip-create-lambda-function.md)

# Step 3: Create a Lambda function


In this section you create a Lambda function using a blueprint (**lex-book-trip-python**) provided in the AWS Lambda console. You also test the Lambda function by invoking it using sample event data provided by the console.

This Lambda function is written in Python.



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. Choose **Use a blueprint**. Type **lex** to find the blueprint, choose the `lex-book-trip-python` blueprint.

1. Choose **Configure** the Lambda function as follows.
   + Type a Lambda function name (`BookTripCodeHook`).
   + For the role, choose **Create a new role from template(s)** and then type a role name.
   + 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. You invoke the Lambda function twice, using sample data for both booking a car and booking a hotel. 

   1. Choose **Configure test event** from the **Select a test event** drop down.

   1. Choose **Amazon Lex Book Hotel** from the **Sample event template** list. 

      This sample event matches the Amazon Lex request/response model. For more information, see [Using Lambda Functions](using-lambda.md).

   1. Choose **Save and test**.

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

   1. Repeat the step. This time you choose the **Amazon Lex Book Car** from the **Sample event template** list. The Lambda function processes the car reservation.





**Next Step**  
[Step 4: Add the Lambda Function as a Code Hook](ex-book-trip-create-integrate.md)

# Step 4: Add the Lambda Function as a Code Hook


In this section, you update the configurations of both the BookCar and BookHotel intents by adding the Lambda function as a code hook for initialization/validation and fulfillment activities. Make sure you choose the \$1LATEST version of the intents because you can only update the \$1LATEST version of your Amazon Lex resources.



1. In the Amazon Lex console, choose the **BookTrip** bot. 

1. On the **Editor** tab, choose the **BookHotel** intent. Update the intent configuration as follows:

   1. Make sure the intent version (next to the intent name) is \$1LATEST. 

   1. Add the Lambda function as an initialization and validation code hook as follows:
      + In **Options**, choose **Initialization and validation code hook**.
      + Choose your Lambda function from the list.

   1. Add the Lambda function as a fulfillment code hook as follows:
      + In **Fulfillment**, choose **AWS Lambda function**.
      + Choose your Lambda function from the list.
      + Choose **Goodbye message** and type a message.

   1. Choose **Save**.

1. On the **Editor** tab, choose the BookCar intent. Follow the preceding step to add your Lambda function as validation and fulfillment code hook.

   

1. Choose **Build**. The console sends a series of requests to Amazon Lex to save the configurations.

1. Test the bot. Now that you a have a Lambda function performing the initialization, user data validation and fulfillment, you can see the difference in the user interaction in the following conversation:  
![\[Conversation with an agent, in which the agent elicits the city, day, number of nights, and type of room for a trip reservation and then confirms the reservation.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-trip-with-lambda-30.png)

   For more information about the data flow from the client (console) to Amazon Lex, and from Amazon Lex to the Lambda function, see [Data Flow: Book Hotel Intent](book-trip-detail-flow.md#data-flow-book-hotel).

1. Continue the conversation and book a car as shown in the following image:  
![\[Conversation with an agent, in which the agent elicits the age of the driver and type of car and then confirms the car reservation.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-trip-with-lambda-40.png)

   When you choose to book a car, the client (console) sends a request to Amazon Lex that includes the session attributes (from the previous conversation, BookHotel). Amazon Lex passes this information to the Lambda function, which then initializes (that is, it prepopulates) some of the BookCar slot data (that is, PickUpDate, ReturnDate, and PickUpCity). 
**Note**  
This illustrates how session attributes can be used to maintain context across intents. The console client provides the **Clear** link in the test window that a user can use to clear any prior session attributes.

   For more information about the data flow from the client (console) to Amazon Lex, and from Amazon Lex to the Lambda function, see [Data Flow: Book Car Intent](book-trip-detail-flow.md#data-flow-book-car).

# Details of the Information Flow


In this exercise, you engaged in a conversation with the Amazon Lex BookTrip bot using the test window client provided in the Amazon Lex console. This section explains the following: 
+ The data flow between the client and Amazon Lex.

   

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

   
+ The data flow between Amazon Lex and the Lambda function. For more information, see [Lambda Function Input Event and Response Format](lambda-input-response-format.md).

**Topics**
+ [

## Data Flow: Book Hotel Intent
](#data-flow-book-hotel)
+ [

## Data Flow: Book Car Intent
](#data-flow-book-car)

## Data Flow: Book Hotel Intent


This section explains what happens after each user input.

1. User: "book a hotel"

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

      ```
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText":"book a hotel",
         "sessionAttributes":{}
      }
      ```

      Both the request URI and the body provides information to Amazon Lex:
      + Request URI – Provides bot name (BookTrip), bot alias (\$1LATEST) and the user name. The trailing `text` indicates that it is a `PostText` API request (and not `PostContent`).
      + Request body – Includes the user input (`inputText`) and empty `sessionAttributes`. Initially, this is an empty object and the Lambda function first sets the session attributes.

      

   1. From the `inputText`, Amazon Lex detects the intent (BookHotel). This intent is configured with a Lambda function as a code hook for user data initialization/validation. Therefore, Amazon Lex invokes that Lambda function by passing the following information as the event parameter (see [Input Event Format](lambda-input-response-format.md#using-lambda-input-event-format)):

      ```
      {
         "messageVersion":"1.0",
         "invocationSource":"DialogCodeHook",
         "userId":"wch89kjqcpkds8seny7dly5x3otq68j3",
         "sessionAttributes":{
         },
         "bot":{
            "name":"BookTrip",
            "alias":null,
            "version":"$LATEST"
         },
         "outputDialogMode":"Text",
         "currentIntent":{
            "name":"BookHotel",
            "slots":{
               "RoomType":null,
               "CheckInDate":null,
               "Nights":null,
               "Location":null
            },
            "confirmationStatus":"None"
         }
      }
      ```

      In addition to the information sent by the client, 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` – All of the slot values are 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. For information about response format, see [Response Format](lambda-input-response-format.md#using-lambda-response-format). 

      ```
      {
         "sessionAttributes":{
            "currentReservation":"{\"ReservationType\":\"Hotel\",\"Location\":null,\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}"
         },
         "dialogAction":{
            "type":"Delegate",
            "slots":{
               "RoomType":null,
               "CheckInDate":null,
               "Nights":null,
               "Location":null
            }
         }
      }
      ```
**Note**  
`currentReservation` – The Lambda function includes this session attribute. Its value is a copy of the current slot information and the reservation type.   
Only the Lambda function and the client can update these session attributes. Amazon Lex simply passes these values.
`dialogAction.type` – By setting this value to `Delegate`, the Lambda function delegates the responsibility for the next course of action to Amazon Lex.   
If the Lambda function detected anything in the user data validation, it instructs Amazon Lex what to do next.

   1. As per the `dialogAction.type`, Amazon Lex decides the next course of action—elicit data from the user for the `Location` slot. It selects one of the prompt messages ("What city will you be staying in?") for this slot, according to the intent configuration, and then sends the following response to the user:   
![\[JSON response containing dialog state, intent name, message, response card, session attributes, slot to elicit, and slots.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-hotel-10.png)

      The session attributes are passed to the client.

      The client reads the response and then displays the message: "What city will you be staying in?"

1. User: "Moscow"

   1. The client sends the following `PostText` request to Amazon Lex (line breaks added for readability):

      ```
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText":"Moscow",
         "sessionAttributes":{
             "currentReservation":"{\"ReservationType\":\"Hotel\",
                                    \"Location\":null,
                                    \"RoomType\":null,
                                    \"CheckInDate\":null,
                                    \"Nights\":null}"
         }
      }
      ```

      In addition to the `inputText`, the client includes the same `currentReservation` session attributes it received. 

   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 `Location` slot). It updates the slot value for the current intent and invokes the Lambda function using the following event:

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "DialogCodeHook",
          "userId": "wch89kjqcpkds8seny7dly5x3otq68j3",
          "sessionAttributes": {
              "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":null,\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}"
          },
          "bot": {
              "name": "BookTrip",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "BookHotel",
              "slots": {
                  "RoomType": null,
                  "CheckInDate": null,
                  "Nights": null,
                  "Location": "Moscow"
              },
              "confirmationStatus": "None"
          }
      }
      ```
**Note**  
`invocationSource` continues to be `DialogCodeHook`. In this step, we are just validating user data.
Amazon Lex is just passing the session attribute to the Lambda function.
For `currentIntent.slots`, Amazon Lex has updated the `Location` slot to `Moscow`.

   1. The Lambda function performs the user data validation and determines that `Moscow` is an invalid location. 
**Note**  
The Lambda function in this exercise has a simple list of valid cities and `Moscow` is not on the list. In a production application, you might use a back-end database to get this information. 

      It resets the slot value back to null and directs Amazon Lex to prompt the user again for another value by sending the following response:

      ```
      {
          "sessionAttributes": {
              "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Moscow\",\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}"
          },
          "dialogAction": {
              "type": "ElicitSlot",
              "intentName": "BookHotel",
              "slots": {
                  "RoomType": null,
                  "CheckInDate": null,
                  "Nights": null,
                  "Location": null
              },
              "slotToElicit": "Location",
              "message": {
                  "contentType": "PlainText",
                  "content": "We currently do not support Moscow as a valid destination.  Can you try a different city?"
              }
          }
      }
      ```
**Note**  
`currentIntent.slots.Location` is reset to null.
`dialogAction.type` is set to `ElicitSlot`, which directs Amazon Lex to prompt the user again by providing the following:   
`dialogAction.slotToElicit` – slot for which to elicit data from the user.
`dialogAction.message` – a `message` to convey to the user.

   1. Amazon Lex notices the `dialogAction.type` and passes the information to the client in the following response:  
![\[JSON response containing dialog state, intent name, message, response card, session attributes, slot to elicit, and slots.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-hotel-20.png)

      The client simply displays the message: "We currently do not support Moscow as a valid destination. Can you try a different city?"

1. User: "Chicago"

   1. The client sends the following `PostText` request to Amazon Lex:

      ```
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText":"Chicago",
         "sessionAttributes":{
             "currentReservation":"{\"ReservationType\":\"Hotel\",
                                    \"Location\":\"Moscow\",
                                    \"RoomType\":null,
                                    \"CheckInDate\":null,
                                    \"Nights\":null}"
         }
      }
      ```

      

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

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "DialogCodeHook",
          "userId": "wch89kjqcpkds8seny7dly5x3otq68j3",
          "sessionAttributes": {
              "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":Moscow,\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}"
          },
          "bot": {
              "name": "BookTrip",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "BookHotel",
              "slots": {
                  "RoomType": null,
                  "CheckInDate": null,
                  "Nights": null,
                  "Location": "Chicago"
              },
              "confirmationStatus": "None"
          }
      }
      ```

      Amazon Lex updated the `currentIntent.slots` by setting the `Location` slot to `Chicago`. 

   1. According to the `invocationSource` value of `DialogCodeHook`, the Lambda function performs user data validation. It recognizes `Chicago` as a valid slot value, updates the session attribute accordingly, and then returns the following response to Amazon Lex. 

      ```
      {
          "sessionAttributes": {
              "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":null,\"CheckInDate\":null,\"Nights\":null}"
          },
          "dialogAction": {
              "type": "Delegate",
              "slots": {
                  "RoomType": null,
                  "CheckInDate": null,
                  "Nights": null,
                  "Location": "Chicago"
              }
          }
      }
      ```
**Note**  
`currentReservation` – The Lambda function updates this session attribute by setting the `Location` to `Chicago`. 
`dialogAction.type` – Is set to `Delegate`. User data was valid, and the Lambda function directs Amazon Lex to choose the next course of action.

       

   1. According to `dialogAction.type`, Amazon Lex chooses the next course of action. Amazon Lex knows that it needs more slot data and picks the next unfilled slot (`CheckInDate`) with the highest priority according to the intent configuration. It selects one of the prompt messages ("What day do you want to check in?") for this slot according to the intent configuration and then sends the following response back to the client:   
![\[JSON response containing dialog state, intent name, message, response card, session attributes, slot to elicit, and slots. The location slot is now filled in as Chicago.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-hotel-30.png)

      The client displays the message: "What day do you want to check in?" 

   

1. The user interaction continues—the user provides data, the Lambda function validates data, and then delegates the next course of action to Amazon Lex. Eventually the user provides all of the slot data, the Lambda function validates all of the user input, and then Amazon Lex recognizes it has all the slot data. 
**Note**  
In this exercise, after the user provides all of the slot data, the Lambda function computes the price of the hotel reservation and returns it as another session attribute (`currentReservationPrice`). 

   At this point, the intent is ready to be fulfilled, but the BookHotel intent is configured with a confirmation prompt requiring user confirmation before Amazon Lex can fulfill the intent. Therefore, Amazon Lex sends the following message to the client requesting confirmation before booking the hotel:  
![\[JSON response containing dialog state, intent name, message, response card, session attributes, slot to elicit, and slots. All the slots are now filled in.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-hotel-40.png)

   The client display the message: "Okay, I have you down for a 5 night in Chicago starting 2016-12-18. Shall I book the reservation?"

1. User: "yes"

   1. The client sends the following `PostText` request to Amazon Lex: 

      ```
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText":"Yes",
         "sessionAttributes":{
             "currentReservation":"{\"ReservationType\":\"Hotel\",
                                    \"Location\":\"Chicago\",
                                    \"RoomType\":\"queen\",
                                    \"CheckInDate\":\"2016-12-18\",
                                    \"Nights\":\"5\"}",
            "currentReservationPrice":"1195"
         }
      }
      ```

   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 reservation. This time Amazon Lex invokes the Lambda function to fulfill the intent by sending the following event. By setting 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": "wch89kjqcpkds8seny7dly5x3otq68j3",
          "sessionAttributes": {
              "currentReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"5\"}",
              "currentReservationPrice": "956"
          },
          "bot": {
              "name": "BookTrip",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "BookHotel",
              "slots": {
                  "RoomType": "queen",
                  "CheckInDate": "2016-12-18",
                  "Nights": "5",
                  "Location": "Chicago"
              },
              "confirmationStatus": "Confirmed"
          }
      }
      ```
**Note**  
`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 BookHotel intent, Amazon Lex completes the reservation, and then it returns the following response: 

      ```
      {
          "sessionAttributes": {
              "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"5\"}"
          },
          "dialogAction": {
              "type": "Close",
              "fulfillmentState": "Fulfilled",
              "message": {
                  "contentType": "PlainText",
                  "content": "Thanks, I have placed your reservation.   Please let me know if you would like to book a car rental, or another hotel."
              }
          }
      }
      ```
**Note**  
 `lastConfirmedReservation` – Is a new session attribute that the Lambda function added (instead of the `currentReservation`, `currentReservationPrice`). 
`dialogAction.type` – The Lambda function sets this value to `Close`, indicating that 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 to the client:  
![\[JSON response containing dialog state, intent name, message, response card, session attributes, slot to elicit, and slots. All the slots are filled in and a last confirmed reservation field under session attributes is now filled in.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-hotel-60.png)
**Note**  
`dialogState` – Amazon Lex sets this value to `Fulfilled`.
`message` – Is the same message that the Lambda function provided.

       The client displays the message.

## Data Flow: Book Car Intent


The BookTrip bot in this exercise supports two intents (BookHotel and BookCar). After booking a hotel, the user can continue the conversation to book a car. As long as the session hasn't timed out, in each subsequent request the client continues to send the session attributes (in this example, the `lastConfirmedReservation`). The Lambda function can use this information to initialize slot data for the BookCar intent. This shows how you can use session attributes in cross-intent data sharing. 

Specifically, when the user chooses the BookCar intent, the Lambda function uses relevant information in the session attribute to prepopulate slots (PickUpDate, ReturnDate, and PickUpCity) for the BookCar intent.

**Note**  
The Amazon Lex console provides the **Clear** link that you can use to clear any prior session attributes. 

Follow the steps in this procedure to continue the conversation.

1. User: "also book a car"

   1. The client sends the following `PostText` request to Amazon Lex.

      ```
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText":"also book a car",
         "sessionAttributes":{
             "lastConfirmedReservation":""{\"ReservationType\":\"Hotel\",
                                           \"Location\":\"Chicago\",
                                           \"RoomType\":\"queen\",
                                           \"CheckInDate\":\"2016-12-18\",
                                           \"Nights\":\"5\"}"
         }
      }
      ```

      The client includes the `lastConfirmedReservation` session attribute.

   1. Amazon Lex detects the intent (BookCar) from the `inputText`. This intent is also configured to invoke the Lambda function to perform the initialization and validation of the user data. Amazon Lex invokes the Lambda function with the following event:

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "DialogCodeHook",
          "userId": "wch89kjqcpkds8seny7dly5x3otq68j3",
          "sessionAttributes": {
              "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"5\"}"
          },
          "bot": {
              "name": "BookTrip",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "BookCar",
              "slots": {
                  "PickUpDate": null,
                  "ReturnDate": null,
                  "DriverAge": null,
                  "CarType": null,
                  "PickUpCity": null
              },
              "confirmationStatus": "None"
          }
      }
      ```
**Note**  
 `messageVersion` – Currently Amazon Lex supports the 1.0 version only.
`invocationSource` – Indicates the purpose of invocation is to perform initialization and user data validation.
`currentIntent` – It includes the intent name and the slots. At this time, all slot values are null.

      

   1. The Lambda function notices all null slot values with nothing to validate. However, it uses session attributes to initialize some of the slot values (`PickUpDate`, `ReturnDate`, and `PickUpCity`), and then returns the following response:

      ```
      {
          "sessionAttributes": {
              "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"5\"}",
              "currentReservation": "{\"ReservationType\":\"Car\",\"PickUpCity\":null,\"PickUpDate\":null,\"ReturnDate\":null,\"CarType\":null}",
              "confirmationContext": "AutoPopulate"
          },
          "dialogAction": {
              "type": "ConfirmIntent",
              "intentName": "BookCar",
              "slots": {
                  "PickUpCity": "Chicago",
                  "PickUpDate": "2016-12-18",
                  "ReturnDate": "2016-12-22",
                  "CarType": null,
                  "DriverAge": null
              },
              "message": {
                  "contentType": "PlainText",
                  "content": "Is this car rental for your 5 night stay in Chicago on 2016-12-18?"
              }
          }
      }
      ```
**Note**  
In addition to the `lastConfirmedReservation`, the Lambda function includes more session attributes (`currentReservation` and `confirmationContext`). 
`dialogAction.type` is set to `ConfirmIntent`, which informs Amazon Lex that a yes, no reply is expected from the user (the confirmationContext set to AutoPopulate, the Lambda function knows that the yes/no user reply is to obtain user confirmation of the initialization the Lambda function performed (auto populated slot data).   
   
The Lambda function also includes in the response an informative message in the `dialogAction.message` for Amazon Lex to return to the client.  
The term `ConfirmIntent` (value of the `dialogAction.type`) is not related to any bot intent. In the example, Lambda function uses this term to direct Amazon Lex to get a yes/no reply from the user.

   1. According to the `dialogAction.type`, Amazon Lex returns the following response to the client:   
![\[JSON response containing dialog state, intent name, message, response card, session attributes, slot to elicit, and slots.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-car-10.png)

      The client displays the message: "Is this car rental for your 5 night stay in Chicago on 2016-12-18?"

1. User: "yes"

   1. The client sends the following `PostText` request to Amazon Lex. 

      ```
      POST /bot/BookTrip/alias/$LATEST/user/wch89kjqcpkds8seny7dly5x3otq68j3/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText":"yes",
         "sessionAttributes":{
            "confirmationContext":"AutoPopulate",
            "currentReservation":"{\"ReservationType\":\"Car\",
                                   \"PickUpCity\":null,
                                   \"PickUpDate\":null,
                                   \"ReturnDate\":null,
                                   \"CarType\":null}",
            "lastConfirmedReservation":"{\"ReservationType\":\"Hotel\",
                                         \"Location\":\"Chicago\",
                                         \"RoomType\":\"queen\",
                                         \"CheckInDate\":\"2016-12-18\",
                                         \"Nights\":\"5\"}"
         }
      }
      ```

   1. Amazon Lex reads the `inputText` and it knows the context (asked the user to confirm the auto population). Amazon Lex invokes the Lambda function by sending the following event:

      ```
      {
          "messageVersion": "1.0",
          "invocationSource": "DialogCodeHook",
          "userId": "wch89kjqcpkds8seny7dly5x3otq68j3",
          "sessionAttributes": {
              "confirmationContext": "AutoPopulate",
              "currentReservation": "{\"ReservationType\":\"Car\",\"PickUpCity\":null,\"PickUpDate\":null,\"ReturnDate\":null,\"CarType\":null}",
              "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"5\"}"
          },
          "bot": {
              "name": "BookTrip",
              "alias": null,
              "version": "$LATEST"
          },
          "outputDialogMode": "Text",
          "currentIntent": {
              "name": "BookCar",
              "slots": {
                  "PickUpDate": "2016-12-18",
                  "ReturnDate": "2016-12-22",
                  "DriverAge": null,
                  "CarType": null,
                  "PickUpCity": "Chicago"
              },
              "confirmationStatus": "Confirmed"
          }
      }
      ```

      Because the user replied Yes, Amazon Lex sets the `confirmationStatus` to `Confirmed`. 

      

   1. From the `confirmationStatus`, the Lambda function knows that the prepopulated values are correct. The Lambda function does the following:
      + Updates the `currentReservation` session attribute to slot value it had prepopulated.
      + Sets the `dialogAction.type` to `ElicitSlot`
      + Sets the `slotToElicit` value to `DriverAge`. 

      The following response is sent:

      ```
      {
          "sessionAttributes": {
              "currentReservation": "{\"ReservationType\":\"Car\",\"PickUpCity\":\"Chicago\",\"PickUpDate\":\"2016-12-18\",\"ReturnDate\":\"2016-12-22\",\"CarType\":null}",
              "lastConfirmedReservation": "{\"ReservationType\":\"Hotel\",\"Location\":\"Chicago\",\"RoomType\":\"queen\",\"CheckInDate\":\"2016-12-18\",\"Nights\":\"5\"}"
          },
          "dialogAction": {
              "type": "ElicitSlot",
              "intentName": "BookCar",
              "slots": {
                  "PickUpDate": "2016-12-18",
                  "ReturnDate": "2016-12-22",
                  "DriverAge": null,
                  "CarType": null,
                  "PickUpCity": "Chicago"
              },
              "slotToElicit": "DriverAge",
              "message": {
                  "contentType": "PlainText",
                  "content": "How old is the driver of this car rental?"
              }
          }
      }
      ```

   1. Amazon Lex returns following response:  
![\[JSON response showing the intent to book a car and a message elicitng the slot for Driver Age slot.\]](http://docs.aws.amazon.com/lex/latest/dg/images/book-car-20.png)

      The client displays the message "How old is the driver of this car rental?" and the conversation continues.