├── Exercice ├── README.MD └── images │ ├── Restaurant-search-flow (1).png │ ├── Restaurant-search-flow.png │ └── reservation_example.png ├── README.md ├── images ├── Restaurant-search-flow.png ├── Restaurant_search_conversation_example.png ├── Weather-forecast-flow.png ├── agent_default.png ├── demo_flows.png ├── flow_rest_reservation.png ├── flows.png ├── flows.svg ├── ok.json ├── reservation_example.png ├── restaurant_reservation.png ├── reuse_info.png ├── weather-forecast-conversation.png └── webhook.png ├── intents ├── GetWeather.txt └── SearchRestaurant.txt └── webhook_service ├── API_credentials.json ├── requirements.txt ├── webhook.py ├── webhook_externalcall.py ├── webhookrequest.json └── webhookresponse.jsonc /Exercice/README.MD: -------------------------------------------------------------------------------- 1 | ## Designing the Restaurant reservation flow 2 | After adding the design of the restaurant reservation flow, the whole agent design should be as follow: 3 | 4 |

5 | 6 |

7 | 8 | ## Creating Restaurant reservation flow 9 | To create this flow, you will almost follow the steps taken for Weather forecast Flow. 10 | 1. Create intent 11 | - Intent: restaurant.search 12 | - Utterances: [SearchRestaurant.txt](https://github.com/hayo03/Dialogflow-CX-Start-Tutorial/blob/main/intents/SearchRestaurant.txt). 13 | - Parameters: 14 | - name: Location; Entity type: @sys.geo_city 15 | - name: food; Entity type: You have to create a new entity type and name it @food, where entity entries can be like Italian, Chinese, Turkish, Indian, Tunisian, etc. 16 | 2. Create Flow named "Restaurant reservation flow" 17 | 3. Create a Route that transitions from the default start flow to Restaurant reservation flow. 18 | - Intent: restaurant.search 19 | - Transition to the Flow: Restaurant reservation flow 20 | 4. Create Page named "Collect food and location" that will collect the location information where users search in and kind of food they prefer. 21 | - Parameters: 22 | - name: Location; Entity type: @sys.geo_city 23 | - name: food; Entity type: @food; 24 | 5. Create a Route that transitions from the Restaurant reservation flow to "Collect food and location" page. 25 | - Intent: restaurant.search 26 | - Transition to the Page: Collect food and location 27 | 6. Create a Route that transitions from the "Collect food and location" page to EndFlow page. 28 | - Condition: $page.params.status="FINAL" 29 | - Fulfillement: This one serves $session.params.food food: Hello world Restaurant, Phone: +0000000, address : Hello world street, $session.params.location 30 | - Transition to the Page: End Flow 31 | 32 | -------------------------------------------------------------------------------- /Exercice/images/Restaurant-search-flow (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/Exercice/images/Restaurant-search-flow (1).png -------------------------------------------------------------------------------- /Exercice/images/Restaurant-search-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/Exercice/images/Restaurant-search-flow.png -------------------------------------------------------------------------------- /Exercice/images/reservation_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/Exercice/images/reservation_example.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dialogflow-CX-Start-Tutorial 2 | 3 | ### Content 4 | - ##### [Introduction](#intro) 5 | - ##### [Environnement Installation](#install) 6 | - ##### [Dialogflow CX Setup ](#Setup) 7 | - ##### [Exploring the created agent](#welcomemessage) 8 | - ##### [Managing Flows & Pages](#FlowsandPages) 9 | - ##### [Exercise](#exercise) 10 | - ##### [Building a webhook](#webhook) 11 | - ##### [Designing more complex conversations](#complexconversations) 12 | - ##### [Conclusion](#conclu) 13 | 14 | 15 | ## Introduction 16 | This guide shows how to use the Dialogflow CX Console to build and test a simple demo agent. When interacting with this agent, you can ask for getting the weather forecast information, search for a restaurant and make a table reservation. Your completed agent for this guide will be graphed by the console like the following: 17 | 18 |

19 | 20 |

21 | 22 | ## Environnement Installation 23 | During this tutorial, we will need to use Python as a programming language, visual studio code to write code, and Ngrok to deploy webhook services in localhost. [Here](https://github.com/hayo03/Installation) are the steps to install all of these. 24 | ## Dialogflow CX Setup 25 | 1. To use services provided by Google Cloud, you need to create a project using [Google Cloud Console](https://console.cloud.google.com/) and enable the Dialogflow API. 26 | 2. Using [DF-CX console](https://dialogflow.cloud.google.com/cx/projects), choose the project you just created and click Create agent.
27 | 3. Complete the form for basic agent settings:
28 | - Name it "Demo-agent"
29 | - Select your preferred location.
30 | - Select your preferred time zone.
31 | - Select "English" as default language for your agent.
32 | 4. Click Save.
33 | 34 | ## Exploring the created agent 35 | The created agent has a default Start Flow with a start page that comes with default welcome intent. Within this default setting, the agent can handle a basic conversation with only a welcome message. 36 | 37 | ![tt](images/agent_default.png) 38 | 39 | To test your new agent: 40 | 1. Click the Test Agent button to open the simulator. 41 | 2. Enter hello in the text entry and press enter. The agent responds with a default welcome response. 42 | 3. Close the simulator 43 | 44 | To edit the welcome response message: 45 | 1. Click the Build tab. 46 | 2. Select the Default Start Flow in the Flows section. 47 | 3. Click the Start node in the graph. This is the start page for the Default Start Flow. 48 | 4. Find the intent route with the Default Welcome Intent and click it. This opens a panel to edit the intent route information. 49 | 5. Find the fulfillment section and delete all response messages, then add "Hello, I am here. How I can help you?" as the only response. 50 | 6. Click Save and Close the intent route editing panel. 51 | 7. Test the updated welcome response message. 52 | 53 | ## Managing Flows & Pages 54 | So far, the agent has one flow with the start page. In this section, we will add another flow that handle requests about the weather forecast. The design of this flow is like the following: 55 | 56 |

57 | 58 |

59 | 60 | Weather forecast flow: allows users to ask about weather forecast in a given city. Before building it, we need to create the intent that once matched, the flow will be called to handle the user request.
61 | Create intent: 62 | 1. Select the Manage tab. 63 | 2. Click Intents, click Create, enter weather.current as an intent name and enter the training phrases in [utterances.text](https://github.com/hayo03/Dialogflow-CX-Start-Tutorial/blob/main/intents/GetWeather.txt). 64 | 3. For each phrase that contains a city, annotate the city with a parameter named "city" and @sys.geo-city as entity type and Click Save. 65 | 66 | Create Flow : 67 | 1. Select the Build tab. 68 | 2. Click Flows. 69 | 3. Click Create and enter Weather forecast as a flow name. 70 | 71 | Create Page :
72 | By default, the Weather forecast flow has a special page named Start. When a flow initially becomes active, this page becomes the current active page. A start page does not have parameters or response messages like normal pages. So we need to create pages that will collect city information from user and handle his/her request (i.e., provide answers to the user).
73 | 1. Click on "Start" page in Weather forecast flow 74 | 2. Click the add + button in the Pages section. 75 | 3. Enter "Collect city" as a display name for the page. 76 | 4. Click the settings more_vert button next to the page display name and select Edit. 77 | 5. Create a new parameter:
78 | - Parameter name: city
79 | - Entity type: @sys.geo-city
80 | - Check "Required"
81 | - Fulfillement (Agent says): What is the city?
82 | 83 | Create Routes:
84 | As you notice there is no link between different flows (i.e., Default Start Flow and Weather forecast Flow) and the newly created page (Collect city). Without those links, the conversation between bot and user can not be handled. Therefore, Routes are introduced to define such links. We need to define three routes as follows: 85 | 1. Create a Route that transitions from the default start flow to Weather forecast flow. This route should be called when the end-user asks for weather forecast. To create this route:
86 | - Select the Default Start Flow in the Flows section. 87 | - Click the Start node in the graph. 88 | - Add the following intent route: 89 | - Intent: weather.current 90 | - Transition: choose Flow and select “Weather forecast” flow 91 | - Click Save 92 | 93 | 2. Create a Route that transitions from the start page of the Weather forecast flow to "Collect city" page. This route should be called when the intent “weather.current” is matched”. To create this route:
94 | - Select the Weather forecast” Flow in the Flows section. 95 | - Click the Start node in the graph. 96 | - Add the following intent route: 97 | - Intent: weather.current 98 | - Transition: choose Page and select “Collect city” page 99 | - Click Save 100 | 101 | 3. Create a route that transitions from “Collect city" page to End Flow page: this route should be called when all parameters are fulfilled. To create this route:
102 | - Select the "Weather forecast” Flow in the Flows section. 103 | - Click the Start node in the graph. 104 | - Add the following intent route: 105 | - condition: $page.params.status="FINAL" 106 | - Fulfillement (What the Agent will answer to the user): There is clear sky in $session.params.city 107 | - Transition: choose Page and select “End Flow” page 108 | - Click Save 109 | 110 | Congratulations! Now you can test your agent to test if your flow is correctly created: 111 | 112 | Test the Weather forecast flow:
113 | 1. Click the Test Agent button to open the simulator.
114 | 2. Enter "What does the weather forecast look like?" and press enter.
115 | 3. The agent will request you to provide the city and then provides you the weather forecast.
116 | 117 | 118 | ## Exercise 119 | Considering the following conversation example: 120 |
121 | 122 | 1. Identify the flow design you think is required to support the given conversation example. Toward a solution, you may need to ask yourself the following questions: 123 | - Do I need to add a new flow? 124 | - Do I need to add a new intent? new parameters? new entity types? 125 | - Do I need to create a page? 126 | - What are the required routes to support this case? 127 | 2. Once you identified the required design, add it to the Demo agent. 128 | 3. Test your Demo agent to check whether what you created will lead to the given conversation example. 129 | 130 | 131 | 132 | ## Building a webhook 133 | At this point, the created agent can answer users only with static response messages. But in real cases, we need to generate dynamic responses, validate collected data, or trigger actions on the backend. Webhooks are introduced to handle all of this. They are simply the backend parts of the agent. 134 | 135 |

136 | 137 |

138 | 139 | As the diagram above shows, when a fulfillment that has a webhook is called, the Dialogflow API sends a webhook request to the webhook service. 140 | The webhook service receives the webhook request and takes any actions necessary, like calling external APIs, querying or updating a database, etc. It builds a response and sends it back to Dialogflow API. A webhook can be created in any server side programming language like Python, PHP or Node.js. We are going to use Python to create a webhook and Ngrok to deploy it. Let’s start building our webhook for handling weather forecast requests. 141 | 142 | ## Creating a webhook service using Python 143 | Create a folder and name it as webhook_service. Under this folder, we are going to create the following two files: webhook.py, requirements.txt. 144 | - webhook.py: it is the webhook service that will handle the requests sent from the Dialogflow agent and provide back a response. To keep it simple, we will create a webhook that gets parameters from an agent request and provides back a static response. 145 | 146 | ``` 147 | #### minimal set of required modules 148 | import json 149 | from flask import Flask 150 | from flask import Response, request 151 | import requests 152 | 153 | 154 | ###create and initialize a flask app for our webhook 155 | app = Flask(__name__) 156 | 157 | 158 | 159 | ### Define a Route 160 | @app.route('/my_webhook', methods=['POST']) 161 | 162 | ### Define the function that will be executed when the associated route is called 163 | 164 | def post_webhook_dialogflow(): 165 | 166 | #1) Getting information from dialogflow agent request 167 | body = request.get_json(silent=True) 168 | 169 | #Get tag used to identify which fulfillment is being called. 170 | fulfillment = body['fulfillmentInfo']['tag'] 171 | 172 | #Get parameters that are required to handle the desired action 173 | prameters = [] 174 | for key, value in body['sessionInfo']['parameters'].items(): 175 | prameters.append({'name':key,'value':value}) 176 | 177 | #2) Execute action 178 | msg = invoke_action(fulfillment, prameters) 179 | 180 | #3) provide a webhook Response to the Dialogflow Agent 181 | WebhookResponse=answer_webhook(msg) 182 | return WebhookResponse 183 | 184 | ### Exploit parameters and incorporate them in the text response 185 | def invoke_action(fulfillment, prameters): 186 | 187 | 188 | #### Processes the webhook answer which should follow a particular JSON format 189 | def answer_webhook(msg): 190 | 191 | ### Run a webhook on localhost 192 | if __name__ == '__main__': 193 | app.run(host="0.0.0.0", port=8081, debug=True) 194 | ``` 195 | 196 | - invoke_action (fulfillment, prameters): defines the action that should be executed for a given fulfillment. It exploits parameters and incorporates them into the response text. 197 | 198 | ``` 199 | def invoke_action(fulfillment, prameters): 200 | print("\n\n\n\n\n=========> CALL ",fulfillment) 201 | if fulfillment == "GetWeather_fulfillment": 202 | city=str( prameters[0]['value']) 203 | msg="There are overcast clouds in "+city 204 | return msg 205 | ``` 206 | - answer_webhook(msg): processes the webhook answer that should follow a particular JSON format. 207 | ``` 208 | def answer_webhook(msg): 209 | message= {"fulfillment_response": { 210 | 211 | "messages": [ 212 | { 213 | "text": { 214 | "text": [msg] 215 | } 216 | } 217 | ] 218 | } 219 | } 220 | return Response(json.dumps(message), 200, mimetype='application/json') 221 | ``` 222 | 223 | - requirements.txt: contain the libraries required to create the webhook service, namelly flask and requests. 224 | ``` 225 | flask 226 | requests 227 | ``` 228 | 229 | Check [here](https://github.com/hayo03/Dialogflow-CX-Start-Tutorial/blob/main/webhook_service/webhookrequest.json) for the full webhook body request.
230 | Check [here](https://github.com/hayo03/Dialogflow-CX-Start-Tutorial/blob/main/webhook_service/webhookresponse.jsonc) for the full webhook body response.
231 | Check [here](https://github.com/hayo03/Dialogflow-CX-Start-Tutorial/blob/main/webhook_service/webhook.py) for the full webhook script that we've built.
232 | 233 | 234 | ## Run the webhook service 235 | 236 | Open terminal, create a virtual environment and install required packages. 237 | - Operating system: macOS/OS X, Linux; 238 | ``` 239 | cd webhook_service 240 | python3 -m venv myenv 241 | source myenv/bin/activate 242 | pip install -r requirements.txt 243 | python webhook.py 244 | ``` 245 | 246 | - Operating system: Windows: 247 | 248 | ``` 249 | cd webhook_service 250 | python3 -m venv myenv 251 | myenv\Scripts\activate.bat 252 | pip install -r requirements.txt 253 | python webhook 254 | 255 | ``` 256 | ## Deploy a webhook service using Ngrok 257 | 258 | In the terminal just run the following commends: 259 | 260 | ``` 261 | cd Path_To_Ngrok 262 | ./ngrok http 8081 (or ngrok http 8081 if the first one does not work) 263 | 264 | ``` 265 | 266 | ## Setup webhook in Dialogflow and test it 267 | 268 | We need to first create a webhook and add it to the fulfillment in "Collect city" page: 269 | 1. Create webhook 270 | - Select the Manage tab. 271 | - Click Webhooks, Click Create and put "my_webhook_service" as display name . 272 | - Enter your webhook url generated by ngrok, some thing like https://2f4168d1c17d.ngrok.io/my_webhook. 273 | - Click Save. 274 | 2. Add a webhook to a fulfillment 275 | - Click on "Collect city" page 276 | - Click on the exsiting route 277 | - Find the fulfillment section and Check "Use Webhook" 278 | - Select "my_webhook_service" and enter "GetWeather_fulfillment" in tag field. 279 | 3. To test the webhook, click the Test Agent and enter "What does the weather forecast look like?". If everything is well settled, the agent should provide you the response text you provided. 280 | 281 | #### Update the webhook for invoking an external service 282 | 283 | At this point, our webhook can only get information and invoke a simple action that provides a static response about the weather conditions. But in real cases, we need to invoke one of the external services such as the well-known [Open weather API](https://openweathermap.org/api) to get real-time weather information. To do so we need to update the invoke-action function so as be able to call Open weather API : 284 | 285 | ``` 286 | def invoke_action(fulfillment, prameters): 287 | print("\n\n\n\n\n=========> CALL API ",fulfillment) 288 | if fulfillment == "GetWeather_fulfillment": 289 | for prameter in prameters: 290 | if prameter['name']=="city": 291 | city=str(prameter['value']) 292 | appid="25e5d7b2fff948d0749a8b9e9e14f5f9" 293 | url = 'http://api.openweathermap.org/data/2.5/weather?q='+city+'&appid='+appid 294 | result = requests.get(url) 295 | jsonResult = result.json() 296 | if result.status_code == 200: 297 | weatherCondition = jsonResult['weather'][0]['description'] 298 | reply = "There is {} there.".format(weatherCondition) 299 | print(reply) 300 | return reply 301 | else: 302 | return "Something wrong with the API." 303 | ``` 304 | 305 | - Test the updated webhook to check if it behaves properly. 306 | ## Designing more complex conversations 307 | - ##### [Handling multiple intents](#multipleintents) 308 | - ##### [Reusing information between flows](#reuseinformation) 309 | 310 | ## Handling multiple intents 311 | Previously, we created two simple flows (i.e., weather forecast and restaurant reservation). In this part, we show you how to design a flow to allow the bot to choose different routes depending on the user intent. Let's extend the "restaurant reservation" flow to allow the user to make a reservation if she/he wants, or the bot says goodbye to the user if she/he doesn't want to make a reservation. To support this scenario, we need to create two new intents "Reservation.YES" and "Reservation.NO". 312 |

313 | 314 | 315 |

316 | 317 | 1. Create intents "Reservation.YES" and "Reservation.NO". 318 | 2. Select the flow "Restaurant reservation" and add these two pages: 319 | - Page name: "Reservation" 320 | - Page name: "Collect seats and date-time" / Add the two parameters "seats" and "date-time". For "seats" parameter agent asks "For how many people would you like to make the reservation"? and for "date-time" agent asks "What time-date would you like to make the reservation?". 321 | 3. Update the route from "Collect food and location" to "End Flow" page. 322 | - Change "End Flow" page to "Reservation" page. 323 | - Add to the Fulfillment section the text "Would you like to make a reservation?". 324 | 4. Add two routes to "Reservation" page. 325 | - Route 1: Put intent as "Reservation.NO", Fulfillment as "Come visit us again when you get hungry! Bye 👋", and transition to "End Flow" page. 326 | - Route 2: Put intent as "Reservation.YES" and transition to "Collect seats and date-time" page. 327 | 5. Add a route to "Collect seats and date-time" page. 328 | - Put condition as $page.params.status="FINAL", Fulfillment as "Done! I have booked a table for $session.params.seats people on $session.params.date-time.", and transition to "End Flow" page. 329 | 330 | ## Reusing information between flows 331 | After completing both flows, the agent will be able to handle user requests about both weather forecast and restaurant reservation. However, when you interact with the agent, you will notice that it may ask you for information that you already provided. As shown below, the agent asks the user "what is your location" despite the fact that he already provided his/her city in one of the previous turns.
332 | 333 |

334 | 335 |

336 | 337 | To avoid such an issue, the agent needs to exploit the context well, i.e., any information that can be leveraged from the previous conversation turns or any other sources (e.g., user profile). In this tutorial, we are interested in exploiting the previous conversation turns as the main source for the context. Indeed, in Dialogflow CX, there is an interesting feature called Parameter preset (in the fulfillment section) that allows to set or override the parameter values. So we will exploit this feature in order to reuse information from session parameters that represents the parameters fulfilled in the previous turns. To do so :
338 | 1. Select “Collect city” page in Weather forecast flow and edit the already defined route. 339 | 2. Find Parameter preset feature within the fulfillment section. 340 | 3. Click on Add Parameter and add the following: 341 | - Parameter: location; 342 | - Value: "$session.params.city" 343 | 4. Test again the agent, what do you notice? 344 | 5. (Exercise) Now what do we need to do to make the agent be able to reuse the location value in the Search restaurant flow for the city parameter in the Weather forecast flow? 345 | 346 | ## Conclusion 347 | So far, we explored how to: 348 | - Setup a DF CX project 349 | - Create an agent. 350 | - Create intents, parameters and entity types . 351 | - Create flows, pages and build links between them using routes 352 | - Create a webhook and make call to an external service 353 | - Design more complex conversations 354 | 355 | There are other interesting agent features that we haven't covered, including integrations, event handlers and so more. Overall, this tutorial covers most of the Dialogflow CX basics that every bot developer should be well-versed in toward building conversational agents doted with advanced capabilities. 356 | Please send your feedback to brabra.hayeet@gmail.com 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /images/Restaurant-search-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/Restaurant-search-flow.png -------------------------------------------------------------------------------- /images/Restaurant_search_conversation_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/Restaurant_search_conversation_example.png -------------------------------------------------------------------------------- /images/Weather-forecast-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/Weather-forecast-flow.png -------------------------------------------------------------------------------- /images/agent_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/agent_default.png -------------------------------------------------------------------------------- /images/demo_flows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/demo_flows.png -------------------------------------------------------------------------------- /images/flow_rest_reservation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/flow_rest_reservation.png -------------------------------------------------------------------------------- /images/flows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/flows.png -------------------------------------------------------------------------------- /images/flows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 |
Weather forecast
Weather forecast
Restaurant  reservation
Restaurant  reservat...
Page-Get current weather
Page-Get current wea...
Parameter1-City
Parameter1-City
Page-Search restaurant
Page-Search restaura...
Parameter 1-location
Parameter 1-loca...
Parameter 2-food
Parameter 2-food
Transition Route
Reservation
Transition Route...
Reservation
Reservation
Parameter 1-restaurant name
Parameter 1-rest...
Parameter 2-seats
Parameter 2-seats
Parameter 3-date
Parameter 3-date
Reservation.NO
Reservation.NO
Reservation. Yes
Reservation. Yes
Transition Route
Reservation
Transition Route...
End Flow
End Flow
Transition Route
Reservation
Transition Route...
End Flow
End Flow
Viewer does not support full SVG 1.1
-------------------------------------------------------------------------------- /images/ok.json: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/reservation_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/reservation_example.png -------------------------------------------------------------------------------- /images/restaurant_reservation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/restaurant_reservation.png -------------------------------------------------------------------------------- /images/reuse_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/reuse_info.png -------------------------------------------------------------------------------- /images/weather-forecast-conversation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/weather-forecast-conversation.png -------------------------------------------------------------------------------- /images/webhook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayo03/Dialogflow-CX-Start-Tutorial/7cbfce14bf6bffdd1aa44c875d60cd955c27a0d4/images/webhook.png -------------------------------------------------------------------------------- /intents/GetWeather.txt: -------------------------------------------------------------------------------- 1 | What is the weather forecast? 2 | What's the temperature like in Milan? 3 | What is the weather in Sydney? 4 | Is it raining in Paris? 5 | tell me weather condition now in Ottawa 6 | -------------------------------------------------------------------------------- /intents/SearchRestaurant.txt: -------------------------------------------------------------------------------- 1 | looking for a restaurant in Grenoble 2 | I am looking for a restaurant in Paris 3 | my taste for today is seafood 4 | I would like to eat indian food 5 | is there any restaurant around 6 | Any restaurant around Paris 7 | Any suggestions where to eat desserts in Newtown 8 | I wanna eat Chinese thick noodle, what's good in Murano 9 | Is there any place serving vegetarian food in North Sydney 10 | tell me some chinese restaurant near the Opera House 11 | -------------------------------------------------------------------------------- /webhook_service/API_credentials.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "api.openweathermap": 4 | { 5 | "appid":"25e5d7b2fff948d0749a8b9e9e14f5f9" 6 | } 7 | 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /webhook_service/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | flask 3 | -------------------------------------------------------------------------------- /webhook_service/webhook.py: -------------------------------------------------------------------------------- 1 | #### minimal set of required modules 2 | import json 3 | from flask import Flask 4 | from flask import Response, request 5 | import requests 6 | 7 | 8 | #### initialize a flask app for our webhook 9 | app = Flask(__name__) 10 | 11 | 12 | 13 | ### Define a Route 14 | @app.route('/my_webhook', methods=['POST']) 15 | 16 | ### Define the function that will be executed when the associated route is called 17 | def post_webhook_dialogflow(): 18 | #1) Getting information from dialogflow agent request 19 | body = request.get_json(silent=True) 20 | #Get tag used to identify which fulfillment is being called. 21 | fulfillment = body['fulfillmentInfo']['tag'] 22 | #Get parameters that are required to handle the desired action 23 | prameters = [] 24 | for key, value in body['sessionInfo']['parameters'].items(): 25 | prameters.append({'name':key,'value':value}) 26 | 27 | #2) Execute action 28 | msg = invoke_action(fulfillment, prameters) 29 | #3) provide a webhook Response to the Dialogflow Agent 30 | WebhookResponse=answer_webhook(msg) 31 | return WebhookResponse 32 | 33 | ### Exploit parameters and incorporate them in the text response 34 | def invoke_action(fulfillment, prameters): 35 | print("\n\n\n\n\n=========> CALL ",fulfillment) 36 | if fulfillment == "GetWeather_fulfillment": 37 | city=str( prameters[0]['value']) 38 | msg="There are overcast clouds in "+city 39 | return msg 40 | 41 | #### Processes the webhook answer which should follow a particular JSON format 42 | def answer_webhook(msg): 43 | message= {"fulfillment_response": { 44 | 45 | "messages": [ 46 | { 47 | "text": { 48 | "text": [msg] 49 | } 50 | } 51 | ] 52 | } 53 | } 54 | return Response(json.dumps(message), 200, mimetype='application/json') 55 | ### Run a webhook on localhost 56 | if __name__ == '__main__': 57 | app.run(host="0.0.0.0", port=8081, debug=True) 58 | -------------------------------------------------------------------------------- /webhook_service/webhook_externalcall.py: -------------------------------------------------------------------------------- 1 | #### minimal set of required modules 2 | import json 3 | from flask import Flask 4 | from flask import Response, request 5 | import requests 6 | 7 | 8 | #### initialize a flask app for our webhook 9 | app = Flask(__name__) 10 | 11 | 12 | 13 | ### Define a Route 14 | @app.route('/my_webhook', methods=['POST']) 15 | 16 | ### Define the function that will be executed when the associated route is called 17 | def post_webhook_dialogflow(): 18 | #1) Getting information from dialogflow agent request 19 | body = request.get_json(silent=True) 20 | #Get tag used to identify which fulfillment is being called. 21 | fulfillment = body['fulfillmentInfo']['tag'] 22 | #Get parameters that are required to handle the desired action 23 | prameters = [] 24 | for key, value in body['sessionInfo']['parameters'].items(): 25 | prameters.append({'name':key,'value':value}) 26 | 27 | #2) Execute action 28 | msg = invoke_action(fulfillment, prameters) 29 | #3) provide a webhook Response to the Dialogflow Agent 30 | WebhookResponse=answer_webhook(msg) 31 | return WebhookResponse 32 | 33 | ### Exploit parameters and incorporate them in the text response 34 | def invoke_action(fulfillment, prameters): 35 | print("\n\n\n\n\n=========> CALL API ",fulfillment) 36 | if fulfillment == "GetWeather_fulfillment": 37 | for prameter in prameters: 38 | if prameter['name']=="city": 39 | city=str(prameter['value']) 40 | appid="25e5d7b2fff948d0749a8b9e9e14f5f9" 41 | url = 'http://api.openweathermap.org/data/2.5/weather?q='+city+'&appid='+appid 42 | result = requests.get(url) 43 | jsonResult = result.json() 44 | if result.status_code == 200: 45 | weatherCondition = jsonResult['weather'][0]['description'] 46 | reply = "There is {} in there.".format(weatherCondition) 47 | print(reply) 48 | return reply 49 | else: 50 | return "Something wrong with the API." 51 | 52 | #### Processes the webhook answer which should follow a particular JSON format 53 | def answer_webhook(msg): 54 | message= {"fulfillment_response": { 55 | 56 | "messages": [ 57 | { 58 | "text": { 59 | "text": [msg] 60 | } 61 | } 62 | ] 63 | } 64 | } 65 | return Response(json.dumps(message), 200, mimetype='application/json') 66 | ### Run a webhook on localhost 67 | if __name__ == '__main__': 68 | app.run(host="0.0.0.0", port=8081, debug=True) 69 | -------------------------------------------------------------------------------- /webhook_service/webhookrequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "detectIntentResponseId":"a034b7f1-c5c9-46ce-bf2c-935396c08926", 3 | "intentInfo":{ 4 | "lastMatchedIntent":"projects/tutoproject-312812/locations/europe-west2/agents/09fe3290-d5fc-4eb7-88fc-c25169027aee/intents/cc2dc2ac-96b9-4a3d-8f1e-8cf272efd1f2", 5 | "displayName":"weather.current", 6 | "confidence":0.6684057 7 | }, 8 | "pageInfo":{ 9 | "currentPage":"projects/tutoproject-312812/locations/europe-west2/agents/09fe3290-d5fc-4eb7-88fc-c25169027aee/flows/68f7790d-5c1f-4546-bb53-8d641f8288b4/pages/21939010-3336-450d-ae8b-0c9926aec791", 10 | "formInfo":{ 11 | "parameterInfo":[ 12 | { 13 | "displayName":"city", 14 | "required":true, 15 | "state":"FILLED", 16 | "value":"Paris" 17 | } 18 | ] 19 | } 20 | }, 21 | "sessionInfo":{ 22 | "session":"projects/tutoproject-312812/locations/europe-west2/agents/09fe3290-d5fc-4eb7-88fc-c25169027aee/sessions/7fab78-aac-10e-989-d99313ca4", 23 | "parameters":{ 24 | "city":"Paris" 25 | } 26 | }, 27 | "fulfillmentInfo":{ 28 | "tag":"GetWeather_fulfillment" 29 | }, 30 | "text":"What does the weather look like?", 31 | "languageCode":"en" 32 | } 33 | -------------------------------------------------------------------------------- /webhook_service/webhookresponse.jsonc: -------------------------------------------------------------------------------- 1 | {"fulfillment_response": { //The fulfillment response to send to the user. 2 | 3 | "messages": [ 4 | { 5 | "text": { 6 | "text": "" 7 | } 8 | } 9 | ] 10 | }, 11 | "page_info":{ //Intend to modify page status. change a parameter state or value 12 | "current_page":"string", 13 | "form_info":{ 14 | "parameter_info":[{"display_name": "string","required":"bool", "state": "INVALID, EMPTY, or FILLED","value":"value", "just_collected":"bool"}] 15 | } 16 | }, 17 | "session_info":{"session":"string", "parameters":{"prameter name":"prameter value"}}, //Intend to modify session status: create, update, or remove a parameter. 18 | // To remove a parameter from the session, the webhook should explicitly set the parameter value to null. 19 | "target_page": "string", //The target page to transition to 20 | "target_flow": "string" //The target flow to transition to 21 | } 22 | --------------------------------------------------------------------------------