How to take input inside a running action in RASA - rasa-nlu

Suppose I’ve a running action that generates a list of dynamic buttons to the user. Generally, the button inputted from the user is going to NLU. But I want to know which button the user just picked and act accordingly in this running action. For example, If the user chose “Toyota” I want to call another action from this running action. All I want is not to go to NLU and not to check there. I want everything in my running action. Is it possible? If so, can someone provide the way I can approach?
My action class is given below.
> class ActionVehicleManufacture(Action):
> def name(self):
> return "action_vehicle_manufacturer"
>
> def run(self, dispatcher: CollectingDispatcher,
> tracker: Tracker,
> domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
>
> r = requests.get('http://mind.zantrik.com/api/A1/GetVehicleManufacturer')
> response = r.text
> json_data = json.loads(response)
> l = []
> buttons = []
> for i in json_data["data"]:
> l.append(i["manufacturerName"])
> for i in l:
> buttons.append({"title": i, "payload": i})
>
> dispatcher.utter_message(text="Please let me know you car manufacturer name:", buttons=buttons)
> # I want to apply some condition here according to users inputted button.
> return []

To call an action after a new user message (e.g, selection of a button or free text) you need to include a story in you storied.md. Which action is arbitrary. For example:
## story example
* ask_about_manufacturers
- action_vehicle_manufacturer
* inform{"manufacturer": "toyota"}
- action_execute
If you have defined manufacturer as a slot, the type of the slot influences the stories. If you have seen Slots Set By Clicking Buttons, to set the slot manufacturer you need to do instead of
buttons.append({"title": i, "payload": i})
the following, where intent is the intent that captures the message "toyota", in the story example above "inform".
buttons.append({"title": i, "payload": f"""/{intent}{{"manufacturer": "i"}}""")

Related

How to rig a bot's command to only a certain user

I've been making this pp size machine, which is somewhat like dank memer's one
#client.command()
async def pp(ctx,member : discord.Member):
size=random.randint(1,10)
message = "8"
for x in range (size):
message= message + "="
if x == size-1:
message = message + "D"
if member == "PROTATO#6826":
message = "8D"
ppsize = discord.Embed(color=discord.Colour.orange(), title=f"PP size",description=f"""{member}'s penis
{message} """)
await ctx.send(embed = ppsize)
But i want to rig the command for a certain user to only show "8D" instead of the random lengths.
But no matter what it is the
if member == "PROTATO#6826":
message = "8D"
code doesnt run or gets over looked?
Can someone help me out with this?
You can check if the member mentioned has the same id as a specific user. You can either enable developer mode on discord, or you can print the member.id at the very beginning. Do view a code example below.
#client.command()
async def pp(ctx, member: discord.Member):
print(member.id) # this would print a user's unique id
message = "Hey!"
if member.id == 394506589350002688: # replace this id with what was printed at the start
message = "Hello!"
await ctx.send(message)
Similar Questions:
How to check if message was sent by certain user? - SO
How do I detect if the message is sent by a specific user id? - SO

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?
I'm assuming the pin is most of your user_details_form. If so, one way to handle this would be to restart the user_details_form:
- rule: corona help with previous pin code
steps:
- intent: corona_help
- action: utter_ask_confirm_pin_code
- intent: affirm # they want to use previous code
- action: do_the_thing_with_old_pin_code
- rule: corona help with new pin code
steps:
- intent: corona_help
- action: utter_ask_confirm_pin_code
- intent: deny # they don't want to use previous code
- action: user_details_form
- active_loop: user_details_form
You'll probably need to override required_slots for your form to make sure that the right slot is being re-asked, you can read more about that here.

How can I retrieve the "Description" field of inspect.exe in my pywinauto based automation script?

I have the following SysTreeView32 element from which I would like to retrieve the "Description" field:
In my pywinauto script (based on win32 backend), I can retrieve pretty easily the TreeViewWrapper element by looking for the class type and eventually looking at the items text, but some information that I need is only available in the Description field of this element.
I was not able to find a way to retrieve this information.
I tried in UIA mode as well:
But in this case, it does not even appear in the information.
So I tried using the TreeItemWrapper element with the UIA backend in pywinauto, but I could not find the appropriate description not even in the UIAElementInfo. Although something looked pretty similar in the following line:
impl = uia_defs.get_elem_interface(elem, "LegacyIAccessible").
When I call the legacy_properties of the uia_controls.TreeItemWrapper, I get:
{'ChildId': 0,
'DefaultAction': '',
'Description': '',
'Help': '',
'KeyboardShortcut': '',
'Name': 'Execute multiple tasks(MultiTask_ImportSysD)',
'Role': 36,
'State': 3145730,
'Value': ''}
And in there, the Description is empty.
I'm guessing that property comes from IAccessible::get_accDescription.
MSDN says that property is deprecated but if you still want to use it, call AccessibleObjectFromWindow to get a IAccessible for a window.
Finally, I could not find this possibility through the pywinauto exposed API.
Although pywniauto does expose the Description property through the legacy_properties of the uia_controls.TreeItemWrapper instance, but it returns an empty string. This correlates with the note in teh Windows SDK documentation that states:
Note The Description property is often used incorrectly and is not supported by Microsoft UI Automation. Microsoft Active Accessibility server developers should not use this property. If more information is needed for accessibility and automation scenarios, use the properties supported by UI Automation elements and control patterns.
In the end, I finally developed a small piece of code to search for the element that I need the description of and I could retrieve the Description from there. Here is the code:
# for OleAcc access
import ctypes
import comtypes, comtypes.automation, comtypes.client
comtypes.client.GetModule('oleacc.dll')
def accDescription(iaccessible, cid):
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objDescription = comtypes.automation.BSTR()
iaccessible._IAccessible__com__get_accDescription(objChildId, ctypes.byref(objDescription))
return objDescription.value
def accRole(iaccessible, cid):
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objRole = comtypes.automation.VARIANT()
objRole.vt = comtypes.automation.VT_BSTR
iaccessible._IAccessible__com__get_accRole(objChildId, objRole)
return AccRoleNameMap[objRole.value]
def accState(iaccessible, cid):
'''Get Element State'''
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objState = comtypes.automation.VARIANT()
iaccessible._IAccessible__com__get_accState(objChildId, ctypes.byref(objState))
return objState.value
def accName(iaccessible, cid):
'''Get Element Name'''
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objName = comtypes.automation.BSTR()
iaccessible._IAccessible__com__get_accName(objChildId, ctypes.byref(objName))
return objName.value
def accDescendants(iaccessible):
"""Iterate all desencendants of an object iaccessible, including the current one.
Arguments:
iaccessible -- the IAccessible element to start from
Yields:
(IAcessible instance, Child id)
"""
yield (iaccessible, 0)
objAccChildArray = (comtypes.automation.VARIANT * iaccessible.accChildCount)()
objAccChildCount = ctypes.c_long()
ctypes.oledll.oleacc.AccessibleChildren(iaccessible, 0, iaccessible.accChildCount, objAccChildArray, ctypes.byref(objAccChildCount))
for i in range(objAccChildCount.value):
objAccChild = objAccChildArray[i]
if objAccChild.vt == comtypes.automation.VT_DISPATCH:
# query the sub element accessible interface
newiaccessible = objAccChild.value.QueryInterface(comtypes.gen.Accessibility.IAccessible)
# then loop over its descendants
for (__i, __c) in accDescendants(newiaccessible):
yield (__i, __c)
else: #if objAccChild.vt == comtypes.automation.VT_I4:
yield (iaccessible, objAccChild.value)
def findObjIAccessible(handle, text):
"""Find the IAccessible based on the name, starting from a specific window handle
Arguments:
handle -- the window handle from which to search for the element
text -- text that should be contained in the name of the IAccessible instance
Return:
(None, 0) if not found
(IAccessible instance, child id) of the first element whose name contains the text
"""
iacc = ctypes.POINTER(comtypes.gen.Accessibility.IAccessible)()
ctypes.oledll.oleacc.AccessibleObjectFromWindow(handle, 0, ctypes.byref(comtypes.gen.Accessibility.IAccessible._iid_), ctypes.byref(iacc))
for (ia, ch) in accDescendants(iacc):
n = accName(ia, ch)
if n != None and text in n:
return (ia, ch)
else:
return (None, 0)

Print from wizard

I would like to print a report from wizard. In this wizard I recover the order selected and call to report_action function with the orders selected.
The problem is that I don't know how to send the orders to this function. This is the code:
def _get_default_orders(self):
return self.env['sale.order'].browse(self.env.context.get('active_ids'))
order_ids = fields.Many2many('sale.order', string='Orders', default=_get_default_orders)
#api.multi
def processed_orders(self):
list = []
for orders in self:
if orders.order_ids:
list.append(orders)
datas = {
'ids': list,
'model': 'sale.order',
}
return self.env.ref('aloha_reports_templates.custom_report_sale_order').sudo().report_action(self, data=datas)
Odoo generate an error because I don't send properly the parameters to the report_action.
Can someone help me?
Thanks
As per your example first, in your system, there is must be aloha_reports_templates.custom_report_sale_order action available for the report.
Let me show you an example from odoo 11 community code
File: account/models/account_invoice.py method(invoice_print)
#api.multi
def invoice_print(self):
""" Print the invoice and mark it as sent, so that we can see more
easily the next step of the workflow
"""
self.ensure_one()
self.sent = True
if self.user_has_groups('account.group_account_invoice'):
return self.env.ref('account.account_invoices').report_action(self)
else:
return self.env.ref('account.account_invoices_without_payment').report_action(self)
As per above code in odoo 11 community there is already account_invoices report action already created as below (account/views/account_report.xml).
<report
id="account_invoices"
model="account.invoice"
string="Invoices"
report_type="qweb-pdf"
name="account.report_invoice_with_payments"
file="account.report_invoice_with_payments"
attachment="(object.state in ('open','paid')) and ('INV'+(object.number or '').replace('/','')+'.pdf')"
print_report_name="(object._get_printed_report_name())"
groups="account.group_account_invoice"
/>
Hope this helps!

Python winappdbg getting process name from event object

I'm developing a debugging automation system using https://github.com/MarioVilas/winappdbg.
I would like to retrieve process name from event object. Here is my code:
def EventHandler(event):
print 'Inside event handler'
# I want to print the process name here, In this case which should be somefile.exe
debug = Debug( EventHandler, bKillOnExit = True )
proc = debug.execv(['c:\somefile.exe','arg'])
debug.loop()
The tool author answered my question on github : Here is the solution
We can do event.get_process().get_filename(), or if we want to be more fancy:
process = event.get_process()
name = process.get_filename()
print "Process: %s" % name

Resources