Use Listen action inside Custom action and get User's response

I have a scenario where I need ‘from’ and ‘to’ dates from a user, and have several use cases like user entered both dates in one message, or entered one date or entered no date at all.

I want to handle all these using custom actions by my own code. So other-than FormAction, how can I ask the user about dates (that’s done using dispatcher utter template), but how can I again wait for users response (We can return action_listen as follow up actions) and get this response in my tracker and again process it inside my custom action e.g. Fill from_date slot if not filled or same with a to_date slot.

def run(self, dispatcher, tracker, domain):
    from_flag = 0
    to_flag = 0
    msg = tracker.latest_message['text']
    DuckTime = DUCKLING.parse_time(msg)
    
    if len(DuckTime) >= 2 :
        if from_flag == 0:    
            from_var = DuckTime[0]['value']['value'][:10]
            from_flag = from_flag + 1
        if to_flag == 0:
            to_var = DuckTime[1]['value']['value'][:10]
            to_flag = to_flag + 1
    elif len(DuckTime) == 1:
        if from_flag == 0 and tracker.get_slot("from_time") == None:    
            from_var = DuckTime[0]['value']['value'][:10]
            from_flag = from_flag + 1
            dispatcher.utter_template("utter_ask_to_time", tracker)
            
            return[SlotSet("from_time", from_var), FollowupAction("action_listen")]
            
        elif to_flag == 0:
            to_var = DuckTime[0]['value']['value'][:10]
            to_flag = to_flag + 1
    else:
        dispatcher.utter_template("utter_valid_dates", tracker)
        FollowupAction("action_listen")
    return[SlotSet("from_time", from_var), SlotSet("to_time", to_var)]

it’s pretty interesting , i have one doubt though , Imagine i have a story like this

*inform

  • action_one
  • action_two

*goodbye

  • action_three

Say action_three has implemented FollowUpAction(“action_one”) and it has forced execution of action_one . So will my bot be running in the sequence action_one > action_two > wait for goodbye intent >action_three ? or after executing action_one it will simply end executing this storyline ?

thanks in advance :slight_smile:

i’m not sure but it might gonna run only action_one after action_three. It will not follow inform intent sequence, so action_two will not gonna run unless forced.

Is there any way to do so ? i am in search of such functionality

It sounds like you are, like me, trying to trigger a specific intent following user input, to guarantee the user response (and any extracted entities) are directed toward a specific custom action. Is this correct?

I’m trying to implement a questionnaire (similar to FormAction or slot filling) using Custom Actions in Javascript but am having trouble capturing user input from the following action_listen event. Seems the only way to do this is to train it to recognize the different types of responses and to classify them into separate intents.

I think i might be able to answer this but will you be able to explain your requirements clearly.

It will go action_one > action_two!

If user then gives /goodbye intent then it will run action_three. It doesn’t wait for the user to say goodbye but more like predict that the next intent given will be /goodbye and if so run action_three.

If user does not give /goodbye it does not run action_three because your story says so. You can verify this in interactive learning

Stories are like flowcharts. This as per my understanding of RASA. so i might be wrong

I found/inform to be difficult as well, so i used the same intent for setting the slot. Meaning if you have en intent /book_table in restaurant bot i would train the intent /book_table with different possible entities. I dont use a separate/inform intent to get the required form slots/info.

This works for me pretty well especially when user asks “book a table” and bot replies with “enter number of people” and user enters again “book table for 5” instead of just “5”. You could use multiple intents in story like *intent OR book_table .

So the training file for book_table would look like this:

- book table for [five](number)
- book table for [5](number)
- book for [10](number)
- [10](number)
- [5](number)
- [4](number) people

I know if we enter just a number it will consider the intent as book_table. So I would go with giving unique entities for each intent and maybe forcing a user to use a particular keyword like “5 people

Another solution would be to take the text as it is using tracker.latest_message['text'] and in the custom action you can extract entities. Probably not the best solution as you have a lot of stuff to handle!

Perhaps this is not the best solution as more wrong intents can be classified but adjusting the fallback policy slightly I was able to overcome this! try it out. It did work for. If anyone has a better solution please do tell!

@akelad