Before you Begin

Background

This article walks you through some of the highlights of a skill's dialog flow that was designed with Oracle Digital Assistant's Visual Flow Designer.

What Do You Need?

  • Access to Oracle Digital Assistant

Get the Sample from the Skill Store

  1. Sign into into Oracle Digital Assistant.
  2. Click icon to open the side menu to open the side menu and select Development > Store.
  3. In the Filter field, enter PizzaSkill - Visual Flow Designer and press Enter to find the sample.
  4. In the PizzaSkill - Visual Flow Designer tile, click icon to open the Options menu and select Pull.
  5. If the skill has already been imported and/or you will be sharing the instance with others who might do this tutorial, clone the skill:
    • On the Skills page, within the tile for PizzaSkill - Visual Flow Designer, click the Options menu icon, and select Clone.
    • In the Display Name field, enter <YourInitials>PizzaSkill - Visual Flow Designer.
    • Select Open cloned skill afterwards. Then click Clone.

Get Familiar with the Flow Designer

Let's take a quick tour of the flow designer through this skill.

Main Flow

We'll first take a look at the main flow, which works as a high-level configuration for the other flows.

  1. Click Flows the Flows icon in the left navbar.
  2. Click Main Flow.
  3. If it isn't already selected, click the Events tab.
    Description of select-main-flow.png follows
    Description of the illustration select-main-flow.png

    Note the event mappings that appear on the page.

    • Under Intent Events, five of the skill's six intents are mapped to flows. (The unmapped intent is an answer intent that is handled by a built-in event.)
    • Under Built-In Events, there are mappings for three of the standard events that are available for every skill, including the Start Skill event.
    • Under End Flow Action Events, there are custom events that are defined specifically for this skill and which can be triggered by actions in end flow states (both states that use the End Flow component and states which implicitly end the flow).

  4. Click the Skill Variables tab.

    Here you can see both system variables (which all skills have) and custom variables (which you define when you need variables to hold values across multiple flows, such as for shopping carts).

    Description of skill-vars.png follows
    Description of the illustration skill-vars.png

Individual Flows

Now let's see how individual flows are represented in the designer by looking at the handler.startSkill flow. This flow is mapped to the Start Skill event in the Main Flow and is therefore the entry point to the skill.

  1. In the list of flows, select handler.startSkill.
  2. If it isn't already selected, select the Flow tab.
    Description of start-skill-flow.png follows
    Description of the illustration start-skill-flow.png

    Here, you can see

    • An Events tile, which holds states for built-in events in the flow.
    • Tiles that represent states in the flow.

    For now, we'll focus on the states in the flow.

  3. Click the checkUserType tile.

    This opens the property inspector on its Component tab for the state. The main functionality of the component is defined here.

    Description of check-user-type-props.png follows
    Description of the illustration check-user-type-props.png
  4. Click the General tab to view a description provided by the author of the flow of what the state does.
  5. Click the Transitions tab to see what states that this state can transition to.

Explore the Skill in the Tester

This tutorial goes into detail about some parts of the dialog flow's design. But if you'd first like to do some exploring on your own, you can learn a lot about the design by using the built-in Skill Tester to observe how user input is handled in the flow. Here's an example:

  1. Click Preview to open the Skill Tester.
  2. Screenshot of Preview button
  3. In the tester, type I want to order some drinks.

    In addition to the skill's response to your input, you also can view a visual representation of the states used in the conversation as well as other debugging information like postback actions and variables.

    Description of tester-vfd.png follows
    Description of the illustration tester-vfd.png

Summary of Flows

Here's a summary of the eight flows in the skill and quick ways to see how they work in the tester.

Tip:

Before starting a new conversation in the Skill Tester, click Reset so that the tester doesn't interpret your input as being the continuation of a previous unfinished conversation.
Flow Description How to See it in Action
Main Flow The control center for the dialog, where skill-level variables and events are defined. In the tester, type Help.
handler.help Responds to unresolved intents and requests for help. In the tester, type Hello.
handler.startSkill Entry point for the skill. It also determines if the user is a returning user. In the tester, type Hello.
intent.reg.cancelOrder Enables a user to cancel an order that they have made. In the tester:
  1. Type I'd like to order a small pepperoni pizza.
  2. Click No, proceed to payment.
  3. Type Cancel.
intent.reg.order The primary flow for processing pizza and drink orders. In the tester, type I'd like to order a pizza.
pizza.ans.genericHandler Handles any answer intents that don't have a specific flow assigned to them. (In this case, it's just the ans.about.calories intent.) In the tester, type what's the calorie count of your pizzas?
pizza.ans.proc.veggiePizza Handles the answer intent for the ans.proc.vegetarianPizza intent. In the tester, type Do you have any veggie pizzas?
service.reg.placeOrder Finalizes the order. In the tester:
  1. Type I'd like to order a small pepperoni pizza.
  2. Click No, proceed to payment.
  3. Click Place Order.

Explore the Flows in Detail

Now let's take a closer look at a couple flows to see how they are implemented.

Main Flow

We'll start with the Main Flow, since much of what is configured there has a direct impact on the individual flows.

  1. In the list of flows, select Main Flow.
  2. Select the Skill Variables tab.

    Both system and custom variables are shown here. Of particular note is the cartItems custom variable, which is the global variable where details of the pizzas and drinks that the user orders will be stored.

  3. Select the Events tab.

    There's a lot going on here, so let's examine the categories one by one.

Intent Events

There are five mappings that determine the flow that is invoked based on the detected user intent. You'll notice:

  • Both the reg.orderPizza and reg.orderDrink intents are mapped to the intent.reg.order flow.
  • The ans.proc.vegetarianPizza answer intent is mapped to its own flow.
  • The ans.about.calories answer intent isn't mapped to its own intent. So when the user's input is resolved to that intent, it is routed to the Answer Intent built-in event (which is mapped to the pizza.ans.genericHandler flow).

Built-In Events

Of the six built-in event types that are available, three are mapped in this skill:

  • Start Skill is mapped to the handler.startSkill flow, which we glanced at earlier.
  • Unresolved Intent is mapped to the handler.help flow, which is used to display help to users whose input can't be resolved.
  • Answer Intent is mapped to the pizza.ans.genericHandler flow, which we'll look at in more detail a little later.

End Flow Action Events

In this skill, there are three events defined that can be triggered at the end of a flow to invoke another flow. The OrderPizza and OrderDrink events are used in the intent.reg.order flow to restart the flow when the user has already ordered one or more items and indicates the desire to add to that order.

You also might notice that the service.reg.placeOrder flow doesn't have a mapping on this page. This flow is invoked directly from the intent.reg.order and is only called when the user decides to finalize their order.

Next we'll look at an answer intent flow and then a "regular" flow.

pizza.ans.genericHandler Flow

The pizza.ans.genericHandler flow is mapped to the built-in Answer Intent event, and therefore handles any answer intents that aren't otherwise mapped to their own flows.

As you may recall, this mapping is done on the Events tab of the Main Flow.

Description of standard-events.png follows
Description of the illustration standard-events.png

To view the flow in the Visual Flow Designer:

  1. In the list of flows, select pizza.ans.genericHandler.
    Description of select-ans-handler.png follows
    Description of the illustration select-ans-handler.png

    You should see a canvas with a tile labeled Events and a tile labeled displayIntentA... (for the displayIntentAnswer state).

    Description of ans-handler-flow.png follows
    Description of the illustration ans-handler-flow.png

    The displayIntentA... tile is for the only state in the pizza.ans.genericHandler flow.

  2. Click displayIntentA... to open its property inspector.
    Description of displayAnswerIntent-props.png follows
    Description of the illustration displayAnswerIntent-props.png
  3. In the property inspector, click View Response Items.

    You should see a snippet of YAML code that contains the expression that accesses the answer for the intent.

    Description of displayIntentAnswer-response.png follows
    Description of the illustration displayIntentAnswer-response.png

    This standard expression accesses the answer that is coded into the resolved answer intent.

Note:

The Events tile is not used in this particular flow. This tile is for events emitted at the flow level and the Answer Intents event that we are concerned with is emitted at the skill level.

Test the pizza.ans.genericHandler Flow

Now let's use the tester to see how the Answer Intent built-in event is used:

  1. Click Preview to open the tester.
  2. In the tester, enter what is the number of calories in a pizza.
Description of tester-answer-intent.png follows
Description of the illustration tester-answer-intent.png

In the Conversation tab on the right side of the tester, you can see that:

  • From the main flow, the handler.startSkill flow is invoked, since this is the flow mapped to the Start Skill built-in event.
  • In the handler.startSkill flow, the user type (new or returning) is checked and then a welcome message is displayed based on the user type.
  • The handler.startSkill ends and passes control back to the Main Flow.
  • The Main Flow passes control to the pizza.ans.genericHandler flow, which is the flow mapped to the Answer Intent event and which contains the displayIntentAnswer state, which provides the static answer.

intent.reg.order Flow

Now let's look at the intent.reg.order flow, which is the heart of the skill's functionality. This flow helps the user select what they want to order, with the help of composite bag entities that contain possible values for pizza and drink items and are used to extract such values from the user's input.

  1. In the list of flows, select intent.reg.order.
  2. If it isn't already selected, select the Flow tab.

    Here you can see the visual representation of the flow for ordering the pizza.

    Description of flow-intent-reg-order.png follows
    Description of the illustration flow-intent-reg-order.png

Here's a quick rundown on how the flow works:

  • The flow begins with the checkIntent state, which checks to see whether the user's intent is to order a pizza or to order a drink.
    • If the intent is to order a pizza, it transitions to the resolveBag state, which attempts to determine what kind of pizza the user wants (based on a composite bag entity to determine pizza type, crust, and size).
    • If the intent is to order a drink, it transitions to the resolveDrink state, which attempts to determine what kind of drink the user wants (based on a composite bag entity for drinks).
  • Once the user specifies the pizza or drink she wants to order (i.e., when the composite bag entity is resolved), the pizza or drink is added to the cart and the user is passed to the orderMore state, where the user can cancel, order more, or check out (place the order). These options are based on entity values that are displayed as buttons.

    When the user selects one of the options, the flow transitions according to the action associated with the selection.

    Description of order-more-props.png follows
    Description of the illustration order-more-props.png
    • If the user cancels the order, the invokeCancel state is called, which invokes the intent.reg.cancelOrder flow.
    • If the user chooses to order another drink or pizza, the invokeCustomEvent end flow state is called, which uses an end flow action event to return the user to the beginning of the intent.reg.order flow so that they can add that drink or pizza to the order.
    • If the user chooses to proceed to payment, the service.reg.placeOrder flow is invoked.

Entity Event Handlers in the resolveBag, resolveDrink, and orderMore States

If you look closely, there's more happening with the resolveBag, resolveDrink, and orderMore states than is shown in their respective property inspectors.

For example, the resolveBag state contains actions for nextPage and previousPage transitions as you can see on the Transitions tab of the state's property inspector.

Description of resolve-bag-trans.png follows
Description of the illustration resolve-bag-trans.png

But there isn't any logic visible on the Component tab of the property inspector that would trigger those actions.

Description of resolve-bag-props.png follows
Description of the illustration resolve-bag-props.png

Also, the diagram doesn't show how or where the cartItems variable (which tracks the items in the user's order) is updated.

The solution to this mystery is that the composite bag entities on which these components are based have entity event handlers that add business logic to the entities. In the cbe.pizza entity, there is an event handler called PizzaEEH. In the cbe.drink entity, there is an event handler called DrinkEEH. The cbe.orderMore entity has a handler called OrderMoreEEH. All three handlers contain logic for displaying buttons for the user options and then triggering the appropriate action event based on what the user selects. PizzaEEH and DrinkEEH also provide logic for adding orders to the cart (represented by the cartItems skill-level variable).

The entity event handlers take the form of Node.js modules. You can access the entity event handler code from the entity's page. For example, to open PizzaEEH:

  1. Click Entities the Entities icon in the left navbar.
  2. Select the cbe.pizza entity.
  3. In the Entity Handler section of the page, click the Edit Event Handler Code icon.

Use of End Flow Action Events

A key part of the design of this skill is the use of end flow action events, which enable you to do conditional routing. End flow action events are defined in the Main Flow.

Description of custom-events.png follows
Description of the illustration custom-events.png

The intent.reg.order uses the OrderPizza and OrderDrink end flow action events to enable a user to add to an order that they have already started.

Let's return to the invokeCustomEvent state and take a look at how it's configured.

Description of state-invoke-custom-event.png follows
Description of the illustration state-invoke-custom-event.png

The state's Action property is set to the value of the intentName variable, the value of which is set in the orderMore state by the entity event handler for the cbe.orderMore composite bag entity.

Description of eeh-snippet.png follows
Description of the illustration eeh-snippet.png

The flow ends and the user is routed back to the Main Flow. An event for the action (either OrderPizza or OrderDrink) that was set at the end of the flow is triggered, which causes the flow that it is mapped to (intent.reg.order) to be invoked from the beginning.

To get a closer look at the way the end flow action events are defined:

  1. In the list of flows, select Main Flow and then make sure that the Events tab is selected.
  2. In the End Flow Action Events table, mouse over the Action column for the OrderPizza entry and click the View icon that appears.
    Description of custom-events-action-icon.png follows
    Description of the illustration custom-events-action-icon.png

    A dialog will open showing the following configuration:

    Description of modify-event-mapping.png follows
    Description of the illustration modify-event-mapping.png

    The OrderPizza end flow action event invokes the intent.reg.order flow by passing the input parameters cartItems and intentName.

Test the intent.reg.order Flow

Let's do a test conversation to observe the way the intent.reg.order flow works and also highlight the use of the OrderPizza end flow action event:

  1. In the tester type order a large cheese basic pizza.

    The skill should respond with the following prompts:

    Description of tester-order-pizza.png follows
    Description of the illustration tester-order-pizza.png
  2. Click Yes, a pizza.

    By doing this, you are initiating an addition to your order.

Here's the diagram that the tester provides to illustrate the flows and states that are called.

Description of tester-order-another-pizza.png follows
Description of the illustration tester-order-another-pizza.png
  • From the main flow, the handler.startSkill flow is invoked, since this is the flow mapped to the Start Skill standard event.
  • In the handler.startSkill flow, the user type (new or returning) is checked and then a welcome message is displayed based on the user type.
  • The handler.startSkill ends and passes control back to the Main Flow.
  • The Main Flow passes control to the intent.reg.order flow, which is the flow mapped to the reg.orderPizza intent. In this flow:
    • The checkIntent state determines whether the user wants to order a pizza or a drink. (In this case, it's a pizza.)
    • The resolveBag state determines what kind of pizza the user wants. Since the input "order a large cheese basic pizza" fulfills the required values for a pizza order, the bag is resolved and the flow navigates to state defined by the next transition, which is the orderMore state.
    • The orderMore state displays the options to order more, cancel, or proceed to checkout. These options are populated with a composite bag entity, and the entity is resolved with the help of an entity event handler. Since you clicked Yes, a pizza, the orderMore action was triggered, causing the flow to transition to the invokeCustomEvent state. In addition, code in the entity event handler changes the value of the flow's intentName variable to OrderPizza.
    • In invokeCustomEvent, which is an End Flow state, the value of intentName (which is now OrderPizza) is passed as an action, which the parent flow (in this case the Main Flow) will treat as an end flow action event.
    • With the OrderPizza end flow action event triggered, the Main Flow again invokes the intent.reg.order flow, which is mapped to that event.

From here, you can continue with the order. Once you have finalized your selections, you will see the options for ordering more or proceeding to payment.

Description of tester-finalized-order-conv1.png follows
Description of the illustration tester-finalized-order-conv1.png

When you click No, proceed to payment, the skill transitions to the service.reg.placeOrder flow.

Description of tester-finalized-order.png follows
Description of the illustration tester-finalized-order.png

The service.reg.placeOrder handles the last steps of the process. It prints a summary of the order, displays the Place Order button, and provides an order confirmation message once you click the button.

Description of tester-finalized-order-conv2.png follows
Description of the illustration tester-finalized-order-conv2.png

Conclusion

This has been a brief walkthrough of some of the key parts of the Visual Flow Designer sample skill. To learn more about the Visual Flow Designer, see the resources below.

Learn More