Search code examples
pythonamazon-web-servicesaws-lambdaamazon-lex

Having problem in generating elicit slot response


I want to create a dialogHook for a certain slot rather better to say a validation type of thing .If the slot returns true then only I will fire my elicit slot otherwise it would go as usual.Please help what would be my approach.I am relatively new to lex.

I have tried to to make a dialoghook on childExists but it is not working.

def lambda_handler(event,context):
    os.environ['TZ']='America/New_York'
    time.tzset();
    logger.debug('event.bot.name={}'.format(event['bot']['name']))
    return dispatch(event);

def dispatch(intent_request):
    intent_name=intent_request['currentIntent']['name']
    if intent_name=='HotelReservation':
        return book_hotel(intent_request)

def book_hotel(intent_request):
    slots=intent_request['currentIntent']['slots']
    welcome=intent_request['currentIntent']['slots']['welcome']
    location=intent_request['currentIntent']['slots']['Location']
    fromDate=intent_request['currentIntent']['slots']['FromDate']
    adultCount=intent_request['currentIntent']['slots']['adultCount']
    nights=intent_request['currentIntent']['slots']['nights']
    childExists=intent_request['currentIntent']['slots']['childExists']
    source=intent_request['invocationSource']
    session_attributes={}
    if source=='DialogCodeHook'and childExists.lower()=='yes':
        session_attributes={}
        return elicit_slot (
        session_attributes,
            'HotelReservation',
            'childCount',
             'AMAZON.NUMBER',            
            {
            'contentType':'PlainText',
            'content':'Please enter number of Children'
            }
        )
    elif source=='DialogCodeHook':
        output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
        return delegate(output_session_attributes, intent_request['currentIntent']['slots'])
    else:

        return close (
            session_attributes,
                'Fulfilled',{
                'contentType':'PlainText',
                'content':'Here is the temparature in'
                }
            )


#for fullfillment function
def close(session_attributes,fulfillment_state,message):
    response={
        'sessionAttributes':session_attributes,
        'dialogAction':{
            'type':'Close',
            'fulfillmentState':fulfillment_state,
            'message':message
        }
    }
    return response
#for elicit slot return
def elicit_slot(session_attributes, intent_name,slots,slot_to_elicit,message):
                        response= {
                         'sessionAttributes': session_attributes,
                         'dialogAction': {
                         'type': 'ElicitSlot',
                         'intentName': intent_name,
                         'slots': slots,
                         'slotToElicit': slot_to_elicit,
                         'message': message
                         }
                       }
    return response;
def delegate(session_attributes, slots):
    return {
        'sessionAttributes': session_attributes,
        'dialogAction': {
            'type': 'Delegate',
            'slots': slots
        }
    }

Actually my slots should run as usual but after childExists slot I want to send a response of elicit This is the image of the slots available


Solution

  • As per my understanding, you are asking the user Do you have any children and storing the response in childExists slot, if the answer is yes then you want to ask number of children.

    So according to me, you need to have an extra slot childCount to store number of children. As this slot is not always required, do not mark this required in amazon lex console.

    Now, you will check this in your DialogCodeHook, and ask the user accordingly only when childExists == 'yes'and there is no value in childCount. We are using combination of these condition is to ensure it does not run indefinitely.

    def book_hotel(intent_request):
        slots = intent_request['currentIntent']['slots']
        welcome = slots['welcome']
        location = slots['Location']
        fromDate = slots['FromDate']
        adultCount = slots['adultCount']
        nights = slots['nights']
        childExists = slots['childExists']
        childCount = slots['childCount']
        source = intent_request['invocationSource']
        if source == 'DialogCodeHook':
            output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
            if childExists.lower() == 'yes':
                if not childCount:
                    return elicit_slot (
                        output_session_attributes,
                        'HotelReservation',
                        slots,
                        'childCount',            
                            {
                                'contentType':'PlainText',
                                'content':'Please enter number of Children'
                            }
                        )
            return delegate(output_session_attributes, intent_request['currentIntent']['slots'])
    
        if source == 'FulfillmentCodeHook':
            return close (
                output_session_attributes,
                    'Fulfilled',{
                    'contentType':'PlainText',
                    'content':'Here is the temparature in'
                    }
                )
    

    Hope it helps.