I would like to ask for a slot first with a question that can be answered with text, and then, if the slot is not filled, ask for the same slot with buttons.
I have tried it with with this custom action.
class AskForComidaAction(Action):
def __init__(self):
self.first_time = True
def name(self) -> Text:
return "action_ask_comida"
def run(
self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
) -> List[EventType]:
if self.first_time:
dispatcher.utter_message(f"¿Qué tipo de comida te gustaría pedir?")
self.first_time = False
else:
dispatcher.utter_message(
text=f"No lo he entendido, ¿qué tipo de comida te gustaría pedir?",
buttons=[{"title": p, "payload": p} for p in ['Pizza', 'Hamburguesa', 'Ensalada']]
)
return []
This action works, the problem is that the parameter first_time is only True when the action server starts, not when a conversation starts.
I think it is a common misunderstand for rasa starter, I have do the same thing like you, then somebody teach me to use slot. You should always use slot instead of variable, because it is the bot’s memory .
Actually I use the slot comida and this action is to ask about it.
I know what I could add in responses utter_ask_comida with a question or buttons, but I want to ask first with a question, and then, if the slot is not filled with the user’s text, ask again with buttons.
Sorry for not being clear earlier, I have an entity with the same name as the slot to be able to extract it from the user’s text, but I would like to limit the possible answers after asking once.
then I have changed the action that asks for the slot as follows:
class AskForComidaAction(Action):
def __init__(self):
self.first_time = True
def name(self) -> Text:
return "action_ask_comida"
def run(
self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
) -> List[EventType]:
first_time_buttons = tracker.get_slot("first_time_buttons")
if first_time_buttons:
dispatcher.utter_message(f"¿Qué tipo de comida te gustaría pedir?")
return [SlotSet("first_time_buttons", False)]
else:
dispatcher.utter_message(
text=f"No lo he entendido, ¿qué tipo de comida te gustaría pedir?",
buttons=[{"title": p, "payload": p} for p in ['Pizza', 'Hamburguesa', 'Ensalada']]
)
return []
and then in the form validation, I create a function that validates the slot only to set the value of first_time_buttons back to True, since I ask this way for multiple slots.