Resetting Slots during conversation

Hey, I have a bot that asks the user for an order number and their postcode, to retrieve information on when their package was shipped.

I implemented a system where the bot checks, in the actions.py, if it’s a valid combination of ordernumber/postcode - if it’s not, you have the option to change the ordernumber or the postcode, done via buttons (/change_ordernumber, /change_postcode intents). If it’s still not right, you get the option to change it again, until it is correct.

Now the problem is, when the user inputs a right combination. The slots are set and the information is given to the user. But since the checking, if the combination is valid, is done in the actoins.py, I’m not sure how to write a story that has a “success”. I would like to reset both slots once the success condition is reached in the actions.py but I’m not sure how.

Here are a few example stories:

7: Ask for Order and Postcode 123456 54321

  • greet
    • utter_greet
  • shipping
    • utter_shipping_info
    • utter_ask_for_more_questions
  • orderstatus
    • get_order_form
    • form{“name”: “get_order_form”}
    • slot{“requested_slot”:“ordernumber”}
  • inform_order{“ordernumber”:“123456”}
    • get_order_form
    • slot{“ordernumber”:“123456”}
    • slot{“requested_slot”:“postcode”}
  • inform_postcode{“postcode”:“54321”}
    • get_order_form
    • slot{“postcode”:“54321”}
    • slot{“requested_slot”:null}
    • form{“name”: null}
  • affirm
    • action_reset_slot_order
    • action_reset_slot_postcode
    • slot{“ordernumber”:null}
    • slot{“postcode”:null}
    • utter_ready_for_next_question
    • action_restart
  • financing
    • utter_financing
    • utter_ask_for_more_questions
  • deny
    • utter_glad_to_help
    • utter_goodbye
    • slot{“requested_slot”:null}
    • action_reset_slot_order
    • action_reset_slot_postcode
    • action_restart

32: Order status, ordernumber, postcode, wrong ordernumber

  • orderstatus
    • get_order_form
    • form{“name”:“get_order_form”}
    • slot{“requested_slot”:“ordernumber”}
  • inform_postcode{“ordernumber”:“400005”}
    • slot{“ordernumber”:“400005”}
    • get_order_form
    • slot{“requested_slot”:“postcode”}
    • action_reset_slot_order
    • slot{“ordernumber”:null}
  • inform_postcode{“postcode”:“46240”}
    • get_order_form
    • slot{“postcode”:“46240”}
    • slot{“ordernumber”:“400005”}
    • form{“name”:null}
    • slot{“requested_slot”:null}
  • change_ordernumber
    • action_reset_slot_order
    • slot{“ordernumber”:null}
    • utter_enter_ordernumber_again
  • inform_order{“ordernumber”:“400004”}
    • get_order_form
    • form{“name”:“get_order_form”}
    • slot{“ordernumber”:“400004”}
    • form{“name”:null}
    • slot{“requested_slot”:null}

34: Story from conversation with test

  • hours
    • utter_hours
    • utter_ask_for_more_questions
  • orderstatus
    • get_order_form
    • form{“name”:“get_order_form”}
    • slot{“requested_slot”:“ordernumber”}
  • inform_order{“ordernumber”:“400004”}
    • get_order_form
    • slot{“ordernumber”:“400004”}
    • slot{“requested_slot”:“postcode”}
  • inform_postcode{“postcode”:“46241”}
    • get_order_form
    • slot{“postcode”:“46241”}
    • form{“name”:null}
    • slot{“requested_slot”:null}
  • change_postcode
    • action_reset_slot_postcode
    • slot{“postcode”:null}
    • utter_enter_postcode_again
  • inform_postcode{“postcode”:“46240”}
    • slot{“postcode”:“46240”}
    • get_order_form
    • form{“name”:“get_order_form”}
    • form{“name”:null}
    • slot{“requested_slot”:null}

I could just do a slot reset via stories after inform_postcode, but that would mean that the customer would have to put in both the order number and the postcode again, instead of just correcting one.

In my actions.py, I have the following check, if the combination is correct:

    if is_correct == 0:
        dispatcher.utter_template('utter_wrong_postcode_ordernumber', tracker, ordernumber=ordernumber, postcode=postcode)
    else:
        data = {'odernumber': ordernumber}
        r = requests.post(url=api_URL, data=data, headers=headers)
        response = r.text
        response_json = json.loads(response)
        paid = response_json['message']['bezahlt']
        shipped = response_json['message']['versand']
        shipped_date = response_json['message']['versanddatum']
        if (shipped_date != None) and (shipped_date != '0000-00-00'):
            shipped_date_obj = datetime.strptime(shipped_date, '%Y-%m-%d')
            weekday = ("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag")[shipped_date_obj.weekday()]
            shipped_date_german = shipped_date_obj.strftime('%d.%m.%Y')
            shipped_string = weekday + " den " + shipped_date_german
        else:
            shipped_string = False
        if paid:
            if shipped:
                if shipped_string == False:
                    dispatcher.utter_template('utter_no_shipping_info', tracker)
                else:
                    dispatcher.utter_template("utter_shipped", tracker, shipped_date=shipped_string)
            else:
                dispatcher.utter_template('utter_paid_not_shipped', tracker)
        else:
            dispatcher.utter_template('utter_not_paid', tracker)

        dispatcher.utter_template('utter_ask_for_more_questions', tracker)

and the following classes to reset the slots:

class ResetSlotOrder(Action):
    """Sets slotvalue to None"""
    def name(self):
        return "action_reset_slot_order"

    def run(self, dispatcher, tracker, domain):
        return [SlotSet("ordernumber", None)]

class ResetSlotPostcode(Action):
    """Sets slotvalue to None"""
    def name(self):
        return "action_reset_slot_postcode"

    def run(self, dispatcher, tracker, domain):
        return [SlotSet("postcode", None)]

I tried calling the run functions to reset the slots but it does nothing.

Does anyone have any advice?

Try adding a return[] after the utter_wrong_postcode_ordernumber and a return [SlotSet(“postcode”, None), SlotSet(“ordernumber”, None)] at the end of the function. Don’t forget to add the slot{“postcode”:null} and the slot{“ordernumber”:null} to your stories to mark the difference between success and failure.

Thanks for your quick reply!

For clarification; does RASA automatically know that if the slots are set to null, after an inform_postcode user action is performed, that the ordernumber/postcode combination was correct?

Because if it is not correct, I don’t want to reset both slots. I want to give the user the opportunity to change one of the two or both (in case the user entered a wrong postcode or mistyped the ordernumber).

I worked on this a bit more yesterday and “solved” this by adding an intent for “/different_order”. If the user asks to check a different order, it resets both slots in the story.md. That seems to work quite well.

Not automatically, you need to add some stories so rasa can learn that. And your slots cannot be of type unfeaturized.