Custom form utterance

This is my form

This is my form validation class:

class ValidateCriarSolicitacaoForm(FormValidationAction):
    def name(self) -> Text:
        return "validate_criar_solicitacao_form"

    # Validate ds_analise, it's got to have at least X words
    def validate_ds_analise(
        self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:
        dispatcher.utter_message("tipo " + str(tracker.get_slot("ds_tipomodulo")))
        dispatcher.utter_message("flag " + str(tracker.get_slot("flag_nfe")))
        dispatcher.utter_message("analise " + str(tracker.get_slot("ds_analise")))
        if not 2 < len(slot_value.split(" ")) or len(slot_value) > 4000:
            dispatcher.utter_message(
                text="A descrição do problema deve ter entre 10 palavras  e 4000 caractéres. Reescreva-a, por favor."
            )
            return {"ds_analise": None}

        else:
            return {"ds_analise": slot_value}

    # Validate ds_tipomodulo even if typos using Levenshtein algorithm
    # Gets cd_tipomodulo if ds_tipomodulo is validated

    def validate_ds_tipomodulo(
        self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:
        user_input = (
            unicodedata.normalize("NFKD", slot_value.lower())
            .encode("ASCII", "ignore")
            .decode()
        )

        dispatcher.utter_message("tipo " + str(tracker.get_slot("ds_tipomodulo")))
        dispatcher.utter_message("flag " + str(tracker.get_slot("flag_nfe")))
        dispatcher.utter_message("analise " + str(tracker.get_slot("ds_analise")))

        events = []

        if slot_value == "NFE":
            dispatcher.utter_message("changing")
            events.append(SlotSet("flag_nfe", True))
        else:
            events.append(SlotSet("flag_nfe", False))

        if next(
            (e for e in tracker.latest_message["entities"] if e["entity"] == "outros"),
            None,
        ):
            events.append(SlotSet("ds_tipomodulo", None))

        rate = process.extractOne(
            user_input, TipoModulo().TIPOMODULO["DS_TIPOMODULO"].values.tolist()
        )
        if rate[1] >= 50:
            ds_tipomodulo = slot_value
            # if modulo isn't registered for the user
            if not DBOperations().get_query(
                f"select * from produtoempresa where CD_EMPRESA = {tracker.get_slot('cd_empresa')} and CD_PRODUTO = {TipoModulo().get_cd_produto_by_ds_tipomodulo(rate[0])}"
            ):
                tipomodulo = None
                dispatcher.utter_message(
                    text=f"Parece que o módulo selecionado ({rate[0]}) não está cadastrado para sua empresa, tente novamente."
                )

        else:
            tipomodulo = None
            dispatcher.utter_message(
                text="Não consegui encontrar nenhum módulo com esse nome, vamos tentar novamente?"
            )

        return events

    def validate_valid_rejeicao(
        self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:
        dispatcher.utter_message(tracker.get_slot("requested_slot"))
        dispatcher.utter_message("tipo " + str(tracker.get_slot("ds_tipomodulo")))
        dispatcher.utter_message("flag " + str(tracker.get_slot("flag_nfe")))
        dispatcher.utter_message("analise " + str(tracker.get_slot("ds_analise")))
        if slot_value:
            pass

    async def required_slots(
        self,
        slots_mapped_in_domain: List[Text],
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:
        req_slots = []
        if tracker.get_slot("flag_nfe") is True:
            dispatcher.utter_message("Flag ta true")
            req_slots.extend(["valid_rejeicao", "nr_rejeicao", "ds_analise"])
        else:
            dispatcher.utter_message("Flag ta false")
            req_slots.extend(["ds_tipomodulo", "ds_analise"])

        if tracker.get_slot("valid_rejeicao") is True:
            req_slots.extend(["nr_rejeicao"])
            dispatcher.utter_message("Valida tru")
        else:
            req_slots.extend(["ds_analise"])
            dispatcher.utter_message("Valida false")
        return req_slots

Firstly, it asks for ds_tipomodulo

if ds_tipomodulo == ‘NFE’, I “try” to set flag_nfe to True. So if flag_nfe is true, I want the bot to ask for valid_rejeicao. If valid_rejeicao is true, I want the bot to ask for nr_rejeicao, if valid_rejeicao is not true i want it to ask for ds_analise.

If ds_tipmodulo is not NFE, i want it to ask for ds_tipoanalise, and finish.

The flow I want is something like this

I tried a lot but its not working properly yet. I’m new to Rasa and kinda new to Python too I’d really appreciate some help

Commenting to reach more people, because post was hidden

You need to use a custom FormValidationAction, and implement that logic in the required_slots() method, as you are doing right now.

Can you tell me more about how exactly it’s not working? What is it doing that was not expected?