3

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

gourabk
  • 177
  • 1
  • 12
  • Double check your call of the `elicit_slot` function because your arguments don't match up. You do need to pass `slots` and don't need `'AMAZON.NUMBER'` there. Also you are trying to elicit slot `childCount` in the intent `HotelReservation`, but your image shows you don't have that slot in that intent. – Jay A. Little Apr 10 '19 at 05:41
  • But how can I get normal flow of slots and the lambda gets initiated only when childExist comes and thanks for helping – Gourab Konar Apr 10 '19 at 06:19
  • return elicit_slot ( session_attributes, 'HotelReservation', slots,'childCount', { 'contentType':'PlainText', 'content':'Please enter number of Children' } ) – Gourab Konar Apr 10 '19 at 06:28
  • still i am getting error response – Gourab Konar Apr 10 '19 at 06:28
  • 1
    Yes, that's better, but it probably errors because you didn't create `childCount` as a slot yet. BTW, your Lambda is initialized with every user input, and you are getting a "normal flow" thanks to your Lambda returning `delegate`, which will elicit the next required slot. And that's why @sid8491's answer tells you to create the slot and do not mark it as required. His answer should do the trick. – Jay A. Little Apr 10 '19 at 08:55

1 Answers1

3

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.

sid8491
  • 6,622
  • 6
  • 38
  • 64
  • Hi thanks for your help I have created childCount slot in my lex console but still I am getting this error:An error has occurred: Invalid Lambda Response: Received error response from Lambda: Unhandled I also have a response card associated with welcome slot where the user is asked to give slot-types like do you want to book a hotel ----yes or no in button options with slot_types – Gourab Konar Apr 10 '19 at 10:03
  • I have even unchecked the welcome slot as well along with childCount still I am getting this error – Gourab Konar Apr 10 '19 at 10:10
  • @GourabKonar there could be number of errors which could occur, it would be very hard to tell. better to put logger in your code and watch them in cloudwatch – sid8491 Apr 10 '19 at 10:23
  • @GourabKonar you have check marked & put your lambda function in `initialization and validation`? your lamda function will be called after all the slots are filled which are marked required, so it is not problem with your welcome slot i guess – sid8491 Apr 10 '19 at 10:33
  • Yes I have checked for intialization and validation – Gourab Konar Apr 10 '19 at 10:56
  • There was a problem in importing the lower() function ,now I am getting response in lex ,Thanks for helping......but the problem now is FulfillmentCodeHook is not at all working ,Even I am not getting logs inside the if condition – Gourab Konar Apr 11 '19 at 04:38
  • Also I have a Confirmation Prompt at the end before fulfillment – Gourab Konar Apr 11 '19 at 05:42
  • @GourabKonar i would recommend to post a new question for your new issue with all relevant code and logs. that would be easy to solve. – sid8491 Apr 11 '19 at 13:28
  • Hi currently I am having problem with sending a response cards .I am getting this error:- – Gourab Konar Apr 16 '19 at 11:44