Greg Thompson commited on
Commit
f549aa3
1 Parent(s): 31caaf3

Update conversation_manager.py for code style and comments

Browse files
Files changed (2) hide show
  1. app.py +1 -14
  2. mathtext_fastapi/conversation_manager.py +82 -42
app.py CHANGED
@@ -52,21 +52,8 @@ def text2int_ep(content: Text = None):
52
 
53
  @app.post("/manager")
54
  async def programmatic_message_manager(request: Request):
55
- print(request)
56
-
57
  data_dict = await request.json()
58
- # print("FULL REQUEST")
59
- # print(data_dict)
60
-
61
- # message_data = data_dict.get('message_data', '')
62
- # context_data = data_dict.get('context', '')
63
-
64
- # print("MESSAGE_DATA")
65
- # print(message_data)
66
- # print("CONTEXT_DATA")
67
- # print(context_data)
68
-
69
- context = generate_message(data_dict)
70
  return JSONResponse(context)
71
 
72
  @app.post("/nlu")
 
52
 
53
  @app.post("/manager")
54
  async def programmatic_message_manager(request: Request):
 
 
55
  data_dict = await request.json()
56
+ context = manage_conversational_response(data_dict)
 
 
 
 
 
 
 
 
 
 
 
57
  return JSONResponse(context)
58
 
59
  @app.post("/nlu")
mathtext_fastapi/conversation_manager.py CHANGED
@@ -10,7 +10,16 @@ load_dotenv()
10
 
11
 
12
  def create_text_message(message_text, whatsapp_id):
13
- data = {
 
 
 
 
 
 
 
 
 
14
  "preview_url": False,
15
  "recipient_type": "individual",
16
  "to": whatsapp_id,
@@ -19,23 +28,46 @@ def create_text_message(message_text, whatsapp_id):
19
  "body": message_text
20
  }
21
  }
22
- return data
 
23
 
24
  def create_button_objects(button_options):
 
 
 
 
 
 
 
 
 
 
25
  button_arr = []
26
  for option in button_options:
27
  button_choice = {
28
  "type": "reply",
29
  "reply": {
30
  "id": "inquiry-yes",
31
- "title": "add"
32
  }
33
  }
34
  button_arr.append(button_choice)
35
  return button_arr
36
 
 
37
  def create_interactive_message(message_text, button_options, whatsapp_id):
 
38
 
 
 
 
 
 
 
 
 
 
 
39
  button_arr = create_button_objects(button_options)
40
 
41
  data = {
@@ -56,38 +88,19 @@ def create_interactive_message(message_text, button_options, whatsapp_id):
56
  return data
57
 
58
 
59
- def generate_message(data_json):
60
- """ pending
61
 
62
- REQUIREMENTS
63
- - implement logging of message
64
- - have a very simple activity which allows for different dialogue
65
- * add - Add the numbers, 1+1, 2+2
66
- * subtract - Subtract the numbers, 1-1, 2-2
67
- * menu - Choose one
68
- - send message data to retrieve dialogue state
69
- - retrieve response and build message object
70
- - send message object
71
-
72
- Need to make util functions that apply to both /nlu and /conversation_manager
73
- """
74
-
75
- message_data = data_json.get('message_data', '')
76
- context_data = data_json.get('context', '')
77
-
78
- whatsapp_id = message_data['message']['_vnd']['v1']['chat']['owner'].replace("+","")
79
- user_message = message_data['message']['text']['body']
80
-
81
- print("===============")
82
- print("message_data")
83
- print(message_data)
84
- print("context_data")
85
- print(context_data)
86
- print("===============")
87
 
 
 
 
88
 
89
  if context_data['user_message'] == '' and context_data['state'] == 'start-conversation':
90
- message_package = {
91
  'messages': [],
92
  'input_prompt': "Welcome to our math practice. What would you like to try? Type add or subtract.",
93
  'state': "welcome-sequence"
@@ -127,27 +140,54 @@ def generate_message(data_json):
127
  'input_prompt': "Please type add or subtract to start a math activity.",
128
  'state': "reprompt-menu-options"
129
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
  headers = {
132
  'Authorization': f"Bearer {os.environ.get('TURN_AUTHENTICATION_TOKEN')}",
133
  'Content-Type': 'application/json'
134
  }
135
 
 
136
  for message in message_package['messages']:
137
  data = create_text_message(message, whatsapp_id)
138
  r = requests.post(f'https://whatsapp.turn.io/v1/messages', data=json.dumps(data), headers=headers)
139
 
140
- # print("==================")
141
- # print("Headers")
142
- # print(headers)
143
- # print("Data")
144
- # print(data)
145
- # print("Request Info")
146
- # print(r)
147
- # print("==================")
148
-
149
-
150
- context = {"context":{"user": whatsapp_id, "state": message_package['state'], "bot_message": message_package['input_prompt'], "user_message": user_message, "type": 'ask'}}
151
 
152
  return context
153
 
 
10
 
11
 
12
  def create_text_message(message_text, whatsapp_id):
13
+ """ Fills a template with the necessary information to send a text message to Whatsapp
14
+
15
+ Inputs
16
+ - message_text: str - the content that the message should display
17
+ - whatsapp_id: str - the message recipient's phone number
18
+
19
+ Outputs
20
+ - message_data: dict - a preformatted template with the inputs' values included
21
+ """
22
+ message_data = {
23
  "preview_url": False,
24
  "recipient_type": "individual",
25
  "to": whatsapp_id,
 
28
  "body": message_text
29
  }
30
  }
31
+ return message_data
32
+
33
 
34
  def create_button_objects(button_options):
35
+ """ Creates a list of button objects using the input values
36
+ Input
37
+ - button_options: list - a list of text to be displayed in buttons
38
+
39
+ Output
40
+ - button_arr: list - a list of button objects that use a template filled with the input values
41
+
42
+ NOTE: Not fully implemented and tested
43
+
44
+ """
45
  button_arr = []
46
  for option in button_options:
47
  button_choice = {
48
  "type": "reply",
49
  "reply": {
50
  "id": "inquiry-yes",
51
+ "title": option['text']
52
  }
53
  }
54
  button_arr.append(button_choice)
55
  return button_arr
56
 
57
+
58
  def create_interactive_message(message_text, button_options, whatsapp_id):
59
+ """ Fills a template with the necessary information to send a message with button options to Whatsapp
60
 
61
+ * NOTE: Not fully implemented and tested
62
+ * NOTE/TODO: It is possible to create other kinds of messages with the 'interactive message' template
63
+ * Documentation: https://whatsapp.turn.io/docs/api/messages#interactive-messages
64
+
65
+ Inputs
66
+ - message_text: str - the content that the message should display
67
+ - button_options: list - what each button option should display
68
+ - whatsapp_id: str - the message recipient's phone number
69
+
70
+ """
71
  button_arr = create_button_objects(button_options)
72
 
73
  data = {
 
88
  return data
89
 
90
 
91
+ def return_next_conversational_state(context_data, user_message):
92
+ """ Evaluates the current state of the conversation to determine resources for the next state of the conversation
93
 
94
+ Input
95
+ - context_data: dict - data about the conversation's current state received from the Turn.io stack
96
+ - user_message: str - the message the user sent in response to the state
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
+ Output
99
+ - message_package: dict - a series of messages and user input to send the user
100
+ """
101
 
102
  if context_data['user_message'] == '' and context_data['state'] == 'start-conversation':
103
+ message_package = {
104
  'messages': [],
105
  'input_prompt': "Welcome to our math practice. What would you like to try? Type add or subtract.",
106
  'state': "welcome-sequence"
 
140
  'input_prompt': "Please type add or subtract to start a math activity.",
141
  'state': "reprompt-menu-options"
142
  }
143
+ return message_package
144
+
145
+
146
+ def manage_conversational_response(data_json):
147
+ """ Parses message data, determines how to respond to user message at a given conversational state, builds/sends messages, and updates/sends context
148
+
149
+ Input
150
+ - data_json: dict - the data for a message the user sent to Turn.io/Whatsapp
151
+
152
+ Output
153
+ - context: dict - a record of the state at a given point a conversation
154
+
155
+ TODOs
156
+ - implement logging of message
157
+ - test interactive messages
158
+ - review context object and re-work to use a standardized format
159
+ - review ways for more robust error handling
160
+ - need to make util functions that apply to both /nlu and /conversation_manager
161
+ """
162
+
163
+ message_data = data_json.get('message_data', '')
164
+ context_data = data_json.get('context', '')
165
+
166
+ whatsapp_id = message_data['message']['_vnd']['v1']['chat']['owner'].replace("+","")
167
+ user_message = message_data['message']['text']['body']
168
+
169
+ message_package = return_next_conversational_state(context_data, user_message)
170
 
171
  headers = {
172
  'Authorization': f"Bearer {os.environ.get('TURN_AUTHENTICATION_TOKEN')}",
173
  'Content-Type': 'application/json'
174
  }
175
 
176
+ # Send all messages for the current state before a user input prompt (text/button input request)
177
  for message in message_package['messages']:
178
  data = create_text_message(message, whatsapp_id)
179
  r = requests.post(f'https://whatsapp.turn.io/v1/messages', data=json.dumps(data), headers=headers)
180
 
181
+ # Update the context object with the new state of the conversation
182
+ context = {
183
+ "context":{
184
+ "user": whatsapp_id,
185
+ "state": message_package['state'],
186
+ "bot_message": message_package['input_prompt'],
187
+ "user_message": user_message,
188
+ "type": 'ask'
189
+ }
190
+ }
 
191
 
192
  return context
193