

# Creating an AWS Lambda function for your Amazon Lex V2 bot
<a name="lambda-attach"></a>

To create a Lambda function for your Amazon Lex V2 bot, access AWS Lambda from your AWS Management Console and create a new function. You can refer to the [AWS Lambda developer guide](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) for more details about AWS Lambda.

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 **Functions** in the left sidebar.

1. Select **Create function**.

1. You can select **Author from scratch** to start with minimal code, **Use a blueprint** to select sample code for common use cases from a list, or **Container image** to select a container image to deploy for your function. If you select **Author from scratch**, continue with the following steps:

   1. Give your function a meaningful **Function name** to describe what it does.

   1. Choose a language from the drop down menu under **Runtime** to write your function in.

   1. Select an instruction set **Architecture** for your function.

   1. By default, Lambda creates a role with basic permissions. To use an existing role or to create a role using AWS policy templates, expand the **Change default execution role** menu and select an option.

   1. Expand the **Advanced settings** menu to configure more options.

1. Select **Create function**.

The following image shows what you see when you create a new function from scratch:

![\[A new Lambda function.\]](http://docs.aws.amazon.com/lexv2/latest/dg/images/lambda/lambda-new-function.png)


The Lambda handler function differs depending on the language you use. It minimally takes an `event` JSON object as an argument. You can see the fields in the `event` that Amazon Lex V2 provides at [AWS Lambda input event format for Lex V2](lambda-input-format.md). Modify the handler function to ultimately return a `response` JSON object that matches the format described in [AWS Lambda response format for Lex V2](lambda-response-format.md).
+ Once you finish writing your function, select **Deploy** to allow the function to be used.

Remember that you can associate each bot alias with at most one Lambda function. However, you can define as many functions as you need for your bot within the Lambda code and call these functions in the Lambda handler function. For example, while all intents in the same bot alias must call the same Lambda function, you can create a router function that activates a separate function for each intent. The following is a sample router function that you can use or modify for your application:

```
import os
import json
import boto3

# reuse client connection as global
client = boto3.client('lambda')

def router(event):
    intent_name = event['sessionState']['intent']['name']
    fn_name = os.environ.get(intent_name)
    print(f"Intent: {intent_name} -> Lambda: {fn_name}")
    if (fn_name):
        # invoke lambda and return result
        invoke_response = client.invoke(FunctionName=fn_name, Payload = json.dumps(event))
        print(invoke_response)
        payload = json.load(invoke_response['Payload'])
        return payload
    raise Exception('No environment variable for intent: ' + intent_name)

def lambda_handler(event, context):
    print(event)
    response = router(event)
    return response
```

**When to use AWS Lambda functions in Amazon Lex V2 bot conversations**

You can use Lambda functions at the following points in a conversation with a user:
+ In the initial response after the intent is recognized. For example, after the user says they want to order a pizza.
+ After eliciting a slot value from the user. For example, after the user tells the bot the size of pizza they want to order.
+ Between each retry for eliciting a slot. For example, if the customer doesn't use a recognized pizza size.
+ When confirming an intent. For example, when confirming a pizza order.
+ To fulfill an intent. For example, to place an order for a pizza.
+ After fulfillment of the intent, and before your bot closes the conversation. For example, to switch to an intent to order a drink.

**Topics**
+ [Attach an AWS Lambda function to a Amazon Lex V2 bot using the console](lambda-attach-console.md)
+ [Attach an AWS Lambda function to a Amazon Lex V2 bot using API operations](lambda-attach-api.md)

# Attach an AWS Lambda function to a Amazon Lex V2 bot using the console
<a name="lambda-attach-console"></a>

You must first attach a Lambda function to your Amazon Lex V2 bot alias before you can invoke it. You can only attach one Lambda function with each bot alias. Perform these steps to attach the Lambda function using the AWS 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. Choose **Bots** from the left side panel and from the list of bots, choose the name of the bot that you want to attach a Lambda function to.

1. From the left side panel, select **Aliases** under the **Deployment** menu.

1. From the list of aliases, choose the name of the alias that you want to attach a Lambda function to.

1. In the **Languages** panel, select the language that you want a Lambda function to. Select **Manage languages in alias** to add a language if it is not present in the panel.

1. In the **Source** dropdown menu, choose the name of the Lambda function that you want to attach.

1. In the **Lambda function version or alias** dropdown menu, choose the version or alias of the Lambda function that you want to use. Then select **Save**. The same Lambda function is used for all intents in a language supported by the bot.

**Setting a Amazon Lex V2 intent to invoke a Lambda function using the console**

1. After selecting a bot, select **Intents** in the left side menu under the language of the bot for which you want to invoke the Lambda function.

1. Choose the intent in which you want to invoke the Lambda function to open the intent editor.

1. There are two options for setting the Lambda code hook:

   1. To invoke the Lambda function after every step of the conversation, scroll to the **Code hooks** section at the bottom of the intent editor and select the **Use a Lambda function for initialization and validation** check box, as in the following image:  
![\[The code hooks section of the Amazon Lex V2 intent editor.\]](http://docs.aws.amazon.com/lexv2/latest/dg/images/lambda/lambda-code-hooks-all.png)

   1. Alternatively, use the **Dialog code hook** section in the conversation stages at which to invoke the Lambda function. The **Dialog code hook** section appears as follows:  
![\[The code hooks section of the Amazon Lex V2 intent editor.\]](http://docs.aws.amazon.com/lexv2/latest/dg/images/lambda/lambda-code-hook-step.png)

      There are two ways to control how Amazon Lex V2 calls the code hook for a response:
      + Toggle the **Active** button to mark it as *active* or *inactive*. When a code hook is *active*, Amazon Lex V2 will call the code hook. When the code hook is *inactive*, Amazon Lex V2 does not run the code hook.
      + Expand the **Lambda dialog code hook** section and select the **Invoke Lambda function** check box to mark it as *enabled* or *disabled*. You can only enable or disable a code hook when it is marked active. When it is marked *enabled*, the code hook is run normally. When it is *disabled*, the code hook is not called and Amazon Lex V2 acts as if the code hook returned successfully. To configure responses after the dialog code hook succeeds, fails, or times out, select **Advanced options**

      The Lambda code hook can be invoked at the following conversation stages:
      + To invoke the function as the **initial response**, scroll to the **Initial Response** section, expand the arrow next to **Response to acknowledge the user's request**, and select **Advanced options**. Find the **Dialog code hook** section at the bottom of the menu that pops up.
      + To invoke the function after **slot elicitation**, scroll to the **Slots** section, expand the arrow next to the relevant **Prompt for slot**, and select **Advanced options**. Find the **Dialog code hook** section near the bottom of the menu that pops up, just above **Default values**.

        You can also invoke the function after each elicitation. To do this, expand **Bot elicits information** in the **Slot prompts** section, select **More prompt options**, and select the check box next to **Invoke Lambda code hook after each elicitation**.
      + To invoke the function for **intent confirmation**, scroll to the **Confirmation** section, expand the arrow next to **Prompts to confirm the intent**, and select **Advanced options**. Find the **Dialog code hook** section at the bottom of the menu that pops up.
      + To invoke the function for **intent fulfillment**, scroll to the **Fulfillment** section. Toggle the **Active** button to set the code hook to *active*. Expand the arrow next to **On successful fulfillment**, and select **Advanced options**. Select the check box next to **Use a Lambda function for fulfillment** under the **Fulfillment Lambda code hook** section to set the code hook to *enabled*.

1. Once you set the conversation stages at which to invoke the Lambda function, **Build** the bot again to test the function.

# Attach an AWS Lambda function to a Amazon Lex V2 bot using API operations
<a name="lambda-attach-api"></a>

You must first attach a Lambda function to your Amazon Lex V2 bot alias before you can invoke it. You can only associate one Lambda function with each bot alias. Perform these steps to attach the Lambda function using API operations. 

If you are creating a new bot alias, use the [CreateBotAlias](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_CreateBotAlias.html) operation to attach a Lambda function. To attach a Lambda function to an existing bot alias, use the [UpdateBotAlias](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_UpdateBotAlias.html) operation. Modify the `botAliasLocaleSettings` field to contain the correct settings:

```
{
    "botAliasLocaleSettings" : {
        locale: {
            "codeHookSpecification": {
                "lambdaCodeHook": {
                    "codeHookInterfaceVersion": "1.0",
                    "lambdaARN": "arn:aws:lambda:region:account-id:function:function-name"
                }
            },
            "enabled": true
        },
        ...
    }
}
```

1. The `botAliasLocaleSettings` field maps to an object whose keys are the locales in which you want to attach the Lambda function. See [Supported languages and locales](how-languages.md#supported-languages) for a list of supported locales and the codes that are valid keys.

1. To find the `lambdaARN` for a Lambda function, open the AWS Lambda console at [https://console.aws.amazon.com/lambda/home](https://console.aws.amazon.com/lambda/home), select **Functions** in the left sidebar, and select the function to associate with the bot alias. On the right side of the **Function overview**, find the `lambdaARN` under **Function ARN**. It should contain a region, account ID, and the name of the function.

1. To allow Amazon Lex V2 to invoke the Lambda function for the alias, set the `enabled` field to `true`.

**Setting a Amazon Lex V2 intent to invoke a Lambda function using API operations**

To set up the Lambda function invocation during an intent, use the [CreateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_CreateIntent.html) operation if you are creating a new intent, or the [UpdateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_UpdateIntent.html) operation if you are invoking the function in an existing intent. The fields that control the Lambda function invocation in the intent operations are `dialogCodeHook`, `initialResponseSetting`, `intentConfirmationSetting`, and `fulfillmentCodeHook`.

If you invoke the function during the elicitation of a slot, use the [CreateSlot](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_CreateSlot.html) operation if you are creating a new slot, or the [UpdateSlot](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_UpdateSlot.html) operation to invoke the function in an existing slot. The field that controls the Lambda function invocation in the slot operations is the `slotCaptureSetting` of the `valueElicitationSetting` object.

1. To set the Lambda dialog code hook to run after every turn of the conversation, set the `enabled` field of the following [DialogCodeHookSettings](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_DialogCodeHookSettings.html) object in the `dialogCodeHook` field to `true`:

   ```
   "dialogCodeHook": {
       "enabled": boolean
   }
   ```

1. Alternatively, you can set the Lambda dialog code hook to run only at specific points in the conversations by modifying the `codeHook` and/or `elicitationCodeHook` field within the structures that correspond to the conversation stages at which you want to invoke the function. To use the Lambda dialog code hook for intent fulfillment, use the `fulfillmentCodeHook` field in the [CreateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_CreateIntent.html) or [UpdateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_UpdateIntent.html) operation. The structures and uses of these three types of code hooks are as follows:

## codeHook
<a name="lambda-code-hook"></a>

The `codeHook` field defines the settings for the code hook to run at a given stage in the conversation. It is a [DialogCodeHookInvocationSetting](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_DialogCodeHookInvocationSetting.html) object with the following structure:

```
"codeHook": {
    "active": boolean,
    "enableCodeHookInvocation": boolean,
    "invocationLabel": string,
    "postCodeHookSpecification": [PostDialogCodeHookInvocationSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PostDialogCodeHookInvocationSpecification.html),
}
```
+ Change the `active` field to `true` for Amazon Lex V2 to call the code hook at that point in the conversation.
+ Change the `enableCodeHookInvocation` field to `true` for Amazon Lex V2 to allow the code hook to run normally. If you mark it `false`, Amazon Lex V2 acts as if the code hook returned successfully.
+ The `invocationLabel` indicates the dialog step from which the code hook is invoked.
+ Use the `postCodeHookSpecification` field to specify the actions and messages that occur after the code hook succeeds, fails, or times out.

## elicitationCodeHook
<a name="lambda-elicitation-code-hook"></a>

The `elicitationCodeHook` field defines the settings for the code hook to run in the event that a slot or slots need to be re-elicited. This scenario may occur if slot elicitation fails or intent confirmation is denied. The `elicitationCodeHook` field is an [ElicitationCodeHookInvocationSetting](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ElicitationCodeHookInvocationSetting.html) object with the following structure:

```
"elicitationCodeHook": {
    "enableCodeHookInvocation": boolean,
    "invocationLabel": string
}
```
+ Change the `enableCodeHookInvocation` field to `true` for Amazon Lex V2 to allow the code hook to run normally. If you mark it `false`, Amazon Lex V2 acts as if the code hook returned successfully.
+ The `invocationLabel` indicates the dialog step from which the code hook is invoked.

## fulfillmentCodeHook
<a name="lambda-fulfillment-code-hook"></a>

The `fulfillmentCodeHook` field defines the settings for the code hook to run to fulfill the intent. It maps to the following [FulfillmentCodeHookSettings](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_FulfillmentCodeHookSettings.html) object:

```
"fulfillmentCodeHook": {
    "active": boolean,
    "enabled": boolean,
    "fulfillmentUpdatesSpecification": [FulfillmentUpdatesSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_FulfillmentUpdatesSpecification.html),
    "postFulfillmentStatusSpecification": [PostFulfillmentStatusSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PostFulfillmentStatusSpecification.html)
}
```
+ Change the `active` field to `true` for Amazon Lex V2 to call the code hook at that point in the conversation.
+ Change the `enabled` field to `true` for Amazon Lex V2 to allow the code hook to run normally. If you mark it `false`, Amazon Lex V2 acts as if the code hook returned successfully.
+ Use the `fulfillmentUpdatesSpecification` field to specify the messages that appear to update the user during fulfillment of the intent and the timing associated with them.
+ Use the `postFulfillmentStatusSpecification` field to specify the messages and actions that occur after the code hook succeeds, fails, or times out.

You can invoke the Lambda code hook at the following points in a conversation by setting the `active` and `enableCodeHookInvocation`/`enabled` fields to `true`:

## During the initial response
<a name="lambda-hook-initial-response"></a>

To invoke the Lambda function in the initial response after the intent is recognized, use the `codeHook` structure in the `initialResponse` field of the [CreateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_CreateIntent.html) or [UpdateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_UpdateIntent.html) operation. The `initialResponse` field maps to the following [InitialResponseSetting](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_InitialResponseSetting.html) object:

```
"initialResponse": {
    "codeHook": {
        "active": boolean,
        "enableCodeHookInvocation": boolean,
        "invocationLabel": string,
        "postCodeHookSpecification": [PostDialogCodeHookInvocationSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PostDialogCodeHookInvocationSpecification.html),
    },
    "initialResponse": [FulfillmentUpdatesSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_FulfillmentUpdatesSpecification.html),
    "nextStep": [PostFulfillmentStatusSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PostFulfillmentStatusSpecification.html),
    "conditional": [ConditionalSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ConditionalSpecification.html)
}
```

## After slot elicitation or during slot re-elicitation
<a name="lambda-hook-elicit-slot"></a>

To invoke the Lambda function after eliciting a slot value, use the `slotCaptureSetting` field within the `valueElicitation` field of the [CreateSlot](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_CreateSlot.html) or [UpdateSlot](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_UpdateSlot.html) operation. The `slotCaptureSetting` field maps to the following [SlotCaptureSetting](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_SlotCaptureSetting.html) object:

```
"slotCaptureSetting": {
    "captureConditional": [ConditionalSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ConditionalSpecification.html),
    "captureNextStep": [DialogState object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_DialogState.html),
    "captureResponse": [ResponseSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ResponseSpecification.html),
    "codeHook": {
        "active": true,
        "enableCodeHookInvocation": true,
        "invocationLabel": string,
        "postCodeHookSpecification": [PostDialogCodeHookInvocationSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PostDialogCodeHookInvocationSpecification.html),
    },
    "elicitationCodeHook": {
        "enableCodeHookInvocation": boolean,
        "invocationLabel": string
    },
    "failureConditional": [ConditionalSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ConditionalSpecification.html),
    "failureNextStep": [DialogState object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_DialogState.html),
    "failureResponse": [ResponseSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ResponseSpecification.html)
}
```
+ To invoke the Lambda function after slot elicitation is successful, use the `codeHook` field.
+ To invoke the Lambda function after slot elicitation fails and Amazon Lex V2 attempts to retry slot elicitation, use the `elicitationCodeHook` field.

## After intent confirmation or denial
<a name="lambda-hook-confirm-intent"></a>

To invoke the Lambda function when confirming an intent, use the `intentConfirmationSetting` field of the [CreateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_CreateIntent.html) or [UpdateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_UpdateIntent.html) operation. The `intentConfirmation` field maps to the following [IntentConfirmationSetting](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_IntentConfirmationSetting.html) object:

```
"intentConfirmationSetting": {
    "active": boolean,
    "codeHook": {
        "active": boolean,
        "enableCodeHookInvocation": boolean,
        "invocationLabel": string,
        "postCodeHookSpecification": [PostDialogCodeHookInvocationSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PostDialogCodeHookInvocationSpecification.html),
    },
    "confirmationConditional": [ConditionalSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ConditionalSpecification.html),
    "confirmationNextStep": [DialogState object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_DialogState.html),
    "confirmationResponse": [ResponseSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_DialResponseSpecificationogState.html),
    "declinationConditional": [ConditionalSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ConditionalSpecification.html),
    "declinationNextStep": [FulfillmentUpdatesSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_FulfillmentUpdatesSpecification.html),
    "declinationResponse": [PostFulfillmentStatusSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PostFulfillmentStatusSpecification.html),
    "elicitationCodeHook": {
        "enableCodeHookInvocation": boolean,
        "invocationLabel": string,
    },
    "failureConditional": [ConditionalSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ConditionalSpecification.html),
    "failureNextStep": [DialogState object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_DialogState.html),
    "failureResponse": [ResponseSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_ResponseSpecification.html),
    "promptSpecification": [PromptSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PromptSpecification.html)
}
```
+ To invoke the Lambda function after the user confirms the intent and its slots, use the `codeHook` field.
+ To invoke the Lambda function after the user denies the intent confirmation and Amazon Lex V2 attempts to retry slot elicitation, use the `elicitationCodeHook` field.

## During intent fulfillment
<a name="lambda-hook-fulfill-intent"></a>

To invoke the Lambda function to fulfill an intent, use the `fulfillmentCodeHook` field in the [CreateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_CreateIntent.html) or [UpdateIntent](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_UpdateIntent.html) operation. The `fulfillmentCodeHook` field maps to the following [FulfillmentCodeHookSettings](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_FulfillmentCodeHookSettings.html) object:

```
{
    "active": boolean,
    "enabled": boolean,
    "fulfillmentUpdatesSpecification": [FulfillmentUpdatesSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_FulfillmentUpdatesSpecification.html),
    "postFulfillmentStatusSpecification": [PostFulfillmentStatusSpecification object](https://docs.aws.amazon.com/lexv2/latest/APIReference/API_PostFulfillmentStatusSpecification.html)
}
```

3. Once you set the conversation stages at which to invoke the Lambda function, use the `BuildBotLocale` operation to rebuild the bot in order to test the function.