-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathapp.py
237 lines (194 loc) · 9.57 KB
/
app.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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# flask modules
from flask import Flask, render_template, request, make_response, jsonify
# dialogflow python SDK
import dialogflow_v2 as dialogflow
# requests modulw
import requests
# UUID to generate session ids
import uuid
# JSON
import json
# CSV
import csv
# OS module
import os
# add the credential file to environment variables
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="<ENTER YOUR CREDENTIAL JSON FILE PATH HERE>"
# Flask app initialization
app = Flask(__name__)
# function to detect intent using text with the help of Dialogflow SDK
# project_id - Id of the Dialogflow Agent
# session_id - Id of the user's session
# language_code - language to be use (default: en)
def detect_intent_texts(project_id, session_id, texts, language_code):
# create a session client
session_client = dialogflow.SessionsClient()
# create a session
session = session_client.session_path(project_id, session_id)
# iterate through the input texts usually in the form of a list
for text in texts:
# create the text input object
text_input = dialogflow.types.TextInput(text=text, language_code=language_code)
# create query input object
query_input = dialogflow.types.QueryInput(text=text_input)
# call detect_intent function to get the response json (DetectIntentResponse object)
response = session_client.detect_intent(session=session, query_input=query_input, timeout=20)
# store all the fulfillment messages into a list
responses = response.query_result.fulfillment_messages
# create a copy for future reuse
df_response = response
# empty variables for different response
text_response = [] # for text response
quick_replies_response = None # for quick replies
card_response = None # for cards
# iterate through the fufillment responses
for i, response in enumerate(responses):
# proceed if the response is a facebook response (FACEBOOK platform ID is 1)
if response.platform == 1:
# check if the response is a card response
if response.card.title != "":
# extract card title
card_title = response.card.title
# extract card buttons
card_buttons = response.card.buttons
# list to store buttons
buttons = []
# iterate through card buttons
for button in card_buttons:
# check if the button is web url button
if button.postback:
# build and append the web_url button to the buttons list
buttons.append({
"type": "web_url",
"url": button.postback,
"title": button.text
})
# else store the button as a text button
else:
buttons.append({
"type": "text",
"title": button.text
})
# create a card response and store it in the card_response variable
# this is a chatfuel format JSON
card_response = {
"attachment": {
"type": "template",
"payload": {
"template_type": "button",
"text": card_title,
"buttons": buttons
}
}
}
# check if the response is a text response
if response.text.text is not None:
# here we are catching exception to ignore errors
try:
# check if the text in the text response is empty or not
if response.text.text[0] != "":
# append to the text response list
text_response.append({
"text": response.text.text[0]
})
except:
# pass if any error
pass
# check if the response is a quick replies repsonse
if response.quick_replies is not None:
# the quick replies text should not be null or empty
if quick_replies_response['text'] != "":
# extract quick replies title
quick_reply_title = response.quick_replies.title
# extract quick replies data
quick_reply_data = response.quick_replies.quick_replies
# a list to store quick replies
quick_replies = []
# iterate through every quick replies element
for qr in quick_reply_data:
# append the quick replies to the list
quick_replies.append({
"title": qr,
"block_names": ["Default Answer"]
})
# build the quick replies JSON
quick_replies_response = {
"text": quick_reply_title,
"quick_replies": quick_replies
}
# a main list to store all the responses
messages = []
# check if the card reponse if not none and text is not empty
if card_response is not None:
if card_response['attachment']['payload']['text'] != "":
# append to the messages list
messages.append(card_response)
# check if the number of text responses is not zero
if len(text_response) > 0:
# iterate through the responses and add to the list
for text in text_response:
# append to the messages list
messages.append(text)
# check for the quick replies response, it should not be None and text should not be empty
if quick_replies_response is not None:
if quick_replies_response['text'] != "":
# append to the messages list
messages.append(quick_replies_response)
# check if the number of elements in the main messages list is not 0
if len(messages) > 0:
main_response = {
"messages": messages
}
else:
# if there are no elements then return the fulfillment_text
main_response = {
"messages": [
{"text": df_response.query_result.fulfillment_text}
]
}
# return the main JSON response
return main_response
# function to get the response from the dialogflow SDK
def get_dialogflow_response(messenger_user_input, messenger_user_id):
# create an empty session variable
session_id = ""
# the sessions.csv file is used to store the user's session so that the context should work properly
# create a sessions.csv file in the root directory
# open the file in the read mode
csvfile = open("sessions.csv", 'r')
# creating a csv reader object
csvreader = csv.reader(csvfile, delimiter=",")
# iterate through the rows in the CSV
for row in csvreader:
# search for an existing user in in CSV, if user already exists use the same session ID
if row[0] == str(messenger_user_id):
session_id = str(row[1])
# break the loop if found
break
# if user is not already in the sessions file
if session_id == "":
# create a session ID
session_id = str(uuid.uuid4())
csvfile.close()
# open the sessions file in append mode
csvfile = open("sessions.csv", 'a')
# creating a csv writer object
csvwriter = csv.writer(csvfile, delimiter=",", lineterminator="\n")
# add the data to the sessions file
csvwriter.writerow([str(messenger_user_id), session_id])
# call the detect_intent_texts functions and pass the project ID, session_id, messenger_user_input, 'en-US'
response = detect_intent_texts('indianrailwayinfo-f4b10', session_id, [messenger_user_input], 'en-US')
# return response
return response
# main flask python route
@app.route('/')
def index():
# messenger user id and messenger user input
messenger_user_id = request.args.get('messenger user id')
messenger_user_input = request.args.get('last user freeform input')
# call the get_dialogflow_response, this will return a chatfuel JSON
response = get_dialogflow_response(messenger_user_input, messenger_user_id)
# return the main chatfuel JSON to
return make_response(jsonify(response))
if __name__ == '__main__':
app.run(host='127.0.0.1', port=5000, debug=True)