-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathactions.py
164 lines (133 loc) · 4.97 KB
/
actions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# This files contains your custom actions which can be used to run
# custom Python code.
#
# See this guide on how to implement these action:
# https://rasa.com/docs/rasa/core/actions/#custom-actions/
# This is a simple example for a custom action which utters "Hello World!"
from typing import Any, Text, Dict, List
#
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction
from rasa_sdk.events import SlotSet, ReminderScheduled, AllSlotsReset, ReminderCancelled
import datetime
def get_medicine_and_time(tracker):
"""This function gets the medicine and tracker name for corresponding reminder
It extracts it from the latest event"""
# print(tracker.events[-1])
last_event = tracker.events[-1]
medicine = last_event['parse_data']['entities'][0]['value']
time = last_event['parse_data']['entities'][1]['value']
interval = last_event['parse_data']['entities'][2]['value']
return medicine,time,interval
class MedicineForm(FormAction):
""" This class gets the required form entries and sets the reminder"""
def name(self) -> Text:
return "medicine_form"
@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
"""A list of required slots the form has to fill"""
return ["medicine_name", "time", "interval"]
def slot_mappings(self):
return {
"medicine_name": [
self.from_entity(entity="medicine_name", intent=["tell_medicine_name","request_medicine_reminder"]),
self.from_text(not_intent=["goodbye","deny","stop"])
# self.from_text(not_intent=["greet","goodbye","chitchat","affirm","deny","stop"]),
],
"time" : [
self.from_entity(entity="time", intent=["tell_medicine_name", "tell_medicine_time","request_medicine_reminder"])
],
"interval" : [
self.from_entity(entity="duration", intent=["tell_interval", "request_medicine_reminder"])
]
}
def validate_interval(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
seconds = None
enitites_from_sentence = tracker.latest_message['entities']
for entities in enitites_from_sentence:
if entities['entity'] == 'duration':
seconds = entities['additional_info']['normalized']['value']
return {"interval":seconds}
def validate_medicine_name(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
value = value.strip()
# print("value: ",value)
if value == None or value == '':
# dispatcher.utter_message(template='utter_wrong_medicine')
return {"medicine_name":None}
else:
return {"medicine_name":value}
async def submit(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
try:
# get medicine, reminder time and interval from corresponding slots
medicine = tracker.get_slot("medicine_name")
full_time = tracker.get_slot("time")[:19]
interval = tracker.get_slot("interval")
resp = "Medbot will remind you daily for your medicine!!"
# strip the time in required format
date_time = datetime.datetime.strptime(full_time,"%Y-%m-%dT%H:%M:%S")
# datetime = str(date_time)
print(medicine,full_time,interval)
# Schedule the reminder
reminder = ReminderScheduled(
"EXTERNAL_reminder",
trigger_date_time=date_time,
entities = {"medicine":medicine,"time":str(date_time),"interval":interval},
kill_on_user_message=False,
)
dispatcher.utter_message(text=resp)
return [reminder, AllSlotsReset()]
except:
dispatcher.utter_message(text="Some error unable to set reminder..")
return []
class ActionReactToReminder(Action):
"""Reminds the user to take the medicine."""
def name(self) -> Text:
return "action_react_to_reminder"
async def run(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[Dict[Text, Any]]:
# get medicine and requied time
medicine,d_time,interval = get_medicine_and_time(tracker)
# print(medicine, d_time)
resp = "Hii it's your time to take medicine: "+str(medicine)
# print(resp)
dispatcher.utter_message(text=resp)
d_time = datetime.datetime.strptime(d_time,"%Y-%m-%d %H:%M:%S")
# new_time = datetime.datetime.utcfromtimestamp(d_time) + datetime.timedelta(seconds=interval)
new_time = d_time + datetime.timedelta(seconds=interval)
print(new_time)
reminder = ReminderScheduled(
"EXTERNAL_reminder",
trigger_date_time=new_time,
entities = {"medicine":medicine,"time":str(new_time),"interval":interval},
kill_on_user_message=False,
)
return [reminder, AllSlotsReset()]
class ForgetReminders(Action):
"""Cancels all reminders."""
def name(self) -> Text:
return "action_cancel_reminder"
async def run(
self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]
) -> List[Dict[Text, Any]]:
dispatcher.utter_message(f"Okay, all your reminders are cancelled !!")
# Cancel all reminders
return [ReminderCancelled(), AllSlotsReset()]