14 Reference

Built-In Components: Properties, Transitions, and Usage

Control Components

The control components route the flow based on whether the user input matches a predetermined value.

System.ConditionEquals

Use this component to check if the variable matches a value that has been passed in. To route the dialog according to the value, define the transitions key using equal and notequal actions.

Properties Description Required?
variable The first value to be compared. No
source In place of the variable property, you can name the source to be compared against the values properties. You can define this using a FreeMarker expression that compares a specific property of the system entity with the values property. For example:
conditionEquals:
    component:"System.ConditionEquals"
    properties:
      source: "${addressVar.value.state} - ${addressVar.value.country}"
      value: "CA - USA"
    transitions:
      actions:
        equal: goCalfifornia
        notequal: goSomewhereElse
Using FreeMarker expressions enables you to use System.ConditionEquals for other types of comparisons. For example:
  conditionEquals2:
    component: "System.ConditionEquals"
    properties:
      source: “<#if age.value gt 18>true<#else>false</#if>"
      value: true
    transitions:
      actions:
        equal: oldEnough
        notequal: tooYoung
No
value The second value to be compared. You can define this property with a FreeMarker expression:
verifyCode:
    component: "System.ConditionEquals"
    properties:
      variable: "code"
      value: "${userEnteredCode.value}"
    transitions:
      actions:
        equal: "wrongCode"
        notequal: "${flow.value}"
Yes

How Do I Use This?

This example shows how the System.ConditionEquals component can fork the dialog based on the value.
main: true
name: "Shoppingbot"
context:
  variables:
    yesnoVar: "YES_NO"
    
...

 confirmBuy:
    component: "System.ConditionEquals"
    properties:
      source: "${yesnoVar.value.yesno}"
      value: "YES"
    transitions:
      actions:
        equal: "deviceDone"
        notequal: "cancelOrder"
  deviceDone:
    component: "System.Output"
    properties:
      text: "Your ${devices.value} is on its way."
    transitions:
      return: "done"
  cancelOrder:
    component: "System.Output"
    properties:
      text: "Thanks for your interest."
    transitions:
      return: "done"
System.ConditionExists

Use this component to check for the existence of a specified variable. To route the dialog according to the value, define the transitions key using exists and notexist actions.

Properties Description Required?
variable The name of the variable Yes
value The value that the Dialog Engine checks for. Yes
main: true
name: "HelloKids"
context:
  variables:
    foo: "string"
    lastQuestion: "string"
    lastResponse: "string"
states:
  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
      confidenceThreshold: 0.4
    transitions:
      actions:
        Talk: "checkUserSetup"
        unresolvedIntent: "checkUserSetup"
  checkUserSetup:
    component: "System.ConditionExists"
    properties:
      variable: "user.lastQuestion"
      value: "unneccessary"
    transitions:
      actions:
        exists: "hellokids"
        notexists: "setupUserContext"
  setupUserContext:
    component: "System.CopyVariable"
    properties:
      from: "lastQuestion,lastResponse"
      to: "user.lastQuestion,user.lastResponse"
    transitions: {}

...
System.Switch

Use this component to switch states based on variable value.

Similar to the System.ConditionEquals component, you can define the state that you want to navigate to as a variable. See System.ConditionExists
Property Description Required?
variable The name of the variable that’s compared against the values properties. For example:
switchOnCategory:
    component: "System.Switch"
    properties:
      variable: "category"
      values:
      - "Vehicle"
      - "Property"
      - "Other"
    transitions:
      actions:
        Vehicle: "getVehicleQuote"
        Property: "getPropertyQuote"
        Other: "getOtherQuote"
No
source In place of the variable property, you can name the source to be compared against the values properties. You can define this using a FreeMarker expression that compares a specific property of the system entity with the values property. For example:
switch1:
    component: "System.Switch"
    properties:
      source: "${yesnoVar.value.yesno}"
      values:
      - "YES"
      - "NO"
    transitions:
      actions:
        YES: goYes
        NO: goNo

  switch2:
    component: "System.Switch"
    properties:
      source: "${startDate.value.date?string('dd-MM-yyyy')}"
      values:
      - "17-12-2017"
      - "18-12-2017"
    transitions:
      actions:
        ¿17-12-2017": goToday
        ¿18-12-2017": goTomorrow
No
values The list of values that the Dialog Engine checks for. Yes

Language

System.Intent
This component detects the user intent and extracts all of the entities and then triggers a subsequent state.
Property Description Required?
variable Holds the value that the Intent Engine resolves from the user input. You can define this property as variable=iResult (with iResult: "nlpresult" defined as one of the context variables). The response from the Intent Engine is stored in the iResult variable. Yes
confidenceThreshold The minimum confidence level required to match an intent. When your bot’s confidence in matching any of its intents with the user message falls below this minimum value, the component triggers its unresolvedIntent action. Yes
optionsPrompt The title for the list of intents when the confidenceWinmargin is set. By default, this string value is Do you want to. No
confidenceWinMargin Sets the maximum level for the win margin, which is the delta between the respective confidence levels for the top intents that bot uses to resolve vague or compound user requests. The value that you set for this property should be greater than or equal to this delta. The intents separated by this delta are presented in a select list. To be included in the list, the intents must exceed the value set for the confidenceThreshold. The default value for the confidenceWinMargin property is 0.0. No
botName The name of the bot that resolves the intent. Use this property when you have a reusable bot that holds all of the intent and entity definitions. To support multiple languages, you can define this property with a variable expression that evaluates to a bot name based on the current language. No
sourceVariable The NLP engine resolves the intent using the sourceVariable as the input. You can combine this with the System.TranslateInput component and assign its value to a variable that’s used as the input to the NLP engine. See System.TranslateInput to find out how. No
translate You can override the boolean value of the autoTranslate context variable here. If autoTranslate is not set, or set to false, you can set this property to true to enable autotranslation for this component only. If the autotranslate context variable is set to true, you can set this property to false to exclude this component from autotranslation. No

How Do I Use This?

This component can be used to detect the user intent from free text input and can be used anywhere in the flow, as shown in the following snippet:
metadata:
  platformVersion: "1.0"
main: true
name: "FinancialBotMainFlow"
context:
 ...

states:
  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
      confidenceThreshold: 0.4
    transitions:
      actions:
        Balances: "startBalances"
        Transactions: "startTxns"
        Send Money: "startPayments"
        Track Spending: "startTrackSpending"
        Dispute: "setDate"
        unresolvedIntent: "unresolved"
...

  askPaymentAmount:
    component: "System.Text"
    properties:
      prompt: "What's the payment amount?"
      variable: "paymentAmount"
      maxPrompts: 1
    transitions:
      actions:
        cancel: "intentCheck"
...

  intentCheck:
    component: "System.Intent"
    properties:
      variable: "iResult2"
      confidenceThreshold: 0.4
    transitions:
      actions:
        Balances: "startBalances2"
        unresolvedIntent: "askPaymentAmount2"

...
The confidenceThreshold Property

When you add the confidenceThreshold property, you can steer the conversation by the confidence level of the resolved intent, which is held in the iResult variable.

If the intent’s ranking exceeds the confidenceThreshold property (which, by default is 40%), then the action defined for that intent is triggered, setting the path for the Dialog Engine. In the opposite case—when the value for the confidenceThreshold property is higher than the ranking for the resolved intent—the Dialog Engine moves to the state defined for System.Intent’s unresolvedIntent action. See The Intent Tester.

Taking the PizzaBot as an example, testing its intents with I want to order pizza resolves to 100%. When you enter the same phrase in the tester’s Bots tab, however, the bot replies with How Old Are You?, a seemingly inappropriate response. Within the context of the PizzaBot dialog flow definition, however, this is the expected response for an intent whose ranking (100%) exceeds the confidence threshold (40%). When you enter 18, the checkage state’s allow: "crust" action directs the Dialog Engine to the crust state. (Because there were no entities to extract from the initial user input, the Dialog Engine bypassed the resolveSize and resolveCrust states and ended up here after the age confirmation instead of completing the order.)

If you entered a wholly inappropriate phrase for the PizzaBot like I want to buy a car , the intent testing window will rank the top intent at only 25%, which is below the 40% threshold. Because neither the OrderPizza nor the CancelPizza intents can resolve the user input satisfactorily, the Dialog Engine moves to the state defined for the unresolvedIntent action (unresolvedIntent: "unresolved"). As a result, the bot responds with "I don't understand, what do you want to do?"
  unresolved:
    component: "System.Output"
    properties:
      text: "I don't understand. What do you want to do?"
    transitions:
      return: "unresolved"
The confidenceWinMargin Property

Adding the confidenceWinMargin property enables your bot to prompt users to pick an intent when it can’t pick one. For example, if a user asks the FinancialBot, “I want to check balance or send money,” the bot responds with a select list naming the top intents, Check Balances and Send Money.
This is an image of the confidenceWinMargin select list.
The bot offers these two intents because its confidence in them exceeds 30% (confidenceThreshold: 0.30 in the following snippet) and they’re separated by a win margin—the difference between their respective confidence levels— that’s within 15% (confidenceWinMargin: 0.15).

states:
  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
      optionsPrompt: "What do you want to do?"
      confidenceThreshold: 0.30
      confidenceWinMargin: 0.15

For example, the bot’s confidence for the Check Balances intent is 38.1%. For the Send Money intent, it’s 35.8%. The win margin is 2.3%, well within the 15% configured for the System.Intent component.
This is an image of the Tester.

System.MatchEntity

The System.MatchEntity calls the Intent Engine to extract entity information from the text held by the sourceVariable property. If a match exists for the variable entity type, the variable is set with this entity value.

Property Description Required?
sourceVariable The variable that holds the input value. Yes
variable The name of the context variable. The value of this variable can be used in a subsequent System.SetVariable component to extract a specific entity using a FreeMarker expression. For example, to extract an EMAIL entity value: ${userInputEntities.value.entityMatches['EMAIL'][0]} Yes

This component also has two predefined transitions, match and nomatch

Transition Description
match Directs the Dialog Engine to go a state when the entities match.
nomatch Defines the Dialog Engine to go to a state when the entities don’t match.
In the following snippet, System.MatchEntity component matches the user-provided value stored in the mailInput variable against the EMAIL entity type that’s been defined for the mailEntity variable. If the user input satisfies the entity type by being an e-mail address, then the System.MatchEntity component writes this value to the mailEntity variable that’s echoed back to the bot user ("You entered ${mailEntity.value.email}"). When the values don’t match, the Dialog Engine moves to the nomatch state.

Note:

The System.MatchEntity component resolves a single value.
context:
  variables:
    iResult: "nlpresult"
    mailInput: "string"
    mailEntity: "EMAIL"
states:
  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
      confidenceThreshold: 0.4
    transitions:
      actions:
        displayMailAdresses: "askMail"
        unresolvedIntent: "dunno"
  askMail:
    component: "System.Text"
    properties:
      prompt: "Please provide a valid email address"
      variable: "mailInput"
    transitions: {}
  matchEntity:
    component: "System.MatchEntity"
    properties:
      sourceVariable: "mailInput"
      variable: "mailEntity"
    transitions:
      actions:
        match: "print"
        nomatch: "nomatch"
  print:
    component: "System.Output"
    properties:
      text: "You entered ${mailEntity.value.email}"
    transitions:
      return: "done"
  nomatch:
    component: "System.Output"
    properties:
      text: "All I wanted was a valid email address."
    transitions:
      return: "done"
  dunno:
    component: "System.Output"
    properties:
      text: "I don't know what you want"
    transitions:
      return: "done"
System.DetectLanguage

Use this component to detect the user’s language.

This component stores the language detected in a variable named profile.languageTag, so, if you want to find out which language has been detected, you can use ${profile.languageTag} or ${profile.languageTag.value}. Because this is a string variable, you don’t necessarily need to add the value suffix.
context:
  variables:
    autoTranslate: "boolean"
    translated: "string"
    someTranslatedText: "string"
states:
  setAutoTranslate:
    component: "System.SetVariable"
    properties:
      variable: "autoTranslate"
      value: true
    transitions: {}
   detect:
    component: "System.DetectLanguage"
    properties: {}
    transitions: {}
  
System.TranslateInput

Use this component when you’ve activated a translation service, but you want to explicitly translate user input and not rely on the autotranslate facility.

This component takes the user input, translates it to English and then stores the translated text into a variable.
Property Description Required?
variable The variable that holds the translated text. Yes.
source Specifies the text values to be translated. No

In the following code snippet, this variable that holds the text string is called translated. It holds the English translation of the user's input, which the NLP engine uses as the source for the Intent resolution. Note that the autoTranslate: “boolean” context variable, which is required for autotranslation services, is defined.

context:
  variables:
    autoTranslate: "boolean" 
    translated: "string"
...

states:
  translate:
    component: "System.TranslateInput"
    properties:
      source: "${somevar.value}" or // "Besoin de pizza"
      variable: "translated"
    transitions: {}

Using the sourceVariable Property

Because the System.Intent’s sourceVariable property holds the value processed by the component, you can use it with the System.TranslateInput component to insert translated text. The following snippet shows assigning the translated variable value so that it can be processed by the NLP engine.
translate:
    component: "System.TranslateInput"
    properties:
      variable: "translated"
    transitions: {}
  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
      sourceVariable: "translated"
      confidenceThreshold: 0.4
System.TranslateOutput

The System.TranslateOutput component allows you to translate text manually.

The System.TranslateOutput component takes the value defined for the source property. It translates the text into the language detected by the System.DetectLanguage component and then stores it in the variable property.
Properties Description Required?
source The text to be translated, or a FreeMarker expression that references a variable whose value needs to be translated. Yes
variable Holds the translated text. Yes
In this example, the System.Output component, which would otherwise display autotranslated text, still outputs translated text, but here it outputs the translation of the text defined for the source property.
  unresolvedTranslate:
    component: "System.TranslateOutput"
    properties:
      source: "Sorry I don't understand"
      variable: "someTranslatedText"
    transitions: {}
  unresolved:
    component: "System.Output"
    properties:
      text: "${someTranslatedText}"
    transitions:
      return: "unresolved"

Security

System.OAuthAccountLink

The System.OAuthAccountLink component enables the bot to make calls to a third-party service on behalf of the user.

This component first directs a user to a third-party OAuth provider’s login page. After a successful login, the bot then receives the access token, which it stores as a variable that’s used by the custom component API. To handle the subsequent calls made through the channel, the custom component API exchanges the access token and a client secret for an OAuth 2 token. It makes another REST call to the OAuth2 provider, which accesses the secured API.
Property Description Required?
prompt A text string that prompts the user to login. Yes
authorizeURL The login URL. See The authorizeURL Property. Yes
translate You can override the boolean value of the autoTranslate context variable here. If autoTranslate is not set, or set to false, you can set this property to true to enable autotranslation for this component only. If the autotranslate context variable is set to true, you can set this property to false to exclude this component from autotranslation. No
variable The name of the variable. You can declare it in the context node as a variable, a string, or another supported variable type. It can also be a user variable. Yes
You can use this component to return access tokens from OAuth providers like Twitter, Google, Microsoft, or as shown in the following example, LinkedIn. This example shows the required properties that you need to define for the System.OAuthAccountLink component: prompt, which outputs the message, variable, which holds the returned code, and authorizeURL which defines both the provider’s OAuth URL and the redirect URL that receives the token used by the bot to access the user’s LinkedIn profile.
login:
  component: "System.OAuthAccountLink"
  properties:
    prompt: "Please login now."
    authorizeURL: "https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=75k0vq4&scope=r_basicprofile&redirect_uri= https://myBotsinstance/connectors/v1/callback"
    variable: "code"
  transitions:{} 
When the Dialog Engine encounters this component, the bot prompts users to with two links, Login and Cancel. The channel then renders the OAuth provider’s login page or its authentication dialog as a webview.

Note:

The test window doesn’t render webviews, so you need to cut and paste the link text into your browser.

The authorizeURL Property

To configure this property, you begin with the OAuth provider URL, such as https://www.linkedin.com/oauth/authorization/ in the example. Next, you need to append the following OAuth parameters to this URL:
  1. response_type—Set to code since the bot expects an authorization code.

  2. client_id—An API key value that you get when you register your app with the OAuth provider.

  3. scope—A list of permissions to access resources on the user’s behalf. These are the permissions that you set when you register your app with the provider. They can vary by provider: for LinkedIn, these include r_basicprofile (shown in the example) and r_emailadress; for Microsoft, they’re defined using openid email and openid profile.

  4. redirect_uri—This is the redirect URI that you used to register your app with the OAuth provider that tells it where it needs to redirect users. This parameter, which is the Bots service host name appended with connectors/v1/callback, is the endpoint that receives the OAuth provider’s token and then associates it with the active channel. The redirect_uri property is based on the Webhook URL that’s generated when you create a channel. See Channels

    Important:

    Be sure that the value you enter for the redirect_uri matches the redirect URI that you provided when you registered your app exactly. In both instances, the URI must be appended with connectors/v1/callback.

User Interface Components

Use these components to display text:
System.Text

The System.Text component enables your bot to set a context or user variable by asking the user to enter some text.

When the Dialog Engine enters a System.Text state for the first time, it prompts the user to enter some text. When the user enters a value, the Dialog Engine returns to this state. The component processes the user response and if it can convert the user input to the variable type, it stores the value in the variable. The Dialog Engine moves on to another state when this variable has a value.

Note:

The Dialog Engine skips over the System.Text state of the variable already has a value.
Property Description Required?
prompt A text string that describes the input required from the user. You can dynamically add values to it using a value expression. For example: Hello ${profile.firstName}, how many pizzas do you want? Yes
variable The name of the variable, which can be either a user variable or one of the variables declared in the context node. Yes
nlpResultVariable Use this property when the variable property references some type of entity (custom or built-in). If the variable property initially holds a null value but the nlpResultVariable holds an entity that matches the entity type that you’ve set for the variable property, then variable property is set with this entity value and the dialog flow will then transition to the next state. You can obtain this entity match by simply adding the nlpResultVariable property; you don’t need to create a separate SetVariable state to set the entity value. No
maxPrompts The number of times that component prompts the user for valid input. See Limiting the Number of User Prompts. No
translate Use this property to override the boolean value that you’ve set for the autotranslate context variable. If you haven’t set this variable, or if you set it to false, then you can set this property to true to enable autotranslation for this component only. If you set the autotranslation variable is set to true, you can set this property to false to exclude this component from autotranslation. See Autotranslation. No

See Transitions for the predefined action types that you can use with this component.

How Do I Use This?

In this example, the type variable holds the values expected by the PizzaType entity, like cheese, Veggie Lover, and Hawaiian. When this information is missing from the user input, the bot can still get it because its dialog flow transitions to the type state, whose Text component prompts them to explicitly state what they want. Keep in mind that even at this point, the user input still needs to resolve to the PizzaType entity to transition to the next state.

main: true
name: "PizzaBot"
parameters:
  age: 18
context:
  variables:
    size: "PizzaSize"
    type: "PizzaType"
    crust: "PizzaCrust"
    iResult: "nlpresult"

...

  type:
    component: "System.Text"
    properties:
      prompt: "What Type of Pizza do you want?"
      variable: "type"
    transitions: {}

The Text component in a chat dialog.
System.List

Your bot can use the System.List component to set a user or context variable or set a transition action. The mode depends on whether a value can be set for the component’s variable property (or if you configure a variable property in the first place).

When the Dialog Engine enters a System.List state for the first time, your bot displays a message containing a list of options. When the user clicks one of these options, the Dialog Engine returns to the System.List state to process the user response. If the component can convert the selected option to a user variable or one of the variables that you’ve defined in the context node, the System.List’s variable property it sets the variable property with this value. When this property can’t be set (or hasn’t been defined), the Dialog Engine triggers a transition action instead.
Property Description Required?
options You can specify the options using comma-separated text strings, FreeMarker value expressions, and as a list of maps. Yes
prompt The text string that prompts the user. Yes
variable The name of the context or user variable that’s populated when the user enters free text as a response instead of choosing a list option. When the user taps on a button rather than entering free text, the button payload determines which variable(s) are set and this property is ignored. When the Dialog Engine enters this state and the variable already has a value, then the state is skipped.  Yes (for value lists only)
maxPrompts The number of times that component prompts the user for valid input. See Limiting the Number of User Prompts. No
nlpResultVariable Set this property when the variable property references an entity. If the referenced variable is null and this property has an entity match of the same type as the variable property, then the variable will be set with this entity value and the dialog flow will then transition to the next state. To get the match for this entity, add this property. You don’t need to create a separate state for the System.SetVariable component to set the entity value. No
translate Use this property to override the boolean value that you’ve set for the autotranslate context variable. If you haven’t set this variable, or if you set it to false, then you can set this property to true to enable autotranslation for this component only. If you set the autotranslation variable is set to true, you can set this property to false to exclude this component from autotranslation. See Autotranslation. No
See Transitions for the predefined action types that you can use with this component.
Value Lists

You can use the System.List component to return a value that satisfies a context variable that’s defined as a primitive (like greeting: "string" in the dialog flow template) or as an entity, as shown in the following snippet. In this dialog flow, the options: "Thick,Thin,Stuffed,Pan" definition returns a value that matches crust variable. The options property defined for size is a value expression (${size.type.enumValues}) that returns the Large, Medium, Small, and Personal list values as options. See Accessing Variable Values with Apache FreeMarker FTL.

This example also shows how the nlpResultVariable property’s iResult definition allows the component to set the entity values for the variable properties for the crust and size states when these values haven’t been previously set. Like the Text component, the System.List component doesn’t require any transitions ({}).
main: true
name: "PizzaBot"

...

context:
  variables:
    size: "PizzaSize"
    crust: "PizzaCrust"
    iResult: "nlpresult"

...

states:

...

crust:
  component: "System.List"
  properties:
    options: "Thick,Thin,Stuffed,Pan"
      prompt: "What crust do you want for your pizza?"
      variable: "crust"
main: true
name: "PizzaBot"

...

context:
  variables:
    size: "PizzaSize"
    crust: "PizzaCrust"
    iResult: "nlpresult"
...

states:

...

crust:
   component: "System.List"
   properties:
     options: "Thick,Thin,Stuffed,Pan"
     prompt: "What crust do you want for your pizza?"
     variable: "crust"
     nlpResultVariable: "iresult"
   transitions: {}
size:
   component: "System.List"
   properties:
     options: "${size.type.enumValues}"
       prompt: "What size Pizza do you want?"
       variable: "size"
       nlpResultVariable: "iresult"
    transitions: {}

The list component in a live chat.

Note:

Users aren’t limited to the options displayed in the list. They can resolve the entity by entering a word that the entity recognizes, like a synonym. Instead of choosing from among the pizza size options in the list, for example, users can instead enter big, a synonym defined for the PizzaSize entity’s Large option. See Custom Entities.
The list component with user input.
The options Property
You can set the options property using any of the following:
  • A list of maps—While you can set the options property as a text string or value expression, you can also configure the options property as list of maps. Each one has a label property, a value property, and an optionalkeyword property. You can localize your list options when you follow this approach because, as noted by the following example, you can reference a resource bundle. See Resource Bundles to find out more about using the dot notation. When users enter a value that matches one the values specified in the keyword property, the bot reacts in the same way that it would if the user tapped the list option itself.
    askPizzaSize:
      component: "System.List" 
      properties:
        prompt: What size do you want?"
        options:
        - value: "small"
          label: "${rb.pizza_size_small}"
          keyword: "1"
        - value: "medium"
          label: "${rb.pizza_size_medium}"
          keyword: "2" 
        - value: "large"
          label: "${rb.pizza_size_large}"
          keyword: "3" 
       variable: "pizzaSize"
  • A text string of comma-separated options, like “small, medium, large” in the following snippet. You can’t add label and value properties when you define options as a string.
    askPizzaSize:
      component: "System.List"
      properties: 
        prompt: "What size do you want?"
        options: "small, medium, large"
        variable: "pizzaSize"
    
  • An Apache FreeMarker value expression that loops over either a list of strings, or a list of maps, where each map must contain both the label and value properties and optionally, a keyword property.
    askPizzaSize:
      component: "System.List" 
      properties:
        prompt: "What size do you want?"
        options: "${pizzaSize.value.enumValues}"
        variable: "pizzaSize"
Refer to the Apache FreeMarker Manual to find out more about the syntax.
Action Lists
You don’t need to define the variable property for a System.List option when you’re configuring a list of actions. In this case, the component sets a transition action based on the option selected by the user. For example:
showMenu:
  component: "System.List" 
  properties:
    prompt: "Hello, this is our menu today"  
    options:

    - value: "pasta"
      label: "Pasta"
    - value: "pizza"
      label: "Pizza"

  transitions:
    actions:
      pasta: "orderPasta"
      pizza: "orderPizza"

Tip:

Not only can you use this approach to configure conditional navigation, you can use an action list in place of a System.Switch component.
System.Output

Use the System.Output component to output a message that doesn't require a user response, or doesn't require your bot to process the user's response. If you need to process the user’s message, use either the System.Text or the Systen.CommonResponse component.

Your System.Output component definition requires the text property. As illustrated in the following example of a confirmation message, you can add value expressions to this string.
done:
    component: "System.Output"
    properties:
      text: "Your ${size.value}, ${type.value} pizza with ${crust.value} crust is on its way. Thank you for your order."
By default, the Dialog Engine waits for user input after it outputs a statement from your bot. If you override this behavior, add the optional property called keepTurn to the System.Output component definition and set it to true to direct the Dialog Engine to the next state as defined by the transitions property. When no transition as been defined, the Dialog Engine moves to the next state in the sequence.
  wait:
    component: "System.Output"
    properties:
      text: "Please wait, we're reviewing your order"
      keepTurn: true
    transitions:
      next: "ready"
 waitmore:
    component: "System.Output"
    properties:
      text: "Almost done..."
      keepTurn: true
    transitions:
      next: "done"
  done:
    component: "System.Output"
    properties:
      text: "Your ${size.value}, ${type.value} pizza with ${crust.value} crust is on its way. Thank you for your order."
    transitions:
      return: "done"

Use the keepTurn option when you want output multiple statements in quick succession and without user interruptions.

Autotranslation

You can suppress or enable the System.Output component’s autotranslated text on a per-component basis using the translate property. By setting it to false, as in the following snippet, the components outputs the text as is, with no translation. By setting this property to true , you can enable autotranslation when the autoTranslate variable is either set to false or not defined. See Autotranslation.

Note:

Typically, you would not set the autoTranslate variable to true if you’re translating text with resource bundles. We do not recommend this approach.
setAutoTranslate:
    component: "System.SetVariable"
    properties:
      variable: "autoTranslate"
      value: "true"
    transitions: {}
...
pizzaType:
   component: "System.Output"
   properties:
     text: "What type of pizza do you want?"
     translate: false
   transitions: {}
Defining Value Expressions for the System.Output Component
You can define one or more value expressions for the text property, as in the following snippet that uses different expressions for outputting the text for an order confirmation (pizza size and type).
confirmation:
    component: "System.Output"
    properties:
      text: "Your ${size.value} ${type.value} pizza is on its way."
    transitions:
      return: "done" 
Your bot outputs raw text when these expressions return a null value for the variable. If you’re defining the text property with multiple expressions, each one must return a value. Otherwise, your bot users will see output text like:
Your ${size.value} ${type.value} is on its way.
It’s all or nothing. To make sure that your bot always outputs text that your users can understand, substitute a default value for a null value using the Apache Freemarker default value operator: ${size.value!\”piping\”} ${type.value!\”hot\”}. The double quotes indicate that the default value is a not a variable reference, but is instead the constant value that the operator expects. For example:
text: "Your ${size.value!\"piping\"} ${type.value!\"hot\"} pizza is on its way."

Important:

Always escape the quotation marks (\"...\") that enclose the default value when you use the Freemarker operator. Your dialog flow’s OBotML syntax won’t be valid unless you use this escape sequence whenever you define a default value operation, or set off output text with double quotes. For example, the following System.Output component definition lets bot users see You said, “Cancel this order.”
confirmCancel:
    component: "System.Output"
    properties:
      text: "You said, \"Cancel this order.\""
    transitions:
      return: "cancelOrder"
System.CommonResponse

The System.CommonResponse component enables you to build a specialized user interface that can include text, action buttons, images, and cards without having to write custom code. Instead, you define the component’s properties and metadata.

You can see an example of using the System.CommonResponse component in the CrcPizzaBot, one of the sample bots. In this spin on the PizzaBot, you can display an image-rich menu with quick action “Order Now” buttons. Within the context of the System.CommonResponse component, the different types of messages are known as “response types” and the CrcPizzaBot shows you how, among other things, they allow the bot users to respond to prompts using action buttons and view the pizza menu as a cascade of card items.
Adding a System.CommonResponse Component to Your Dialog Flow

Use the Add Components menu to add template System.CommonResponse states for the text, card, and attachment responses to your OBotML definition. These templates include the properties that are common to all of these response types as well as the ones that particular to each one. While the Add Components menu adds separate states for each response type, you can combine one or more response types into a single state. The CrcPizzaBot shows you examples of both in its ShowMenu (text response) and OrderPizza (text and card responses) states.This is an image of the Add Component dialog.

The Component Properties
As shown in the following OBotML snippet from the CrcPizzaBot, configuring the System.CommonResponse component includes setting properties that direct the Dialog Engine along with metadata properties that describe not only how the component delivers messages (as text prompts, cards, or attachments), but also sets the content and behavior for the messages themselves.
  AskPizzaSize:
    component: "System.CommonResponse"
    properties:
      variable: "pizzaSize"
      nlpResultVariable: "iresult"
      maxPrompts: 2
      metadata:
        responseItems:
        - type: "text"
          text: "<#if system.invalidUserInput == 'true'>Invalid size, please try again.\
            \ </#if>What size do you want?"
          name: "What size"
          separateBubbles: true
          actions:
          - label: "${enumValue}"
            type: "postback"
            payload:
              action: ""
              variables:
                pizzaSize: "${enumValue}"
            name: "size"
            iteratorVariable: "pizzaSize.type.enumValues"
      processUserMessage: true
    transitions:
      actions:
        cancel: "Intent"
      next: "AskLocation" 

Tip:

The text property in this snippet is defined using Apache FreeMarker Template Language (FTL). To find out how to add FTL expressions and use FreeMarker built-in operations to transform variable values, see Accessing Variable Values with Apache FreeMarker FTL.
Name Description Required?
metadata The chat response created by this component is driven by the contents of the metadata property. See The Metadata Property. Yes
processUserMessage Set this property to true to direct the Dialog Engine to return to the state after the user enters text or taps a button. Set this property to false if no user input is required (or expected). When you set this property to false, the System.CommonResponse component behaves like the System.Output component. Yes
variable This variable holds the name of the context or user variable that gets populated when a user responds by entering free text instead of tapping a button. This property is ignored when a user taps a button, because the button’s payload determines which variables values get set. If the variable property has already been set when the Dialog Engine enters this state, then the state is skipped. No
nlpResultVariable This property only applies when you set the variable as an entity-type variable. If the variable is null and the nlpResultVariable has an entity match that’s the same type as the variable property, then the variable will be set with this entity value and the dialog flow will then transition to the next state. You can get this entity match by simply adding the nlpResultVariable property; you don’t need to create a separate System.SetVariable state to set the entity value. No
maxPrompts Before the System.CommonResponse component can populate the variable value that you’ve specified for the variable property from the text entered by the user, it validates the value against the variable type. This can be entity-type validation, or in the case of a primitive type, it’s a value that can be coerced to the primitive type.

When the component can’t validate the value, the Dialog Engine sends the message text and options again. (You can modify this message to reflect the validation failure.) To avoid an endless loop resulting from the user’s inability to enter a valid value, set a limit on the number of attempts given to the user with the maxPrompts property. When the user exceeds this allotment, the System.CommonResponse component transitions to the cancel action. See Limiting the Number of User Prompts.

No
keepTurn The keepTurn property only applies when you set the processUserMessage property to false. See System.Output to find out how to set this property. No
translate Use this property to override the boolean value that you’ve set for the autotranslate context variable. If you haven’t set this variable, or if you set it to false, then you can set this property to true to enable autotranslation for this component only. If you set the autotranslation variable is set to true, you can set this property to false to exclude this component from autotranslation. See Autotranslation. No
The Metadata Property

You define the metadata at two levels for the System.ComponentResponse component: at the root level, where you define the output and actions specific to the component itself, and at the response item level, where you define the display and behavior particular to the text, list, card, or attachment messages that are displayed by this component.

The component-level metadata describes the component’s overall output in terms of the type of items, or messages, that it sends to the user along with any actions that particular to the component itself (and are independent of the message processing actions configured for the list items).
  AskLocation:
    component: "System.CommonResponse"
    properties:
      variable: "location"
      metadata:
        responseItems:
        - text: "To which location do you want the pizza to be delivered?"
          type: "text"
          name: "What location"
          separateBubbles: true
        globalActions:
        - label: "Send Location"
          type: "location"
          name: "SendLocation"      
Property Description Required?
responseItems A list of response items, each of which results in a new message sent to the chat client (or multiple messages when you set iteration for the response item using the iteratorVariable property). Define these response items using these values:
  • text—Text bubbles (the text property) that can include a list of buttons that typically display as buttons

  • cards—A series of cards that scroll horizontally or vertically.

  • attachment—An image, audio, video, or file attachment.

Yes
globalActions A list of actions that are not related to the specific response item. These actions are typically displayed at the bottom of the chat window. In Facebook Messenger, for example. these options are called quick replies. No
You also configure the metadata for the various response items, such the text, card, or attachment messages.
Property Description Required?
type The type of response item that determines the message format. You can set a message as text, attachment, or cards. Yes
name A name for the response item that’s used for identification within the Bots platform. It’s not used at runtime. No
visible Display properties. No
Property Description
expression A boolean FreeMarker expression for conditionally showing or hiding text, a card, or attachment. For example, the CrcPizzaBot’s OrderPizza state defines this property as follows:
expression: "<#if cardsRangeStart?number+4 < pizzas.value?size>true<#else>false</#if>"
channels:
 include:
 exclude:
For include and exclude, enter a comma-separated list of channel types for which the text, card, or attachment should be shown (include) or hidden (exclude). The valid channel values are:
  • facebook

  • webhook

  • web

  • android

  • ios

  • twilio

  • kakaotalk

  • test

onInvalidUserInput A boolean flag that shows the text item or attachment either when the user enters valid input (value=false) or when the user enters input that’s not valid (value=true).
iteratorVariable

Dynamically adds multiple text items to the response by iterating over the items stored in the variable that you specify for this property. Although you define the variable as a string, it holds JSON array when it’s used as an iterator variable. You can reference properties in an object of the array with an expression like ${iteratorVarName.propertyName}. For example, with an iterator variable named pizzas, the name property of a pizza can be referenced using the expression: ${pizzas.name}.

No
rangeStart If you’ve specified an iteratorVariable, you can stamp out a subset of response items by specifying the rangeStart property in combination with the rangeSize property. You can enter a hardcoded value or use a FreeMarker expression that references a context variable that holds the range start. By using a rangeStart variable, you can then page to the next set of data by setting the rangeStart variable in the payload of the browse option. You can see an example of the rangeStart and rangeSize properties in the CrcPizzaBot’s OrderPizza state. No
rangeSize The number of response items that will be displayed as specified by the iteratorVariable and rangeStart properties. No
channelCustomProperties A list of properties that trigger functions that are particular to a channel. Because these functions are platform-specific, they’re outside of the System.CommonResponse component and as such, can’t be controlled by either the component’s root-level or response item-level properties. You can find an example of this property in the CrcPizzaBot’s OrderPizza state.
channelCustomProperties:
          - channel: "facebook"
            properties:
              top_element_style: "large"
No
The Action Metadata Properties

You can assign various actions to the response items.

Property Description Required?
type The action type:
  • postback—Sends the payload of the action back to the Dialog Engine.

  • share—Opens a share dialog in the messenger client, enabling users to share message bubbles with their friends.

  • call—Calls the phone number that’s specified in the payload.

  • url—Opens the URL that’s specified in the payload in the browser. For Facebook Messenger, you can specify thechannelCustomProperties property with webview_height_ratio, messenger_extensions and fallback_url.

  • location—Sends the current location. On Facebook Messenger, current location is not supported for text or card responses. It’s only supported using a Quick Reply. For more information, see the Facebook Messenger Platform documentation.

Yes
label A label for the action. To localize this label, you can use a FreeMarker expression to reference an entry in your bot’s resource bundle. Yes
iteratorVariable Use this option to stamp out multiple actions by iterating over the items stored in the variable that you specify for this property. You can’t use this property with the share and location actions. No
imageUrl The URL of image used for an icon that identifies and action. You can use this property to display an icon for the Facebook quick reply button (which is a global action). No
channelCustomProperties A list of properties that some trigger channel-specific functionality that isn’t controlled by the standard action properties. You can find an example in the CrcPizzaBot’s OrderPizza state. No
payload A nested payload object that has the following properties.  
Payload Property Description  
action The transition action set by the Dialog Engine when the user taps this action. You can only use this property for the postback action type. No
variables When you set the action type to postback, the payload may have additional properties named after context variable or user variable. When the user taps this action, the variables are set to the values specified in this property.

For the unexpectedAction transition, you can store the value for the unexpected action in the user.botsUnexpectedAction variable so that it’s included in the postback payload. See Transitions.

No
url The URL of the website that opens when users tap this action. Yes ( only for the url action type)
phoneNumber The phone number called when a user taps this action. Yes (only for the call action type)
name A name that identifies the action on the Bots platform. This name is used internally and doesn’t display in the message. No
visible Display properties. No
Property Description
expression A boolean FreeMarker expression for conditionally showing or hiding an action.
channels:
 include:
 exclude:
For include and exclude, enter a comma-separated list of channel types for which the action can be shown (include) or hidden (exclude). The valid channel values are:
  • facebook

  • webhook

  • web

  • android

  • ios

  • twilio

  • kakaotalk

  • test

onInvalidUserInput A boolean flag that shows the action either when the user enters valid input (value=false) or when the user enters input that’s not valid (value=true).
The Text Response Item
After you add a textResponse state to your dialog flow, you can rename it and then either replace the placeholder properties with your own definitions, or delete the ones that you don’t need. The template state includes properties the following text-specific properties.
Property Description Required?
text The text that prompts the user. Yes
iteratorVariable Dynamically adds multiple text items to the response by iterating over the items stored in the variable that you specify for this property. Although you define the variable as a string, it holds JSON array when it’s used as an iterator variable. You can reference properties in an object of the array with an expression like ${iteratorVarName.propertyName}. For example, with an iterator variable named pizzas, the name property of a pizza can be referenced using the expression: ${pizzas.name}. No
separateBubbles You can define this property if you also define the iteratorVariable property. When you set this property to true, each text item is sent as separate message, like Pizzas and Pastas in the CrcPizzaBot’s ShowMenu and OrderPizza states. If you set it to false, then a single text message is sent, one in which each text item starts on a new line. No
visible Text display properties No
Property Description
expression A boolean FreeMarker expression for conditionally showing or hiding tex. For example, the CrcPizzaBot’s OrderPizza state defines this property as follows:
expression: "<#if cardsRangeStart?number+4 < pizzas.value?size>true<#else>false</#if>"
channels:
 include:
 exclude:
For include and exclude, enter a comma-separated list of channel types for which the text should be shown (include) or hidden (exclude). The valid channel values are:
  • facebook

  • webhook

  • web

  • android

  • ios

  • twilio

  • kakaotalk

  • test

onInvalidUserInput A boolean flag that shows the text item when the user enters valid input (value=false) or when the user enters input that’s not valid (value=true).
In addition to the metadata properties, you can assign the following actions for a text response item.
  • Postback

  • Share

  • Call

  • URL

  • Location

If you want to see an example of text response item, take a look at the CrcPizzaBot’s showMenu state. Because it names postback as an action, it enables the bot to handle unexpected user behavior, like selecting an item from an older message instead of selecting one from the most recent message.
  ShowMenu:
    component: "System.CommonResponse"
    properties:
      metadata:
        responseItems:
        - type: "text"
          text: "Hello ${profile.firstName}, this is our menu today:"
          name: "hello"
          separateBubbles: true
          actions:
          - label: "Pizzas"
            keyword: "1"
            type: "postback"
            payload:
              action: "pizza"
            name: "Pizzas"
          - label: "Pastas"
            keyword: "2"
            type: "postback"
            payload:
              action: "pasta"
            name: "Pastas"
      processUserMessage: true
The Card Response Item

Like the textResponse state, you can rename the cardResponse state that’s added to your dialog flow and then update the properties with your own definitions. Specifically, you can configure a card response item by defining the following properties. You can delete the properties that you don’t need.

Property Description Required?
cardLayout The card layout: horizontal (the default) and vertical. Yes
title The card title Yes
description The card description, which displays as a subtitle. No
imageUrl The URL of the image that displays beneath the subtitle. No
cardUrl The URL of a website. It displays as a hyperlink on the card that user open by tapping on it. No
iteratorVariable Dynamically adds multiple cards to the response by iterating over the items stored in the variable that you specify for this property. Although you define the variable as a string, it holds a JSON array when it’s used as an iterator variable. You can reference properties in an object of the array with an expression like ${iteratorVarName.propertyName}. For example, with an iterator variable named pizzas, the name property of a pizza can be referenced using the expression: ${pizzas.name}. No
visible Card display properties No
expression A boolean FreeMarker expression for conditionally showing or hiding tex. For example, the CrcPizzaBot’s OrderPizza state defines this property as follows:
expression: "<#if cardsRangeStart?number+4 < pizzas.value?size>true<#else>false</#if>"
channels:
 include:
 exclude:
For include and exclude, enter a comma-separated list of channel types for which the card should be shown (include) or hidden (exclude). The valid channel values are:
  • facebook

  • webhook

  • web

  • android

  • ios

  • twilio

  • kakaotalk

  • test

onInvalidUserInput A boolean flag that shows the text item when the user enters valid input (value=false) or when the user enters input that’s not valid (value=true).
rangeStart If you’ve specified an iteratorVariable, you can stamp out a subset of cards by specifying the rangeStart property in combination with the rangeSize property. You can enter a hardcoded value or use a FreeMarker expression that references a context variable that holds the range start. Using a rangeStart variable, you can then page to the next set of data by setting the rangeStart variable in the payload of a browse option. No
rangeSize The number of cards that will be displayed as specified by the iteratorVariable and rangeStart properties. No

You can assign a set of actions that are specific to a particular card, or a list of actions that are that are attached to the end of the card list.

The CrcPizzaBot’s OrderPizza state includes a card response item definition, as shown in the following snippet:
cards:
          - title: "${pizzas.name}"
            description: "${pizzas.description}"
            imageUrl: "${pizzas.image}"
            name: "PizzaCard"
            iteratorVariable: "pizzas"
            rangeStart: "${cardsRangeStart}"
            rangeSize: "4"
            actions:
            - label: "Order Now"
              type: "postback"
              payload:
                action: "order"
                variables:
                  orderedPizza: "${pizzas.name}"
                  orderedPizzaImage: "${pizzas.image}"
              name: "Order"
The Attachment Response Item

The attachmentResponse state includes the following properties.

Property Description Required?
attachmentType The type of attachment: image, audio, video, and file. Yes
attachmentURL The attachment’s download URL or source. Yes
The CrcPizzaBot’s Confirmation state uses an attachment response item to display picture of the order, one that’s different from the item pictured in the menu.
  Confirmation:
    component: "System.CommonResponse"
    properties:
      metadata:
        responseItems:
        - text: "Thank you for your order, your ${pizzaSize} ${orderedPizza} pizza\
            \ will be delivered in 30 minutes at GPS position ${location.value.latitude},${location.value.longitude}!"
          type: "text"
          name: "conf"
          separateBubbles: true
        - type: "attachment"
          attachmentType: "image"
          name: "image"
          attachmentUrl: "${orderedPizzaImage}"
      processUserMessage: false
User Message Validation
The System.CommonResponse, System.Text, and System.List components validate the user-supplied free-text value that gets set for the variable property. For example, when the variable property is defined as a primitive type (string, boolean, float, double), these components try to reconcile the value to one of the primitive types. When the variable property is defined for an entity-type variable, these components call the NLP Engine to resolve the value to one of the entities. But when these components can’t validate a value, your bot can display an error message. By referencing the system.invalidUserInput variable, you can add a conditional error message to your bot’s replies. This variable is a boolean, so you can use it as a condition with the FreeMarker if directive to display the message only when a user enters an invalid value. Otherwise, the message is hidden. The CrcPizzaBot’s AskPizzaSize state in the following snippet demonstrates this by adding this variable as condition within a FreeMarker template that’s evaluated by the if directive. Because it’s set to true, the bot adds an error message to the standard message (What size do you want?) when the user enters an invalid value.
  AskPizzaSize:
    component: "System.CommonResponse"
    properties:
      variable: "pizzaSize"
      nlpResultVariable: "iresult"
      maxPrompts: 2
      metadata:
        responseItems:
        - type: "text"
          text: "<#if system.invalidUserInput == 'true'>Invalid size, please try again.\
            \ </#if>What size do you want?"
          name: "What size"
          separateBubbles: true
System.Interactive

Instant apps are rich, interactive widgets that you can embed as web links in your dialog. Your bot can transition to an instant app when it needs to data using structured forms.

After you create one with the Instant App Builder, you can integrate it into your OBotML definition using the System.Interactive component. See Instant Apps.

When you add this component using the Add Components menu, it generates a state called interactive, which has placeholders for the following properties.
Property Description Required?
sourceVariableList A comma-separated list of context or user variable names. These variable names are the parameters that are that’s sent to the instant app. You can set each variable by adding a series of System.SetVariable states before the System.Interactive state. To get an idea, take a look at the setDate, setAmount, setMerchant, and SetDescription states in the FinancialBot. Yes
variable The name of the variable (a string value) that identifies the instant app’s callback payload. When the bot user completes the instant app, it sends a callback with a payload which is stored by this variable. At a later point in your OBotML definition, you can use this payload in a System.Output component. Yes
id The id of the instant app schema that gets instantiated. Enter the ID from the App Settings page of the Instant App Builder. See App Settings.
This is an image of the Id field in the Instant App Builder.
Yes
prompt A text string. By default, this component outputs “Please tap on the link to proceed.” No
linkLabel The label for the button that invokes the instant app. The default string is Link. No
cancelLabel The label for the Cancel button that lets users leave the state without invoking the instant app. By default, the string is Cancel. No
translate Use this property to override the boolean value that you’ve set for the autotranslate context variable. If you haven’t set this variable, or if you set it to false, then you can set this property to true to enable autotranslation for this component only. If you set the autotranslation variable is set to true, you can set this property to false to exclude this component from autotranslation. See Autotranslation. No

How Do I Use This?

The FinancialBotWithQnA uses an intent called startDispute to trigger an instant app. At runtime, when the Dialog Engine moves to the System.Interactive state called startDispute, the bot returns a link to the user. (This is the URL that’s configured for the Invite Message in the Instant App Builder. See App Settings.) The component identifies the instant app (Bank_Transaction_Interactive_With_Verify). The sourceVariableList names the variables whose values get passed to the instant app, namely date, merchant, amount, and description.

Note:

For the purposes of this reference bot, the values for these variables are populated with sample data through the System.SetVariable component.
The instant app defines parameter counterparts for each of these variables called inputDate, inputDescription, inputMerchant, and inputDescription. See Parameters and Using Brace Notation in Element and Parameter Values.

The snippet also shows how the bot returns the reason and dispute ID from the instant app’s return action. See Exit to Bot.

context:
  variables:
...
    dispute: "string"
    amount: "string"
    merchant: "string"
    date: "string"
    description: "string"
states:
  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
      confidenceThreshold: 0.4
    transitions:
      actions:
        Balances: "startBalances"
        Transactions: "startTxns"
        Send Money: "startPayments"
        Track Spending: "startTrackSpending"
        Dispute: "setDate"
        unresolvedIntent: "unresolved"
...

# Populate the required variables
  setDate:
    component: "System.SetVariable"
    properties:
      variable: "date"
      value: "2017-10-25T11:34:31Z"
    transitions: {}
  setAmount:
    component: "System.SetVariable"
    properties:
      variable: "amount"
      value: "$60"
    transitions: {}
  setMerchant:
    component: "System.SetVariable"
    properties:
      variable: "merchant"
      value: "PizzaUGotcha"
    transitions: {}
  setDescription:
    component: "System.SetVariable"
    properties:
      variable: "description"
      value: "restaurants"
    transitions: {}
# Call instant app
  startDispute:
    component: "System.Interactive"
    properties:
      sourceVariableList: "date, merchant, amount, description"
      variable: "dispute"
      id: "Bank_Transaction_Interactive_With_Verify"
    transitions: {}
# Use the callback payload data
  instantAppOutput:
    component: "System.Output"
    properties:
      text: "Successfully filed dispute, your reference number is '${dispute.value.disputeID}'\
        \ and reason is '${dispute.value.reason}'"
    transitions:
      return: "instantAppOutput"
Transitions
The System.CommonResponse , System.List, and System.Text component use these transitions. See Message Handling for Output Components to find out how these transitions get triggered.
Transition Description
cancel Set this transition when a user exceeds the allotted attempts set by the maxAttempts property.
textReceived Set this when users send text or emojis. For example:
  ShowMenu:
    component: "System.CommonResponse"
    ...
      processUserMessage: true
    transitions:
      actions:
        pizza: "OrderPizza"
        pasta: "OrderPasta"
        unexpectedAction: "HandleUnexpectedAction"
        textReceived: "Intent"
attachmentReceived Set this when a user sends an image, audio, video, or file attachment.
locationReceived Set this when the user sends a location.
unexpectedAction Set this to circumvent unexpected user behavior. Specifically, when a user doesn’t tap an action item in the current message, but instead taps an action belonging to an older message in the chat session. You can access the unexpected action by referencing the system.botsUnexpectedAction variable.
Message Handling for Output Components
Typically, a user might respond to a message in the following ways:
  • By entering free text.

  • By sending their location.

  • Using a multi-media option to send an image, audio file, video, or file attachment.

  • Tapping one of the postback buttons displayed in the most recent message output by the bot.

  • By scrolling to a previous message in the conversation and tapping one of its buttons.

Handling Free Text
When a user enters free text, the System.CommonResponse, System.List and System.Text components first validate the value. For valid values, the components trigger the textReceived transition. You don’t have to set this transition in the OBotML definition; if you don’t define this transition, then the Dialog Engine transitions to the next state, or performs the default transition.

Tip:

Use textReceived to handle unexpected user messages when you expect the user to tap a button, send an attachment, or a location.
Handling Multimedia Messages
When a users sends a file, image, video, or audio file, the System.CommonResponse, System.List, and System.Text component stores the attachment information as a JSON object in the variable property that’s specified for the component. This object has the following structure:
{
  "type": "video",
  "url": "https://www.youtube.com/watch?v=CMNry4PE93Y"
}
For example, if a video attachment is stored in a variable called myVideo, you can access the video using the FreeMarker expression, ${myVideo.value.url}. It also sets the transition action to attachmentReceived. You don’t have to specify this transition in your OBotML definition. If you don’t define this transition, then the Dialog Engine transitions to the next state, or performs the default transition.

Tip:

Use attachmentReceived to handle situations where users send an attachment unexpectedly.
Handling Location Messages
When a user sends his or her current location, the System.CommonResponse, System.List, and System.Text components store the location information as a JSON object in the variable property specified for the component. This object has the following structure:
{
  "title": "Oracle Headquarters",
  "url": "https://www.google.com.au/maps/place/…",
  "longitude": -122.265987,
  "latitude": 37.529818
}
For example, if the location is stored in a variable called location, you can access the latitude using the FreeMarker expression, ${location.value.latitude}. It also triggers the locationReceived action, so you don’t have to specify this transition in your OBotML definition. If you don’t define this transition, then the Dialog Engine transitions to the next state, or performs the default transition.

Tip:

Include locationReceived transition to handle situations where users send a location unexpectedly, or when you want to ensure that a user sends a location at the point where it’s expected.
Handling Button Postback Actions
When a user taps a button in the most recent message, that button’s payload gets processed. This payload is a JSON object which can hold an action property and one or more payload variables (all of which are optional). The payload’s action is set as a transition action. Each user or context variable that’s included in the payload is set to the value that’s included in the payload. For example, when a user taps the Order Now button for a pepperoni pizza, the System.List or System.CommonResponse components receive the payload as a stringified JSON object:
{
	"action": "order",
	"state": "OrderPizza",
	"variables": {
		"orderedPizza": "PEPPERONI",
		"orderPizzaImage": "http://pizzasteven/pepperoni.png"
	}
In this example, the component parses the payload object with the order value, sets the transition to order, and sets the orderedPizza and orderedPizzaImage variables to the value specified in the payload.
Handling Button Postback Actions for an Older Message
A user might ignore the most recent message and instead scroll up and tap a button that’s part of an earlier message. For example, user might tap the Order Now button for a pepperoni pizza, but is now asked which size. At this point, he might change his mind and click the Order Now button for another type of pizza, or he might decide on pasta rather than pizza, so he scrolls further up to a previous message and clicks Order Now for a pasta dish. When this happens, the component processes the button payload and sets any user or context variables as a postback action. But in this case, if the payload action has been specified, the action is not used to set the conversation transition. Instead, the unexpectedAction transition is triggered and the action value is stored in the system.unexpectedAction variable. This allows you to have one generic state to handle all of the unexpected user actions and messages.
...
defaultTransitions:
   unexpectedAction: "HandleUnexpectedAction" 
states:
 OrderPizza:
    component: "System.CommonResponse"
    properties:
      metadata:
        responseItems:
        - type: "text"
          text: "Here are our pizzas you can order today"  
...  

      processUserMessage: true
    transitions:
      actions:
        order: "AskPizzaSize"
        more: "OrderPizza"
        textReceived: "Intent"

...

  HandleUnexpectedAction:
    component: "System.Switch"
    properties:
      variable: "system.unexpectedAction"
      values:
      - "pizza"
      - "pasta"
      - "order"
    transitions:
      actions:
        NONE: "ActionNoLongerAvailable"
        pizza: "OrderPizza"
        pasta: "OrderPasta"
        order: "AskPizzaSize"
Detecting Unexpected Actions
Because the built-in components that send bot messages with postback actions store the name of the state in the state property of the postback payload, they allow your bot to detect when a user does the unexpected by tapping a button from a previous message, essentially traversing backwards through the dialog flow. When a user taps this button, the name of the state is set for the postback’s state property. The bot compares the payload’s state name against the current state. When the two no longer match, the bot fires the unexpectedAction transition.

Note:

Only components that set the state property in the payload can enable the bot to respond when the user skips back in the flow. The SystemOAuthAccountLink doesn’t set this property, so tapping the button on an older message can’t trigger the unexpectedAction transition.
Limiting the Number of User Prompts

The maxPrompts property limits the number of times that the output components can prompt the user when they can’t match the input value to any of the values defined for the entity or input type that’s referenced by the variable property. While this is an optional property, adding it can prevent your dialog from going in circles when users repeatedly enter invalid values. You can set the maximum number of prompts using an integer (like 2 in the following snippet). The dialog moves onto the next state if the user enters a valid value before reaching this limit. Otherwise, the dialog transitions to the state defined by the cancel action. In the following sample, the dialog moves to the setDefaultSize state when users run out of chances. At this point, the bot makes their choice for them, because the System.SetVariable component sets the pizza size to large.

  size:
    component: "System.List"
    properties:
      prompt: "What size Pizza do you want?"
      options: "${size.type.enumValues}"
      variable: "size"
      maxPrompts: 2
    transitions:
      actions:
        cancel: "setDefaultSize"
  setDefaultSize:
    component: "System.SetVariable"
    properties:
      variable: "size"
      value: "Large"
    transitions: {}

Note:

Setting the maxPrompts property to a negative number is same as not entering a value, or not including the property at all: the bot will continue to prompt the user until it receives a valid value.

Variable Components

System.SetVariable

The System.SetVariable component sets the value of a pre-defined variable. For example, you can set the value for an entity variable because this component can extract the entity match that's held by the iResult variable that's set for the System.Intent component.

Property Description Required?
variable The name of the variable that’s defined as one of the context properties. This can be a variable defined for an entity or a predetermined value, like a string. Yes
value The target value, which you can define as a literal or as a expression that references another variable. Yes

The startTxns state in the following code snippet shows how you can define the target value using an expression that references another entity variable. In this case, "${iResult.value.entityMatches['AccountType'][0]” references the iResult variable that’s resolved earlier in the flow by the System.Intent component. This variable sets the accountType variable if the AccountType entity is associated with the intent that’s resolved by the System.Intent component. For example, if a user enters, “I want to transfer money to checking,” then this expression sets the accountType variable value to “checking.” If the System.SetVariable component can’t find matches, then the Dialog Engine moves on to the next state in the dialog flow (declared by transitions: {}).

main: true
name: "FinancialBotMainFlow"
context:
  variables:
    accountType: "AccountType"
    txnType: "TransactionType"
    txnSelector: "TransactionSelector"
    toAccount: "ToAccount"
    spendingCategory: "TrackSpendingCategory"
    paymentAmount: "string"
    iResult: "nlpresult"
states:

...

  startTxns:
    component: "System.SetVariable"
    properties:
      variable: "accountType"
      value: "${iResult.value.entityMatches['AccountType'][0]}"
    transitions: {}
...
Besides entity variables, you can set a predetermined value for a variable using an Apache FreeMarker expression or, as shown in the following snippet, a literal. You can find out more about FreeMarker here.
setOAuthRedirectURL:
    component: "System.SetVariable"
    properties:
      variable: "redirectURL"
      value: "https://thatcompany.io/connectors/v1/tenants/5c824-45fd-b6a2-8ca/listeners/facebook/channels/78B5-BD58-8AF6-F54B141/redirect"
    transitions: {}
See System.OAuthAccountLink
System.ResetVariables

This component resets the values of the variables to null. This component doesn’t require any transitions (use transitions :{}).

Property Description Required?
variableList A comma-separated list of variable names. Yes
System.CopyVariables

Copies the variable values.

Define this component using from and to properties as in the following snippet, where the value is copied to a user context:
setupUserContext:
    component: "System.CopyVariables"
    properties:
      from: "lastQuestion,lastResponse"
      to: "user.lastQuestion,user.lastResponse"
This component needs both of these properties, but their definitions don’t have to mirror one-another. While you can define both from and to as lists of variables, you can also define from with a single variable and to as a list. If you set an additional to property, it inherits the variable value of the proceeding from property.

Apache FreeMarker Reference

Built-In String FreeMarker Operations

The following table shows you how to use some of the built-in string operations using a string variable called tester as an example. As shown in the following snippet, its value is set to "hello world " (with three trailing blank spaces):
context:
  variables:
    tester: "string"
…
states:
  setVariable:
    component: "System.SetVariable"
    properties:
      variable: "tester"
      value: "hello world   "
  

Note:

The following text property definition allows the bot to output either the tester value, or, no string found if no value has been set for the variable.
printVariable:
  component: "System.Output"
  properties:
    text: "${tester.value!'no string found'}"
  transitions: {} 
Built-In Operation Usage Output
capitalize ${tester.value?capitalize} Hello World
last_index_of ${tester.value?last_index_of('orld')} 7
left_pad ${tester.value?left_pad(3,'_')} ___hello world
length ${tester.value?length} 14
lower_case ${tester.value?lower_case} hello world
upper_case ${tester.value?upper_case} HELLO WORLD
replace ${tester.value?replace('world', 'friends')} hello friends
remove_beginning ${tester.value?remove_beginning('hello')} world
trim ${tester.value?trim} hello world (the trailing three spaces are removed)
ensure_starts_with ${tester.value?ensure_starts_with('brave new ')} brave new hello world
ensure_ends_with ${tester.value?ensure_ends_with(' my friend')}$ hello world my friend
contains ${tester.value?contains('world')?string ('You said world', 'You did not say world')} You said world

The contains('world') expressions returns either true or false. These boolean values are replaced with a string using the string ('string1','string2') function.

ends_with ${tester.value?ends_with('world')?string ('Ends with world', 'Doesn't end with world')} Ends with world
starts_with ${tester.value?starts_with('world')?string ('Starts with world', 'Doesn't start with world')} Doesn't start with world
matches (regular expression returns true or false) ${tester.value?matches('^([^0-9]*)$')} The regular expression returns true or false depending on whether the value contains a number (in which case the boolean value is returned as false). The tester value returns true.
matches (regular expression returns a string) ${tester.value?matches('^([^0-9]*)$')?} Same as above, but this time, true is returned as a string. The matches('regular expression') function returns true or false as boolean types. To print true or false in a System.Output component, use ?string to perform a to-string conversion.

Note: regular expressions can’t be used in expressions that return groups. Use them in expressions that returns a single match or no match.

Example: Improving the Confidence Level with Casing
While The casing of the user input can impact the confidence level of the intent resolution. For example, May might refer to the month or the verb and user input can be erratic (Pizza, piZza, PIZZA). Instead of catching all of the possible case variations as synonyms in the entity definition, you can make the casing uniform using the an FTL operator like lower_case in the following snippet.
getIntent:
    component: "System.Text"
      properties:
        prompt: "Hi, I am a the Pizza Palace bot. How can I help?"
        variable: "userstring"
      transitions: {}
toLowercase:
    component: "System.SetVariable"
      properties:
      variable: "userstring"
      value: "${userstring.value?lower_case}"
    transitions: {}
intent:
     component: "System.Intent"
      properties:
      variable: "iResult"
      confidenceThreshold: 0.8
      sourceVariable: "userstring"
    transitions:
      actions:
      orderPizza: "orderPizza"
      cancelOrder: "cancelOrder"
      unresolvedIntent: "handleUnresolved"

To implement this, you first ask the for the user input using the System.Text component. In this example, the System.Text component saves the user input in the userstring variable. The Sytem.SetVariable uses FTL to change the case of the user input string to lower case and saves the modified string to the same userstring variable. Finally, the userstring variable is referenced by the System.Intent component using the sourceVariable property to run the modified user string against the intent engine.

Example: Transforming Case with the System.Switch Component

Another component that can be simplified with FTL is System.Switch.

In the following snippet shows different states that get called depending on the user input (wine or beer), which is stored in the choice variable.
switch:
    component: "System.Switch"
    properties:
      variable: "choice"
      values:
      - "wine"
      - "beer"
    transitions:
      actions:
        wine: "serverWine"
        beer: "serveBeer"
        NONE: "serveWater"
The casing of the input collected using the System.Text component may inconsistent, even within a word (WiNE). Instead of adding all possible variations to the System.Switch definition, use an FTL operation like upper_case to make the casing uniform:
switch:
  component: "System.Switch"
  properties:
    source: "${choice.value?upper_case}"
    values:
    - "WINE"
    - "BEER"
transitions:
 actions:
  WINE: "serveWine"
  BEER: "serverBeer"
  NONE: "serveWater"
Example: Concatenating FTL Expressions
The following snippet shows how concatenating FTL expressions transforms user input UA1234 and UA 1234, to simply 1234.
normalizeFlightNumber:
  component: "System.SetVariable"
  properties:
    variable: "flight"
    value: "${flight.value?trim?lower_case?remove_beginning('ua ')
            ?remove_beginning('ua')}"

Built-In FreeMarker Number Operations

The following table lists the built-in number operations and shows how they output the value set for the negativeValue (-2.5) and positiveValue (0.5175) context variables in the following snippet.
context:
  variables:
    negativeValue: "float"
    positiveValue: "float"
states:
  setNegativeValue:
    component: "System.SetVariable"
    properties:
       variable: "negativeValue"
       value: -2.5
setPositiveValue:
  component: "System.SetVariable"
  properties:
    variable: "positiveValue"
    value: 0.5175
Operation Example Output
abs ${negativeValue.value?abs} 2.5

The operator turns the negative numeric value into a positive value.

string (used with a numerical value) ${negativeValue.value?abs?string.percent} 250%

The operator first changes the negative value to a positive. Then it converts it into percent, implicitly multiplying the value by 100.

string (with the decimal format value and various currencies)

Tip: Check out Charbase for other currency symbols.

${positiveValue.value?string['###.##']} 0.51
${positiveValue.value?string['###.##%']} 51%

The operator adds adding a percentage character after multiplying the value by 100.

${positiveValue.value?string['##.###\u00A4']} 0.51 $
${positiveValue.value?string['##.###\u20AC']} 0.51 €
${positiveValue.value?string['##.###\u00A3']} 0.51 £
round ${negativeValue.value?round} -2

The operator rounds to the nearest whole number. If the number ends with .5, then it rounds upwards.

${positiveValue.value?round} 1

The operator rounds to the nearest whole number. If the number ends with .5, then it rounds upwards.

floor ${positiveValue.value?floor} 0

The operator rounds downwards.

ceiling ${positiveValue.value?ceiling} 1

The operator rounds upwards.

lower_abc ${negativeValue.value?abs?round?lower_abc} c

The operator turns the negative value into a positive, then rounds it to 3. It returns c, the third letter of the alphabet.

upper_abc ${negativeValue.value?abs?round?upper_abc} C

The operator turns the negative value into a positive, then rounds it to 3. It returns C, the third letter of the alphabet.

is_infinite ${positiveValue.value?is_infinite?string} false

The operator returns false, because a float value is not infinite according to IEEE 754 (Standard for Floating-Point Arithmetic).

Note: The returned value would be a boolean without ?string.

Built-In FreeMarker Array Operations

Array (or sequence) operations enable your bot to, among other things, determine the size of an array, sort arrays, or find content within an array.

Arrays return the results from the intent and entity processing. For example:
  • ${iResult.value.entityMatches[‘name of entity’]} returns an array of entities found in a user string that’s passed to the System.Intent component and stored in the iResult: nlpresult variable.

  • ${iResult.value.intentMatches.summary} returns an array of intents and the confidence level for the given user input.

You can save an array in a custom component, in a user-scoped variable, or as shown in the following snippet, a context variable. In it, there are arrays set for the person and colors variables.
context:
  variables:
    person: "string"
    colors: "string"
...

setPerson:
    component: "System.SetVariable"
    properties:
      variable: "person"
      value:
        - firstName: "Frank"
          lastName: "Normal"
        - firstName: "Grant"
          lastName: "Right"
        - firstName: "Geoff"
          lastName: "Power"
        - firstName: "Marcelo"
          lastName: "Jump"

...

setColors:
    component: "System.SetVariable"
    properties:
      variable: "colors"
      value:
        - "yellow"
        - "blue"
        - "red"
        - "black"
        - "white"
- "green"
These colors and person arrays are used to illustrate the array operations and in Example: Iterating Arrays.
You can use arrays with different components like the System.Output and System.SetVariable to accomplish different things:
  • To create mock data for testing.

  • To define data structures that persist beyond user sessions.

You can define array properties for different components, like System.Output or System.SetVariable (illustrated in the following snippet).
Operator Example Output
size ${person.value?size?number} 4—The size (four members) of the person array
array index ${person.value[1].firstName} Grant—It’s the value of the second firstName property in the person array.
${person.value[1].firstName !'unknown'} Same as the above, but in this case, the bot outputs unknown if the second firstName property has no value.
first ${person.value?first.firstName} Frank—The first entry of the person array. This operation doesn’t use the array index.
last ${person.value?last.firstName} Marcelo—The final lastName value in the person array.
sort_by ${person.value?sort_by('lastName') [0].firstName} Marcelo
This operator sorts the person array by the lastName property in ascending order. It then prints the value of the corresponding firstName property for final entry in the person array:
  • Jump, Marcelo

  • Normal, Frank

  • Power, Geoff

  • Right, Grant

Note: Unless you save the sorted array in a variable using System.SetVariable, the data remains sorted for a single request only.

${person.value?sort_by('lastName')?reverse[0].firstName} Grant—the values are sorted in descending order:
  • Right, Grant

  • Power, Geoff

  • Normal, Frank

  • Jump, Marcelo

seq_index_of ${colors.value?seq_index_of('red')} 2—The index value for red in the colors array.
seq_last_index_of ${colors.value?seq_last_index_of('red')} 2—The last index value for red in the
join ${colors.value?join(',')} Returns the colors array as a comma-separated string: yellow, blue, red, black, white, green
seq_contains ${colors.value?seq_contains('red')? Returns Yes because the array contains red.

Note: ?seq_contains returns a boolean value. This value is then replaced by a string using the ?string(‘...’.’...’) expression.

sort ${colors.value?sort?join(',')} Returns the colors array as a comma-separated string in ascending order: black, blue, green, red, white, yellow
reverse ${colors.value?sort?reverse?join(',')} Returns the colors array as a comma-separated string in descending order: yellow, blue, red, black, white, green
Example: Iterating Arrays
Arrays determine the number of entities in the user input. The following snippet shows how to determine the size of the array held in the person variable and then iterate over its elements so that the bot outputs something like:

    component: "System.CommonResponse"
    properties:
      metadata:
        responseItems:
        - type: "text"
          text: "${person?index+1}. ${person.firstName} ${person.lastName}"
          name: "Sorry"
          separateBubbles: true
          iteratorVariable: "person"
      processUserMessage: false

Note:

The output described in this code is not sorted (that is, no sort_by operation is used).

Built-In FreeMarker Date Operations

The following snippet derives the current date using the FreeMarker special variable reference, .now and the built-in date operator.
PrintToday:
  component: "System.Output"
  properties:
   text: "${.now?date}"
   keepTurn: false
The following table lists some of the built-in date operations that you can use to define properties and manipulate entity values.
Operation(s) Example Output
date ${.now?date} The current date
time ${.now?time} The time of day, like 5:46:09 PM
datetime ${.now?datetime} Prints current date and time, like Jan 17, 2018 5:36:13 PM.
long and number_to_date ${(.now?long + 86400000)?number_to_date } Adds 24 hours to the current date. If the call is made on January 17, 2018, FreeMarker outputs January 18, 2018.
string (with formatting styles) ${.now?string.full} Converts the current date to string formatted as Wednesday, January 17, 2018 6:35:12 PM UTC.
${.now?string.long} Converts date to string with the following formatted output: January 17, 20186:36:47 PM UTC.
${.now?string.short} Converts date to string with the following formatted output: 1/17/18 6:37 PM
${.now?string.medium} Converts date to string with the following formatted output: Jan 17, 2018 6:38:35.
${.now?string.iso}

Prints the date in the ISO 8601 standard like 2018-01-17T18:54:01.129Z.

string (with specified output formats) ${.now?string['dd.MM.yyyy, HH:mm']}

Prints the current date in a custom format, like 17.01.2018, 18:58.

${.now?string['yyyy']}

2018

datetime (with string and formatting style) ${date_variable?datetime?string.short} Converts the date to a string formatted as 1/17/18 6:37 PM.

The datetime operator enables FreeMarker to tell if the variable holds a date that contains both date and time information. Similarly, you can use the date or time operators to indicate if the date value contains only the date or only the time, but using datetime?string avoids errors.

Converting the entity value to a string using
  • date

  • long

  • number_to_date

  • formatting styles

  • custom date formats

${dateVar.value.date?long?number_to_date?date?string.short} Converts the date from the entity extraction to a string formatted as 11/17/18.

The date operator tells FreeMarker that the variable only holds a date, not time information. Using this format avoids errors.

${dateVar.value.date?long?number_to_date?string.medium} Converts the date that’s derived from entity extraction to a string formatted as Jan 17, 2018.

Note: All other formats like full, short, long and iso work the same with dates derived from entity extraction.

${dateVar.value.date?long?number_to_date?string['dd.MM.yyyy']} Prints the date in custom format. For example: 17.01.2018, 18:58.
${dateVar.value.date?long?number_to_date?string['yyyy']} Prints the date derived from entity in a custom format.
Example: Extracting Dates from User Input
The following snippet is from a bot that manages appointments. When a user asks it, Can you arrange a meeting with Mr. Higgs a day later than tomorrow?, the bot uses a complex entity, DATE, to extract tomorrow from the request. It outputs the requested date using ${(theDate.value.date?long + 86400000)?number_to_date} to add 24 hours (or 86,400,000 milliseconds) to the current date.
OBotML Code Output
context:
  variables:
    iResult: "nlpresult"
    theDate : "DATE"
states:
   intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
      confidenceThreshold: 0.4
    transitions:
      actions:
        unresolvedIntent: "dunno"
        Appointment: "printToday"
printToday:
  component: "System.Output"
  properties:
    text: "Today is: ${.now}"
    keepTurn: true
startAppointement:
  component: "System.SetVariable"
  properties:
    variable: "theDate"
    value: "${iResult.value.entityMatches['DATE'][0]}"
printDateFound:
  component: "System.Output"
  properties:
    text: "Date found is: ${theDate.value.date}"
    keepTurn: true
printDayAfter:
  component: "System.Output"
  properties:
    text: "A day later is ${(theDate.value.date?long + 86400000)?number_to_date}"
  transistions:
    return: "done"
Example: Setting a Default Date (When No Date Value Is Set)
If the user message doesn’t include any date information, your bot can prompt users for the date, or provide a default date, as shown by the following snippet (which augments the dialog flow in the previous example). To perform the latter, your bot needs to check if date variable has been set after the NLP engine extracts entities from the user input.
  conditionEquals:
    component: "System.ConditionEquals"
    properties:
      variable: "theDate"
      value: null
    transitions:
      actions:
        equal: "setDefaultDate"
        notequal: "printDateFound"
If no date value has been set, the System.SetVariable component defines a default value in a variable and transform it into a string.
  setDefaultDate:
    component: "System.SetVariable"
    properties:
     variable: "defaultDateInput"
     value: "${.now?datetime?string.long}"
The System.MatchEntity component verifies that this value is a date and then sets thetheDATE variable:
  matchEntity:
    component: "System.MatchEntity"
    properties:
      sourceVariable: "defaultDateInput"
      variable: "theDate"
    transitions:
      actions:
        match: "printDateFound"
        nomatch: "exit"
OBotML Output
context:
  variables:
    iResult: "nlpresult"
    theDate : "DATE"
    #need extra variable for default date input
    defaultDateInput: "string"
states:
 ...

#try to extract date information from user sentence
  startAppointement:
    component: "System.SetVariable"
    properties:
      variable: "theDate"
      value: "${iResult.value.entityMatches['DATE'][0]}"
#set default date if none found
  conditionEquals:
    component: "System.ConditionEquals"
    properties:
      variable: "theDate"
      value: null
    transitions:
      actions:
        equal: "setDefaultDate"
        notequal: "printDateFound"
  setDefaultDate:
    component: "System.SetVariable"
    properties:
     variable: "defaultDateInput"
     value: "${.now?datetime?string.long}"
  matchEntity:
    component: "System.MatchEntity"
    properties:
  sourceVariable: "defaultDateInput"
    variable: "theDate"
    transitions:
      actions:
        match: "printDateFound"
        nomatch: "exit"
  printDateFound:
    component: "System.Output"
    properties:
      text: "Date found is:
             ${theDate.value.date?long?number_to_date?date?string.medium}"
      keepTurn: true
  printDayAfter:
    component: "System.Output"
    properties:
    text: "A day later is ${(theDate.value.date?long + 86400000)?number_to_date}"
    transistions:
      return: "done"

The SDK Helper Methods

Function Usage
conversation.payload() Retrieves the payload of the current user message. The payload contains the message text and other information, like the user ID.
conversation.text() Accesses the text string.
conversation.attachment() Accesses an attachment message.
conversation.location() Accesses a location message.
conversation.postback() Accesses a postback message.
conversation.transition(“action”) and conversation.transition() Directs the Dialog Engine to the next state in the dialog flow. The custom component can influence the navigation by returning an action string that you’ve mapped to state in the dialog flow.
  • Component-controlled navigation (conversation.transition(“action”))—To set the target state, pass a string argument that matches one of the supportedActions strings in the component module’s metatdata function, like nameFound and nameNotFound in the following snippet:
    metadata: () => ({
        "name": "helloWorld",
        "properties": {
          "properties": {
            "name": {
            "type": "string",
            "required": false"
          }
        },
        "supportedActions": ["nameFound", "nameNotFound"]
      }),      
    
  • Dialog flow-controlled navigation (conversation.transition())—You can call this function with no arguments when the component module has no supportedActions definition (and therefore, no arguments to pass). In this case, the dialog flow definition sets the transition, not the component. For example, depending on the dialog flow definition, the Dialog Engine might move to the next state in the flow after transition method executes (transitions: {}) or on to a specific state:
    transitions:
      next: "newState"

    The dialog flow will also determine the transition when the component module has a supportedActions definition, but the function itself has no arguments.

conversation.channelType() Allows you to determine the messaging channel.
conversation.keepTurn(boolean) Enables your bot to retain control of the conversation. keepTurn essentially decides who provides input or a response: the bot or its user. So before you call done, you can indicate who goes next by calling either conversation.keepTurn(true) or convesationkeepTurn(false).
  • conversation.keepTurn(true)—Set to true to allow the bot to control the conversation. This is essentially the bot (through the component) asserting “It’s still my turn to speak.” Use this setting when the component doesn’t require user input or when it needs to send multiple replies in quick succession while suppressing user input.

  • conversation.keepTurn(false)—Set to false (the default) to enable the user to reply. This setting essentially hands control back to the user until the next reply from the component. It enables a typical back-and-forth conversation.

conversation.reply({text: "..."}) Returns the response from the messaging client. This response can be a simple text message, or a a more complex response with a rich UI that uses the functions of the MessageModel class in the Custom Component SDK. This function enables you to build more a complex response, such as a scrolling carousel on Facebook. For this type of response, you need to structure the JSON payload appropriately.

Important:

You must call done() to send the response, regardless of the number of calls made to conversation.reply.
conversation.properties() Provides access to the component input properties (conversation.properties().accountType).
conversation.error Indicates that there was an error in the processing.
conversation.botId() Returns the ID of the bot that sent the request.
conversation.platformVersion() Returns the version of the message platform (such as Facebook 1.0).
conversation.text() Provides access to the NLP text message that triggered the invocation of the intent and the component.
conversation.variable(“name”,value) Provides read or write access to variables defined in the current flow. This function takes the following arguments:
  • variable(name)—Reads the name variable and returns its value.

  • variable(name, value)—Writes the value of the value variable to the name variable. Only enclose the value in quotes when it’s a string.

This function also creates a variable at runtime, one that can be used to track the state of component. You can use this when component needs to track its internal state because it doesn’t transition to the next state in the dialog flow.
conversation.nlpResult() Returns an NLPResult helper object for nlpresult variables. For example, you can find the value of an entity that was extracted from the user input by calling conversation.nlpResult.entityMatches(entity name). You can use this value to update an entity type variable.
conversation.request() Accesses the JSON object body that’s sent by the bot. Use this function to parse the payload for any information that's not directly exposed by one of the SDK functions.
conversation.response() Grants access to the HTTP response payload (a JSON object) that’s sent back to the bot when you call done().

Navigation with keepTurn and transition

Use different combinations of the keepTurn and transition functions to define how the conversation continues once the component has finished processing.
invoke: (conversation, done) ==> {
   ...
   conversation.keepTurn(true);
   conversation.transition ("success"); 
   done();
    }
Use Case Values Set for keepTurn and transition

A custom component’s reply that doesn’t require any user interaction.

  • Set keepTurn to true: conversation.keepTurn(true).

  • Set transition with a supportedActions string(conversation.transition("success")) or with no arguments (conversation.transition()).

For example, a custom component updates a context variable with a list of values that is then displayed by a System.List component that’s defined for the next state in the dialog flow definition.
invoke: (conversation, done) => {
    const listVariableName = conversation.properties().variableName;
  ...
 
  //
write list of options to a context variable 
   conversation.variable(listVariableName, list);

   //navigate to next state. No user interaction.
   conversation.keepTurn(true);
   conversation.transition();
   done();
 }

Note:

When component doesn’t transition to the next state, it needs to track its own state by creating a runtime variable using the conversation.variable (“name”, variable) method.
A sequential user conversation in which the user provides input, the bot replies, and so on.
  • Set keepTurn to false.

  • Set transition with a supportActions string

For example:
conversation.keepTurn(false);
conversation.transition("success");
The bot to passes control back to the user without navigating to the next dialog state. This allows the component to process the user input. Here are a couple of examples:
  • A component passes the user input to query a backend search engine. If the chatbot can only accommodate a single result, but the query instead returns multiple hits, the component can then prompt the user more input to filter the results. In this case, the custom component continues to handle the user input; it holds the conversation until the search engine returns a single hit. When the backend system is satisfied, the component calls conversation.transition() to move on to the next state as defined in the dialog flow definition.

  • A questionnaire, wherein a custom component handles all of the questions and only transitions to the next state when each of them gets answered.

  • Do not call transition.

  • Set keepTurn to false.

For example:
conversation.reply("text");
conversation.keepTurn(false);
done();

The custom component goes into a loop, which can’t be stopped by user input. For example, a component pings a remote service for the status of an order until the status is returned as accepted or when the component times out. If the accepted status is not returned after the fifth ping, then the component transitions to a failedOrder state, which is defined in the dialog flow.
  • Do not call transition.

  • Set keepTurn to true: conversation.keepTurn(true).

For example:
conversation.reply("text");
conversation.keepTurn(true);
done();

Note:

Always call keepTurn after reply and not before, because reply implicitly sets keepTurn to false.

The Custom Component Payload

Taking a Look at the Metadata Retrieval

The response payload for the GET endpoint is made up of properties that are required to call the component along the name of the component itself. You can shape this payload by defining the state machine transitions (that is, the possible actions returned by this component). As illustrated by the array in this example, you can add as many components as you need.
{
	"version": "1.0",
	"components": [{
			"name": "AgeChecker",
			"properties": {
				"minAge": {
					"type": "integer",
					"required": true
				}
			},
			"supportedActions": [
				"success",
				"fail"
			]
		}, {
			"name": "PizzaBaker",
			"properties": {
				"size": {
					"type": "string",
					"required": true
				},
				"crust": {
					"type": "string",
					"required": true
				},
				"type": {
					"type": "string",
					"required": true
				}
			},
			"supportedActions": [
				"pizzaReady",
				"fail"
			]
		}
	]
}{

Taking a Look at the Invocation Request and Response Payloads

For the POST, the request contains the bot’s GUID, the platform version of Bots, and a context definition for the dialog flow variables, the state’s properties, the original message, the channel that delivered it, and the tenant.
This is an example of a request JSON.
The POST response payload also includes the context definition for all of the variable values, including those that have been mutated by the component. The response payload can also control the routing through properties like exit, done, and error. You don’t have to parse the JSON if you use our SDK. Instead, you just need to set the variables. See The SDK Helper Methods.
This is an image of a response JSON