Create a Dialogue Skill Graph

Before starting the creation of a car insurance quote bot with Dialogue Graph, plan the conversation flow based on user cases and chat logs. Tools such as Draw.io can illustrate the conversation . Here is a flow chart of insurance quote conversation drawn in Draw.io.

This tutorial will demonstrate how to build an insurance quote bot from zero based on this flowchart.

Create a new skill

Log in at Whisper Platform.

Switch to My Skills view by clicking the MY SKILLS link on the homepage.

Click Create My First Skill button to create a skill.

In the pop-up window, choose type Dialogue Graph and edit the skill's name.

Click the OK button, there will be an empty page with a default node "main". The "main" node is the entry of the dialogue graph.

Build the fundamental framework of the insurance quote bot

Start by drawing the root of the graph which will take three types of user input and lead the user to different branches.

Drag a User Says node from the Inputs panel and drop it into the edit area. User Says node will catch a pre-determined phrase. Double click the node to open the node editing window and input "quote". This will enable the node to catch the user's input "quote".

Hover over the main node, there is a hollow circle on each edge. Click and drag one of the hollow circles to the User Says node when the cursor becomes an x. Now, there is a dialog flow from main node to the User Says node.

Now let the insurance bot say something after the user inputs the "quote". Drag and drop a Bot Says node. Double click the node and type some response sentences.

Connect the User Says node and Bot Says node. By now, the dialogue graph can listen for the user’s input “quote” and respond. Click the Train button.

After training successfully, click the Test button to open a dialogue window. Type "quote" and the bot will respond with the pre-set response.

The User Says node can only recognize the exact “quote” it is listening for. What if the user inputs "I want a quote", "car quote" or something that does not match the “quote” but has the same meaning? Intent nodes can be used to catch phrases with similar text and the same intent as the "quote".

Add an Intent node and double click the node to open an editor window. Type "quote" as the name of new intent.

Press "Enter" to finish creating this intent.

Click the edit button of intent "quote" to open the intent edit window.

Enter template in the box and press "Enter" to add this template.

Add two more templates.

Close the window and go back to the intent edit window. Select intent "quote" by clicking the radio button.

Replace the User Says node with an Intent node.

Train the skill and test again. The bot can understand different user inputs with the same intent "quote".

Next, handling user inputs including "exit" and all other unpredictable input.

Add a User Says node and edit content as "exit".

Drag and drop a Quit node. Double left click the node to edit an end message.

Connect the main node and the User Says "exit" node, as well as the User Says node and the Quit node.

Handling all the user's other input except for "quote" and "exit". Wildcard is the node which can accept all input.

Drag and drop a Wildcard node. Add a BotSays node to show user our input examples. Connect the main node, Wildcard node and the BotSays node.

After showing the user the input example, use a Go To node to move the flow to the main node. Double left click the Go To node to edit, and select node-main.

Connect the Bot says node and the Go To node. Now, train and test the bot again.

Build a customer info collection module

After drawing the fundamental branches of the dialog graph, moving onto the core of the car insurance quote bot: collect user's info and provide a quote.

Based on common use cases, car insurance providers usually need the customer's postal code, age, year, make and model of vehicle to provide a basic quote. Collect this info one by one.

Drag and drop a Module node to edit the area for collecting postal code. Module nodes are used for grouping some blocks which have a common goal such as collecting customer's postal code or age. The dialog graph could also work without any module. The graph could be more brief and elegant with modules. Double click the Module node to edit the name.

Click the "Edit Module" button to open an empty edit area for this module.

Draw a dialog graph to collect the user's postal code

Add a Bot Says node. Double click the node and type in the question the bot should ask.

The user enters their postal code. This can be done using an Entity Extraction node to catch a valid Canadian postal code input such as "N2L 3K8".

Add an Entity Extraction node to the edit area. Double click the node to open the Entity edit window and select the built-in entity "ensystem_zip_caZip" which can catch a Canadian postal code.

Connect the Bot Says node and the Entity Extraction node. After catching the postal code entity, process the result of entity extraction. This can be done with a Script node. Add a Script node to the graph.

Double click the node and type in the following code. The code extracts and capitalizes postal code from the entity.

postalcode=com.rsvp.context.util.StringUtil.getStrFromPartialResult(ensystem_zip_caZip, "value", true);
postalcode=postalcode.toUpperCase();

Connect the Entity Extraction node and the Script node. Also add a Wildcard node to catch any input which cannot be recognized as a postal code by the Entity Extraction node.

Add a Bot Says node to show the user a postal code example.

Drop a Go To node and select "botsay-bot ask postal code".

Add a Bot Says node to show the user that the bot has accepted their postal code correctly. In the Script node, user's postal code is saved in a variable named "postalcode". Use "$postalcode" to print this variable.

Make sure you connect all nodes correctly. The complete dialog graph for collecting postal code looks like the following graph.

Now, click the "main" button to go back to the main dialog graph.

Connect the Bot Says node and the Module node. Train the graph and let's test if the dialog graph works.

Draw dialog graph for collecting user's age

Add a new module and edit its name as "ask age". Click the "Edit Module" button to open an empty edit area.

In the module's edit area, add a Bot Says node and edit its name and content as follows.

As the postal code module, add an Entity Extraction node to catch the user's age. Select the built-in entity "ensystem_math_Number" which will catch a math number.

As in the postal code module, a Script node is needed to extract age from the "ensystem_math_Number" entity. Add a Script node and input the following code in the edit window.

age=com.rsvp.context.util.StringUtil.getStrFromPartialResult(ensystem_math_Number, "value", true);
factor=1 - (age-25)*0.01;

Because user' age is a factor that affects insurance cost, the second line of the code is simulating this effect.

With the Entity Extraction node and the Script node, there is a number representing the user's age. However, it is not guaranteed whether the number is a reasonable age. 1000 Would probably not be a plausible age. Draw two branches from the Script node to handle valid and invalid numbers.

For a valid number branch, add a Knot node and edit its condition to check if the number is no less than 16 and no greater than 100. Double click the Knot node, and click the setting button to open the advanced setting window. Set the entering conditions as age >= 16 and age <= 100.

Connect the Script node and the Knot node. For the test, add a Bot says node to show if age is recorded correctly.

For invalid ages, editing conditions is unneeded as in the valid age branch. Because if a number doesn't match the conditions in the valid age branch, it will fall into the invalid age branch automatically. It's better to show the user what a valid age should be. So add a Bot Says node and edit the chatbot's response.

Add a Go To node and select "bot ask age" to ask the user's age again.

As the postal code module, add a branch including a Wildcard node and a Go To node to process user's non-numeric input.

Draw a dialog graph for collecting the production year of the car

Go back to the main graph and add a module named "ask car year". Open the module's edit window by double clicking the module node and click the "Edit Module" button.

Use a Card List node to show a list of years. Then the user can select a year by clicking instead of typing.

Add a Card List node and double click the node. Select "Single" in the edit window and click the "Add" button.

Edit the card title in the pop up window.

Click "+ New Button" to add and edit the button. Button text is the text shown to the user. Postback is the value returned to the backend if the user clicks the button. For the production year of the car, the same content can be used. Click "Submit" to add this button.

Add more buttons for the year following the same steps. Click "Submit" after adding all buttons.

Add a Wildcard node after Card List node to accept user's any choice. User's response will be saved in a variable named "sentence".

Because the production year of the car is also a factor that affects insurance cost, let add a Script node to simulate this effect as in the age module.

Add the following code to the Script node.

currentYear=2020;
caryear=Integer.parseInt(sentence);
factor=1 - (caryear-currentYear)*0.01;

Finally, add a Bot Says node to show the production year is recorded correctly.

Draw dialog graph for collecting make of car

Ask the user for the make of the car next. Add a module named "ask car make" after the "ask car year" module.

Click "Edit Module" to open the empty edit window. Add a Card List node for showing the user a list of makes.

Select "Single" type and click "Add" to edit the card title and add makes. For simplicity, only some some popular makes were added.

Add a Wildcard node as in the production year module to catch the user's response and save the response in variable "sentence".

The value of sentence will be changed by any User Says node or Wildcard node. So we need to save the car make to another variable after catching it. This can be done in Wildcard's leave node settings.

Double click the Wildcard node and open advanced settings. Switch to "Leave node settings" and click the "Add to" button to set variables when leaving the node.

Following the Wildcard node, add a Bot Says node to verify if car make is caught.

Draw dialog graph for collecting model of car

In the main graph, add a new module following the module "ask car make" and open the module's edit window as has been done several times in the preceding steps.

In the empty module page, add several Card List node to show user car models for different car makes.

Add a Card List for models of Ford and name it as "Ford".

Click the setting button and set matches condtion as carMake=="Ford". This means the card list will only show if user's car make is Ford.

Click the "Add" button to open the edit window. Edit card title and add some models of Ford.

Click the "Submit" button to finish editing the card.

Add a new Card List node for Hyundai models.

Set matches condition of this node as carMake=="Hyunadi".

Click "Add" button to open edit window. Edit card title and add some models of Hyundai.

Click "Submit" button to finish editing card.

Add three more Card List nodes for showing models of Nissan, Honda and Toyota following the same steps. Don't forget to set matching conditions.

add a Script node to process car models. Paste the following code to the edit window of the Script node.

// Construct sample car models
Map<String,List> carMakeModelMap = new HashMap<>();
List<String> fordModels = new ArrayList<String>(Arrays.asList("Edge", "Escape", "Expedition", "Explorer"));
carMakeModelMap.put("Ford",fordModels);
List<String> hondaModels = new ArrayList<String>(Arrays.asList("Accord", "Civic", "CR-V", "Odyssey", "Pilot"));
carMakeModelMap.put("Honda",hondaModels);
List<String> hyundaiModels = new ArrayList<String>(Arrays.asList("Accent", "Elantra", "Tucson"));
carMakeModelMap.put("Hyundai",hyundaiModels);
List<String> nissanModels = new ArrayList<String>(Arrays.asList("Altma", "Armada", "Frontier"));
carMakeModelMap.put("Nissan",nissanModels);
List<String> toyotaModels = new ArrayList<String>(Arrays.asList("Camry", "Corolla", "Highlander", "4Runner"));
carMakeModelMap.put("Toyota",toyotaModels);
- // Construct a Card List node
modelButtons = []
List<String> models = carMakeModelMap.get(carmake);
for (int i=0; i< models.size(); i++){
item = new com.alibaba.fastjson.JSONObject();
item.put("text",models.get(i));
item.put("postback",models.get(i));
modelButtons.add(item);
}
- modelItem = new com.alibaba.fastjson.JSONObject();
modelItem.put("buttons",modelButtons);
modelItem.put("title","Please select the model of your car: ");
modelItemArray = new com.alibaba.fastjson.JSONArray();
modelItemArray.add(modelItem);
modelList=new com.alibaba.fastjson.JSONObject();
modelList.put("items",modelItemArray);
modelList.put("type","single");
modelResponse=new com.alibaba.fastjson.JSONObject();
modelResponse.put("list",modelList);
sentence=com.alibaba.fastjson.JSON.toJSONString(modelResponse);

Add a Bot Says node, and type "$sentence" to show the card list constructed in the Script node.

Now there is a Card List node for each make. Add a Wildcard node to catch the user's selection and connect each Card List node with the Wildcard node.

Need to use another variable such as "carModel" to save user's selection. Open the advanced setting of Wildcard node to set a variable when leaving the node.

Add a Bot Says node to show the "carModel" variable.

Confirm Information with user

Now all the information has been collected. Confirm this information with the user before providing a quote.

First, get the image of the user's model. Add a Script node and paste the following code to the edit area. Most of the code is URLs of different models, and the last line gets the image url of the user's car based on the user's car model.

// Image urls for models
Map<String,String> modelImageMap = new HashMap<>();
modelImageMap.put("Edge","http://resource.doudoubot.cn/download/qingyu/rui_1582736679925.jpg");
modelImageMap.put("Escape","http://resource.doudoubot.cn/download/qingyu/rui_1582736735548.webp");
modelImageMap.put("Expedition","http://resource.doudoubot.cn/download/qingyu/rui_1582736781332.webp");
modelImageMap.put("Explorer","http://resource.doudoubot.cn/download/qingyu/rui_1582740735183.webp");
modelImageMap.put("F150","http://resource.doudoubot.cn/download/qingyu/rui_1582740853080.webp");
modelImageMap.put("Accord","http://resource.doudoubot.cn/download/qingyu/rui_1582740999387.jpg");
modelImageMap.put("Civic","http://resource.doudoubot.cn/download/qingyu/rui_1582741176096.png");
modelImageMap.put("Odyssey","http://resource.doudoubot.cn/download/qingyu/rui_1582741237354.webp");
modelImageMap.put("Pilot","http://resource.doudoubot.cn/download/qingyu/rui_1582741313206.png");
modelImageMap.put("Accent","http://resource.doudoubot.cn/download/qingyu/rui_1582741485119.jpg");
modelImageMap.put("Elantra","http://resource.doudoubot.cn/download/qingyu/rui_1582741612204.jpg");
modelImageMap.put("Tucson","http://resource.doudoubot.cn/download/qingyu/rui_1582741644648.png");
modelImageMap.put("Altma","http://resource.doudoubot.cn/download/qingyu/rui_1582742169490.jpg");
modelImageMap.put("Armada","http://resource.doudoubot.cn/download/qingyu/test_1582743046154.webp");
modelImageMap.put("Frontier","http://resource.doudoubot.cn/download/qingyu/test_1582743101767.jpeg");
modelImageMap.put("Camry","http://resource.doudoubot.cn/download/qingyu/rui_1582736303952.webp");
modelImageMap.put("Corola","http://resource.doudoubot.cn/download/qingyu/rui_1582736065468.webp");
modelImageMap.put("Highlander","http://resource.doudoubot.cn/download/qingyu/rui_1582734916140.webp");
modelImageMap.put("4Runner","http://resource.doudoubot.cn/download/qingyu/rui_1582735694410.jpeg");
- // Get image url based on user's car model
modelImageUrl = modelImageMap.get(carModel);

Now add a Card List to confirm information with the user.

Edit the Card List node as following. The title is "Thank you for providing your information. Would you like to get a quote for your $carYear $carMake $carModel?".

Handle user's selection with three User Says node. Content of User Says node are the same with the postbacks of buttons in preceding Card List node.

For modify branch, add a Go To node and select "module-ask postal code". Then bot will ask for all the information again.

For exit branch, add a Quit node and say goodbye to the user.

For quote branch, add a Script node and paste the following code which sets annualPayment and monthlyPayment with variable factor.

annualPayment = (int) (2500 * factor);
monthlyPayment = (int) (annualPayment / 12);

Add a Bot Says node to show the user the quote.

Finally, add a Quit node to exit the graph after showing the user the quote.

Try the car insurance quote bot

Congratulations! The dialog graph for a car insurance quote bot is complete. Chat with the bot to get a quote now.