The following dialog event modes are listed in alphabetical order for convenience. Any of these events can occur in almost any order during user interaction.
Dialog Event | Description |
---|---|
ActionAborted | Responds to the user aborting a transactional action at a confirmation prompt. |
Authorization | Notifies the user that authorization is needed, such as OAuth. |
Confirmation | Asks for confirmation to invoke an action. |
Elicitation | Requests one or more values from the user so that an action can proceed. |
NoAuth | Explains the lack of function authorization needed to proceed. |
NoFunction | Explains an inability to continue due to the lack of a supporting function implementation. |
NoResult | Explains an empty result set in context. |
Progress | Explains an action that has been invoked and has not yet completed. |
Result | Explains the result set in context. |
ResultCommentary | Adds commentary to the result set in context. |
Selection | Prompts the user to select a value from an intermediate result set. |
Storage | Asks for confirmation to store one or more values. |
This event signifies that the user selected the "Cancel" option on a confirmation prompt.
dialog (ActionAborted) {
match : paymentService.MakeRequest
template ("Okay, I won't request the payment")
}
An authorization dialog event notifies the user about an activity which requires an authorization, such as OAuth.
dialog (Authorization) {
match: rideShare.Activity(this) {
from-output: rideShare.BookRideShare
}
template ("I need your permission to book a ride share for you...")
}
dialog (Authorization) {
match : paymentService.Payee
template ("Please authorize access to your Venmo account")
}
By default, this dialog event uses the following template:
You'll need to authorize me to #{action (this)}...
Confirmation prompts ask the user if they wish to proceed with an action. They are generally shown alongside with a layout that summarizes the action about to take place and gives the user the opportunity to update the inputs. For more information, see action Confirmation Prompts.
For example, this is the dialog shown so users have a chance to double-check payment details before sending money.
dialog (Confirmation) {
match : viv.paymentService.MakePayment (this)
template ("Ready to send?")
}
By default, this dialog event uses the following template:
Are you sure you want to #{action (this)}?
Elicitation prompt that invites the user to enter a missing input to continue.
Here are some examples:
dialog (Elicitation) {
match : viv.florist.FlowerType (this)
template("What kind of flowers are you looking for?")
}
dialog (Elicitation) {
match {
route.SourcePoint
}
template ("Where would you like to be picked up from?")
}
I need one or more #{concept (this)} to continue.
I need #{concept (this, 'Indefinite')} to continue.
The NoAuth
dialog event notifies the user that the system isn't authorized to carry out an action. This might happen if the user cancels an OAuth prompt or fails to login with valid credentials. For more information, see Authorizing Access with OAuth.
Here's an example:
dialog (NoAuth) {
match: viv.rideShare.Activity(this) {
from-output: viv.rideShare.BookRideShare
}
template ("I'm sorry but I don't have permission to book a ride share for you.")
}
dialog (NoAuth) {
match {
paymentService.FindPayee
}
template ("I can't proceed without access to your Venmo account")
}
By default, this dialog event uses the following template:
I'm not authorized to #{action(pre(this))}.
This delegates to the action fragment for the current action, resetting Bixby's execution state to Pre
.
A NoFunction
dialog event notifies the user that an action has no implementations. For example:
dialog (NoFunction) {
match {
viv.residence.FindResidenceListing (action)
}
template ("[#{$user.nickName}, ]I'm still learning about real estate. I'll let you know when I can help you with questions like this.")
}
}
dialog (NoFunction) {
match: viv.rideShare.FindRideShare(this)
template ("Sorry, I can't find ride shares.")
}
This dialog event uses one of the following default templates:
- I don't currently have a way to #{action(pre(this))}.
- I currently don't have the ability to #{action(pre(this))}.
When an action finds no results, the user sees this:
dialog (NoResult) {
match {
viv.event.EventSet (this) {
from-output: viv.event.FindEvents(action)
}
}
// I couldn't find any events
template ("I couldn't find any #{concept(this)}")
}
This dialog event uses one of the following default templates:
- I couldn't #{action(this)}.
- I couldn't find any #{concept(this)}.
- I couldn't #{action(pre(this))}.
Used to inform the user about ongoing actions. It will be built automatically by appending the ellipsis “...” to the Mid
action, or can be edited to be more entertaining. In general, it is good practice to remove it for fast operations and only define it for slow operations.
This will pick a random sentence to show while waiting.
dialog (Progress) {
match: viv.weather.SolarNoon {
from-output: viv.weather.GetSolarNoon (this)
}
choose (Random) {
template (Performing solar calculations...)
template (Consulting my analemma...)
}
}
This will remove the Progress
Dialog when Bixby saves the shipping selection.
dialog (Progress) {
match {
viv.ticketmaster.PutShippingOption (this)
}
template()
}
Whenever possible, this event answers the question by paraphrasing the result in a succinct way. Otherwise, it presents the results that follow in the layout. You can use a Result
event to provide some high-level useful information such as the number of results or the search inputs that were used.
This event describes a result set, the output from an action. If you can single out one result whose value is easy to paraphrase, this is a good place to do that.
This Result
provides the answer directly in dialog:
dialog (Result) {
match {
viv.weather.DayHighTemperature (this) {
from-property: viv.weather.LocusInformation (locus)
}
}
// There will be a high of 35 degrees at 3pm
template ("There will be a high of #{value (this)} #{input (locus.when)}")
}
This Result
adjusts the response based on the number of recipes found:
dialog (Result) {
match: viv.recipe.RecipeForIngredients (this)
switch (plural(this)) {
case (One) {
// Here are the ingredients for apple pie
template ("Here are the ingredients for #{value(this)}")
} default {
template ("It depends on the recipe... here are a few ideas")
}
}
}
- #{concept (this, 'Definite')} is #{value (this)}.
- Here's #{concept (this, 'Definite')}
###{concept (this, 'Definite')} are #{value (this)}
- Here are #{concept (this, 'Indefinite')}:
- I found #{concept (this, 'Proximal')}:
A ResultCommentary
event can provide developer-implemented commentary about a result set. This event is mostly used when Enriching the Conversation. This dialog always comes after a Result
event, as additional commentary to the results returned.
The following example event makes a comment based on the moon phase.
It is a full moon tonight. Beware of werewolves.
dialog (ResultCommentary) {
match : viv.moon.MoonPhase (this) {
min (Required) max (One)
}
switch (this.name) {
case (FullMoon) {
template ("Beware of werewolves")
}
...
}
}
This event wishes the user a good flight.
dialog (ResultCommentary) {
match: viv.air.FlightReservation (this) {
from-output: viv.air.BookFlight (action)
}
if (exists(itinerary.trips[0].destination.locality.name)) {
template ("Enjoy your time in #{value (itinerary.trips[0].destination.locality.name)}...")
}
}
There are no default templates for result commentary.
Using ResultCommentary
dialog events affects the user experience, so you should consider if adding this commentary is useful. Make sure you follow the Writing Dialog Design Guide when using this.
A Selection
dialog event asks the user to choose from a set of results.
Here are some examples:
dialog (Selection) {
match : viv.email.EmailAddress (this)
// Which email address?
template("Which#{concept(this)}?")
}
dialog (Selection) {
match: viv.rideShare.RideShare {
from-output: viv.rideShare.FindRideShare {
from-input: viv.route.SourcePoint(address)
}
to-input: viv.rideShare.BookRideShare
}
template ("How should we pick you up from #{value (address)}")
}
###{concept (this, 'Proximal')}?
- Which of #{concept (this, 'Proximal')}?
- Which one of #{concept (this, 'Proximal')}:
For no results, the default template is as follows:Ummm... #{event (this, 'Elicitation')}
A storage dialog event asks the user for permission to store a value. For more information, see persistence confirmation prompts.
Here is an example:
dialog (Storage) {
match: viv.payment.CreditCardPaymentSource (this)
template ("Would you like us to save this #{concept (this)} for future use?")
}
- Do you want me to remember #{concept (this, 'Proximal')} for next time?
- Would you like to store #{concept (this, 'Proximal')} for later?
- Should I store any of #{concept (this, 'Proximal')} for later?
- Would you like to store any of #{concept (this, 'Proximal')} for later?
An unlock event notifies the user that the phone is currently locked and needs to be unlocked in order to continue execution.
dialog(Unlock){
match: viv.air.CheckFlight (this)
template ("Please unlock your phone in order to check this flight's information")
}
The default template is one of the following:
- You'll need to unlock your %device%
- Please unlock your %device% for this
- You need to unlock your %device% to do this
- Please unlock your %device% first
The %device%
that gets outputted by the dialog is dependent on which target
the dialog file is located. You do not control this directly.
This event indicates that no function implementations satisfy the inputs.
dialog (UnsupportedFunctionInputs) {
match {
viv.air.FindFlightStatus (action)
}
choose (First) {
if (exists(action.carrier.name) && exists(action.flightNumber)) {
template ("I don't currently have a way to find status information for #{value (action.carrier.name)} #{value (action.flightNumber)}[ from #{value (action.origin)}][ to #{value (action.destination)}].")
}
if (not exists(action.flightNumber)) {
template ("I don't currently have a way to find status information for [#{value (action.testFlightState)} ][#{value (action.carrier.name)} ]flights[ from #{value (action.origin)}][ to #{value (action.destination)}].")
}
}
}