article by Frank Nimphius, January 2021
Composite bag entities model real world objects like "order", "person", "car", "account" etc. Each attribute in such an object is referred to as a bag item. Bag items usually reference other entities (built-in or custom). The System.CommonResponse component and the System.ResolveEntities component can be used to generate dialogs at runtime for users to be prompted to provide input for each bag item.
A common use case for objects is that some of their attributes (bag items) are treated as optional. This means that the item will be prompted but the user can choose not to provide any information. In this article I explain by an example how you achieve the same behavior with composite bag entities.
Use case
The sample that you can download as a skill uses a composite bag entity to model an account. The account information is collected by the following bag items:
- first name
- last name
- email (optional)
- address
The following image shows how the user is prompted for the information. When specifying the first name, the bot uses the provided name in the prompt when it asks for the last name. The EMail prompt is rendered with a skip button. In addition, users could type "skip" or "none" to leave the field without providing a valid email address. When the mail address is skipped, the next prompt is for the address.
Implementation
There are two implementations required for the usecase
- Mail entry should be skipped when the user presses the "skip" button or types one of its associated keywords
- Mail entry should be skipped when the user types a sentence that contains "skip" or "none" (e.g. "Skip that mail thing for me" or "I have none"
To handle messages that contain a magic word like "skip" or "none" when the user is prompted for the mail address, a value list entity OptionalIndicator is used. You can extend the list of synonyms with all keywords that you want to indicate that a prompt should be skipped. The entity can be used for all bag items that you want to be treated as optional.
…
In the example, only the mail address is optional. For this I created a bag item skiMail that references the OptionalIndicator entity. If I wanted to make e.g. the Address too optional, I could create one more field skipAddress with a reference to the OptionalIndicator entity.
All custom entities and all composite bag items have a Prompt for Value property that you can use to suppress the item from being prompted to the user. If you set the value of this property to a value of false, then the item is not getting prompted for. The image below shows an expression to determine whether the Prompt for Value field should set to true or false. Basically what the expression does is to check wether the skipMail bag item has a content (value) set or not.
The skipMail property contains a value when the user types a message containing "skip" or "none" when prompted to provide a mail address, or when a user presses the skip button.
To make sure the skipMail property is set when a user is prompted for providing her mail address, you need to set its Extract With property to EMail (the bag item name for the mail address).
Note: The image below shows the Out of Order Extraction toggle as enabled. This would allow a user to say e.g. "Create an account but skip the mail address". In this case the mail address would not be prompted for. However, if you have two or more bag items that you flag as optional, then it does not work well this way. In this case I recommend to disable the toggle so that the skip command is only executed when an optional bag item is prompted for.
Also note that the Prompt for Value property of the skipMail bag item is set to the value false. This avoids that the skipMailb bag item gets prompted for (skipMail is used as metadata, so no need to display it as a prompt).
The image below shows the System.CommonResponse component that resolved the composite bag entity (through its variable reference to a variable of type Account).
Notice the following BotML code that displays the skip button when the rendered bag item is EMail.
visible:
entitiesToResolve:
include: "EMail"
So whenever the bag item name EMail is recognized, the button is displayed.
When the "Skip" button is pressed, navigation goes to the "handleSkipMaiL" dialog flow state.
The handleSkipMail dialog flow state manually sets the skipMail bag item value to "skip". It then performs navigation back into the account state that uses the System.CommonResponse component to prompt users for bag items. Because the skipMail bag item now has its content set, the EMail item is not rendered.
Note: I hope that it is obvious to see how the "optional" behavior can be added to another bag item like the "Address" bag item. All you need to do is to render a button for the Address bag item. Then have the action of the button navigating to a state that sets the skipAddress bag item (which you would need to create before) to a value of "skip" or "none" (or whatever alias to create for this).
Summary
This article explained how easy it is to add bag items as metadata to a composite bag entity that flags another bag item as "optional" at runtime. The sample is kept simple and there are certainly improvements to add. One improvement would be to change the prompt for the EMail bag item to tell the user that the prompts is optional and how it can be skipped.
Download Sample Skill
Skill (ZIP) – ODA 20.09 and later
Related Content
TechExchange Quick-Tip: How to Intelligently Cancel Composite Bag Entity Driven User Dialog Flows