28 Components

Components give your bot the functionality that lets it interact with users and carry out their requests.

Each state within your flow calls a component to perform actions that can range from basic interactions like taking user input and outputting response text to some service-specific action like fulfilling an order or booking a flight. We provide a set of built-in components that support basic actions like setting variables, allowing OAuth, and enabling user input. If your bot calls for a specific action that’s outside of these functions, you’ll need to use a custom component. These components let your bot call REST APIs that implement business logic and channel-specific rendering.

Built-In Components

The following components allow your bot to perform typical interactions with its users

How Do I Add Built-In Components to the Dialog Flow?

While you can enter the state definitions for built-in components by hand, you can add these components more quickly (and minimize validation errors at the same time) when you use templates.

Wherever your dialog flow requires a built-in component, you can insert a basic state definition for it by first clicking Add Components. Next, choose the category type from the menu. Next, choose the category type from the menu.
Choose this category... ...to add state definitions for these components
Control
Language You need to add the System.DetectLanguage and System.TranslateInput before the System.Intent component to allow the user input to be translated into English before it can be processed by the NLU Engine. See Autotranslation .
Security System.OAuthAccountLink
User Interface
Variable
You can edit the template within the dialog and then use the Insert After menu to position the state within your dialog flow, and then click Apply

Note:

Remember that because the Dialog Engine reads the dialog flow from the top-down, you need to add these (or for that matter, any) state definitions where they make sense within the flow.
. From there, you can rename the state and define the properties and actions as needed. (Keep in mind that you that you shouldn’t rename the intent state.) Each template is tailored to a built-in component: while the variableList state template for the System.List component includes theoptions, prompt, variable, and translate properties, for example, the state created for a System.SetVariable component has only the variable property.

You need to add states for custom components manually. Refer to the properties and actions described in the Components page (This is an illustration of the Components icon.) when you add custom components to your dialog flow.

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.

NLP Components

The NLP components set variable values from the intents and entities that are resolved by the NLP component. These include:
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

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 FinancialBot 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"

Variable Components

Use these components to set (or reset) string, integer, and boolean variable values:
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
Adding Sample Data
For testing scenarios, you can load sample dating using the System.SetVariable component.
context:
  variables:
...
    
    salesQuotaList: string
...

states:
  loadSalesQuota:
    component: System.SetVariable
    transitions: {}
    properties:
      variable: salesQuotaList
      value:
        - QuoteId: '13'
          EmpId: '2012123'
          Quarter: Q1
          Year: '2017'
          Sales: '6.25'
          Targets: '5.5'
          Region: Northern California
        - QuoteId: '14'
          EmpId: '2012123'
          Quarter: Q2
          Year: '2017'
          Sales: '2.6'
          Targets: '4'
          Region: Central Valley
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.

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 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 user.botsUserError == '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

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
rendered

An Apache FreeMarker expression that enables the item to be dynamically included or excluded from the response. For example, the CrcPizzaBot’s OrderPizza state defines this property as follows:

rendered:"<#if cardsRangeStart?number+4 < pizzas.value?size>true<#else>false</#if>"

No
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
variable names 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. 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
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
rendered A boolean Apache FreeMarker expression that enables the text to be dynamically included or excluded from the response. No
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
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
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.
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 adding the user.botsUserError 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 user.botsUserError == 'true'>Invalid size, please try again.\
            \ </#if>What size do you want?"
          name: "What size"
          separateBubbles: true

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.
Message Handling for Output Components

Typically, a user might respond to a message in the following ways:
  • By entering free text.

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

  • By sending their location.

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

  • By scrolling to a previous message (not the last) and by tapping a button.

Handing 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 Button Postback Actions

When a user taps a button that’s included in the most recent message, the button’s payload gets processed. This payload is a JSON object which can hold an action property and one or more payload variables (which are all 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 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. 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 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 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, the payload action has been specified, the action is not used to set the conversation transition. Instead, the unexpectedAction is triggered and the actual payload is stored in the user.botsUnexpectedAction variable. This allows you to have one generic state to handle all of the unexpected user actions and messages.
  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"
        unexpectedAction: "HandleUnexpectedAction"
...
  HandleUnexpectedAction:
    component: "System.Switch"
    properties:
      variable: "user.botsUnexpectedAction"
      values:
      - "pizza"
      - "pasta"
      - "order"
    transitions:
      actions:
        NONE: "ActionNoLongerAvailable"
        pizza: "OrderPizza"
        pasta: "OrderPasta"
        order: "AskPizzaSize"

So how can the System.List, System. CommonResponse, and System.Text components detect that a user scrolled up to a previous response and tapped a button? It’s because each of these components include the name of the state in the payload when the message is sent. Consequently, when a user taps an action in an older message, the state names no longer match and the unexpectedAction transition is triggered.

Handling Unexpected User Actions or Messages

When designing your dialog flow, you typically start modeling the “happy” flow, the path that the user is most likely to follow. But the user may be unpredictable and deviate from the happy flow. For example, users might enter free text instead of tapping a button, or scrolling to an earlier message and entering text, even when they’re expected to tap the button in the current response. The System.Text, System.CommonResponse, and System.List components enable your bot to handle unexpected user actions gracefully. Specifically, when a user enters free text, the component always triggers the textReceived action. When the user taps a button in an older message, the component triggers the transition to unexpectedAction and stores the payload action property in a user variable, such as user.botsUnexpectedAction in the following snippet:
  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
    transitions:
      actions:
        pizza: "OrderPizza"
        pasta: "OrderPasta"
        unexpectedAction: "HandleUnexpectedAction"
        textReceived: "Intent"
...
  HandleUnexpectedAction:
    component: "System.Switch"
    properties:
      variable: "user.botsUnexpectedAction"
      values:
      - "pizza"
      - "pasta"
      - "order"
    transitions:
      actions:
        NONE: "ActionNoLongerAvailable"
        pizza: "OrderPizza"
        pasta: "OrderPasta"
        order: "AskPizzaSize"
Adding an unexpectedAction transition to all of the states that process a user message handles situations where a user taps the button belonging to an older message, because this action tells the Dialog Engine to transition to a single state that handles all of the unexpected actions, such as the HandleUnexpectedAction state in the OBotML snippet above. You can use different approaches to create this state:
  • You can use the System.Output or System.CommonResponse component that outputs a message like “Sorry, this option is no longer available” along with a return: “done” transition to invalidate the session so that the user can start over. For example:
    ActionNoLongerAvailable:
        component: "System.Output"
        properties:
          text: "Sorry, this action is no longer available"
        transitions:
          return: "done"
    
  • Using a System.Switch component, you can enable your bot to honor some of the request actions by transitioning to another state.

Note:

Depending on the factors involved in honoring the request, you may need to create a custom component to implement the routing.
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
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 FinancialBot uses an intent called Dispute 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"

Conditional Components

Conditional 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. Yes
value The second value to be compared. 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:
    yesno: "YES_NO"
    
...

 confirmBuy:
    component: "System.ConditionEquals"
    properties:
      variable: "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"
You can define the value property using a value expression.
verifyCode:
    component: "System.ConditionEquals"
    properties:
      variable: "code"
      value: "${userEnteredCode.value}"
    transitions:
      actions:
        equal: "wrongCode"
        notequal: "${flow.value}"
 
...
  buyFlow:
    component: "System.SetVariable"
    properties:
      variable: "flow"
      value: "buyFlowSymbol"
    transitions:
      next: verifyCode
  buyFlowSymbol:
    component: "System.SetVariable"
    properties:
      variable: "stockSymbol"
      value: "${iResult.value.entityMatches['stockSymbol'][0]}"
    transitions: {}
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.

Property Description Required?
variable The name of the variable. yes
values The list of values that the Dialog Engine checks for. yes
Returns the value matched from the values list. If no matches are found, it returns NONE.
switchOnCategory:
    component: "System.Switch"
    properties:
      variable: "category"
      values:
      - "Vehicle"
      - "Property"
      - "Other"
    transitions:
      actions:
        Vehicle: "getVehicleQuote"
        Property: "getPropertyQuote"
        Other: "getOtherQuote"

Tip:

Similar to the System.ConditionEquals component, you can define the state that you want to navigate to as a variable. See System.ConditionExists.

Translation Components

Use these components if you’re configured a translation service.

System.DetectLanguage

Use this component to detect the user’s language.

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"

Custom Components

Your bot uses custom components when it needs to return data, execute some kind of business logic, or render channel-specific UI components like the carousel in Facebook Messenger.

Like the built-in components, the custom components are re-usable units of work that you define within each state node of your dialog flow. But unlike the built-in components, custom components perform actions that are specific to your bot. They execute functions that the system components can’t. While the FinancialBot uses system components for generic tasks like setting variables and outputting text, it uses custom components for the operations that are unique to banking transactions, such as returning account balances (BalanceRetrieval in the following state node, printBalance).
printBalance:
    component: "BalanceRetrieval"
    properties:
      accountType: "${accountType.value}"
    transitions:
      return: "printBalance"

Custom components don’t reside within Bots. Their functionality is provided through backend services that are accessed through calls made to, and returned from, a REST service called the Component Service. As the Dialog Engine enters a state in the dialog flow, it assesses the component. When it encounters one of the built-in components (noted by System.), it executes one of the generic tasks described in Built-In Components. When the Dialog Engine discovers a custom component, however, it calls the Component Service, which hosts one or more custom components.

The Component Service is like a shim. It first finds and then invokes the custom component on behalf of the Dialog Engine. When a custom component is invoked, it can pass input parameters to a backend service and return the result. The Dialog Engine then resumes, moving on to the next sate in the dialog flow (or to the state dictated by the action described in the returned JSON payload).

The Component Service assists the bot through two methods: GET and POST. The GET method returns the metadata for all of the components hosted by the Component Service. This is a design time call, one that returns the names of the components along with their properties and actions that you include in your dialog flow definition. At runtime, the POST method invokes the component named in the state definition.

The JSON payload of the call made by the Dialog Engine includes input parameters, variable values, user-level context, and the user’s message text. When the component gets this input from the Component Service, it mutates the variable values, and then returns the call. The Dialog Engine parses the returned payload and proceeds.

The Component Service

The Component Service doesn’t reside within Bots, but is instead hosted in a separate Node container. Because the Component Service is a REST service, you can implement using any language.

As pictured here, the Node container can be part of OMCe, but it can be part of any other REST infrastructure. If you opt for OMCe as the container for your custom components, you can integrate them with remote services using various connectors. Because they are implemented as custom code APIs, they can access the OMCe platform APIs (such as the Analytics API) through the OMCe SDK. There’s another advantage to implementing the Component Service in OMCe: you can get it up and running with minimal coding using the Bots SDK because it provides you with a starter application that gives you everything you need. To find out about the artifacts included in the SDK, see Implementing the Component Service in OMCe.

Note:

You can still integrate them with remote services if you use another Node container, but keep in mind that direct REST calls can give rise to additional concerns and tasks. With no backend to manage the connection, for example, you’ll need to update the code whenever the connection changes.
The Shell

The Shell routes the GET and POST requests. It produces a list of components in response to the GET call made by Bots when you register a Component Service. The Shell also invokes the component using the component name that’s appended to the POST call (POST uri/components/{ComponentName}). To respond to these requests, the Shell component references a file in the Registry component that maps the component names to their corresponding JavaScript implementation files.

The Registry

The Registry component maps each component to its implementation.

Within the Registry.js file, a JSON object definition surfaces the components to the Shell. Each component is described by a name-value pair in which the name is the name of the component (like ‘Balance Retrieval’ in the following import statement) and the value is a return function with a reference to the JavaScript module location relative to the Registry.js file (./). In this snippet, the three components, BalanceRetrieval, TrackSpending, and Payments are custom components, each of which map to a separate JavaScript module. The require function includes these separate modules in the Registry.js file.
'use strict';

module.exports = {

'BalanceRetrieval': 
require('./banking/balance_retrieval'),

'TrackSpending': 
 require('./banking/track_spending'),

'Payments': 
require('./banking/payments')}

Tip:

Declare strict mode (‘use strict’) at the beginning of the Registry.js file to safeguard against the inadvertent creation of global variables from erroneous user input. The strict mode improves error checking by throwing exceptions for errors that would otherwise occur silently, like values set on a read-only property.
Because the Shell.js component assumes that it shares the same file location as the Registry.js , the Shell.js file uses the following import statement:
var registry = require('./registry'); 
Remember that you don’t need to edit the Shell.js file. You just need to make sure that it’s in the same directory with the Registry.js module (and if you’re using OMCe, the SDK.js module as well).
Component Modules

Each component is written as JavaScript module. If you’re writing one of these modules, then you need to include two functions that mirror the GET and POST calls in the Component Service REST contract: metadata and invoke. You also need to conclude the module with the callback function,done.

The metadata function provides the component descriptions that you use when you define your dialog flow. It includes a name (which must be unique), and the names and types of the input parameters that it expects. It also includes the actions supported by the component. For example:
metadata: () => ({
    "name": "helloWorld",
    "properties": {
      "properties": {
        "name": {
          "type": "string",
          "required": false"
      }
    },
    "supportedActions": ["nameFound", "nameNotFound"]
  }),      
The invoke function executes the REST call. It includes two arguments: conversation, which is a reference to the SDK and done, a callback invoked by the component when it has finished processing. The done function tells the Shell to create the component’s response payload and send it back to the bot.

Important:

Always include the done() callback at the end of each component. The component can’t send its response without it and as a result, the bot will time out.
module.exports = {
    metadata: () => (
    {
        "name": "BalanceRetrieval",                   },
        "properties": {
                "accountType": { "type": "string", "required": true }
            },
            "supportedActions": []
        }
    }, 
...

invoke: (conversation, done) => {
      var accountType = conversation.properties().accountType;
...

      var accounts = AccountService.account(accountType);

...
      done();

         }
};
Along with the component name and properties that get returned during design time by the invoke function, this code sample shows how the invoke function uses one of the SDK’s helper methods (conversation.properties) to retrieve the value of the accountType from the payload of the POST request. With the value retrieved, the custom code can use it to call connectors or other APIs running in OMCe.

Note:

The invoke function enables access to the OMCe platform APIs using the conversation.OracleMobile object. To find out how to instrument the custom component code to call the Analytics API (conversation.oracleMobile.analytics.postEvent), see Setting up the PizzaBot Custom Component.
The SDK

If you implement the Component Service with OMCe, you can also leverage the SDK, whose helper methods enable the components to access the context of a bot’s request messages, which can be comprised of elements that describe the variable values, the language processing results, the extracted entities, and any input parameters that have been defined for the component. The SDK also enables the components to return a response to the bot.

The Shell passes the SDK to the custom components with each call to the invoke function. To access the SDK’s methods, the invoke function uses an argument called conversation, which is automatically passed with each request along with the essential done () callback that signals the Shell when the component has completed its work.
invoke: (conversation, done) => {

    var listdata = 
        "item1, item2, item3";

    conversation.variable("listDataVar", listdata);
    conversation.transition();
    conversation.keepturn(true);

    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. See NLP Components.
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 Message Model
The Message Model is a utility class that creates and validates the message structure. An instance of this class is instantiated with the payload that represents the message so that the message can be parsed and validated.

Note:

Version 1.1 of the Bots SDK lets you leverage the Conversation Message Model (the CMM), a framework that defines various platform-agnostic templates for the messages sent between the bot and its users. Not only does the CMM allow your bot to output messages as loops of cards that have actions configured for both the images and buttons that display within each of them, it also gives your bot other capabilities as well, such displaying context- specific messages and allowing users to share locations or upload audio, video, file, or image attachments. The Bots SDK documentation describes how you integrate the CMM into the code for your custom components, the methods for different types of message formats, and how you can upgrade your custom component service to use the CMM.
Implementing the Component Service in OMCe

While you can use the Shell and Registry components in any REST framework that produces a JSON object from the incoming request, you can only use the SDK’s helper methods if you implement the Component Service in OMCe. To use the SDK and get ready-made versions of the Shell and Registry, you need the Bots SDK.

Accessing the Bots SDK

You can get the Bots SDK (omce-bots-sdk-version_number.zip) from the Oracle Mobile Cloud Enterprise Downloads page. You can also access this page by clicking Downloads in the left navbar.

After you unzip the file, open the api_implementation folder. It contains the following artifacts that you modify to build your service. It includes JavaScript files for the Shell, Registry and the SDK (shell.js, registry.js, and sdk.js). It also includes the following:
  • mcebots.js—Contains the generic component logic. You copy and paste this into your own component service.

  • package.json—Contains the node.js module dependencies required for the project’s package.json file.

  • mcsbots.raml—A template for creating the OMCe custom API.

Creating the Component Service in OMCe

You can find out more in Custom APIs, but the process in terms of the custom components is as follows:
  1. Define the GET and POST endpoints—You can define these endpoints on your own, or use the starter RAML template (mcebots.raml).

    1. In OMCe, click New API.

    2. Enter the API name, a description, and a short description.

    3. Drag mcebots.raml into the dialog and then click Create.

  2. If you want to enable anonymous access, click Security in the left navbar and then switch off Login Required.

  3. Click Save.

  4. Download the JavaScript scaffold:
    1. Click Implementation in the left navabr.

    2. Choose Download JavaScript Scaffold.

    3. Unzip the scaffold file. This file contains the following:
      • The component service file—This file, which is named after your API, contains the REST endpoints defined for OMCe custom code APIs.

      • package.json—The project configuration file. It includes a list of module dependencies.

  5. Implement the Custom Component:

    1. Within the scaffold file, add a directory with the SDK, Registry, and Shell modules.

      Note:

      The Shell, Registry, and SDK components must reside within the same directory as the Component Service.
      This is an image of the SDK, Registry, and Shell in the implementation file.
    2. Implement the scaffold’s JavaScript to add the custom component logic. To do this, you’re going to replace most of the contents of the component service file with those of the mcebots.js file from the Bots SDK:
      1. Open the component service file in the JavaScript editor of your choice.

      2. Note the service.get function URI. It looks something like /mobile/custom/MyFirstComponentService/components.

      3. Delete all of the contents of the file except for the comments at the top of the file.

      4. Open the mcebots.js file and then copy its contents to the component service file.

      5. Replace the value of const apiURL = ‘/mobile/custom/bots/components’; with the value of the service.get function. For example, const apiURL = ‘//mobile/custom/MyFirstComponentService/components’;.

      6. Point to the shell.js file. Because the component service file and the directory containing the Bots SDK artifacts (which includes the shell.js file) are not located in the same folder, you need to modify the Shell variable’s ./shell parameter to reference the location of the shell.js file. For example, if shell.js resides in a directory called js, you would change the default parameter from this:
        var shell = require('./shell')();
        to this:
        var shell = require('./js/shell')();
      7. Save the file.

    3. Edit the package.json file in the scaffold file with the Bot SDK dependencies in the package.json file from the Bots SDK:

      1. Open the Bots SDK’s package.json file in the text editor of your choice and then copy and paste its dependencies definition to a clipboard:
          "dependencies": {
            "joi": "^9.2.0"
          },
      2. In the scaffold’s package.json file, paste the definition on its own line, one directly after the “main”: attribute.

  6. Create the custom component module by creating a JavaScript file. This file includes the metadata and invoke functions described in Component Modules. The scaffold for the file looks like this:
    "use strict";
    
    module.exports = {
            metadata: () => (
            {
                "name": "sample.hello",
                "properties": {
                    "name": { "type": "string", "required": true }
                 },
                 "supportedActions": []
            }
        ),
        invoke: (conversation, done) => {
            const name = conversation.properties().name ? conversation.properties().name : '';
            conversation.reply({ text: 'Hello ' + name });
            conversation.transition();
            done();
        }
    };
    Use the functions exposed by the SDK to allow interactions with the bot’s request payload. See The SDK Helper Methods.

    Important:

    All custom component files must reside within the same directory. Also, make sure that all of your component files all have the .js extension.
  7. Edit the registry.js file with the name and location the component file.

  8. Install the node modules.

  9. Package the scaffold and upload the node project to OMCe.

  10. Associate the custom API with a backend and then test your API.

  11. Register the component service with Bots so that it can be discovered by the Dialog Engine. To do this first click Components (This is an image of the Components icon.) in the left navbar and then Add Service. Complete the dialog by adding a name, selecting Mobile Cloud, and then by providing the following:
    • Backend ID—This value is generated when you create a mobile backend. It’s listed on the Settings page.

    • Metadata URL—The is custom API URL, which is displayed in the Overview panel of the API Designer when you click the GET method in the

      Important:

      Be sure to append this URL with /components so that it can return the component information in the Bot Builder’s Components page.
    • The user name and password. If you selected Use anonymous Access, you need to provide the Anonymous Key. This value is generated when you create a backend. It’s displayed on the Settings page for the backend that manages your API.

    You’re now ready to add the custom components to your OBotML definition.

Configuring Services for Custom Components

Configuring a custom component service makes custom components available to your bot’s dialog flow.

A custom component service defines name of the custom component service implementation that provides the bot with its custom components. This configuration also includes that URL that invokes this service and the basic authentication settings that allow the bot to access the service itself. Each bot can have one or more of these custom component services configured for it. By configuring a custom component service, you allow Bots to query the service for its metadata and display this information in the custom components registry. You can refer to this page (accessed by clicking This is an image of the Components icon.) as you write your OBotML definition.

Note:

Every custom component that you’ve declared in your OBotML definition needs a corresponding custom component service configuration. In other words, your bot can’t work without this configuration, which allows Bots to call the custom code service implementation that defines the components.

This is an image of the custom components registry.
How Do I Create a Custom Component Service?
The Custom Component Service authenticates the bot with the service using basic auth. You can implement this on your authentication mechanism, or if you use the node.js SDK, your bot can authenticate through a mobile backend. To create this service:
  1. In the left navbar, click Components (This is an image of the Components icon.).
  2. Click the Component Services and then open the Create Service dialog by clicking Add Service .
    This is the Create Service dialog.
  3. Complete the Create Service dialog by adding a service name and, to enable the metadata to display in the Components page, the URL that points to the root of the service. If your service requires specific parameters, click Add HTTP Header and then define the key-value pairs for the headers.
    If your bot doesn’t authenticate through a backend, choose Basic. Otherwise, use the default option, Oracle Mobile Cloud–enterprise (OMCe). To complete the following parameters, you’ll need to reference the Settings page for the backend that hosts the API that implements the Custom Component Service. You can find out more about in Backend Authentication and Connection Info.
    This is an image of the mobile backend Settings page.
    • Use Anonymous Access—Enter the Anonymous Key, a unique string that allows your app to access anonymous APIs without sending an encoded username and password combination. The Anonymous Access Key is passed to OMCe instead.

    • Backend ID—The unique identifier assigned to a mobile backend. This ID, which associates a mobile app with its mobile backend, is passed in the REST header of every call made from a mobile app to OMCe. All mobile apps associated with a mobile backend use the same mobile backend ID.

    • Username and Password—The user name and password.

  4. Click Create.