How to get user input inside a custom action

I am working on a chatbot that will filter data from a database and will answer queries based on dates, count or general.

for example the question When will my order arrive is a date based query and the bot should filter the database based on the user’s UserID and return the result.

In case of multiple orders by the user, The bot should ask for the OrderID to return the date.

How can I ask for user input inside an action?

This is my code so far

actions.py

class ActionNumberOfOrders(Action):

    def name(self) -> Text:
        return "action_numberOfOrders"

    def run(self, dispatcher, tracker, domain):

        user_id = tracker.get_slot('UserID')
        query = 'SELECT COUNT(*) FROM sales WHERE UserID=?'

        conn = sqlite3.connect("shipment.db")
        cursor = conn.cursor()
        cursor.execute(query, (user_id,))

        num_of_orders = len(cur.fetchall())
        return [SlotSet('num_of_orders', num_of_orders)]

class ActionGetDetails(Action):

    def name(self) -> Text:
        return "action_getDetails"

    def run(self, dispatcher, tracker, domain):

        conn = sqlite3.connect("shipment.db")
        cursor = conn.cursor()
        
        # FIND OUT HOW MANY ORDERS HAVE BEEN MADE BY USER
        num_of_orders = tracker.get_slot("num_of_orders")
        intent = tracker.get_slot("intent_slot")
        user_id = tracker.get_slot('UserID')
        status = tracker.get_slot('Status')
        mode = tracker.get_slot('Mode')

        if intent == 'query_date':

            # IF num_of_orders IS MORE THAN ONE, ASK FOR ORDER ID
            # WAIT FOR USER INPUT AND STORE THE INPUT IN VARIABLE order_id

            if mode == 'deliver':
                query = 'SELECT Delivery_date FROM sales WHERE UserID=?'

            elif mode == 'ship':
                query = 'SELECT Ship_date FROM sales WHERE UserID=?'

            else:
                query = 'SELECT Dispatch_date FROM sales WHERE UserID=?'

            cursor.execute(query, (user_id,))
            items_date = cursor.fetchall()
            msg = f"{items_date}"

        dispatcher.utter_message(msg)

please look the comments in the code. I will change the rest of the code once I solve this problem

You can handle that via your stories. If there are multiple orders, you could set the slot multiple_orders to true in your action action_num_of_orders. In your stories you can then do

# story 1: just one order
- action_num_of_orders
- slot{"multiple_orders": false}
- action_whatever_else
# story 2: multiple orders
- action_num_of_orders
- slot{"multiple_orders": true}
* enter_order_id
- action_get_order_id
- action_whatever_else

So depending on the slot value, a different action would be picked after action_num_of_orders. Does that help?

This helps thanks.

1 Like

@sashaank have you defined entities for all the slots?

----stories.md file-----------------

Generated Story -5208991511085841103

  • goodbye
    • utter_goodbye
    • export

Generated Story -5208991511085841103

  • greet
    • utter_greet
  • goodbye
    • utter_goodbye
    • export

story_jehanzaib

  • greet
    • utter_greet
  • inform -utter_ask_brand
  • inform{“name”:“China Bistro”} -slot{“name”:“China Bistro”}
    • action_brand
  • goodbye
    • utter_goodbye

story_jehanzaib_001

  • greet
    • utter_greet
  • inform -utter_ask_brand
  • inform{“name”:“Pranzo”} -slot{“name”:“Pranzo”}
    • action_brand
  • goodbye
    • utter_goodbye

story_jehanzaib_002

  • greet
    • utter_greet
  • inform -utter_ask_brand
  • inform{“name”:“Lalqila”} -slot{“name”:“Lalqila”}
    • action_brand
  • goodbye
    • utter_goodbye

story_jehanzaib_004

  • greet
    • utter_greet
  • inform -utter_ask_brand
  • inform{“name”:“Kaybees”} -slot{“name”:“Kaybees”}
    • action_brand
  • goodbye
    • utter_goodbye

story_jehanzaib_005

  • greet
    • utter_greet
  • inform -utter_ask_brand
  • inform{“name”:“EGO”} -slot{“name”:“EGO”}
    • action_brand
  • goodbye
    • utter_goodbye

story_jehanzaib_006

  • greet
    • utter_greet
  • inform -utter_ask_brand
  • inform{“name”:“Oh My Grill”} -slot{“name”:“Oh My Grill”}
    • action_brand
  • goodbye
    • utter_goodbye

story_jehanzaib_007

  • greet
    • utter_greet
  • inform{“name”:“Krispy2GO”} -slot{“name”:“Krispy2GO”}
    • action_brand
  • goodbye
    • utter_goodbye

story_jehanzaib_007

  • greet
    • utter_greet
  • inform -utter_ask_brand
  • inform{“name”:“Kaybees”} -slot{“name”:“Kaybees”}
    • action_brand
  • goodbye
    • utter_goodbye

New Story

  • greet
    • utter_greet
  • inform
    • utter_ask_brand
  • inform
    • action_brand

---------------domain.yml------------------------ session_config: session_expiration_time: 0.0 carry_over_slots_to_new_session: true intents:

  • greet
  • inform
  • goodbye entities:
  • name slots: name: type: unfeaturized responses: utter_greet:
    • text: Hello! How can I help? utter_goodbye:
    • text: Talk to you later.
    • text: Bye bye :frowning: utter_ask_brand:
    • text: What is your favourite brand? actions:
  • utter_greet
  • utter_ask_brand
  • utter_goodbye
  • action_brand

---------------data.json------------------------------ { “rasa_nlu_data”: { “common_examples”: [ { “text”: “Hello”, “intent”: “greet”, “entities”: [] }, { “text”: “goodbye”, “intent”: “goodbye”, “entities”: [] }, { “text”: “What is your favourite brand name?”, “intent”: “inform”, “entities”: [ { “start”: 23, “end”: 27, “entity”: “name”, “value”: “brand” } ] },

  {
    "intent": "greet",
    "text": "hey"
  },
  {
    "intent": "greet",
    "text": "hello"
  },
  {
    "intent": "greet",
    "text": "hi"
  },
  {
    "intent": "greet",
    "text": "heya"
  },
  {
    "intent": "greet",
    "text": "howdy"
  },
  {
    "intent": "greet",
    "text": "hey there"
  },
  {
    "intent": "goodbye",
    "text": "bye"
  },
  {
    "intent": "goodbye",
    "text": "bye bye"
  },
  {
    "intent": "goodbye",
    "text": "see ya"
  },
  {
    "intent": "goodbye",
    "text": "see you later"
  },
  {
    "intent": "inform",
    "text": "What's do you want to eat?"
  },
  {
    "text": "Is Facebook your favourite brand?",
    "intent": "inform",
    "entities": [
      {
        "start": 3,
        "end": 10,
        "entity": "name",
        "value": "Facebook"
      }
    ]
  },
  {
     "text": "Show me what's is the best discount in China Grill",
    "intent": "inform",
    "entities": [
      {
        "start": 38,
        "end": 49,
        "entity": "name",
        "value": "China Grill"
      }
    ]
  },

  {
     "text": "I wonder what is the most demanded brand here?",
    "intent": "inform",
    "entities": [
      {
        "start": 35,
        "end": 39,
        "entity": "name",
        "value": "brand"
      }
    ]
         },
  {
    "intent": "inform",
    "text": "what is the top rated brand product?"
  },
  {
    "intent": "inform",
    "text": "Tell me the top 5 brands"
  },
  {
    "text": "Is Gloria Jeans Coffee favourite brand?",
    "intent": "inform",
    "entities": [
      {
        "start": 3,
        "end": 21,
        "entity": "name",
        "value": "Gloria Jeans Coffee"
      }
    ]
          },
  {
    "text": "I am going to visit China Bistro. Dont know what are the favourite items there.",
    "intent": "inform",
    "entities": [
      {
        "start": 20,
        "end": 31,
        "entity": "name",
        "value": "China Bistro"
      }
    ]
          },
  {
    "text": "My friend are going to eat burger from burger lab. Do you have any idea what are the deals out there?",
    "intent": "inform",
    "entities": [
      {
        "start": 39,
        "end": 48,
        "entity": "name",
        "value": "burger lab"
      }
    ]
  },
  {
      "text": "Show me the deals of Tavern Gill, please",
    "intent": "inform",
    "entities": [
      {
        "start": 21,
        "end": 31,
        "entity": "name",
        "value": "Tavern Gill"
      }
    ]
        },
  {
     "text": "What are the deals of Tavern Grill",
    "intent": "inform",
    "entities": [
      {
        "start": 22,
        "end": 33,
        "entity": "name",
        "value": "Tavern Grill"
      }
    ]
         },
  {
    "text": "I need discount for Rochester Cafe and Grill restaurant",
    "intent": "inform",
    "entities": [
      {
        "start": 20,
        "end": 43,
        "entity": "name",
        "value": "Rochester Cafe and Grill restaurant"
      }
    ]
          },
  {
     "text": "Oh, sorry, tell me the most demanded menu of Tandoor",
    "intent": "inform",
    "entities": [
      {
        "start": 45,
        "end": 51,
        "entity": "name",
        "value": "Tandoor"
      }
    ]
  },
  {
            "text": "I want food from LAZZO De Cafe",
    "intent": "inform",
    "entities": [
      {
        "start": 17,
        "end": 29,
        "entity": "name",
        "value": "LAZZO De Cafe"
      }
    ]
  },
  {
      "text": "Is Beezer Bytz open now",
    "intent": "inform",
    "entities": [
      {
        "start": 3,
        "end": 13,
        "entity": "name",
        "value": "Beezer Bytz"
      }
    ]
        },
  {
    "text": "My Favourite brand is China Bistro",
    "intent": "inform",
    "entities": [
      {
        "start": 22,
        "end": 33,
        "entity": "name",
        "value": "China Bistro"
      }
    ]
  },
  {
    "intent": "inform",
    "text": "I need to know the brand detail?"
  },
  {
    "intent": "inform",
    "text": "Kaybees"
  }
],
"regex_features": [],
"lookup_tables": [],
"entity_synonyms": []

} }

----actions.py-----------------------

from future import absolute_import from future import division from future import unicode_literals

from rasa_core_sdk import Action from rasa_core_sdk.events import SlotSet #key 8c96f578e5b37e9083158c1f6eb8bf57

class ActionBrand(Action): def name(self): return ‘action_brand’

def run(self,dispatcher,tracker,domain):
	from apixu.client import ApixuClient
	import requests

	brand_response = requests.get(
		"http://165.227.69.207:9001/api/brand/get?city_id=5d6fafacdd5a444cf6925cf2&customer_id=53616c7465645f5f6c986d50cabe1890102dc607dc988e30db0859d4a8211bf604d6d524d26f693228b24a18b2fb715f")

	brand_response_json = brand_response.json()
	print(brand_response.status_code)

	name = tracker.get_slot('name')

	if name == None:
		print("name not coming")
	else:
		print(name)

	ls = []
	for i in range(0, len(brand_response_json["data"])):
		#if name in i:
			brand_name = brand_response_json["data"][i]["name"]
			ls.append(brand_name)

	if ls.__contains__(name):
		response = """The brand which you have selected is {} exists in our application""".format(name)
		print(name)
	else:
		response = """The brand which you have selected is {} doesn't exists in the application""".format(name)
		print(name)

	print(name)
	dispatcher.utter_message(response)

	#return []
	return [SlotSet('name',name)]

----- I am getting null on “name” field. Please help me

@Tanja I tried this solution on a similar use case and it doesn’t work. It gives me an error saying slot{“whatever”} was not defined. Has this approach been deprecated?