Need to build a bot which has an intent with required entities

Hi All, Actually I wanted to build a chatbot that has an intent to book an appointment. There are three entities for this intent ( which are mandatory) to book an appointment. I am confused on how to make these 3 entities as required so, that the chatbot prompts the user for all the required entities. Also if the user has given 1 entity in his/her statement then the chatbot should prompt for remaining two entities. I am not sure on how to achieve this, please suggest me on how to do this.

Welcome, @cs-2007! It looks like you’re looking to work with forms, which ask for required slots until they’re filled, before doing something (i.e. book an appointment) upon submitting.

1 Like

Hi @erohmensing! I am facing an issue with slot types, actually i wanted to fill a particular slot with multiple values through button clicks in UI. I am not sure on how to send the values from UI to rasa either I should use a coma separated list or an array. or should I give different values separated with blank space. And what code should I write in rasa to recieve these multiple values for a slot. Please help me with the same.

How is your UI connected to rasa? And what do you mean by fill a particular slot with multiple values through button clicks in UI – why are you filling your slot with multiple values, is it a list type?

Our UI is developed using Angular 6 and it is connected to rasa core by making a http call . By fill a particular slot with multiple values we mean that a slot should accept more than one value in some way. Also we are not sure that should we use list type or not. what do you suggest. Our goal is to fill the slot (ingredients) with multiple value like cheese,butter,roti,bread. How can we achieve this?

Yes I would say a list type is the way to go then! What you might also need is some sort of slot like list_complete where you confirm that the user has stopped adding ingredients if you’re looking to do something with that list. Since you normally check if all slots are filled before submitting a form, a list slot won’t work in the same way, which is why I would suggest direct confirmation.

I don’t believe you can append a list directly through SlotSet events, but you can pull the current list in the slot, append your next value, and then reset the slot as the new list.

1 Like

Please can you share some example code . I am not able to understand what needs to be done.

I’m sorry, I don’t have example code for this specific use case, what do you have set up so far? I would recommend getting started by implementing a FormAction first – you can check out the Formbot for an example of form actions. Start small and build up, don’t try to implement everything at once :slight_smile: I would get the bot working in the command line before connecting it to your UI too. If you need help, the community is really good at helping, especially with very specific usage questions! If you get to the point of having a regular form action up and running, I can help out with the list slot that people might not have as much experience with.

Thanks for your help @erohmensing. I was facing another issue, I now wanted to display a different set of buttons for filling a particular slot in form action. These list of buttons would depend on values of two previous slots, that have already been filled through form action. So, I wasn’t able to understand how and where to give the required condition for this.

1 Like

Ah, I see! Hm this is an interesting case, I don’t know if it’s supported out of the box at the moment as form actions just call the relevant utter_ask which is defined in the domain file, so the buttons cant currently be changed on the fly. What I would recommend in the meantime is filling your first two slots with a form, then calling a separate custom action that utters the button message using either utter_button_message or utter_button_template. With these you can define the buttons on the fly.

1 Like

So should I include the slot with these buttons in form action or not? As I had tried calling a custom action for this slot in my stories after the form had been initiated, but the custom action wasn’t called properly.

No, I believe you’d have to submit the form for the two you gathered, so form{"name": null} in stories, then call the custom action. The custom action wasn’t called properly because the FormPolicy will keep predicting your form action until the form is submitted.

1 Like

But I have to fill this particular slot with buttons in between, their are other slots to be filled after this. Using form{“name”: null} will deactivate the form and remaining alots will be left unfilled.

Yes, what I’m saying is that there is unfortunately currently no way to change the button titles and payloads on the fly. This was a suggestion for a workaround, where you would have separate forms where you’d fill the first form, fill the slot with a custom action, and then fill another form to get all of your information.

A different way you could do it if the different options for the buttons aren’t too many (maybe 2 or 3) is by adding logic into your required_slots method. E.g. you can in that method check what the values of the first two slots are and then add the correct required slot depending on their values. Then you would define each of these options in the domain file.

1 Like

Hi @erohmensing How to define parameters in utter_button_template() or utter_button_message()? I am either getting errors in the defined parameters in case of utter_button_template() and the custom action is not even triggered in case of utter_button_message(). Could you please help.

Hey there, you can see the parameters here. Utter_button_template takes three: ("template_name", buttons, tracker) where the buttons is a list of button dicts. Utter_button_message just takes ("message", buttons).

1 Like

Thanks @erohmensing, that helped !

Could you help with this code segment? Here I want to fill a slot based on the payload value of button selected by the user when the custom action is triggered. But the slot is directly filled with the button array only instead of particular value. So, how can I access the payload of button?

def run(self, dispatcher, tracker, domain):
      if tracker.get_slot('Slot_name') == 'yes':
         buttons = [{'title': 'title1', 'payload': '/intent{\"Other_slot\": "payload1"}'},{'title': 'title2', 
                           'payload': '/intent{\"Other_slot\": "payload2"}'}]
         dispatcher.utter_button_template('utter_message', buttons, tracker)
         return [SlotSet("Other_slot", buttons)] 
      else:
         buttons = [{'title': 'titlex', 'payload': '/intent{\"Other_slot\": "payloadx"}'},{'title': 'titley', 
                           'payload': '/intent{\"Other_slot\": "payloady"}'}]
         dispatcher.utter_button_template('utter_message', buttons, tracker)
         return [SlotSet("Other_slot", buttons)]