How to add basic permission validation with forms and user input -> ending the conversation if wrong answer is provided

Hi Guys,

after like searching 4 hours on the internet and trying out several things, I gave up fixing the error by myself.

I am new to rasa and just built the “getting started” contextual assistant. After I finished it and I wanted to add some custom logic.

I wanted to add a validation function, which checks if the slot ‘job_function’ is ‘sales manager’ otherwise it should directly end the form. This is my validation function:

    def get_allow_jobs() -> List[Text]:
        """Database of allowed job functions"""

        return [
            "sales manager",
        ]

    def validate_job_function(
            self,
            value: Text,
            dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any],
        ) -> Dict[Text, Any]:
            """validate_job_function"""
    				if any(tracker.get_latest_entity_values("job_function")):
    	        if value.lower() in self.get_allow_jobs():
    	            # validation succeeded, set the value of the "cuisine" slot to value
    	            return {"job_function": value}
    	        else:
    	            dispatcher.utter_message(f"Sorry, your job {value} is not allowed to contact sales, only sales manager allowed to contact sales. \n Please reach out to your sales manager")
    	            # validation failed, deactivating the form
    	            self.deactivate()

The problem is if I answer the question “what`s your job?” with lets say “engineer”. its return correctly my message from the validation but it directly start asking the question again “what´s your job”.

Can you help me? My goal is the messages gets send and the form is cancelled and the user could ask different question or say goodbye or do what ever he wants

Hi,

i resolved the issue by myself. I thought it could be helpful for others if i share it here. I think i misunderstood, what the validate_{slot} function can do. So i deleted it and created my own authorize_{slot} function, which checks the value of slot and returns True or false on a given input value. After this is implemented it into the request_next_slot() function.

def authorize_job_function(self,
                               dispatcher: CollectingDispatcher,
                               tracker: Tracker,
                               slot: Text,
                               value: Text):
        if tracker.get_slot(slot) != None and tracker.get_slot(slot) != value:
            dispatcher.utter_message(
                f"Sorry, your job {value} is not allowed to contact sales, only sales manager allowed to contact sales. \n Please reach out to your sales manager.")
            return False
        else:
            return True

    def request_next_slot(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any]
    ):
        intent = tracker.latest_message.get("slot", {}).get("name")
        if intent == 'cancel':
            return self.deactivate()
        else:
            for slot in self.required_slots(tracker):
                if self._should_request_slot(tracker, slot):

                    if not self.authorize_job_function(dispatcher, tracker, 'job_function', 'sales manager'):
                        return self.deactivate()

                    dispatcher.utter_message(template="utter_ask_{}".format(slot), **tracker.slots)
                    return [SlotSet(REQUESTED_SLOT, slot)]
            return None
2 Likes

hi @philschmid I have the same problem! just a question. i just want to confirm where you placed the authorize_{slot} function; not inside the FormValidationAction, right?