Lambda and Lex integration no String-argument constructor/factory method to deserialize from String value

346 Views Asked by At

I'm new to Lex integration with Lambda, have used lambda before with Connect but not sure why this sample code is failing on me and don't understand the error message.

I have two slots setup in Lex (empid and fever). The utterance kicks of the bot and then I get the error message instead of the question "please enter your employee id?".

import json

def build_response(message):
    return {
        "dialogAction":{
            "type":"Close",
            "fulfillmentState":"Fulfilled",
            "message":{
                "contentType":"PlainText",
                "content":message
            }
        }
    }

def elicit_slot(intent_name, slots, slot_to_elicit, message):
    return {
        'dialogAction': {
            'type': 'ElicitSlot',
            'intentName': intent_name,
            'slots': slots,
            'slotToElicit': slot_to_elicit,
            'message': message
        }
    }

def delegate(session_attributes, slots):
    return {
        'sessionAttributes': session_attributes,
        'dialogAction': {
            'type': 'Delegate',
            'slots': slots
        }
    }

def perform_action(intent_request):
    source = intent_request['invocationSource']   # DialogCodeHook or FulfillmentCodeHook
    slots = intent_request['currentIntent']['slots']  # your slots 
    if source == 'DialogCodeHook':
        # Perform basic validation on the supplied input slots.
        if slots['empid'] is None:  # or any other validation that you want to perform
            return elicit_slot(
                intent_request['currentIntent']['name'], # current intent name
                slots, # current intent slots
                'empid',  # slot name
                'Please enter your employee id'  # prompt the user to empid
            )
        if slots['fever'] is None:
            return elicit_slot(
                intent_request['currentIntent']['name'], # current intent name
                slots, # current intent slots
                'fever',  # slot name
                'Do you have a fever?' # prompt the answer do you have a fever
            )
        # delegate means all slot validation are done, we can move to Fulfillment
        return delegate(output_session_attributes, slots) 
    if source == 'FulfillmentCodeHook':
        #result = your_api_call(slots['city'], slots['country'])
        result = "Your employee id is you answered to having a fever."
        return build_response(result)  # display the response back to user

def dispatch(intent_request):
    intent_name = intent_request['currentIntent']['name']
    # Dispatch to your bot's intent handlers
    if intent_name == 'covidqs':
        return perform_action(intent_request)
    raise Exception('Intent with name ' + intent_name + ' not supported')

def lambda_handler(event, context):
    #logger.debug(event)
    return dispatch(event)

Am getting this error:

An error has occurred: Invalid Lambda Response: Received invalid response from Lambda: Can not construct instance of Message: no String-argument constructor/factory method to deserialize from String value ('Please enter your employee id') at [Source: {"dialogAction": {"type": "ElicitSlot", "intentName": "covidqs", "slots": {"empid": null, "fever": null}, "slotToElicit": "empid", "message": "Please enter your employee id"}}; line: 1, column: 143]
1

There are 1 best solutions below

0
ShujolNYC On

I figured this out. The message response has to be in a specific format. So where it is

"message": message 

it should have been

"message":{
    "contentType":"PlainText",
    "content":message
 }