# Custom form utterance

**URL:** <https://forum.rasa.com/t/custom-form-utterance/49788>\
**Category:** Rasa Open Source\
**Created:** [December 6, 2021, 8:10pm UTC](https://forum.rasa.com/t/custom-form-utterance/49788 "2021-12-06T20:10:52Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![vapdev](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/vapdev/32/18469_2.png) [@vapdev](https://forum.rasa.com/u/vapdev)\
**Post date:** [December 6, 2021, 8:10pm UTC](https://forum.rasa.com/t/custom-form-utterance/49788/1 "2021-12-06T20:10:52Z")

</div>

This is my form

 ![image](https://europe1.discourse-cdn.com/flex013/uploads/rasa/original/3X/6/a/6ac7e726a31b01173071f3f0a02be439ea5fd864.png)

This is my form validation class:

```auto
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

 ![image](https://europe1.discourse-cdn.com/flex013/uploads/rasa/original/3X/3/4/34c5cb2a393eac49c459af920ac17a958316f338.png)

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

 ![image](https://europe1.discourse-cdn.com/flex013/uploads/rasa/original/3X/8/a/8a7fa31d9cd819c9a783e6d3494658c042d956b7.png)

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

---

<div class="post-metadata">

**Author:** ![vapdev](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/vapdev/32/18469_2.png) [@vapdev](https://forum.rasa.com/u/vapdev)\
**Post date:** [December 7, 2021, 11:49am UTC](https://forum.rasa.com/t/custom-form-utterance/49788/2 "2021-12-07T11:49:22Z")

</div>

Commenting to reach more people, because post was hidden

---

<div class="post-metadata">

**Author:** ![ChrisRahme](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/chrisrahme/32/15572_2.png) [@ChrisRahme](https://forum.rasa.com/u/ChrisRahme)\
**Post date:** [December 7, 2021, 7:05pm UTC](https://forum.rasa.com/t/custom-form-utterance/49788/3 "2021-12-07T19:05:31Z")

</div>

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?
