Using an AWS Lambda function - Amazon Lex

Using an AWS Lambda function

This section describes how to attach a Lambda function to a bot alias and the structure of the event data that Amazon Lex V2 provides to a Lambda function. Use this information to parse the input to your Lambda code. It also explains the format of the response that Amazon Lex V2 expects your Lambda function to return.

Amazon Lex V2 uses one Lambda function per bot alias per language instead of one Lambda function for each intent. To use an individual function for each intent, the Lambda function router section provides a function that you can use.

You can use Lambda functions at the following points in a conversation with a user:

  • Before the conversation starts. For example, after telling the user the recognized intent.

  • 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 the intent has been fulfilled. For example, to switch to an intent to order a drink.

Attaching a Lambda function to a bot alias

With Amazon Lex V2 you indicate that an intent should use a Lambda function for each intent. But you assign the Lambda function that your intents use for each language supported by a bot alias. That way you can create a Lambda function tailored to each language that your bot alias supports.

You indicate that an intent should use a Lambda function using the console or the CreateIntent or UpdateIntent operation. In the intent editor, you turn on Lambda functions in the advanced options in the Dialog code hook section for each response in the editor.

There are two ways to control how Amazon Lex V2 calls the code hook for a response. You can mark the code hook active or inactive, and you can mark in enabled or disabled.

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.

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.


                The code hooks section of the Amazon Lex V2 intent
                    editor.

You define the Lambda function to use in each bot alias. The same Lambda function is used for all intents in a language supported by the bot.

To choose a Lambda function to use with a bot alias

  1. Open the Amazon Lex console at https://console.aws.amazon.com/lexv2/.

  2. From the list of bots, choose the name of the bot that you want to use.

  3. From Create versions and aliases for deployment, choose View aliases.

  4. From the list of aliases, choose the name of the alias that you want to use.

  5. From the list of supported languages, choose the language that the Lambda function is used for.

  6. Choose the name of the Lambda function to use, then choose the version or alias of the function.

  7. Choose Save to save your changes.

Input event format

The following is the general format of an Amazon Lex V2 event that is passed to a Lambda function. Use this information when you're writing your Lambda function.

Note

The input format may change without a corresponding change to the messageVersion. Your code shouldn't throw an error if new fields are present.

{ "messageVersion": "1.0", "invocationSource": "DialogCodeHook | FulfillmentCodeHook", "inputMode": "DTMF | Speech | Text", "responseContentType": "CustomPayload | ImageResponseCard | PlainText | SSML", "sessionId": "string", "inputTranscript": "string", "invocationLabel": "string", "bot": { "id": "string", "name": "string", "aliasId": "string", "localeId": "string", "version": "string" }, "interpretations": [ { "intent": { "confirmationState": "Confirmed | Denied | None", "name": "string", "slots": { "string": { "value": { "interpretedValue": "string", "originalValue": "string", "resolvedValues": [ "string" ] } }, "string": { "shape": "List", "value": { "interpretedValue": "string", "originalValue": "string", "resolvedValues": [ "string" ] }, "values": [ { "shape": "Scalar", "value": { "originalValue": "string", "interpretedValue": "string", "resolvedValues": [ "string" ] } }, { "shape": "Scalar", "value": { "originalValue": "string", "interpretedValue": "string", "resolvedValues": [ "string" ] } } ] } }, "state": "Failed | Fulfilled | FulfillmentInProgress | InProgress | ReadyForFulfillment | Waiting", "kendraResponse": { // Only present when intent is KendraSearchIntent. For details, see // https://docs.aws.amazon.com/kendra/latest/dg/API_Query.html#API_Query_ResponseSyntax } }, "nluConfidence": number, "sentimentResponse": { "sentiment": "string", "sentimentScore": { "mixed": number, "negative": number, "neutral": number, "positive": number } } } ], "proposedNextState": { "dialogAction": { "slotToElicit": "string", "type": "Close | ConfirmIntent | Delegate | ElicitIntent | ElicitSlot" }, "intent": { "name": "string", "confirmationState": "Confirmed | Denied | None", "slots": {}, "state": "Failed | Fulfilled | InProgress | ReadyForFulfillment | Waiting" }, "prompt": { "attempt": "string" } }, "requestAttributes": { "string": "string" }, "sessionState": { "activeContexts": [ { "name": "string", "contextAttributes": { "string": "string" }, "timeToLive": { "timeToLiveInSeconds": number, "turnsToLive": number } } ], "sessionAttributes": { "string": "string" }, "runtimeHints": { "slotHints": { "string": { "string": { "runtimeHintValues": [ { "phrase": "string" }, { "phrase": "string" } ] } } } }, "dialogAction": { "slotToElicit": "string", "type": "Close | ConfirmIntent | Delegate | ElicitIntent | ElicitSlot" }, "intent": { "confirmationState": "Confirmed | Denied | None", "name": "string", "slots": { "string": { "value": { "interpretedValue": "string", "originalValue": "string", "resolvedValues": [ "string" ] } }, "string": { "shape": "List", "value": { "interpretedValue": "string", "originalValue": "string", "resolvedValues": [ "string" ] }, "values": [ { "shape": "Scalar", "value": { "originalValue": "string", "interpretedValue": "string", "resolvedValues": [ "string" ] } }, { "shape": "Scalar", "value": { "originalValue": "string", "interpretedValue": "string", "resolvedValues": [ "string" ] } } ] } }, "state": "Failed | Fulfilled | FulfillmentInProgress | InProgress | ReadyForFulfillment | Waiting", "kendraResponse": { // Only present when intent is KendraSearchIntent. For details, see // https://docs.aws.amazon.com/kendra/latest/dg/API_Query.html#API_Query_ResponseSyntax } }, "originatingRequestId": "string" } }, "transcriptions": [ { "transcription": "string", "transcriptionConfidence": number, "resolvedContext": { "intent": "string" }, "resolvedSlots": { "string": { "shape": "List", "value": { "originalValue": "string", "resolvedValues": [ "string" ] }, "values": [ { "shape": "Scalar", "value": { "originalValue": "string", "resolvedValues": [ "string" ] } }, { "shape": "Scalar", "value": { "originalValue": "string", "resolvedValues": [ "string" ] } } ] } } } ] }

Note the following additional information about the event fields:

  • messageVersion – The version of the message that identifies the format of the event data going into the Lambda function and the expected format of the response from a Lambda function.

    Note

    You configure this value when you define an intent. In the current implementation, only message version 1.0 is supported. Therefore, the console assumes the default value of 1.0 and doesn't show the message version.

  • invocationSource – Indicates the action that called the Lambda function. When the source is DialogCodeHook, the Lambda function was called after input from the user. When the source is FulfillmentCodeHook the Lambda function was called after all required slots have been filled and the intent is ready for fulfillment.

  • inputMode – The type of user utterance. Valid values are Speech, DTMF, or Text.

  • responseContentType – Determines whether the bot responds to user input with text or speech.

  • sessionId – Session identifier used for the conversation.

  • inputTranscript – The text that was used to process the input from the user. For text or DTMF input, this is the text that the user typed. For speech input, this is the text that was recognized from the speech.

  • invocationLabel – A value that indicates the response that invoked the Lambda function. You can set invocation labels for the initial response, slots, and confirmation response.

  • bot – Information about the bot that processed the request.

    • id – The identifier assigned to the bot when you created it. You can see the bot ID in the Amazon Lex V2 console on the bot Settings page.

    • name – The name that you gave the bot when you created it.

    • aliasId – The identifier assigned to the bot alias when you created it. You can see the bot alias ID in the Amazon Lex V2 console on the Aliases page. If you can't see the alias ID in the list, choose the gear icon on the upper right and turn on Alias ID.

    • localeId – The identifier of the locale that you used for your bot. For a list of locales, see Languages and locales supported by Amazon Lex V2.

    • version – The version of the bot that processed the request.

  • interpretations – One or more intents that Amazon Lex V2 considers possible matches to the user's utterance. For more information, see Interpretation.

  • proposedNextState – The predicted next state of the dialog between the user and the bot if the Lambda function sets the dialogAction of the sessionState to Delegate. If you override the dialog behavior in sessionState, the next state depends on the settings that you return from your Lambda function. You can use the information to modify your Lambda function's behavior based on what Amazon Lex V2 proposes as the next action. Note that this structure is only present when the invocationSource field is DialogCodeHook and when the predicted dialog action is ElicitSlot.

    • dialogAction – Contains the slotToElicit and the type of action that Amazon Lex V2 proposes in the next turn.

    • intent – The intent that the bot has determined that the user is trying to fulfill. For more information, see Intent.

    • prompt – The prompt that the bot uses to elicit the slot.

  • requestAttributes – Request-specific attributes that the client sends in the request. Use request attributes to pass information that doesn't need to persist for the entire session.

  • sessionState – The current state of the conversation between the user and your Amazon Lex V2 bot. For more information about the session state, see SessionState.

    • dialogAction – Determines the type of action that Amazon Lex V2 should take in response to the Lambda function. This field is always blank for now.

  • transcriptions – one or more transcriptions that Amazon Lex V2 considers possible matches to the user's audio utterance. For more information, see Using voice transcription confidence scores.

Response format

Amazon Lex V2 expects a response from your Lambda function in the following format:

{ "sessionState": { "activeContexts": [ { "name": "string", "contextAttributes": { "key": "value" }, "timeToLive": { "timeToLiveInSeconds": number, "turnsToLive": number } } ], "sessionAttributes": { "string": "string" }, "runtimeHints": { "slotHints": { "string": { "string": { "runtimeHintValues": [ { "phrase": "string" }, { "phrase": "string" } ] } } } }, "dialogAction": { "slotElicitationStyle": "Default | SpellByLetter | SpellByWord", "slotToElicit": "string", "type": "Close | ConfirmIntent | Delegate | ElicitIntent | ElicitSlot" }, "intent": { "confirmationState": "Confirmed | Denied | None", "name": "string", "slots": { "string": { "value": { "interpretedValue": "string", "originalValue": "string", "resolvedValues": [ "string" ] } }, "string": { "shape": "List", "value": { "originalValue": "string", "interpretedValue": "string", "resolvedValues": [ "string" ] }, "values": [ { "shape": "Scalar", "value": { "originalValue": "string", "interpretedValue": "string", "resolvedValues": [ "string" ] } }, { "shape": "Scalar", "value": { "originalValue": "string", "interpretedValue": "string", "resolvedValues": [ "string" ] } } ] } }, "state": "Failed | Fulfilled | FulfillmentInProgress | InProgress | ReadyForFulfillment | Waiting" } }, "messages": [ { "contentType": "CustomPayload | ImageResponseCard | PlainText | SSML", "content": "string", "imageResponseCard": { "title": "string", "subtitle": "string", "imageUrl": "string", "buttons": [ { "text": "string", "value": "string" } ] } } ], "requestAttributes": { "string": "string" } }

Note the following additional information about the response fields:

  • sessionState – Required. The current state of the conversation with the user. The actual contents of the structure depends on the type of dialog action. For more information, see SessionState.

    • activeContexts – Contains information about the contexts that a user is using in a session. For more information, see ActiveContext and Setting intent context.

    • sessionAttributes – A map of key/value pairs representing session-specific context information. For more information, see Setting session attributes.

    • runtimeHints – Provides hints to the phrases that a customer is likely to use for a slot. For more information, see RuntimeHints.

    • dialogAction – Required. Determines the type of action that Amazon Lex V2 should take in response to the Lambda function.

      • slotElicitationStyle – Determines whether the slot uses spell-by-letter or spell-by-word style. For more information, see Using spelling styles to capture slot values .

      • slotToElicit – Required only when dialogAction.type is ElicitSlot. Defines the slot to elicit from the user.

      • type – Required. Defines the action that the bot should execute.

    • intent – The name of the intent that Amazon Lex V2 should use. Not required when dialogAction.type is Delegate or ElicitIntent.

      • state – Required. The state can only be ReadyForFulfillment if dialogAction.type is Delegate.

  • messages – Required if dialogAction.type is ElicitIntent. One or more messages that Amazon Lex V2 shows to the customer to perform the next turn of the conversation. If you don't supply messages, Amazon Lex V2 uses the appropriate message defined when the bot was created. For more information, see the Message data type.

    • contentType – The type of message to use.

    • content – If the message type is PlainText, CustomPayload, or SSML, the content field contains the message to send to the user.

    • imageResponseCard – If the message type is ImageResponseCard, contains the definition of the response card to show to the user. For more information, see the ImageResponseCard data type.

  • requestAttributes – Request-specific attributes that the client sent in the request.

Lambda router function

When you build a bot with the Amazon Lex V2 APIs, there is only one Lambda function per bot alias per language instead of a Lambda function for each intent. To use separate functions, you can create a router function that activates a separate function for each intent. The following is a 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