Ask questions again if particular intent is triggered by the user

I am trying to build a chatbot which mainly comprises of 2 tasks: Task 1. Ask users to share their pincode and choose the category. Fetch results using these two inputs and display the message. Task 2. 1. After the flow ends - If a user says “corona help“ - prompt him asking if he wants to get them for the above given pincode if not - give him a provision to input a new pincode.

Follow similar flow for category as well. For example ( let us say user asked for - Free Food in 600036 )

User : corona help Bot : Do you want to get the resources for - 600036. Press yes to confirm and no to change another pincode User : no Bot: Please share the pincode User : 500081 Bot : Do you want to get “ Free Food” . Press yes to confirm and no to change User : Yes Bot : Show results for 500081 and Free Food

I have already done with task 1 but having difficulty with task 2. I want to know how to ask questions and fill the required slots if a particular intent is triggered.

Here’s my rules.yml:

version: "2.0"

rules:

- rule: trigger corona help
  steps:
  - intent: corona_help
  - action: action_check_user_intent

- rule: Activate form
  steps:
  - intent: greet
  - action: user_details_form
  - active_loop: user_details_form

- rule: Submit form
  condition:
  # Condition that form is active.
  - active_loop: user_details_form
  steps:
  # Form is deactivated
  - action: user_details_form
  - active_loop: null
  - slot_was_set:
    - requested_slot: null
  # The actions we want to run when the form is submitted.
  - action: action_submit

Actions.py:

class ValidateUserDetailsForm(FormValidationAction):
    def name(self) -> Text:
        return "validate_user_details_form"
    
    def validate_pin_code(self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:

        print("HERE1")
        url = f"https://api.postalpincode.in/pincode/{slot_value}"
        r = requests.get(url)
        data = json.loads(r.content)
        status = data[0]['Status']
        print(status)

        if status == 'Error':
            dispatcher.utter_message(text="Invalid PIN code. Enter again.")
            return {"pin_code": None}
        else:
            return {"pin_code": slot_value}

class ActionCheckUserIntent(Action):
    def name(self) -> Text:
        return "action_check_user_intent"

    def run(
        self,
        dispatcher,
        tracker: Tracker,
        domain: "DomainDict",
    ) -> List[Dict[Text, Any]]:

        intent = tracker.latest_message['intent'].get('name')
        print(intent)
        pin_code = tracker.get_slot("pin_code")
        print(pin_code)
        category = tracker.get_slot("category")

        if intent == "corona_help":
            dispatcher.utter_message(response="utter_ask_confirm_pin_code")
            return {"confirm_pin_code": None, "confirm_category": None}

class ActionSubmit(Action):
    def name(self) -> Text:
        return "action_submit"

    def run(
        self,
        dispatcher,
        tracker: Tracker,
        domain: "DomainDict",
    ) -> List[Dict[Text, Any]]:

        pin_code = tracker.get_slot("pin_code")
        category = tracker.get_slot("category")
        print("HERE2")
        pin_code_url = f"https://api.postalpincode.in/pincode/{pin_code}"
        r1 = requests.get(pin_code_url)
        data1 = json.loads(r1.content)
        city = data1[0]['PostOffice'][0]['District']
        print("HERE3")
        city_url = "http://ec2-3-23-130-174.us-east-2.compute.amazonaws.com:8000/cities"
        r2 = requests.get(city_url)
        data2 = json.loads(r2.content)
        cities = data2['data']

        if city in cities:
            city = city.replace(" ", "%20")
            category = category.replace(" ", "%20")
            print("HERE4")
            category_url = f"http://ec2-3-23-130-174.us-east-2.compute.amazonaws.com:8000/resource?city={city}&category={category}"
            r = requests.get(category_url)
            data = json.loads(r.content)
            data = data['data']
            print(data)

            if not data:
                print("HERE5")
                dispatcher.utter_message(text="No resources found.")
                return []
                # return [AllSlotsReset()]

            contact = data[0]["contact"]
            description = data[0]["description"]
            organisation = data[0]["organisation"]
            phone = data[0]["phone"]
            state = data[0]["state"]

            category = category.replace("%20", " ")

            dispatcher.utter_message(response="utter_submit",
                                    pin_code=pin_code,
                                    category=category,
                                    contact = contact,
                                    description = description,
                                    organisation = organisation,
                                    phone = phone,
                                    state = state
                                    )
            # return [AllSlotsReset()]

        # elif intent == "corona_help":

        
        else:
            dispatcher.utter_message(text="No resources found.")
            # return [AllSlotsReset()]

Any ideas how to achieve this?

Can someone please help me with this? I am still stuck.

Hi @arpit0903, how far is your bot getting in your workflow? And is there something specifically that isn’t working as you would expect it to?

Bot is working fine until user says “corona help”. I want to execute task 2 (mentioned in my question above). “After the flow ends - If a user says “corona help“ - prompt him asking if he wants to get them for the above given pincode if not - give him a provision to input a new pincode.” I am not able to execute this part.

@Juste I’m still stuck at this. Please help.

@m.vielkind Now the bot is working as desired bu it is not asking just the last question i.e., to ask the user to confirm the category as already mentioned in my question above.

Here’s actions.py: import typing from typing import Any, Text, Dict, List, Union, Optional

from rasa_sdk import Action, Tracker, FormValidationAction
from rasa_sdk.events import SlotSet, UserUtteranceReverted, EventType, AllSlotsReset
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.types import DomainDict
import requests, json

class ValidateUserDetailsForm(FormValidationAction):
    def name(self) -> Text:
        return "validate_user_details_form"

    async def required_slots(
        self,
        slots_mapped_in_domain: List[Text],
        dispatcher: "CollectingDispatcher",
        tracker: "Tracker",
        domain: "DomainDict",
    ) -> Optional[List[Text]]:
        
        required_slots = []
        if tracker.latest_message["intent"].get("name") == "corona_help":
            print("corona_help")
            required_slots = ["pin_code", "category", "confirm_pin_code", "confirm_category"]
        else:
            required_slots = ["pin_code", "category"]

        return required_slots
    
    def validate_pin_code(self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:

        print("HERE1")
        url = f"https://api.postalpincode.in/pincode/{slot_value}"
        r = requests.get(url)
        data = json.loads(r.content)
        status = data[0]['Status']
        print(status)

        if status == 'Error':
            dispatcher.utter_message(text="Invalid PIN code.")
            return {"pin_code": None}
        else:
            return {"pin_code": slot_value}

    def validate_confirm_pin_code(self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:

        print("validate confirm pin code")

        pin_code = tracker.get_slot("pin_code")

        if slot_value.lower() == 'no':
            return {"pin_code": None, "confirm_category": None}
        else:
            return {"pin_code": pin_code, "confirm_category": None}


    def validate_confirm_category(self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:

        category = tracker.get_slot("category")
        print(category)
        if slot_value.lower() == "no":
             return {"category": None}
        else:
            return {"category": category}

class ActionSubmit(Action):
    def name(self) -> Text:
        return "action_submit"

    def run(
        self,
        dispatcher,
        tracker: Tracker,
        domain: "DomainDict",
    ) -> List[Dict[Text, Any]]:

        pin_code = tracker.get_slot("pin_code")
        category = tracker.get_slot("category")
        print("HERE2")
        pin_code_url = f"https://api.postalpincode.in/pincode/{pin_code}"
        r1 = requests.get(pin_code_url)
        data1 = json.loads(r1.content)
        city = data1[0]['PostOffice'][0]['District']
        print("HERE3")
        city_url = "http://ec2-3-23-130-174.us-east-2.compute.amazonaws.com:8000/cities"
        r2 = requests.get(city_url)
        data2 = json.loads(r2.content)
        cities = data2['data']

        if city in cities:
            city = city.replace(" ", "%20")
            category = category.replace(" ", "%20")
            print("HERE4")
            category_url = f"http://ec2-3-23-130-174.us-east-2.compute.amazonaws.com:8000/resource?city={city}&category={category}"
            r = requests.get(category_url)
            data = json.loads(r.content)
            data = data['data']
            print(data)

            if not data:
                print("HERE5")
                result = "No resources found."
                dispatcher.utter_message(response="utter_submit",
                                    pin_code=pin_code,
                                    category=pin_code,
                                    contact = result,
                                    description = result,
                                    organisation = result,
                                    phone = result,
                                    state = result)
                return []
                # return [AllSlotsReset()]

            contact = data[0]["contact"]
            description = data[0]["description"]
            organisation = data[0]["organisation"]
            phone = data[0]["phone"]
            state = data[0]["state"]

            category = category.replace("%20", " ")

            dispatcher.utter_message(response="utter_submit",
                                    pin_code=pin_code,
                                    category=category,
                                    contact = contact,
                                    description = description,
                                    organisation = organisation,
                                    phone = phone,
                                    state = state
                                    )
        else:
            result = "No resources found."
            dispatcher.utter_message(response="utter_submit",
                                    pin_code=pin_code,
                                    category=category,
                                    contact = result,
                                    description = result,
                                    organisation = result,
                                    phone = result,
                                    state = result)

Rules.yml

version: "2.0"

rules:

- rule: trigger corona help
  steps:
  - intent: corona_help
  - action: user_details_form
  - active_loop: user_details_form

- rule: Activate form
  steps:
  - intent: greet
  - action: user_details_form
  - active_loop: user_details_form

- rule: Submit form
  condition:
  # Condition that form is active.
  - active_loop: user_details_form
  steps:
  # Form is deactivated
  - action: user_details_form
  - active_loop: null
  - slot_was_set:
    - requested_slot: null
  # The actions we want to run when the form is submitted.
  - action: action_submit

Domain.yml

version: "2.0"

intents:
  - greet
  - goodbye
  - affirm
  - deny
  - mood_great
  - mood_unhappy
  - bot_challenge
  - corona_help
  - chitchat
  - out_of_scope
  - pin_code:
      use_entities:
        - pin_code
  - category:
      use_entities:
        - category
  - confirm_pin_code:
      use_entities:
        - confirm_pin_code
  - confirm_category:
      use_entities:
        - confirm_category

entities:
- pin_code
- category
- confirm_pin_code
- confirm_category

slots:
  pin_code:
    type: text
  category:
    type: text
  confirm_pin_code:
    type: text
  confirm_category:
    type: text

actions:
  - action_submit
  - validate_user_details_form
  - action_check_user_intent

forms:
  user_details_form:
    pin_code:
    - type: from_entity
      entity: pin_code
    category:
    - type: from_entity
      entity: category
    confirm_pin_code:
    - type: from_entity
      entity: confirm_pin_code
    confirm_category:
    - type: from_entity
      entity: confirm_category
  
responses:
  utter_greet:
  - text: "Hey! How may I help you today?"

  utter_cheer_up:
  - text: "Here is something to cheer you up:"
    image: "https://i.imgur.com/nGF1K8f.jpg"

  utter_did_that_help:
  - text: "Did that help you?"

  utter_happy:
  - text: "Great, carry on!"

  utter_goodbye:
  - text: "Bye"

  utter_iamabot:
  - text: "I am a bot, powered by Rasa."

  utter_chitchat/ask_name:
  - image: "https://i.imgur.com/zTvA58i.jpeg"
    text: Hello, my name is Retrieval Bot.
  - text: I am called Retrieval Bot!

  utter_chitchat/ask_weather:
  - text: Oh, it does look sunny right now in Berlin.
    image: "https://i.imgur.com/vwv7aHN.png"
  - text: I am not sure of the whole week but I can see the sun is out today.

  utter_please_rephrase:
  - text: I'm sorry, I didn't quite understand that. Could you rephrase?

  utter_out_of_scope:
  - text: "Sorry, I didn't get it!!!"

  utter_ask_pin_code:
  - text: "Please share your PIN code"

  utter_ask_category:
  - text: "What are you looking for?"
    buttons:
    - title: "Free Food"
      payload: '/category{{"category": "Free Food"}}'

    - title: "COVID-19 Testing Labs"
      payload: '/category{{"category": "COVID-19 Testing Labs"}}'

    - title: "Hospitals and Centers"
      payload: '/category{{"category": "Hospitals and Centers"}}'

    - title: "Fundraisers"
      payload: '/category{{"category": "Fundraisers"}}'

    - title: "Delivery"
      payload: '/category{{"category": "Delivery"}}'

    - title: "Police"
      payload: '/category{{"category": "Police"}}'

    - title: "Government Helpline"
      payload: '/category{{"category": "Government Helpline"}}'

    - title: "Mental well being and Emotional Support"
      payload: '/category{{"category": "Mental well being and Emotional Support"}}'

    - title: "Accommodation and Shelter Homes"
      payload: '/category{{"category": "Accomodation and Shelter Homes"}}'

    - title: "Senior Citizen Support"
      payload: '/category{{"category": "Senior Citizen Support"}}'

    - title: "Transportation"
      payload: '/category{{"category": "Transportation"}}'

    - title: "Community Kitchen"
      payload: '/category{{"category": "Community Kitchen"}}'

    - title: "Ambulance"
      payload: '/category{{"category": "Ambulance"}}'

    - title: "Fire Brigade"
      payload: '/category{{"category": "Fire Brigade"}}'

    - title: "Quarantine Facilty"
      payload: '/category{{"category": "Quarantine Facilty"}}'

    - title: "Helpline for cyclone Amphan"
      payload: '/category{{"category": "Helpline for Cyclone Amphan"}}'

    - title: "Fever Clinic"
      payload: '/category{{"category": "Fever Clinic"}}'

    - title: "Other"
      payload: '/category{{"category": "Other"}}'

  utter_ask_confirm_pin_code:
  - text: "Do you want to get the resources for - {pin_code}. Press Yes to confirm and No to change another pincode"
    buttons:
    - title: "Yes"
      payload: '/confirm_pin_code{{"confirm_pin_code": "Yes"}}'

    - title: "No"
      payload: '/confirm_pin_code{{"confirm_pin_code": "No"}}'

  utter_ask_confirm_category:
  - text: "Do you want to get {category} resources. Press Yes to confirm and No to change."
    buttons:
    - title: "Yes"
      payload: '/confirm_category{{"confirm_category": "Yes"}}'

    - title: "No"
      payload: '/confirm_category{{"confirm_category": "No"}}'

  utter_submit:
  - text: "Show results for {pin_code} and {category}\n
          - Contact: {contact}\n
          - Description: {description}\n
          - Organisation: {organisation}\n
          - Phone: {phone}\n
          - State: {state}"

session_config:
  session_expiration_time: 60
  carry_over_slots_to_new_session: true

The bot is not asking question for the last slot (confirm_category) if the user intent is “corona_help”. Please help. Thank you.