# How to repeat a story ,to repeat itself until satisfied for user

**URL:** <https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103>\
**Category:** Rasa Open Source\
**Created:** [January 7, 2019, 2:29pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103 "2019-01-07T14:29:50Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![manslogic](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/manslogic/32/747_2.png) [@manslogic](https://forum.rasa.com/u/manslogic)\
**Post date:** [January 7, 2019, 2:29pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/1 "2019-01-07T14:29:50Z")

</div>

rasa core version: 0.12.3 python version : 3.6.7 64 bit os : windows 10

Scenario : My bot must suggest a nearby parking location .

```
		BOT User

```

* * *

```
	Hello, how can i help
											      i want to know near by parking places
   OK sure!
   Please share the location
											       "user selects location in map"                      
	Sorry, No parking places available here,
	Do, you want to search in different location
											         Yes
	OK sure!
	Please share the location
										            "user selects location in map"                      
	sorry, No parking places available here,
	Do, you want to search in different location
											         Yes
	OK sure!
	Please share the location
														"user selects location in map"                      
	Parking available in half Km 
	from your location

	thanks for contacting       

```

=========================================================================

here the story has to repeat same from asking location( _Please share the location_ ), how can i achieve this with rasa stack. bot has to repeat the steps n number of time until a valid parking spot is obtained please help me .

---

<div class="post-metadata">

**Author:** ![naoko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/naoko/32/196_2.png) [@naoko](https://forum.rasa.com/u/naoko)\
**Post date:** [January 7, 2019, 3:11pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/2 "2019-01-07T15:11:14Z")

</div>

Sounds like FormAction should work well. Documentation of FormAction is located here: [Slot Filling](https://rasa.com/docs/core/slotfilling/) You can check out Example bot here: [rasa\_core/examples/formbot at master · RasaHQ/rasa\_core · GitHub](https://github.com/RasaHQ/rasa_core/tree/master/examples/formbot)

FormAction allow you to do fine control of the flow as long as you are in the FormAction. I would create 2 slots `parking_location` and `user_selected_location` and set as required\_fields in FormAction.

---

<div class="post-metadata">

**Author:** ![manslogic](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/manslogic/32/747_2.png) [@manslogic](https://forum.rasa.com/u/manslogic)\
**Post date:** [January 7, 2019, 3:29pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/3 "2019-01-07T15:29:00Z")

</div>

Hi Naoko, thanks for the reply .

Actually here in the flow slots are filled and processed and given Output to the user. but here i want to **repeat same story again** with new values in the slots n Number of times based on the user decision.

---

<div class="post-metadata">

**Author:** ![naoko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/naoko/32/196_2.png) [@naoko](https://forum.rasa.com/u/naoko)\
**Post date:** [January 7, 2019, 11:37pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/4 "2019-01-07T23:37:55Z")

</div>

You can repeat as long as you want using FormAction because as long as all required\_field is filled, FormAction will continue to ask questions. So here is what I would do. As I noted I will declare 2 slots + user\_select\_different\_location. If user\_select\_different\_location is No, then I will set slot value of parking\_location to None. then form will ask parking\_location again. Do you think that would work?

---

<div class="post-metadata">

**Author:** ![enzechua](https://avatars.discourse-cdn.com/v4/letter/e/ad7895/32.png) [@enzechua](https://forum.rasa.com/u/enzechua)\
**Post date:** [June 4, 2019, 3:52pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/5 "2019-06-04T15:52:15Z")

</div>

Hi @naoko, I am new to this and am also wanting to do the same thing. Which is to loop through the stories until the user is satisfy with all the inputs he has make. I have look through your example and it seems like it will work.( Have not tested it out yet ) But am I able to check what Intent it is? Like user is able to reply “no”, “don’t want” and all of this is under the intent “deny”. So if user\_select\_different\_location is under intent “deny” then i will reset the first 2 slots so that the bot will reask this question. How would I be able to do this?

---

<div class="post-metadata">

**Author:** ![naoko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/naoko/32/196_2.png) [@naoko](https://forum.rasa.com/u/naoko)\
**Post date:** [June 4, 2019, 8:48pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/6 "2019-06-04T20:48:18Z")

</div>

Hello @enzechua, So after I went step by step, no 2 slot is required. Just one. Here is the flow I think it should work…

FormAction: require `parking_location`

BOT says: Please share your location

USER: select location on map

FormAction SET parking\_location and Check Parking availability

BOT says: Sorry no parking places available. do you want to search in different location?

USER says: Okay, sure (intent AFFIRM) or No thanks (intent DENY)

IN FORM ACTION: if user intent is AFFIRM then: reset `parking_location` in FormAction func `validate`. `return [SlotSet('parking_location', None)]` Once the parking\_location is reset, the BOT should ask user “Please share your location”

If user intent is DENY then: in `request_next_slot` you add something like

```auto
	intent = tracker.latest_message.get("intent", {}).get("name")
    if intent == 'DENY':
        return self._deactivate()

```

to exit FormAction.

---

<div class="post-metadata">

**Author:** ![enzechua](https://avatars.discourse-cdn.com/v4/letter/e/ad7895/32.png) [@enzechua](https://forum.rasa.com/u/enzechua)\
**Post date:** [June 5, 2019, 5:23am UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/8 "2019-06-05T05:23:53Z")

</div>

@naoko Thank you so much for the reply I have tried it at the validate function of Form Action and it seems to go well. Just that I have a slight problem. So let’s say,

BOT says: Do you want to confirm this parking location?

USER says: No (intent DENY)

And therefore I would reset the SLOT(parking\_location, None). So base on your reference, it will be something like this.

```auto
intent = tracker.latest_message.get("intent", {}).get("name")
if intent == 'DENY':
    return [SlotSet('parking_location', None)]

return [] # does not save slot values. 

```

It seems like return[] does not save my slot values. Therefore bot would keep ask the question regardless the answer is. So how do I return back all the values if the intent is not DENY.

PS. Thanks so much once again, your answer has really helped me alot! And the way you format your answers makes it so much easier for me to understand which is why I am trying to do it like yours. haha.

---

<div class="post-metadata">

**Author:** ![naoko](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/naoko/32/196_2.png) [@naoko](https://forum.rasa.com/u/naoko)\
**Post date:** [June 5, 2019, 2:55pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/9 "2019-06-05T14:55:08Z")

</div>

To save the Slot value, you want to return

```auto
return [SlotSet('parking_location', "value of parking location")]

```

See if that helps!

---

<div class="post-metadata">

**Author:** ![enzechua](https://avatars.discourse-cdn.com/v4/letter/e/ad7895/32.png) [@enzechua](https://forum.rasa.com/u/enzechua)\
**Post date:** [June 8, 2019, 7:46pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/10 "2019-06-08T19:46:51Z")

</div>

Hello @naoko didn’t see this but yes it works, thank you so much once again! 😃

---

<div class="post-metadata">

**Author:** ![littlerain2310](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/littlerain2310/32/10808_2.png) [@littlerain2310](https://forum.rasa.com/u/littlerain2310)\
**Post date:** [September 1, 2020, 4:33am UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/11 "2020-09-01T04:33:20Z")

</div>

can i see your whole actions file because i have the same issue but i dont know how to apply your solution into my project

---

<div class="post-metadata">

**Author:** ![enzechua](https://avatars.discourse-cdn.com/v4/letter/e/ad7895/32.png) [@enzechua](https://forum.rasa.com/u/enzechua)\
**Post date:** [September 1, 2020, 8:48am UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/12 "2020-09-01T08:48:52Z")

</div>

Hi there, may I know what is your issue on? Is it referring to the question itself? So let’s say I have a slot that is needed to be filled up

```auto
def slot_mappings(self):
        return {
            "outlet_menu_question": self.from_text(),
        }

```

If I want the story to repeat itself, in my validation function, I will do this:

```auto
def validate(self, dispatcher, tracker, domain):
        value = int(tracker.latest_message.get("text"))
        if value > 0:
            return[
                SlotSet("outlet_menu_question", value)
            ]
        dispatcher.utter_template('utter_wrong_command', tracker)
        return [SlotSet("outlet_menu_questions", None)]

```

What this function does is that it checks the value that the user had entered. Base on the condition given, if the value is not what I want, I will set the slot to be none. When a slot is not filled up, the question would then be repeated once again. However, if I meet the condition, I will return back a value to the slot and thus the validation function would be completed. The question would not be repeated anymore since the slot is filled up.

Btw, I am not sure how much Rasa had change. It had been 1 year since I last touch it.

---

<div class="post-metadata">

**Author:** ![littlerain2310](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/littlerain2310/32/10808_2.png) [@littlerain2310](https://forum.rasa.com/u/littlerain2310)\
**Post date:** [September 1, 2020, 9:59am UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/13 "2020-09-01T09:59:25Z")

</div>

Thanks for the reply.My situation is that i want to ask my user name and ask them to confirm it.The story will not end until users confirm it’s true.Thus,I creat a form with 2 slot.One is for the name and the other is for the comfirmation.My validate func look like this:

```
def validate(self, dispatcher, tracker, domain):
    value = tracker.get_slot("name1")
    intent=tracker.get_slot("user_confirm")
    if intent == True:
        return [SlotSet("name1",value)]
    return [SlotSet("name1",None)] 

```

but eventually it cant save the name so it keep asking.Please help,i’m just a beginner

---

<div class="post-metadata">

**Author:** ![enzechua](https://avatars.discourse-cdn.com/v4/letter/e/ad7895/32.png) [@enzechua](https://forum.rasa.com/u/enzechua)\
**Post date:** [September 1, 2020, 11:51am UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/14 "2020-09-01T11:51:37Z")

</div>

No worries, looking from your codes, it just mean that you did not enter the conditional statement.

1. First of all, may I look at your slot\_mappings? If the slot returns self.from\_text() then it makes sense why the conditional statement did not work.

2. To emphasise on the first point, you are looking for intent and not the value of user\_confirm itself. I assume they could type “yes”, “confirm” etc, and therefore when you use **tracker.get\_slot(“user\_confirm”)**, you are actually getting the pure value of that slot. One way to confirm this is to **print(intent)** and see what you get.

To be honest, I kind of forgot how to do it since it’s been 1 year. But as shown above, I think you could do this

```auto
def validate(self, dispatcher, tracker, domain):
    value = tracker.latest_message.get("text")
    slot_to_fill = tracker.get_slot("requested_slot")
    intent = tracker.latest_message.get("intent", {}).get("name")
    if slot_to_fill == "user_confirm": 
        if intent =="true":
            return [SlotSet("user_confirm", value)]
        else:
            return [SlotSet("user_confirm", None)]
    return [SlotSet(slot, value) for slot, value in slot_values.items()]

```

From what I recall, the validate function is called for every single slot. Which is why I use **tracker.latest\_message.get(“text”)** to get the last message from the slot.

1. I think your name1 question gets called first. Therefore, since none of the if statement is true, it will return its own value.

2. Since the next slot to fill with be “user\_confirm”, check the intent of it. If it is not true, set “user\_confirm” slot to be none and have the question repeat again till the intent is true.

---

<div class="post-metadata">

**Author:** ![littlerain2310](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/littlerain2310/32/10808_2.png) [@littlerain2310](https://forum.rasa.com/u/littlerain2310)\
**Post date:** [September 2, 2020, 4:50am UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/15 "2020-09-02T04:50:02Z")

</div>

God bless you sir! Thanks to your instructions,finally my bot can ask the same questions until user confirm their name.However,following your code make my bot keep asking for user\_confirm instead of name1 thus i changed it a little bit.Thanks for your help!

---

<div class="post-metadata">

**Author:** ![enzechua](https://avatars.discourse-cdn.com/v4/letter/e/ad7895/32.png) [@enzechua](https://forum.rasa.com/u/enzechua)\
**Post date:** [September 3, 2020, 1:26am UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/16 "2020-09-03T01:26:34Z")

</div>

Glad to know it works! Oh, haha I might have read your previous question wrongly but am glad you have manage to change and make it work 🙂 Cheers!

---

<div class="post-metadata">

**Author:** ![IsraaMohamedHamid](https://avatars.discourse-cdn.com/v4/letter/i/a9a28c/32.png) [@IsraaMohamedHamid](https://forum.rasa.com/u/IsraaMohamedHamid)\
**Post date:** [March 13, 2021, 10:41pm UTC](https://forum.rasa.com/t/how-to-repeat-a-story-to-repeat-itself-until-satisfied-for-user/4103/17 "2021-03-13T22:41:24Z")

</div>

> [@enzechua](#):
>
> ```auto
> def validate(self, dispatcher, tracker, domain):
> value = tracker.latest_message.get("text")
> slot_to_fill = tracker.get_slot("requested_slot")
> intent = tracker.latest_message.get("intent", {}).get("name")
> if slot_to_fill == "user_confirm": 
> if intent =="true":
> return [SlotSet("user_confirm", value)]
> else:
> return [SlotSet("user_confirm", None)]
> return [SlotSet(slot, value) for slot, value in slot_values.items()]
> 
> ```

HI @littlerain2310, I have the same issue and was wondering if you can help? I am creating a loop based on whether the user would like to pay or order more. This is my function:

```
class FormGetRestaurantMenuCategoryOrderMoreDishes_en(FormValidationAction):
	
	
    def name(self):
        return 'form_get_restaurant_menu_category_order_more_dishes_en'
		
    @staticmethod
    def required_slots(tracker: Tracker) -> List[Text]:
        """A list of required slots that the form has to fill"""
        return ["order_more_or_pay_en"]

    def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
        """A dictionary to map required slots to
            - an extracted entity
            - intent: value pairs
            - a whole message
            or a list of them, where a first match will be picked"""

        return {"order_more_or_pay_en":[self.from_text()]}
    
    def validate(self, dispatcher, tracker, domain):
        value = tracker.latest_message.get("text")
        slot_to_fill = tracker.get_slot("requested_slot")
        intent = tracker.latest_message.get("intent", {}).get("order_more_or_pay_en")
        if slot_to_fill == "order_more_or_pay_en": 
            if intent =="pay":
                return [SlotSet("order_more_or_pay_en", value)]
            else:
                return [SlotSet("order_more_or_pay_en", None)]
        return [SlotSet(slot, value) for slot, value in slot_values.items()]
   
    #def submit(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], ) -> List[Dict]:

    # if tracker.get_slot('order_more_or_pay_en') == 'Order More':
    # dispatcher.utter_message(text="Choose wisely...")

    # elif tracker.get_slot('order_more_or_pay_en') == 'Pay':
    # dispatcher.utter_message(text="Please be patient you will need to answer more questions before you can pay :)")

    # return []

```

I want it to repeat if the user chooses from a button that he/she wants to order more but it continues with the story for if the user wants to pay. Can you please tell me what I did wrong?
