User Interface Components

These are the components that are available in the User Interface category of YAML-based dialog flow editor.

Use these components to display text and interface with the user:

System.CommonResponse

The System.CommonResponse component enables you to build messages with rich UI features like card carrousels with images and action buttons, or forms with tables and input fields.

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see Common Response Component Templates.

Templates for the System.CommonResponse are available in the User Messaging section of the Add Component dialog.

How you build messages based on this component depends on the skill's dialog mode. In the YAML mode, you edit the OBotML component state templates. The process is simplified in the Visual Mode, where you can create these rich UI messages by just updating the fields and response item metadata in the property window of the Common Response component-based user messaging templates. For YAML-based skills, 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.

Description of crc_pizzabot.png follows

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.

From the Add Component menu, you can select different System.CommonResponse templates for cards, text, attachment responses, and for composite bag entities (demonstrated by the CbPizzaBot). These templates include both properties that are common to all of these response type properties that are specific to the individual response types. While the Add Component 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.

Note

You should test each skill in your target channels early in the development cycle to make sure that your components render as desired.

The Component Properties

Configuring System.CommonResponse components entails 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.

Name Description Required?
metadata The chat response created by this component is driven by the contents of the metadata property. See The Metadata Property in Common Response Components. 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).

Set this property to true when setting a location.

Yes
autoNumberPostbackActions This property is used for composite bags, text responses, card responses. When set to true, this option prefixes numbers to options. Even when you haven’t set this option to true, auto-numbering can be enforced on card items when the digital assistant’s Enable Auto Numbering on Postback Actions configuration is set to true. As demonstrated by its default configuration, channel-specific auto-numbering can be applied to any skill bot that registered to a digital assistant (${(system.channelType=='twilio')?then('true','false')}): No
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.

For composite bag entities, reference the composite bag entity variable. Users get prompted for the individual entity values in the bag. When all the entity values are set, the component transitions to the next state.

No
nlpResultVariable Sets the variable property with an entity value (when that entity value hasn’t already been set for the referenced variable). You can enable nlpResultVariable to return value when you define it using a variable that holds the NLP results (such as iResult: "nlpresult" that’s used in our sample bots). By doing this, the nlpResultVariable property can still populate the value when it’s null if it finds a resolved entity that matches the one referenced by the variable. The dialog transitions to the next state when the nlpResultVariable sets the value. You can use this property in place of the System.SetVariable component. No
useFullEntityMatches When set to true, custom entity values are stored as JSON objects (similar to built-in entity values). This enables you to create expressions to access properties such as value, primaryLanguageValue, and originalString, which are particularly important for skills that are currently or eventually might become multi-lingual. 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 continued inability to enter a valid value, use this property to set a limit on the number of attempts given to the user. When the user exceeds this allotment, the System.CommonResponse component transitions to the cancel action. See Limiting the Number of User Prompts.

As described in Create a Composite Bag Entity, individual entities in the composite bag can override this setting when the Maximum User Input Attempts option is set.

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 Translation Services in Skills. No
footerText Enhances the output on text-only channels. As described in Footers, you can use FreeMarker expressions to conditionalize the footer text for text-only channels. No
transitionAfterMatch (deprecated) A boolean that, when you set it to true, enables a temporary transition from the entity matching performed by this component to another state. This property is no longer supported. To get this functionality, use an entity event handler No
cancelPolicy Determines the timing of the cancel transition:
  • immediate—Immediately after the value set for the bag item’s Maximum User Input Attempts has been met. If this value has not been set, then the component fires this transition when the component-wide maxPrompts value has been met.

  • lastEntity—When the last entity in the bag has been matched with value.

This property is ignored if you've registered an entity event handler with an item- or event-level maxPromptsReached handler.
No

Here's the YAML for an example state based on the System.CommonResponse component.

  AskPizzaSize:
    component: "System.CommonResponse"
    properties:
      variable: "pizzaSize"
      nlpResultVariable: "iresult"
      maxPrompts: 2
      metadata:
        responseItems:
        - type: "text"
          text: "<#if system.invalidUserInput == 'true'>Invalid size, please try again.\
            \ </#if>What size do you want?"
          name: "What size"
          separateBubbles: true
          actions:
          - label: "${enumValue}"
            type: "postback"
            payload:
              action: ""
              variables:
                pizzaSize: "${enumValue}"
            name: "size"
            iteratorVariable: "pizzaSize.type.enumValues"
      processUserMessage: true
    transitions:
      actions:
        cancel: "Intent"
      next: "AskLocation" 

Tip:

The text property in this snippet is defined using Apache FreeMarker Template Language (FTL). To find out how to add FTL expressions and use FreeMarker built-in operations to transform variable values, see Apache FreeMarker Template Language Syntax.

Transitions for the System.CommonResponse Component

Common Response components use the following transitions.
Transition Description
cancel Triggered when a user exceeds the allotted attempts set by the maxAttempts property, or redirect the flow .
textReceived Triggered when a user sends text or emojis instead of tapping an action button or link.
attachmentReceived Triggered when a user sends an image, audio, video, or file attachment.
locationReceived Triggered when the user sends a location.
system.outOfOrderMessage 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.

Composite Bag Transitions in the System.CommonResponse Component

These System.CommonResponse components triggers the match and cancel actions based the values matched from the user input and on your configuration of the cancelPolicy property.
Action Description Required?
match The component triggers this action to navigate to the specified state when at least one entity in the bag has matched the user input. No
cancel The component triggers this action to navigate to the specified state based on the setting for the cancelPolicy property. No

System.Webview

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see Webview Component.

The System.Webview component opens a webview within your skill, or for skills that run in a web channel, in an browser tab.

System.WebView Component Properties

Property Description Required?
sourceVariableList A comma-separated list of context or user variable names. These variable names are the parameters that are sent to the webview; they’re the input parameters from your bot. You can set each variable by adding a series of System.SetVariable states before the System.Webview state. Yes
variable The name of the variable (a string value) that identifies the webview payload that’s returned to the bot after the user completes his or her interactions within the webview.

Because the payload is stored in this variable, which you can access at a later point in your dialog flow definition. For example, you can reference this in an output component.

Yes
prompt A text string like “Tap to continue.” No
service The name of the webview component service. No
imageUrl The URL to the image that accompanies a prompt. No
linkLabel The label for the button that invokes the web app. No
cancelLabel The label for the Cancel button that lets users leave the state without invoking the web app. No
autoNumberPostbackActions Enables user input in SMS channels, which don’t support buttons, by adding number equivalents to the UI elements.
  • false—Overrides the global autoNumberPostbackActions variable.

  • true

    Prefixes the Cancel button with a sequence number, which when entered, executes the button postback payload as if the user tapped the button rather than enter its number equivalent.
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 Translation Services in Skills. No

Transitions for the System.Webview Component

Transitions Description
next Names the next state in the dialog flow after the successful callback from the web app.
return Exits the conversation after the successful callback from the web app.
error Names the state that handles errors.
actions
  • cancel—Names the state that handles the "user taps cancel" scenario.
  • textReceived—Names the state when users enter text rather than tapping one of the buttons.

System.IncidentCreation

You can use the System.IncidentCreation component to create an incident on a customer service site. Note that you must create a customer service integration from the Settings > Additional Services > Customer Service Integration page before you can use this component in your instance.

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see Incident Creation.

Here's an example of using this component to transfer the conversation back to a Oracle B2C Service site.

  component: "System.IncidentCreation"
    properties:
      serviceName: "IncidentService"
      subject: "${incident.value.subject}"
      attachmentUrl: <#if (incident.value.Attachment.url)??>${incident.value.Attachment.url}<#else></#if>
      customFields: 
        description: "${incident.value.description}"
        contactInfo: "<#if (profile.contactInfo)??>${profile.contactInfo}<#else></#if>"
      contactProperties: 
        firstName: "${profile.firstName}"
        lastName: "${profile.lastName}"
        email: "${incident.value.email}"
      incidentNumberVariable: "incidentNumber"
    transitions:
      error: "incidentError" 
      next: "exitIncident"

And here's an example for Oracle Fusion Service:

  component: "System.IncidentCreation"
  properties:
    serviceName: "IncidentServiceB2BEndUserAuth"
    subject: "${service.value.subject}"
    attachmentUrl: <#if (service.value.Attachment.url)??>${service.value.Attachment.url}<#else></#if>
    agentReportFilter: "ODAQueue"
    addChatTranscript: "true"      
    customFields: 
      description: "${service.value.description}"
      contactInfo: "<#if (profile.contactInfo)??>${profile.contactInfo}<#else></#if>"
    contactProperties: 
      firstName: "${profile.firstName}"
      lastName: "${profile.lastName}"
      email: "<#if (profile.email)??>${profile.email}<#else></#if>"
    incidentNumberVariable: "incidentNumber"
  transitions:
    error: "incidentError" 
    next: "exitIncident"
Property Description Required?
serviceName The name of the integration as configured in Settings > Additional Services > Customer Service Integration. Yes
subject The text for the subject of the incident. Yes
attachmentUrl The URL of a document or image that's related to the incident. Note that adding attachments is not supported for DA as Agent skills. No
agentReportFilter (For Oracle Fusion Service incidents), text to filter the incidents. The default value is ODA. No
addChatTranscript (For Oracle Fusion Service incidents only.) When set to true, chat transcript is added to the incident. Defaults to false.

Insights must be enabled for the skill in order for the chat transcript to be made available.

A transcript can only be added to the incident when using a DA as an Agent integration in combination with Web Chat for Service or Oracle Inlay Toolkit inlays.

No
customFields A map that contains the description and, optionally, contactInfo, which can contain additional details about the incident.

The map is passed unvalidated as a text version of the object and inserted into the incident message as a private note.

No
contactProperties A map of name/value pairs that contains the information that's required to look up or create customer service contact information. It must contain email, and can optionally contain firstName and lastName.

If email isn't provided, then you must provide both firstName and lastName.

Only for Oracle B2C Service
incidentNumberVariable The name of the string context variable in which to store the incident number. No

System.IntelligentAdvisor

Use this component to access an Oracle Intelligent Advisor interview from a skill.

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see Intelligent Advisor.

You must create an Intelligent Advisor service integration before you can use this component. See Add an Intelligent Advisor Service. In addition, the interview must have been deployed to the Intelligent Advisor Hub and activated on the chat service channel. The interview must be for anonymous users. You can't access interviews for portal users or agent users.

You can use the component's properties to specify the following interview settings:

  • Whether to display the titles and the explanation
  • The labels for the yes, no, and uncertain buttons
  • The strings that the user enters to reset, go back to the previous question (undo), and exit the interview
  • The text to display at the end of the interview
  • How to phrase the question about whether to display the explanation
  • The string the user enters to indicate they are done uploading files
  • The attribute values and connector params to pass to the interview
  • The project locale to use

Here's an example:

  loanAdvisorIA:
    component: "System.IntelligentAdvisor"
    properties:
      intelligentAdvisorService: "myService"
      deployment: "Loan Advisor"
      # default yesLabel: "yes"
      # default noLabel: "no"
      uncertainLabel: "not sure"
      endLabel: "You can ask me another question if there's something else that I can help
    you with."
      # default doneLabel: "/done"
      # default undoLabel: "/back"
      # default resetLabel: "/reset"
      # default exitLabel: "/exit"
      showExplanation: "ask"
      # default explanationAskLabel: "Do you want to see the explanation?"
      # default removeHtml: false        
    transitions:
      error: "handleIAError"
      next: "endOfFlow"

  handleIAError:
    component: "System.Output"
    properties:
      text: |
        We are having a problem with a connection.
        Can you please send email to 
        contact@example.com to let them know that
        the loan advisor isn't working? Thank you.
    transitions:
      next: "endOfFlow"
      

See Use the Intelligent Advisor Component in Your Skill for an example that uses the component in a dialog flow.

Tip:

The default values for all the label properties are stored in the skill's resource bundle. To change a default, open the skill's Resources Bundle page, click Resource Bundles icon, select the Configuration tab, and change the message for the IntelligentAdvisor - <property name> key. If you use the skill's resource bundle to change the default, then you don't need to include the label property in the component unless you want to override the default.

The configuration resource bundle also allows you to change the IntelligentAdvisor - defaultValue, IntelligentAdvisor - doneHelp, IntelligentAdvisor - maskLabel, IntelligentAdvisor - outOfOrderMessage, IntelligentAdvisor - resumeSessionPrompt, IntelligentAdvisor - numberMinMax, IntelligentAdvisor - outOfOrderMessage, IntelligentAdvisor - resumeSessionPrompt, and IntelligentAdvisor - yesNoMessage messages. For example, the IntelligentAdvisor - doneHelp message is output for attachment fields, and it defaults to When you are done with the upload, say {0}. You might want to change it to something like Say {0} to let me know that you are done uploading.

Property Description Required?
currency The ISO-4217 currency code for the currency that's used in the interview. When this code is specified, the user only can input currency values in the formats that are allowed for that currency. You can set this property to blank or exclude it if the interview doesn't prompt for currency amounts or is not expecting any certain currency. No
deployment The name of the active deployment project on the Intelligent Advisor Hub. Yes
doneLabel The text that the users type to indicate that they are done uploading a file.

The default is /done.

No
endLabel Text to display in the chat at the end of the interview.

The default is Interview ended. You can set the property to "" to prevent text from being displayed.

No
exitLabel The text that users type to indicate that they want to exit the interview.

The default is /exit.

No
explanationAskLabel The question to ask when showExplanation is set to ask.

The default is Do you want to see the explanation?

No
hideScreenTitle Indicates whether to hide all the screen titles in the interview.

The default is false, meaning that the screen titles must be displayed.

No
intelligentAdvisorService The name of the Intelligent Advisor service as configured in Settings > Additional Services. Yes
interviewAttributes The name of a context variable of type string in which to store the interview's attribute values. The attribute values are stored as an array of key/value pairs. No
locale

This property affects both the target interview and date and number resolution.

The component initiates the version of the named interview (deployment) that's associated with the language specified by the component's locale property. If there isn't a Hub deployment for the specified locale, then the component uses the default locale that's associated with the deployment.

For date and number input, the values are resolved per the DATE and NUMBER entity settings. When Consider End User Locale is switched to On for the entity, then the value is resolved for the locale that is specified by this property (or the default if not specified). See Locale-Based Entity Resolution.

This property defaults to the profile.locale value. If profile.locale doesn't have a value, then it uses the channel's locale.

No
noLabel The label to use to represent Boolean FALSE values.

The default is No.

No
params A map of key-value connection parameters to pass upon the start of interview. This is typically needed for interviews with external data integration. No
removeHtml Indicates whether to remove the HTML markup from the text. The default is false. No
resetLabel The text that users type to indicate that they want to go back to the first question.

The default is /reset.

No
seedData A map of Intelligent Advisor attribute names and values to pass to the interview. For date and time attributes, use the standard Intelligent Advisor date and time formats. For example: start_date: "2010-01-31".

The attribute that you are passing the value to must have the Seed from URL parameter option enabled in Policy Modeling.

No
showExplanation Specifies whether to show the Intelligent Advisor explanation. The allowed values are never, always and ask.

If you set to ask, then use the explanationAskLabel property to specify the text for asking if the user wants to see the explanation.

The default is never.

No
uncertainLabel The label that the user can type if they don't know the value. This label appears for optional Boolean radio buttons.

The default is Uncertain.

No
undoLabel The text that the users type to indicate that they want to go back to the previous question.

The default is /back.

No
yesLabel The label to use to represent Boolean TRUE values.

The default is Yes.

No

Example: Use the Intelligent Advisor Component in Your Skill

  ####################    
  # Loan Advisor
  ####################

  loanAdvisorStart:
    component: "System.Output"
    properties:
      keepTurn: true
      text: |
        OK, I can initiate a loan request for you.
        But first I'll transfer you to an 
        automated advisor that will ask some
        questions about the loan that you want, 
        your assets, your liabilities, and your 
        financial history. It shouldn't take 
        more than 5 minutes.
        <#if (user.notFirstTime)??><#else>
        At any time, you can say 
        /back to go to the previous question, 
        /reset to start over or 
        /exit to stop the questions.</#if>
    transitions:
      next: "setNotFirstTime"
      
  setNotFirstTime:
    component: "System.SetVariable"
    properties:
      variable: "user.notFirstTime"
      value: true
    transitions:
      next: "loanAdvisorIA"  
      
  loanAdvisorIA:
    component: "System.IntelligentAdvisor"
    properties:
      intelligentAdvisorService: "myService"
      deployment: "Loan Qualifier"
      # default yesLabel: "yes"
      # default noLabel: "no"
      uncertainLabel: "not sure"
      endLabel: " "
      # default doneLabel: "/done"
      # default undoLabel: "/back"
      # default resetLabel: "/reset"
      # default exitLabel: "/exit"
      showExplanation: "ask"
      # default explanationAskLabel: "Do you want to see the explanation?"
      interviewAttributes: "interviewDetails"      
    transitions:
      error: "handleIAError"
      next: "handleEligibility"

  handleEligibility:
    component: "System.Switch"
    properties:
      source: <#list interviewDetails.value as i><#if i.key = 'eligibility'>${i.val}</#if></#list>
      # The values that are matched against the value of the variable or source property. The value that matches is set as transition action
      values:
      - "eligible"
      - "noteligible"
    transitions:
      actions:
        eligible: "initiateLoan"
        noteligible: "suggestNextSteps"
        NONE: "handleUnexpectedAttributeValue" # the attribute value was other than eligible or noteligible or the user exited interview
      error: "handleAttributeNotSet" # the attribute wasn't set during the interview or the key is incorrect

  handleIAError:
    component: "System.Output"
    properties:
      text: |
        We are having a problem with a connection.
        Can you please send email to 
        contact@example.com to let them know that
        the loan advisor isn't working? Thank you.
    transitions:
      next: "endOfFlow"
...
      

Example: Access Interview Attributes

Here's a simple example of accessing an interview's attribute values:

context:
  variables:
    iResult: "nlpresult"
    interviewDetails: "string"

states:
  ...
  loanAdvisorIA:
    component: "System.IntelligentAdvisor"
    properties:
      intelligentAdvisorService: "myService"
      deployment: "Loan Qualifier"
      # default yesLabel: "yes"
      # default noLabel: "no"
      uncertainLabel: "not sure"
      endLabel: " "
      # default doneLabel: "/done"
      # default undoLabel: "/back"
      # default resetLabel: "/reset"
      # default exitLabel: "/exit"
      showExplanation: "ask"
      # default explanationAskLabel: "Do you want to see the explanation?"
      interviewAttributes: "interviewDetails"      
    transitions:
      error: "handleIAError"
      next: "handleEligibility"

  handleEligibility:
    component: "System.Switch"
    properties:
      source: <#list interviewDetails.value as i><#if i.key = 'eligibility'>${i.val}</#if></#list>
      # the values that are matched against the value of the variable or source property. The value that matches is set as transition action
      values:
      - "eligible"
      - "noteligible"
    transitions:
      actions:
        eligible: "initiateLoan"
        noteligible: "suggestNextSteps"
        NONE: "handleUnexpectedAttributeValue" # the attribute value was other than eligible or noteligible or the user exited interview
      error: "handleAttributeNotSet" # the attribute wasn't set during the interview or the key is incorrect
  ...

System.KnowledgeSearch

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see Knowledge Search.

Use this component to search Oracle B2C Service Knowledge Foundation or Oracle Fusion Service Knowledge Management for information about a given search term and to display the results.

For Oracle B2C Service, the results that the service returns depend on whether the answers are public and what the access level, product, or category settings are.

Note that you must create a knowledge search service before you can use this component. See Add a Knowledge Search Service.

Here's an example of using this component. It searches a Knowledge Management service for all information that's related to the user's last utterance. For additional examples, see Use the Knowledge Search Component.

  searchFor:  knowledgeSearch:
    component: "System.KnowledgeSearch"
    properties:
      searchServiceName: "myKnowledgeSearch"
      searchTerm: "${iResult.value.query}"
      searchPrelude: "I don't know the answer for that. Let me search for an answer."
      resultSizeLimit: 5
      resultVersion: "Special Response"
      resultVersionExclusive: true
      resultLinkLabel: "Show More"
      searchLinkLabel: "Open Page with All Answers" # For B2B set to "Go to search home page"
      noResultText: "I don't have an answer for that. Try rephrasing your question."
    transitions:
      actions:
        resultSent: "reset"
        noResult: "reset"
        serverError: "handleSearchServerProblem"
      error: "handleSearchError"
      next: "reset"  

Tip:

The default values for the defaultAttachmentLabel, noResultText, and resultLinkLabel properties are stored in the skill's resource bundle. To change a default, open the skill's Resources Bundle page, click Resource Bundles icon, select the Configuration tab, and change the message for the KnowledgeSearch - <property name> key. If you use the skill's resource bundle to change the default, then you don't need to include the property in the component unless you want to override the default.
Property Description Required?
cardLayout Specifies whether to display the result cards vertically or horizontally. Defaults to horizontal. No
customFilters A list of search result filters presented as name-value pairs. The allowable filter names are product and category. Each of them allows only one filter declaration. See Filter Results by Product and Category. No
customProperties Oracle B2C Service only: A map of key/value pairs to send to the search service. Currently, this property supports only the word_connector key. You use the word_connector property set to AND to prepend every word in the search term with +. No
defaultAttachmentLabel

The default label to use for the result card's URL action that's linked with an attachment whenever the attachment doesn't have a configured display name. When used, it's appended by an index number. For example, if the second attachment doesn't have a display name, then the default attachment label is appended with 2.

Defaults to Download.

No
locale Defaults to the value of the profile.locale variable.

For Oracle B2C Service multi-interface knowledge integration services, the five-character ISO or BCP locale code that specifies which interface to use to perform the search (example: en_GB). If there isn't an interface that supports the locale, then the default interface is used. See Implement Multi-Lingual Knowledge Search.

For Oracle Fusion Service it fetches the articles that are associated with the specified locale. If matching articles don't exist for the locale, it returns noResult.

No
noResultText

The text to output when no search result is available.

Defaults to the text from the KnowledgeSearch - noResultText resource bundle entry

No
resultLinkLabel

The label to use for the result card's URL action (button) that links to the web version of the information.

Defaults to the text from the KnowledgeSearch - resultLinkLabel resource bundle entry

If you set this property to ${r""} then the result link button is not displayed and the full text is output. This is not recommended if you have very long articles that would be hard to read in a typically-sized skill widget.

No
resultSizeLimit

The maximum number of results to display.

The default is 10.

No
resultVersion

Oracle B2C Service only: The preferred version to return when there are multiple versions for a result.

You can set this property to either Answer or Special Response.

You can leverage special responses to display output that's specifically tailored for chat conversations as opposed to web pages.

The default version is Answer. The default might change in a later release.

No
resultVersionExclusive

Oracle B2C Service only: Specifies whether only results that are available in the preferred version should be displayed.

When false, it first includes all matching answers that are available with the preferred version (resultVersion). If the number of included answers is less than the limit, then it continues to include answers in the non-preferred version until the limit is met.

The default is false.

No
searchLinkLabel

Oracle B2C Service: The label to use for the card message payload action that's linked to the web page with the full search result list.

Oracle Fusion Service: The label to use for the card message payload action that's linked to the home search page.

If this property isn't set, then the card message payload doesn't display the action.

No
searchPrelude

The text to output before the search result is displayed.

If this property isn't set, then the text from the KnowledgeSearch - searchPrelude resource bundle entry is output.

If you don't want the search prelude to be displayed, then set this property to ${r""}.

No
searchServiceName The name of the knowledge search integration as configured in Settings. Yes
searchTerm The text to use as the search term for the knowledge search invocation. A search term is required for Oracle Fusion Service Knowledge Management. For Oracle B2C Service Knowledge Foundation, it returns the most popular articles if no search term is provided.

For search term techniques, see Use the Knowledge Search Component.

Yes

System.KnowledgeSearch Transitions

Action Description
resultSent The search returned at least one result.
noResult There were no results for the search term.
serverError An error occurred on the knowledge search service's server during the invocation, such as a server error fault or an unexpected error fault.

When this error occurs, the error message is stored in system.state.<state-name>.serverError.message.

Example: Associate Related Questions with a Search Term in a YAML Dialog Flow

The following diagram illustrates how to implement the single-state method if your dialog flow is created in YAML mode. 1) You use a map context variable to associate the knowledge intents with search terms. 2) You set each knowledge intent's action in the Intent state to transition to a data flow that uses the map to set the searchTerm context variable to the intent's search term. 3) You then transition to a state that searches the knowledge base for the searchTerm value.

Description of kf-assoc-intent-term.png follows

Here's an example of a dialog flow in which there are individual intents for each knowledge base answer.

context:
  variables:
    iResult: "nlpresult"
    intentName: "string"
    searchTerm: "string"
    searchTerms: "map"
    someVariable: "string" # For the reset state

states:

  #
  # Set search term for each knowledge intent
  #

  setSearchTerms:
    component: "System.SetVariable"
    properties:
      variable: "searchTerms"
      value:
        knowledge.Shipping Return Costs: "Shipping Return Costs"
        knowledge.Locate Service Tag or Serial: "Locating Your Service Tag or Asset Serial Number"
        knowledge.Support Account: "My Support Account"
        knowledge.Product Registration: "How do I register my product?" # (1)
        knowledge.Noncontiguous Delivery Time: "What is the delivery time to Alaska, Hawaii and the U.S. Territories?"
        knowledge.Return Policy: "What is your return policy?"
    transitions:
      next: "intent"
  
  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
    transitions:
      actions:
        system.Greeting: "welcome"
        system.Unsatisfactory Response: "transferToAgent"
        system.Request Agent: "transferToAgent"
        knowledge.Shipping Return Costs: "startIntentKnowledgeSearch"
        knowledge.Locate Service Tag or Serial: "startIntentKnowledgeSearch"
        knowledge.Support Account: "startIntentKnowledgeSearch"
        knowledge.Product Registration: "startIntentKnowledgeSearch" # (2)
        knowledge.Noncontiguous Delivery Time: "startIntentKnowledgeSearch"
        knowledge.Return Policy: "startIntentKnowledgeSearch"
        unresolvedIntent: "genericKnowledgeSearch"

  #
  # Start knowledge search for a knowledge intent's search term
  # based on searchTerms context variable
  # 
  # First, reset variables
  #
  
  startIntentKnowledgeSearch: # (2)
    component: "System.ResetVariables"
    properties:
      variableList: "searchTerm, intentName"
    transitions:
      next: "setIntentName"
      
  # 
  # Set the intentName context variable
  #
  
  setIntentName:     
    component: "System.SetVariable"
    properties:
      variable: "intentName"
      value: "${iResult.value.intentMatches.summary[0].intent}"
    transitions:
      next: "setSearchTerm"      
    
  # 
  # Get the search term to use for the intent
  #
  
  setSearchTerm:
    component: "System.SetVariable"
    properties:
      variable: "searchTerm"
      value: "${searchTerms.value[intentName.value]}"
    transitions:
      next: "knowledgeSearchForGivenSearchTerm" # (3)            
      
  # 
  # This state searches for the searchTerm variable's value
  #
  
  knowledgeSearchForGivenSearchTerm:   
    component: "System.KnowledgeSearch"
    properties:
      # Set to the name of the search service that is configured in Settings
      searchServiceName: "KnowledgeSearch"
      searchTerm: "${searchTerm.value}" # put the search term here (3)
      # searchPrelude: Optional property. If missing, there's no search prelude.      
      resultSizeLimit: 1 # Change to how many articles to show. 
      # resultVersion: Optional property. Defaults to "Answer".
      # resultVersionExclusive: Optional property. Defaults to false.
      resultLinkLabel: "Show More"
      # defaultAttachmentLabel: Optional property. Defaults to "Download"
      searchLinkLabel: "Search for Similar Answers"
      noResultText: >
        I don't have an answer for that. Try rephrasing your question 
        (or you can ask to speak to a live agent).
      # cardLayout: Optional property. Defaults to "horizontal"
    transitions:
      actions:
        resultSent: "offerMoreHelp"
        noResult: "reset"
        serverError: "handleSearchServerProblem"
      error: "handleSearchError"
      next: "reset"    

  #
  # This state is called after knowledge search returns its results.
  #
  
  offerMoreHelp:
    component: "System.Output"
    properties:
      text: > 
        You can ask me another question if there's something 
        else that I can help you with.
    transitions:
      return: "offerMoreHelp"

  #
  # This state is called when there's a problem accessing the knowledge base such
  # as a server error fault or an unexpected error fault. When this error occurs,
  # the error message is stored in system.state.<state-name>.serverError.message. 
  # 
  
  handleSearchServerProblem:
    component: "System.Output"
    properties:
      text: >
        I'm not able to get an answer for that question. Let me know 
        if there's anything else I can help you with.
    transitions:
      return: "handleSearchServerProblem"      
  
  #
  # This state is called when there's a problem using the knowledge search component
  # such as when there's a problem with the knowledge search integration configuration
  # 
  
  handleSearchError:
    component: "System.Output"
    properties:
      text: >
        Oops, my answer mechanism for that isn't working properly.
        You can ask a different question or ask to speak to an agent?
    transitions:
      return: "handleSearchError"      

  #
  # This state ends the conversation
  #
  
  reset:
    component: "System.SetVariable"
    properties:
      variable: "someVariable"
      value: "x"
    transitions:
      return: "reset"

Example: Employ User Utterance as Search Term

The following example shows how to set the searchTerm to the user's utterance in a YAML dialog skill. For a visual dialog skill, you use ${skill.system.nlpresult.value.query} instead.

context:
  variables:
    iResult: "nlpresult"
    someVariable: "string" # For the reset state

states:

  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
    transitions:
      actions:
        system.Greeting: "welcome"
        system.Unsatisfactory Response: "transferToAgent"
        ...
        unresolvedIntent: "genericKnowledgeSearch"
  
  #
  # This state searches the knowledge base with the user input as the search term.
  #

  genericKnowledgeSearch: 
    component: "System.KnowledgeSearch"
    properties:
      # Set to the name of the search service that is configured in Settings
      searchServiceName: "KnowledgeSearch"
      searchTerm: "${iResult.value.query}"
      searchPrelude: "I don't know the answer offhand. Let's see what articles we have..."      
      resultSizeLimit: 3 # Change to how many articles to show. Defaults to 10.
      # resultVersion: Optional property. Defaults to "Answer".
      # resultVersionExclusive: Optional property. Defaults to false.
      resultLinkLabel: "Show More"
      # defaultAttachmentLabel: Optional property. Defaults to "Download"
      searchLinkLabel: "Open Page with All Answers"
      noResultText: >
        I couldn't find any articles about that. Try rephrasing your 
        question (or you can ask to speak to a live agent).
      # cardLayout: Optional property. Defaults to "horizontal"
    transitions:
      actions:
        resultSent: "offerMoreHelp"
        noResult: "reset"
        serverError: "handleSearchServerProblem"
      error: "handleSearchError"
      next: "reset"

  #
  # This state is called after knowledge search returns its results.
  #
  
  offerMoreHelp:
    component: "System.Output"
    properties:
      text: > 
        You can ask me another question if there's something 
        else that I can help you with.
    transitions:
      return: "offerMoreHelp"

  #
  # This state is called when there's a problem accessing the knowledge base such
  # as a server error fault or an unexpected error fault. When this error occurs,
  # the error message is stored in system.state.<state-name>.serverError.message. 
  # 
  
  handleSearchServerProblem:
    component: "System.Output"
    properties:
      text: >
        I'm not able to get an answer for that question. Let me know 
        if there's anything else I can help you with.
    transitions:
      return: "handleSearchServerProblem"      
  
  #
  # This state is called when there's a problem using the knowledge search component
  # such as when there's a problem with the knowledge search integration configuration
  # 
  
  handleSearchError:
    component: "System.Output"
    properties:
      text: >
        Oops, my answer mechanism for that isn't working properly.
        You can ask a different question or ask to speak to an agent?
    transitions:
      return: "handleSearchError"      

  #
  # This state ends the conversation
  #
  
  reset:
    component: "System.SetVariable"
    properties:
      variable: "someVariable"
      value: "x"
    transitions:
      return: "reset"

System.AgentTransfer

You use the System.AgentTransfer component in DA-as-agent digital assistants to transfer the conversation back to the chat service. The conversation will be routed to a live agent per the chat rules that have been configured in the chat service.

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see Agent Transfer.

This component is for conversations that originate in a service chat, as described in The Digital Assistant as Agent Framework in Action. For conversations that originate in the skill, use System.AgentConversation instead.

Here's an example of using this component to transfer the conversation back to the chat service.

  transferToAgent:
    component: "System.AgentTransfer"
    properties:
      maxEngagementsInQueue: "8"
      maxWaitSeconds: "300"
      waitingMessage: "Let me see if a human agent is available to help you. Hold tight."
      rejectedMessage: "No agents are available at this time. Please try again later."
      errorMessage: "We're unable to transfer you to a human agent because there was a system error."
    transitions:
      actions:
        accepted: "reset"
        rejected: "handleRejected"
        error: "offerMoreHelp"
      next:
        "reset"

Tip:

In skills with platform version 21.04 and later, the default values for the acceptedMessage, errorMessage, rejectedMessage, and waitingMessage properties are stored in the skill's resource bundle. To change a default, open the skill's Resources Bundle page, click Resource Bundles icon, select the Configuration tab, and change the message for the AgentTransfer - <property name> key. If you use the skill's resource bundle to change the default message, then you don't need to include the message property in the component unless you want to override the default.
Property Description Required?
agentStatusVariable The name of the context variable of type map to use to store the agent availability status information. No information is stored if the property is not specified. To reference a map variable, use a value expression like this: ${<mapVariableName>.value.<key>}. For example, agentStatus.value.expectedWaitMinutes.

To learn about the values returned in this variable, see System.AgentTransferCondition.

No
allowTransferIf Specifies the conditions under which the skill should transfer the chat session.
  • agentsAreRequestingNewEngagements: (default) For Oracle B2C Service agents who must pull chats (request new engagements), this is the most restrictive set of conditions, and the user doesn't have to wait too long before they speak to an agent. The skill attempts to transfer the conversation only if there are agents who have requested new engagements. In all other cases, this option has the same behavior as agentSessionsAreAvailable. Don't use this option forOracle Fusion Service Chat, since the total Oracle Fusion Service agents requesting new engagements is always 0.
  • agentSessionsAreAvailable: The skill attempts to transfer the conversation if any of the available agents have not reached the maximum number of chats that they are allowed to have at one time. The user may have to wait if the agents are involved in long-running conversations or are doing some post-chat follow-up.
  • agentsAreAvailable: The skill attempts to transfer the conversation if there are any agents online regardless of whether they have reached their maximum number of chats or are requesting new engagements. With this option, the users may have long waits.

If the specified conditions aren't met, then the rejected action occurs.

No
customProperties A map that holds information to pass to the service. See Pass Information to the Service. No
errorMessage The message that's shown to the user when a system error occurs while transferring the chat session to an agent. Defaults to We were unable to transfer you because there was a system error. You can set the property to a blank or empty string to suppress message output. No
maxEngagementsInQueue The maximum number allowed for engagements waiting in the destination queue. When the chat request is sent, the chat service responds with the current number of engagements waiting in the queue. If this value exceeds maxEngagementsInQueue, then the rejected action occurs. Defaults to -1, which means that there's no engagement limit.

Note that for Oracle Fusion Service Chat, the response is always 0, so this property is of no value for Oracle Fusion Service.

No
maxWaitSeconds The maximum number of estimated wait seconds that are allowed. When the chat service receives the transfer request, it responds with the estimated wait time. If this value exceeds maxWaitSeconds, then the rejected action occurs. This property defaults to -1, which means that there's no maximum wait time. When set to -1, the digital assistant transfers the user to a human agent regardless of what the estimated wait time is.

Note that the rejected action is based on the estimated wait time and not the actual wait time. After the conversation is transferred, the digital assistant doesn't have control over the conversation, nor does it have access to information about it. Therefore, it's possible for the actual wait time to exceed the estimated wait time.

No
rejectedMessage The message that's shown to the users whenever one of the following occurs:
  • The allowTransferIf conditions weren't met.
  • The estimated wait time exceeds maxWaitSeconds.
  • The number of engagements in the queue exceeds maxEngagementsInQueue.
Defaults to Agent rejected. You can set the property to a blank or empty string to suppress message output.
No
waitingMessage The message that's shown to users when they're transferred to a queue. Defaults to Agent chat session established. Waiting for agent to join. You can set the property to a blank or empty string to suppress message output. No

This component can return the following actions:

Action Description
accepted The accepted transition is set when the chat is successfully transferred to a queue.

Note that after a chat request is accepted, the conversation must end with a return. For example, you can navigate to a state that outputs a string (which is not seen by the user), or sets a variable.

    transitions:
      actions:
        accepted: "reset"
        rejected: "handleRejected"
        error: "offerMoreHelp"
      next: "reset"
rejected The rejected transition is set when one of the following occurs:
  • The allowTransferIf conditions weren't met.
  • The estimated wait time exceeds maxWaitSeconds
  • The number of engagements in the queue exceeds maxEngagementsInQueue.
error The error transition is set when there's a system error that prevents the transfer to a human agent.

Example: Transfer to a Human Agent

Here's an example of a dialog flow that transfers to an agent when the customer asks to speak to an agent:

metadata:
  platformVersion: "1.1"
main: true
name: "AutomatedAgentConversation"
context:
  variables:
    iResult: "nlpresult"
    someVariable: "string"
states:
  intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
    transitions:
      actions:
        ...
        system.Unsatisfactory Response: "transferToAgent"
        system.Request Agent: "transferToAgent"
        ...
  
  #
  # This state tries to transfer the user to another agent when the user explicitly requests for it.
  #
  transferToAgent:
    component: "System.AgentTransfer"
    properties:
      maxWaitSeconds: "300"
      waitingMessage: "I'm transferring you to a human agent. Hold tight."
      rejectedMessage: "I wasn't able to transfer you to a human agent. Please try again later."
      errorMessage: "We're unable to transfer you to a human agent because there was a system error."
    transitions:
      actions:
        accepted: "reset"
        rejected: "handleRejected"
        error: "offerMoreHelp"
      next: "reset"
  #
  # This state is called when an agent transfer is rejected. 
  # It lets the customer know they can ask for something else.
  # 
  handleRejected:
    component: "System.Output"
    properties:
      text: "Meanwhile, let me know if there's anything else I can help you with."
    transitions:
      return: "handleRejected"
  
  #
  # This state is called when an agent transfer encounters a system error. 
  # It lets the customer know they can ask for something else.
  #
  offerMoreHelp:
    component: "System.Output"
    properties:
      text: > 
        You can ask me another question if there's something 
        else that I can help you with.
    transitions:
      return: "offerMoreHelp"
      
  #
  # This state ends the conversation with a return transition for insights purposes, 
  # after the user has been transferred to another agent.
  #
  reset:
    component: "System.SetVariable"
    properties:
      variable: "someVariable"
      value: "x"
    transitions:
      return: "reset"

Example: Pass Information to the Service

When you transfer a conversation from a digital assistant to a live agent, you can use custom properties in the System.AgentTransfer component to pass this information.

Here's the structure for Oracle B2C Service:


      customProperties:
        - name: 
          value: 
          type:

The type property is required for custom fields, otherwise, it's optional.

Here's the structure for Oracle Fusion Service:


      customProperties:
        - name: 
          value:

Here's an example customProperties setting for Oracle Fusion Service:

  doTransfer:
    component: "System.AgentTransfer"
    properties:
      maxWaitSeconds: "300"
      allowTransferIf: "agentSessionsAreAvailable"
      # Example of passing a custom property to Oracle Fusion
                                Service      
      customProperties:
        # This is a checkbox custom field in the Universal Work Object.
        # Checkboxes take the value of Y (selected) or N (unselected).
        - name: "TriagedByODA_c"
          value: "Y"
      acceptedMessage: "The conversation has been transferred to a live agent."
      waitingMessage: "I'm transferring you to a human. Hold tight"
      rejectedMessage: "Looks like no one is available. Please try later"
      errorMessage: "We're unable to transfer you to a live agent because there was a system error."
    transitions:
      actions:
        accepted: "reset"
        rejected: "handleRejected"
        error: "offerMoreHelp"
      next: "reset"

Tip:

For Oracle Fusion Service, the rules evaluation stops at the first rule where all conditions are met. When you configure your rules, ensure that the transferred conversation isn't routed back to the digital assistant agent. In the doTransfer example, the custom property TriagedByODA_c is set to Y, and the rules can use this custom property to ensure that when it is set to Y, the conversation isn't routed to the digital assistant agent. (For Oracle B2C Service, the Transition State and stop configuration determines the routing.)

System.AgentTransferCondition

You can use the System.AgentTransferCondition component in DA-as-agent digital assistants to determine whether agents are available and, if so, the expected wait time.

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see Agent Transfer Condition.

You use the component's properties to specify the transfer conditions, and it returns an action that indicates whether the conditions were met. In addition, it sets the values of the named context map variable as follows:

queueId (integer, optional): The engagement queue ID,
expectedTotalWaitSeconds (integer, optional): Expected wait time in the queue in seconds
        ( -1 if there's inadequate information, zero or greater otherwise ).,
expectedWaitSeconds (integer, optional): The number representing the "ss" segment of the expected wait time of format mm:ss 
        ( -1 if there's inadequate information, zero or greater otherwise ).,
expectedWaitMinutes (integer, optional): The number representing the "mm" segment of the expected wait time of format mm:ss 
        ( -1 if there's inadequate information, zero or greater otherwise ).,
availableAgentSessions (integer, optional): Total number of sessions available across all agents.,
totalAvailableAgents (integer, optional): Total number of agents whose status is available.,
totalUnavailableAgents (integer, optional): Total number of agents whose status is unavailable.,
totalAgentsRequestingNewEngagement (integer, optional): Total number of agents who are available and have capacity.,
outsideOperatingHours (boolean, optional): True if outside operating hours. False if inside operating hours.,
engagementsInQueue (integer, optional): The number of engagements currently in the queue.,
sessionId (string, optional): The session ID.,
clientId (integer, optional): The client ID.

Here's an example of using this component to find out if agents are available, report the wait time, and allow the users to cancel the transfer request if they don't want to wait that long.

  handleAgentRequest:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      metadata:
        responseItems:        
        - type: "text" 
          text: "I understand. Give me a moment while I see who might be available to help you."
    transitions:
      next: "evaluateAgentTransferCondition"

  ############################
  # Agent Transfer
  ############################  

  # See if there are any agents available 
  
  evaluateAgentTransferCondition:
    component: "System.AgentTransferCondition"
    properties:
      maxWaitSeconds: 300
      maxEngagementsInQueue: 20
      allowTransferIf: "agentsAreAvailable"
      agentStatusVariable: "agentStatus"
    transitions:
      actions:
        conditionsMet: "askIfWillWait"
        conditionsNotMet: "handleRejected"
        error: "handleTransferError"
      next: "done"
            
  askIfWillWait:
    component: "System.CommonResponse"
    properties:
      processUserMessage: true
      metadata:
        responseItems:
          - type: "text"
            text:  "${rb('promptTextForTransferDecision','minutes,seconds',agentStatus.value.expectedWaitMinutes,agentStatus.value.expectedWaitSeconds)}"
            separateBubbles: true
            actions:
              - label: "Yes, I'll wait"
                type: "postback"
                keyword: "yes"
                payload:
                  action: "yes"
                name: "Yes"
              - label: "No, nevermind"
                keyword: "no"
                type: "postback"
                payload:
                  action: "no"
                name: "No"
    transitions:
      actions:
        yes: "transferToAgent"
        no: "handleCancelled"
        textReceived: "intent"
      next: "handleCancelled"     
      
  # Perform the actual transfer
  #
  # The maxWaitSeconds, maxEngagementsInQueue, allowTransferIf,
  # and customProperties, if any, should match those used for 
  # System.AgentTransferCondition 
  
  transferToAgent:
    component: "System.AgentTransfer"
    properties:
      maxWaitSeconds: 300
      maxEngagementsInQueue: 20
      allowTransferIf: "agentsAreAvailable"
    transitions:
      actions:
        accepted: "done"
        rejected: "handleRejected"
        error: "handleTransferError"
      next: "handleTransferError"

Tip:

Here's a suggested resource bundle definition that you can use to display the expected wait time:
This might take {minutes, plural,
     =-1 {}
     =0 {}
     =1 {1 minute and }
     other {# minutes and }
}{seconds, plural,
     =-1 {a while}
     =0 {{minutes, plural,
          =0 {a short wait time}
          other {0 seconds}
        }}
     =1 {1 second}
     other {# seconds}
} to connect. Are you willing to wait?
Property Description Required?
agentStatusVariable The name of the context variable of type map to use to store the agent availability status information. No information is stored if the property is not specified. To reference a map variable, use a value expression like this: ${<mapVariableName>.value.<key>}. For example, agentStatus.value.expectedWaitMinutes. No
allowTransferIf Specifies the base set of conditions that must be met.
  • agentsAreRequestingNewEngagements: (default) For B2C agents who must pull chats (request new engagements), requires that agents have pulled chats. In all other cases, this option has the same behavior as agentSessionsAreAvailable.
  • agentSessionsAreAvailable: Requires that agents are requesting chats.
  • agentsAreAvailable: Requires that at least one agent is active regardless of whether they have reached their maximum number of chats or are requesting new engagements.

If the specified conditions aren't met, then the conditionsNotMet action occurs.

No
customProperties A map that holds information to pass to the service. See Pass Information to the Service. This property is supported in version 21.04 and later. No
errorMessage The message shown to the user when Digital Assistant experiences trouble with the agent chat service. Defaults to We were unable to check the agent transfer conditions because there was a system error. This default string is stored in the configuration resource bundle under the systemComponent_AgentTransferCondition_errorMessage key. You can set the property to a blank or empty string to suppress message output. No
maxEngagementsInQueue The maximum number allowed for engagements waiting in the destination queue. When the request is sent, the chat service responds with the current number of engagements waiting in the queue. If this value exceeds maxEngagementsInQueue, then the conditionsNotMet action occurs. Defaults to -1, which means that there's no engagement limit. No
maxWaitSeconds The maximum number of estimated wait seconds that are allowed. When the chat service receives the request, it responds with the estimated wait time. If this value exceeds maxWaitSeconds, then the conditionsNotMet action occurs. This property defaults to -1, which means that there's no maximum wait time.

Note that the conditionsNotMet action is based on the estimated wait time and not the actual wait time.

No

This component can return the following actions:

Action Description
conditionsMet The conditionsMet transition is set when when it's inside business hours and the maxWaitSeconds, maxEngagementsInQueue and allowTransferIf conditions are met.
conditionsNotMet The conditionsNotMet transition is set when one of the following occurs:
  • It's outside business hours.
  • The allowTransferIf conditions weren't met.
  • The estimated wait time exceeds maxWaitSeconds
  • The number of engagements in the queue exceeds maxEngagementsInQueue.
error The error transition is set when there's an issue with the connection to the agent chat service during the agent conditions check.

Example: Get Agent Availability and Wait Time

Here's an example of a dialog flow that invokes the component, displays the wait time, and gives the user the opportunity to cancel their transfer request.

  ############################
  # Agent Transfer
  ############################  

  # See if there are any agents available 
  
  evaluateAgentTransferCondition:
    component: "System.AgentTransferCondition"
    properties:
      maxWaitSeconds: 300
      maxEngagementsInQueue: 20
      allowTransferIf: "agentsAreAvailable"
      agentStatusVariable: "agentStatus"
    transitions:
      actions:
        conditionsMet: "askIfWillWait"
        conditionsNotMet: "setInsightsCustomMetricsConditionsNotMet"
        error: "handleTransferError"
      next: "done"
      
  # Measure when agents aren't available

  setInsightsCustomMetricsConditionsNotMet:
    component: "System.SetCustomMetrics"
    properties:
      dimensions: 
      - name: "Agent Transfer Choice"
        value: "No agents available for new chats"
    transitions:
      next: "handleRejected"      
                  
  askIfWillWait:
    component: "System.CommonResponse"
    properties:
      processUserMessage: true
      metadata:
        responseItems:
          - type: "text"
            text:  "${rb('promptTextForTransferDecision','minutes,seconds',agentStatus.value.expectedWaitMinutes,agentStatus.value.expectedWaitSeconds)}"
            separateBubbles: true
            actions:
              - label: "Yes, I'll wait"
                type: "postback"
                keyword: "yes"
                payload:
                  action: "yes"
                name: "Yes"
              - label: "No, nevermind"
                keyword: "no"
                type: "postback"
                payload:
                  action: "no"
                name: "No"
    transitions:
      actions:
        yes: "setInsightsCustomMetricsAgentTransferInitiated"
        no: "setInsightsCustomMetricsAgentTransferCancelled"
        textReceived: "intent"
      next: "handleCancelled"
      
  # Measure when user chooses to wait for transfer

  setInsightsCustomMetricsAgentTransferInitiated:
    component: "System.SetCustomMetrics"
    properties:
      dimensions: 
      - name: "Agent Transfer Choice"
        value: "User chose to wait"
    transitions:
      next: "transferToAgent"        
      
  # Measure when user chooses to not wait for transfer

  setInsightsCustomMetricsAgentTransferCancelled:
    component: "System.SetCustomMetrics"
    properties:
      dimensions: 
      - name: "Agent Transfer Choice"
        value: "User didn't want to wait"
    transitions:
      next: "handleCancelled"
      
  # Perform the actual transfer
  #
  # The maxWaitSeconds, maxEngagementsInQueue, allowTransferIf,
  # and customProperties, if any, should match those used for 
  # System.AgentTransferCondition 
  
  transferToAgent:
    component: "System.AgentTransfer"
    properties:
      maxWaitSeconds: 300
      maxEngagementsInQueue: 20
      allowTransferIf: "agentsAreAvailable"
    transitions:
      actions:
        accepted: "done"
        rejected: "handleRejected"
        error: "handleTransferError"
      next: "handleTransferError"
     
  ############################
  # All done
  ############################
                  
  done:
    component: "System.Output"
    properties:
      text: "Let me know if you need help on anything else."
    transitions:
      return: "done"  
      
  handleRejected:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      metadata:
        responseItems:        
        - type: "text"
          text: > 
            Unfortunately, none of my colleagues are currently available to assist with this.
            Still, we’d love to see this through for you. 
            Please feel free to reach us through email@example.com.
    transitions:
      next: "done"
      
  handleCancelled:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      metadata:
        responseItems:        
        - type: "text" 
          text: "OK. Maybe some other time. Please feel free to reach us through email@example.com."
    transitions:
      next: "done"
      
  handleTransferError:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      metadata:
        responseItems:        
        - type: "text" 
          text: "Unfortunately, we can't transfer you at this time. Please try again later."
    transitions:
      next: "done"
      
  ############################
  # Global error handler
  ############################
  
  globalErrorHandler:
    component: "System.Output"
    properties:
     text: "Sorry, we were unable to do the action that you requested." 
    transitions:
      next: "done"

The askIfWillWait state uses a resource bundle entry to form the wait time message so that the message makes sense whether the time is more or less than a minute and whether a number is 0, one or more.

There are some experts online. But it might take {minutes, plural,
     =-1 {}
     =0 {}
     =1 {1 minute and }
     other {# minutes and }
}{seconds, plural,
     =-1 {a while}
     =0 {{minutes, plural,
          =0 {a very short wait time}
          other {0 seconds}
        }}
     =1 {1 second}
     other {# seconds}
} for one to join. Are you willing to wait?

Note that this example uses System.SetCustomMetrics to track if agents were available, and, if so, how many users chose to wait and how many canceled the transfer request.

Live-Agent-Transfer Components

System.AgentInitiation

If you want to transfer a skill's conversation to an Oracle B2C Service agent, add this component to the dialog flow to initiate the handshake with the agent-integration channel that's specified by the agentChannel property. You must call this component before you call the System.AgentConversation component.

This component is for conversations that originate in the skill. Do not use this component for conversations that originate in Oracle B2C Service chat, as described in The Digital Assistant as Agent Framework in Action.

Here's an example of using this component to initiate the handshake with the Oracle B2C Service instance that's defined by the agent integration channel named ServiceCloudIntegration.

  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      agentChannel: "ServiceCloudIntegration"
      nlpResultVariable: "iResult"
      waitingMessage: "Waiting for an agent..."
      rejectedMessage: "Agents are not available right now."
      resumedMessage: "We're connecting you to an agent..."
      errorMessage: "Oops! We're having system issues. We're sorry, but we can't connect you with an agent right now."
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "tryAgain"
        error: "tryAgain"
   agentConversation:
    component: "System.AgentConversation"
    properties:
      agentChannel: "ServiceCloudIntegration"
      nlpResultVariable: "iResult"
      exitKeywords: "bye, exit, take care, goodbye, quit"
      expiryMessage: "Your chat with the agent timed out."
      conclusionMessage: "Your chat with the agent has ended."
      waitMessage: "You are number ${system.message.messagePayload.position} in the queue. Your waiting time is ${(system.message.messagePayload.waitTime>60)?then('${(system.message.messagePayload.waitTime/60)?int} mins','${system.message.messagePayload.waitTime} seconds')}."
    transitions:
      next: "endPrompt"
      actions:
        agentLeft: "endPrompt"
        expired: "sessionExpired"
        error" "agentConversationError"

Tip:

In skills with platform version 21.04 and later, the default values for the agentActionsMessage, errorMessage, rejectedMessage, resumedMessage, and waitingMessage properties are stored in the skill's resource bundle. To change a default, open the skill's Resources Bundle page, click Resource Bundles icon, select the Configuration tab, and change the message for the AgentInitiation - <property name> key. If you use the skill's resource bundle to change the default message, then you don't need to include the message property in the component unless you want to override the default.
Property Description Required?
agentActions A list of actions that the agent can trigger to terminate the chat and move the flow to the state defined for the transition action. In the customer service representative's console, these actions display as slash commands when the agent conversation is initiated, as shown in this example:
Here are the available actions that you can send to transfer the conversation
back to the bot. Prepend the action with a forward slash (for example, /actionName).
/OrderPizza : Order Pizza : Order a pizza.
/ShowMenu : Show Menu : Show order options.

The action names must correspond to the System.AgentConversation’s actions properties. For example, in the following agentInitiation state, the ShowMenu and OrderPizza entries in the agentActions property correspond to actions that are defined for the agentConversation state:

  agentInitiation:
    component: "System.AgentInitiation"
    ...
    properties:
      agentChannel: "ServiceCloudIntegration"
      agentActions:
      - action: "OrderPizza"
        label: "Order Pizza"
        description: "Order a pizza."
      - action: "ShowMenu"
        label: "Show Menu"
        description: "Show order options. "
      …
  agentConversation:
    component: "System.AgentConversation"
    ...
    transitions:
      next: "terminatedWithoutAction"
      actions:
        ShowMenu: "ShowMenu"
        OrderPizza: "OrderPizza"

You can define the agentActions list elements in several ways:

  • As a list of maps, where each map must contain an action property, a value property, and optionally, a description property. For example:
          - action: "action1"
            label: "label1"
            description: "description1"
          - action: "action2" 
            label: "label2"
            description: "description2"
  • As a JSON array, where each object in the array must contain an action property, a value property, and optionally, a description property. For example:
          [
          {action: "action1",
          label: "label1",
          description: "description1"},
          {action: "action2",
          label: "label2",
          description: "description2"}      
          ]
  • As a comma-delimited string of action values. The label and description are the same as the action value. For example:
    "action1, action2"
No
agentActionsMessage If the agentActions property is set, then the agent console displays this value instead of the default message. For example:

agentActionsMessage: "\nYou can terminate when done or send one of these actions.\n"

No
agentChannel Names the Agent Integration channel. This value, the name of the Agent Integration channel, and the agentChannel property defined for the System.AgentConversation component must all match. Yes
allowTransferIf Specifies the conditions under which the skill should transfer the chat session. The component uses the queueId value to identify the queue from which to obtain the statistics. You should verify that the chat rules will actually transfer the conversation to the identified queue, and not some other queue.
  • agentsAreRequestingNewEngagements: This is the most restrictive set of conditions. The skill attempts to transfer the conversation only if there are agents who have requested new engagements (pulled chats) and are assigned to the specified queue or, if the chat server automatically pushes chats to agents, there are agents who are available to receive chats, haven't reached their maximum number of chats, and are assigned to the specified queue. With this option, the user doesn't have to wait too long before they speak to the agent.
  • agentSessionsAreAvailable: The skill attempts to transfer the conversation if there are available agents who haven't reached their maximum number of chats and are assigned to the specified queue. The user may have to wait if the agents are involved in long-running conversations or are doing some post-chat follow-up.
  • agentsAreAvailable: The skill attempts to transfer the conversation if there are any agents online who are assigned to the specified queue regardless of whether they have reached their maximum number of chats or are requesting new engagements. With this option, the users may have long waits.

If the specified condition is not met, the component returns rejected.

When you include this property, you must also include the queueId property.

This property is only available in instances of Oracle Digital Assistant that were provisioned on Oracle Cloud Infrastructure (sometimes referred to as the Generation 2 cloud infrastructure).

No
chatResponseVariable Names the map variable that holds the agent response information. After the System.AgentInitiation component connects successfully, the map contains the following properties:
{
  "sessionID": "string", // agent session id

  "completedSurveyID": {
    "id": "int"
  },

  "engagementID": { // survey id
    "id": "int"
  },

  "cancelledSurveyID": {
    "id": "int"
  }
}
No
customProperties A map that holds the incident ID, interface, contact, or custom fields (or a combination thereof) to pass to the service. To reference a map variable, use a value expression like this: ${mapVariableName.value}. See Pass Customer Information to a Live Chat. No
errorMessage The message to display when there's a problem establishing a connection with Oracle B2C Service. For example, the password in the Agent Integration channel is no longer valid, or there's a problem with the server. No
nlpResultVariable The variable that stores the customer’s query message. No
rejectedMessage A message that displays if the AgentInitiation handshake was rejected, such as if it's outside of the configured operating hours. For example:

rejectedMessaage: "Sorry, no agents are available at this time."

No
resumedMessage A message (such as, Just a minute...we're connecting you to an agent.) that displays when the customer's chat with the customer service representative resumes. Adding this property prevents customers whose requests have already been queued from receiving a misleading Resuming chat with agent message when they repeatedly request a live chat. No
subject The subject line that displays in the agent's console after the hand off to the agent platform. By default, this is the last customer message stored in the nlpResultVariable property, but you can also define this using a variable that you set earlier in the dialog flow definition. For example, you can define a string type context variable whose value gets set prior to the System.AgentInitiation component:

subject: "A customer needs help regarding ${context_variable.value}"

No
queueId The ID of the queue that the component must use to determine whether the specified allowTransferIf condition is met. This must be the ID of the queue that the Oracle B2C Service chat rules will route that conversation to.

This property is ignored if the allowTransferIf property isn't present.

Required when the allowTransferIf property is present.
transcriptDateTimeFormat The format for the date and time in the conversation transcript messages that are forwarded to the agent. Refer to the DateTimeFormatter Java class for valid patterns. Example: dd/MM/yyyy HH:mm. Defaults to yyyy-mmm-ddThh:mm:ssZ. No
transcriptTimezoneName The Internet Assigned Numbers Authority (IANA) name of the time zone to use to format the conversation transcript using transcriptDateTimeFormat property. Example: America/Sao_Paulo. Defaults to Europe/London. If you don't include the transcriptDateTimeFormat property, then this property is ignored. No
waitingMessage A message that displays while customers wait to connect to an agent. For example:

waitingMessage: "You’ve joined the chat session. An agent will be right with you.

No

System.AgentInitiation Transitions

The System.AgentInitiation component returns the accepted, rejected, and error actions. These actions can each point to a different state, with the accepted action typically naming the state for the System.AgentConversation component:
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      agentChannel: "ServiceCloudIntegration"
      ...
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "noAgentsAvailable"
        error: "handshakeError"
Action Description
accepted The handshake completed successfully and the state can transition to the state with the System.AgentConversation component.
error There's a problem establishing a connection with Oracle B2C Service. For example, the password in the Agent Integration channel is no longer valid, or there's a problem with the Service Cloud server.
rejected Oracle B2C Service has rejected the connection request. Some of the reasons for rejecting a connection request are:
  • No agents are available (requires allowTransferIf and queueId properties)
  • It's outside of the configured operating hours
  • It's a holiday
  • There's a problem with the chat server

Note that if you don't set allowTransferIf and queueId, the rejected action will not occur when no agents are available, instead, the transfer will remain in a wait condition.

Example: Handle Agent Initiation Rejection and System Errors

Here's an example of handling system errors and the error and rejected actions.

  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      agentChannel: "B2CServiceIntegration"
      nlpResultVariable: "iResult"
      waitingMessage: "Let me connect you with someone who can further assist you."
      resumedMessage: "Someone will be with you shortly."
      errorMessage: "Oops! We're having system issues and we can't connect you with an agent right now."
      rejectedMessage: "Unfortunately, no one's available right now."     
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "initiationRejected"
        error: "tryAgain"
      error: "agentInitiationSystemError"
  initiationRejected:
    component: "System.Output"
    properties:
      text: "Perhaps it's outside their working hours or it's a holiday."
    transitions:
      return: "initiationRejected"
  tryAgain:
    component: "System.Output"
    properties:
      text: "Please try again later."
    transitions:
      return: "tryAgain"
  agentInitiationSystemError:
    component: "System.Output"
    properties:
      text: "I seem to be having a connection problem. Can you please email email@example.com to let them know?"
    transitions:
      return: "done"

Example: The incidentID Property

context:
  variables:
    liveChatInfo: "map"
    customerTicketId: "int"
...
  setCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        incidentID: "${customerTicketId}" # long value
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      ...
      customProperties: "${liveChatInfo.value}"

Example: The Standard customerInformation Object

This example sets the contactID.

context:
  variables:
    liveChatInfo: "map"
    contactId: "int"
...
  setCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        customerInformation:
          contactID:
            id: "${customerId}"
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      ...
      customProperties: "${liveChatInfo.value}"

Example: The Legacy customerInformation Object

This example sets the interfaceID and contactID.

Tip:

Because the WSDL specifies that interfaceID is of type NamedID, we could've used name: "myInterfaceName" instead of id: id: "${interfaceId}".
context:
  variables:
    liveChatInfo: "map"
    interfaceId: "int"
    contactId: "int"
...
  setCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        customerInformation:
          interfaceID:
            id:
              id: "${interfaceId}"
          contactID:
            id: "${customerId}"
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      ...
      customProperties: "${liveChatInfo.value}"

Example: The Standard customFields Object

context:
  variables:
    liveChatInfo: "map"
...
  setupCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        customFields:
          - name: "c$text_field"        # text field
            type: "STRING"
            value: "SILVER"
          - name: "c$text_area"         # text area
            type: "STRING"
            value: "My package arrived but there were no contents in the box. Just bubble wrap."
          - name: "c$integer"           # integer
            type: "INTEGER"
            value: 21
          - name: "c$yes_no"  # yes/no (1=yes and 0=no)
            type: "BOOLEAN"
            value: 1
          - name: "c$date_field"        # date (yyyy-MM-dd'T'00:00:00. Use 0 for time)
            type: "DATE"
            value: "2020-02-04T00:00:00+00:00" 
          - name: "c$date_time"         # datetime (yyyy-MM-dd'T'HH:mm:ssXXX)
            type: "DATETIME"
            value: "2020-02-04T21:24:18+00:00" 
          - name: "c$menu"              # menu (no type property, you can pass the string or the ID for the value property)
            value: "12"
    transitions:
      ...
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      ...
      customProperties: "${liveChatInfo.value}"

Example: The Legacy customFields Object

context:
  variables:
    liveChatInfo: "map"
    skillType: "string"
...
  setupCustomFields:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        customerInformation: 
          interfaceID:
            id:
              id: 1     
        customFields:
# Text Field
          - name: "c$da_text_field"
            dataType: "STRING"
            dataValue:
              stringValue: "SILVER"
# Text Area
          - name: "c$da_text_area"
            dataType: "STRING"
            dataValue:
              stringValue: "This is a very long string that is more than 32 characters."
# Integer
          - name: "c$da_integer"
            dataType: "INTEGER"
            dataValue:
              integerValue: 21
# Menu
          - name: "c$da_menu"
            dataType: "NAMED_ID"
            dataValue: 
              namedIDValue:
                name: "Item 1"
# Instead of name, you can use
#                id:
#                  id: 1
#
# Yes/No
          - name: "c$da_is_from_skill"
            dataType: "BOOLEAN"
            dataValue:
              booleanValue: true
# Date (XML Schema Date)
          - name: "c$da_date"
            dataType: "DATE"
            dataValue:
              dateValue: "2019-10-26" 
# DateTime (XML Schema DateTime)
          - name: "c$da_datetime"
            dataType: "DATETIME"
            dataValue:
              dateTimeValue: "2019-10-26T21:32:52"               
    transitions:
      ...
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      ...
      customProperties: "${liveChatInfo.value}"

Example: Assemble the Custom Properties Object

These steps describe how you can declare the customProperties object and setting its various values.

Step 1: Declare the Custom Properties Variable
In the context node, define a map variable for the customProperties property in the System.AgentInitiation component. It’s a JSON object that can hold the chat customer information and custom field values. In the following example, this variable is declared as liveChatInfo:
context:
  variables:
    size: "PizzaSize"
    type: "PizzaType"
    crust: "PizzaCrust"
    iResult: "nlpresult"
    interfaceId: "string"
    categoryId: "string"
    skillType: "string"
    liveChatInfo: "map"
Step 2: Set the Values for the customProperties Map Variable
In the context node, define a map variable for the customProperties property in the System.AgentInitiation component. It’s a JSON object that can hold the chat customer information and custom field values. In the following example, this variable is declared as liveChatInfo:
context:
  variables:
    size: "PizzaSize"
    type: "PizzaType"
    crust: "PizzaCrust"
    iResult: "nlpresult"
    interfaceId: "string"
    categoryId: "string"
    skillType: "string"
    liveChatInfo: "map"
Step 3: Define the Fields for the customProperties Map Variable
Whether you set the map values through a custom component or through the dialog flow, you need to structure the map object. Use the standard object formats unless the agent integration channel was created before version 20.1 or the channel connects to an Oracle B2C Service version that's earlier than 19A. Here's an example of the standard format:

  setLiveChatInfo:
    component: "System.SetVariable"
    properties:
      variable: "liveChatInfo"
      value:
        customerInformation: 
          categoryID:
            id: "${categoryId}"             
        customFields: 
          - name: "c$skilltype"
            type: "STRING"
            value: "${skillType}"
    transitions:
      next: "agentInitiation"
Step 4: Add the customProperties to the System.AgentInitiation Component
Finally, add the customProperties property to the System.AgentInitiation component and define it using an expression that accesses the map variable value.
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      subject: "A customer needs help regarding ${skillType}."
      agentChannel: "ServiceCloudIntegration"
      waitingMessage: "Let me connect you with someone who can further assist you."
      resumedMessage: "Please wait, someone will be with you shortly."
      rejectedMessage: "Sorry no one is available now."
      errorMessage: "We're sorry! We're having system issues and we can't connect you with an agent."
      customProperties: "${liveChatInfo.value}"
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "initiationRejected"
        error: "tryAgain"
  initiationRejected:
    component: "System.Output"
    properties:
      text: "Perhaps it's outside their working hours or it's a holiday."
    transitions:
      return: "tryAgain"
  tryAgain:
    component: "System.Output"
    properties:
      text: "Please try again later."
    transitions:
      return: "tryAgain"

System.AgentConversation

Use this component to transfer a skill's conversation to an Oracle B2C Service live agent and to manage the skill-live agent interchange. Note that you must call the System.AgentInitiation component before you can use this component.

System.AgentConversation is for conversations that originate in the skill. Do not use this component for conversations that originate in Oracle B2C Service chat, as described in The Digital Assistant as Agent Framework in Action.

Here's an example of using this component to transfer the conversation to the Oracle B2C Service instance that's defined by the agent integration channel named ServiceCloudIntegration.

  agentConversation:
    component: "System.AgentConversation"
    properties:
      agentChannel: "ServiceCloudIntegration"
      nlpResultVariable: "iResult"
      errorMessage: "Oops, we lost connection with the agent. If you need further help, please call customer support."
      exitKeywords: "bye, exit, take care, goodbye, quit"
      expiryMessage: "Your chat with the agent timed out"
      waitExpiryMessage: "The chat expired while waiting for an agent"
      conclusionMessage: "Your chat with the agent has ended."
      waitMessage: "You are number ${system.message.messagePayload.position} in the queue. Your waiting time is ${(system.message.messagePayload.waitTime>60)?then('${(system.message.messagePayload.waitTime/60)?int} mins','${system.message.messagePayload.waitTime} seconds')}."
    transitions:
      next: "endPrompt"
      actions:
        agentLeft: "endPrompt"
        expired: "sessionExpired"
        waitExpired: "expiredWhileWaiting"
        error: "handleConnectionError"
Property Description Required?
agentChannel Names the Agent Integration channel. This value, the name of the Agent Integration channel, and the agentChannel property defined for the System.AgentInitiation component must all match. Yes
conclusionMessage An automated message sent to the customer when either the user enters an exit keyword, the agentLeft action is triggered, or the agent terminates the conversation without sending one of the agentActions. For example, Your chat with the agent has ended. No
errorMessage The message that the chat displays if there is a problem with the connection to Oracle B2C Service.

The default message is Chat session error. The reason is {cause}.

This property only works with instances of Oracle Digital Assistant that were provisioned on Oracle Cloud Infrastructure (sometimes referred to as the Generation 2 cloud infrastructure).

No
exitKeywords A comma-delimited list of typical exit words used by a customer to end the conversation with the live agent. For example:

exitKeywords: "bye, exit, take care, goodbye, quit"

The property value defaults to bye, take care, see you, goodbye.

No
expiryMessage A message that displays when the expired action is triggered. The default message is Chat session expired. Thanks for chatting with us.

Note that the conclusionMessage is not output if the expiryMessage is output.

The expiry message isn't output when the conversation concludes because the Service Cloud USER_WAIT_QUEUE_TIMEOUT was exceeded.

No
nlpResultVariable The nlpResultVariable variable that holds the customer's query message. No
waitExpiryMessage The message that's shown to the user when the chat expires while waiting for an agent. The default message is The request for live chat expired while waiting for an agent. No
waitMessage By default, after the conversation transfer is initiated, the skill displays the wait message that the live chat service sends to the skill, such as the queue position and wait time. Use this property to customize the message. For example:

waitMessage: "You are number ${system.message.messagePayload.position} in the queue. Your waiting time is ${(system.message.messagePayload.waitTime>60)?then('${(system.message.messagePayload.waitTime/60)?int} mins','${system.message.messagePayload.waitTime} seconds')}."

No

System.AgentConversation Transitions

The System.AgentConversation can trigger the expired, agentLeft, error, or waitExpired action. In addition, it can trigger any action from the System.AgentInitiation component's agentActions property. You need to add a next transition as well, because a customer might enter one of the exitKeywords to leave the chat before any of these actions can get triggered.


  agentConversation:
    component: "System.AgentConversation"
    properties:
      agentChannel: "ServiceCloudIntegration"
      nlpResultVariable: "iResult"
      exitKeywords: "bye, adios, take care, goodbye"
      ...
    transitions:
      next: "endPrompt"
      actions:
        agentLeft: "endPrompt"
        expired: "endPrompt"
        waitExpired: "endPrompt"
        error: "agentConversationError"
  ...
  endPrompt:
    component: "System.List"
    properties: 
      prompt: "Your session has ended. What would you like to do?"
      options: 
      - label: "Order a Pizza"
        value: "OrderPizza" 
      - label: "Nothing. I'm done here."
        value: "Finished" 
      autoNumberPostbackActions: true
    transitions:
      actions:
        OrderPizza: "resolvePizzaSize"
        Finished: "done"
...
      
    
Action Description
agentActions If the System.AgentInitiation component has an agentActions property, then this component should have a transition action for every supported action that's specified by agentActions.
agentLeft The agent terminated the session without using a slash action (for example, /Order). Alternatively, the session ended because there was no activity within the time specified by the Oracle B2C Service CS_IDLE_TIMEOUT configuration and that configuration is less than the Session Expiration setting for the agent-integration channel. See the expired action for more information.

Note that this action is not returned when the user leaves the conversation by entering an exit keyword. In that case, the flow transitions to the state that's named by the next transition, or, if there is no next transition, to the next state in the flow.

error

There is a problem connecting to the live agent service.

This action only works with instances of Oracle Digital Assistant that were provisioned on Oracle Cloud Infrastructure (sometimes referred to as the Generation 2 cloud infrastructure).

expired

If the Oracle B2C Service CS_IDLE_TIMEOUT is equal to or more than the Session Expiration setting for the agent-integration channel, then this action is triggered when neither the end-user nor the agent sends a message within the session expiration limit. If CS_IDLE_TIMEOUT is less than the Session Expiration setting for the agent-integration channel, and there is no activity, then Oracle B2C Service terminates the chat and the agentLeft action is triggered instead.

By default, CS_IDLE_TIMEOUT is 10 minutes.

The expired action isn't returned when the conversation concludes because the Service Cloud USER_WAIT_QUEUE_TIMEOUT was exceeded. Consider setting this configuration to a high value, such as 7200 seconds (2 hours).

To view or change your Oracle B2C Service instance's settings, open the Desktop Console, click Navigation, click the first Configuration item in the menu, and click Configuration Settings. Then search the for the setting in the Chat folder.

waitExpired The chat request expired while waiting for an agent. This happens when the wait time exceeds the value in the chat client's USER_WAIT_QUEUE_TIMEOUT setting.

Example: Configure the Agent Transfer Dialog Flow

In this example, the GetAgent intent is trained to understand distress calls like help me please!

intent:
    component: "System.Intent"
    properties:
      variable: "iResult"
    transitions:
      actions:
        OrderPizza: "resolvesize"
        CancelPizza: "cancelorder"
        GetAgent: "agentInitiation"
        unresolvedIntent: "agentInitiation"

Here are the basic steps for configuring the dialog flow:

  1. Initiate the live-agent transfer.

    1. Add a state for the System.AgentInitiation component.

    2. Set the state's agentChannel property to the name of the Agent Integration channel that you configured for the live-agent system.

    After the Agent Integration channel establishes a connection and Oracle B2C Service sends the chat request to its queue (that is, after it creates a help ticket), the System.AgentInitiation component allows the transition to the next state, which is typically defined for the System.AgentConversation component (agentConversation in the following example).
    
      agentInitiation:
        component: "System.AgentInitiation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          nlpResultVariable: "iResult"
          waitingMessage: "Waiting for an agent..."
          rejectedMessage: "Agents are not available right now."
          resumedMessage: "We're connecting you to an agent..."
          errorMessage: "Oops! We're having system issues. We're sorry, but we can't connect you with an agent right now."
        transitions:
          actions:
            accepted: "agentConversation"
            rejected: "tryAgain"
            error: "tryAgain"
      tryAgain:
        component: "System.Output"
        properties:
          text: "Please try again later."
        transitions:
          return: "tryAgain"

    Tip:

    Customers may repeatedly request a live chat even though their requests have already been queued in the agent's chat console. Add a resumedMessage property to the System.AgentInitiation state to prevent such customers from receiving a misleading Resuming chat with agent message.
  2. Add and configure the System.AgentConversation component. While the dialog engine is in the state defined for this component, the skill passes messages back and forth between the customer and the agent. The skill listens for exit keywords in the customer input, like bye. When the skill detects one of these keywords, the System.AgentConversation component ends the live-chat session and triggers its next transition.

    Here's an example:

      agentConversation:
        component: "System.AgentConversation"
        properties:
          agentChannel: "ServiceCloudIntegration"
          nlpResultVariable: "iResult"
          errorMessage: "Oops, we lost connection with the agent. If you need further help, please call customer support."
          exitKeywords: "bye, exit, take care, goodbye, quit"
          expiryMessage: "Your chat with the agent timed out."
          conclusionMessage: "Your chat with the agent has ended."
          waitMessage: "You are number ${system.message.messagePayload.position} in the queue. Your waiting time is ${(system.message.messagePayload.waitTime>60)?then('${(system.message.messagePayload.waitTime/60)?int} mins','${system.message.messagePayload.waitTime} seconds')}."
        transitions:
          next: "endPrompt"
          actions:
            agentLeft: "endPrompt"
            expired: "endPrompt"
            error: "endPrompt"
      endPrompt:
        component: "System.Output"
        properties:
          text: "Returning you to your bot."
        transitions:
          return: "endPrompt"

Example: Get Survey Information

In the following example that uses the standard format, the AgentConversation component outputs a survey link after the agent conversation ends. The link includes the session and engagement ID from the map that was named by the chatResponseVariable property.

context:
  variables:
    agentSystemResponse: "map" # chat request response is stored in this variable.
    ...
states:
  ...
  agentInitiation:
    component: "System.AgentInitiation"
    properties:
      agentChannel: "B2CServiceIntegration"
      nlpResultVariable: "iResult"
      chatResponseVariable: "agentSystemResponse"  
    transitions:
      actions:
        accepted: "agentConversation"
        rejected: "tryAgain"
        error: "tryAgain"
  agentConversation:
    component: "System.AgentConversation"
    properties:
      agentChannel: "B2CServiceIntegration"
      nlpResultVariable: "iResult"
      exitKeywords: "bye, exit, take care, goodbye, quit"
      expiryMessage: "Your chat with the agent timed out."
      conclusionMessage: "Can you please fill out this survey: <PUT SURVEY URL HERE>?session=${agentSystemResponse.value.sessionId}&surveyid=${agentSystemResponse.value.engagementId}"
    transitions:
      next: "endPrompt"
      actions:
        agentLeft: "endPrompt"
        expired: "sessionExpired"
        error: "agentConversationError"

Example: Transfer the Chat to a Specific Oracle B2C Service Queue

  1. If you haven't already, in the context node, define a map variable to use with the System.AgentInitiation component's customProperties property. For example:

    context:
      variables:
        greeting: "string"
        name: "string"
        liveChatInfo: "map"
    
  2. Define the fields for the map variable.

    Here's an example of the standard format for agent-integration channels that were created in version 20.01 or later and that connect to Oracle B2C Service version 19A or later.

      setLiveChatInfo:
        component: "System.SetVariable"
        properties:
          variable: "liveChatInfo"
          value:
            customFields: 
              - name: "c$frombot"
                type: "BOOLEAN"
                value: 1
        transitions:
          next: "agentInitiation"

    Here's an example of the legacy format for agent-integration channels that were created prior to version 20.01 or that connect to a version that is earlier than Oracle B2C Service version 19A.

      setLiveChatInfo:
        component: "System.SetVariable"
        properties:
          variable: "liveChatInfo"
          value:
            customFields: 
              - name: "c$frombot"
                dataType: "BOOLEAN"
                dataValue:
                  booleanValue: true
        transitions:
          next: "agentInitiation"
  3. Add the customProperties property to the System.AgentInitiation component, and set it to the value of your map variable. For example:

      agentInitiation:
        component: "System.AgentInitiation"
        properties:
          agentChannel: "B2CServiceIntegration"
          nlpResultVariable: "iResult"
          customProperties: "${liveChatInfo.value}"
          waitingMessage: "Waiting for an agent..."
          rejectedMessage: "Agents are not available right now."
          resumedMessage: "We're connecting you to an agent..."
          errorMessage: "Oops! We're having system issues. We're sorry, but we can't connect you with an agent right now."
        transitions:
          actions:
            accepted: "agentConversation"
            rejected: "tryAgain"
            error: "tryAgain"
      tryAgain:
        component: "System.Output"
        properties:
          text: "Please try again later."
        transitions:
          return: "tryAgain"

System.ResolveEntities

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see Resolve Entity.

Iterates through all the entity fields in the composite bag, converses with the user and resolves all the fields. The component randomly chooses the prompts that you provide for each entity while resolving that entity.

Property Description Required
variable Refers to the composite bag entity context variable that’s populated by this component. If all child entities of the composite entity variable already have a value, then the dialog flow transitions to the next state without sending the user a message. Yes
nlpResultVariable Populates the variable property (which references the composite bag entity variable) using the values stored in the nlpresult context variable. You can define this property by naming the nlpresult variable (typically, iResult). When the framework resolves a single child entity, then the variable property gets populated with just that entity value. When the nlpresult variable holds values for all of the child entities, then the dialog flow transitions to the next state. You can use this property in place of the SetVariable states that populate the child entity values. No
maxPrompts Specifies the number of attempts allotted to the user to enter a valid value that matches the child entity type. If the maximum number of attempts is exceeded for the first child entity, this property resets to 0 and the bot outputs the prompt for the next child entity. As described in Create a Composite Bag Entity, individual entities in the composite bag can override this setting when the Maximum User Input Attempts option is set. No
autoNumberPostbackActions When you set to true, this option prefixes numbers to options. Even when you haven’t set this option to true, auto-numbering can be enforced on list items when the digital assistant’s Enable Auto Numbering on Postback Actions configuration is set to true. Channel-specific auto-numbering can be applied to any skill bot that's registered to a digital assistant:
${(system.channelType=='twilio')?then('true','false')}
No
useFullEntityMatches When set to true, custom entity values are stored as JSON objects (similar to built-in entity values). This enables you to create expressions to access properties such as value, primaryLanguageValue, and originalString, which are particularly important for skills that are currently or eventually might become multi-lingual.  
footerText Enhances the output on text-only channels. As described in Footers, you can use FreeMarker expressions to conditionalize the footer text for text-only channels. No
headerText A message that displays before the component prompts the user for the next item in the bag. You can use this header to provide feedback on the previous entities in the bag that have been matched (or updated).
headerText: "<#list system.entityToResolve.value.updatedEntities>I have updated <#items as ent>${ent.description}<#sep> and </#items>. </#list><#list system.entityToResolve.value.outOfOrderMatches>I got <#items as ent>${ent.description}<#sep> and </#items>. </#list>"
No
transitionAfterMatch A boolean that, when you set it to true, enables a temporary transition from the entity matching performed by this component to a custom component. By default, this is false. This property is ignored (and the match transition is not triggered) if you've registered an entity event handler. No
cancelPolicy Determines the timing of the cancel transition:
  • immediate—Immediately after the allotted maxPrompts attempts have been met for an entity in the bag.

  • lastEntity—When the last entity in the bag has been matched with a value.

This property is ignored if you've registered an entity event handler with an item- or event-level maxPromptsReached handler.
No

Calendar Components

Use these calendar components to interact with Outlook and Google calendars:

Calendar Authorization

To enable interaction between a skill and a calendar provider, you need to set up a service and modify the skill and dialog flow to enable the user to sign into their calendar through that service.

Before you use any calendar component, you must register an application with the calendar provider and create an authorization code service. See these topics to learn how:

In your dialog flow, you use the System.OAuth2AccountLink component to prompt the user to sign into their calendar through the authorization code service that you created. Note that you can't set the component's enableSingleSignOn property to true when you use the component for calendar component authorization.

You can leverage the "requires authorization" feature to automatically ensure that the user has signed in (obtained an access token) before invoking any calendar components. This feature only asks the user to sign in if they don't have an access token yet or it has expired and can't be refreshed. You can use the skill's Requires Authorization configuration to set the default for the whole skill, and then use the state-level requiresAuthorization setting to override the default. That is, you use the skill setting to set the default, and then only include the component requiresAuthorization setting in the states for which the default doesn't apply.

To use the requires authorization feature, you must you add a system.authorizeUser action to the defaultTransitions node to name the state that starts the authorization flow. For example:

defaultTransitions:
  error: "globalErrorHandler"
  actions:
    system.authorizeUser: "userAuthN.performOAuth"

Before a skill transitions to a state that requires authorization, it checks to see if there's a valid access token for the calendar service. If not, it does the following actions:

  1. Invokes the state that you've defined for the system.authorizedUser action in the defaultTransitions node.

  2. Asks the user to sign in.

  3. Transitions to the state that required authorization (that is, the state defined by ${system.requestedState}).

Here's an authorization dialog flow example:

defaultTransitions:
  error: "globalErrorHandler"
  actions:
    system.authorizeUser: "userAuthN.performOAuth"

...

  ############################
  # Authenticate
  ############################
     
  userAuthN.performOAuth:
    component: "System.OAuth2AccountLink"
    properties:
      prompt: "User Authentication"
      variable: "code"
      linkLabel: "Sign into ${system.config.calendarProvider}"
      authenticationService: "${system.config.authService}"
      accessTokenVariableName: "user.accessToken"
      authenticatedUserVariableName: "user.authenticatedUser"
      enableSingleSignOn: false # SSO not supported for calendar components
    transitions:
      actions:
        pass : "${system.requestedState}"
        fail : "handleFailedLogin"
        textReceived: "intent"
  handleFailedLogin:
    component: "System.Output"
    requiresAuthorization: false
    properties:
      text: "Sorry, you aren't authorized to do that"
    transitions:
      return: "doneHandleFailedLogin" 

For a skill that's mostly focused on calendar components, consider setting the skill's Requires Authorization configuration to true, and then set the value to false only for those states that don't require authorization. In this example, any user can execute the initTimezoneOffset and intent states. Therefore, requiresAuthorization is set to false for those states. The states that work with the calendar components don't need to include requiresAuthorization because the default is true.

  initTimezoneOffset:
    requiresAuthorization: false
    component: "System.SetVariable"
    properties:
      variable: "timezoneOffset"
      value: <#attempt>${profile.timezoneOffset}<#recover>0</#attempt>      
    transitions:
      next: "intent"

  intent:
    component: "System.Intent"
    requiresAuthorization: false
    properties:
      variable: "iResult"
    transitions:
      actions:
        SetupMeeting: "setUpMeeting"
        CancelMeeting: "cancelMeeting"
        ListMeetings: "listMeetings"
        UpdateMeeting: "updateMeeting"
        ListInvites: "listInvites"
        RespondInvites: "respondInvites"
        LogoutUser: "logoutUser"
        unresolvedIntent: "greeting"

...
  cancelMeeting.performDelete:
    component: "System.DeleteCalendarEvent"
    properties:
      eventId: "${eventId}"
      provider: "${system.config.calendarProvider}"
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "cancelMeeting.printSuccessMessage"
  cancelMeeting.printSuccessMessage:
    component: "System.Output"
    properties:
      text: "I've cancelled the meeting"
    transitions:
      return: "doneCancel"

Working with Calendar Dates and Times

When working with the calendar components, it's important to understand the relationship between calendar start and end times, DATE and TIME entities, and the local timezone.

When you create, update, or retrieve events, you use the local datetime for the start and end values, and you use either the timezoneOffset or the timezone property to tell the component how to calculate the universal time (UTC).

The calendar components' timezoneOffset is different from the profile.timezoneOffset. For calendar components, timezoneOffset is the value that the component must add to the start and end values to obtain the UTC. You can derive a calendar component's' timezoneOffset property value by multiplying profile.timezoneOffset by -1.

The profile.timezoneOffset might not always be available. This depends on whether the client provided the offset. For example, someone might build an Oracle Web app that doesn't set profile.timezoneOffset. Therefore, it's a good idea to create a default timezone for cases where the profile.timezoneOffset hasn't been set. For example:

  initTimezoneOffset:
    requiresAuthorization: false
    component: "System.SetVariable"
    properties:
      variable: "timezoneOffset"
      value: <#attempt>${profile.timezoneOffset}<#recover>${system.config.defaultTimezoneOffset}</#attempt>      
    transitions:
      next: "intent

When you retrieve an event, the component returns the datetime values in UTC format. For example: 2021-04-15T22:00:00.000Z. Your skill needs to convert the value to the local time.

  updateMeeting.printEventDetails:
    component: "System.Output"
    properties:
      keepTurn: true
      text: |
        You selected:
        ${eventDetails.value.subject}
        ${(eventDetails.value.start?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['MMM d']}
        ${(eventDetails.value.start?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['hh:mm a']}-${(eventDetails.value.end?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['hh:mm a']}
        Location: ${eventDetails.value.location}        
        Attendees: ${eventDetails.value.attendees?join(', ')}     
    transitions:
      next: "updateMeeting.selectItemToChange"

When you use the DATE and TIME entities, here are some things to consider:

  • If you use a composite bag that has both a DATE entity and one or more TIME entities, then you must disable Out of Order Extraction. Otherwise, when the entities are resolved, you don't have control over which values resolve to the DATE entity and which values resolve to the TIME entity (or both). For example, when the TIME is resolved, it might change the value of the DATE entity.

  • When an utterance contains text such as "yesterday", "today", or "tomorrow", the parser doesn't take the local time zone into consideration. Therefore, it's possible that, in the early morning and late afternoon, the wrong date might be used. For that reason, it's a good idea to echo back the resolved date so that the user can verify it before the skill adds an event or updates an event's start or end time.

  • To set a calendar's start and end property values, you must use the date from the DATE entity and the time from the TIME entity. For example:

          start: "${newEvent.value.date.date?number_to_date?string['yyyy-MM-dd']}T${newEvent.value.startTime.date?number_to_date?string['HH:mm:ss']}"
          end: "${newEvent.value.date.date?number_to_date?string['yyyy-MM-dd']}T${newEvent.value.endTime.date?number_to_date?string['HH:mm:ss']}"

Handling Calendar Errors

The calendar provider may reject an event request. For example, it might return an error if the user tries to create an event that has an end time earlier than the start time. In most cases, the calendar provider returns a 400 error, which, in turn, transitions the skill to the global error handler.

Consider validating the values to prevent these errors from occurring. Here are examples of composite bag entity validations:

  • DATE entity: For new and updated meetings, validate that the date is on or after the current date.

    ${(meetingSlot.value.date.date?number?long gte  ((.now?date?long - timezoneOffset?number?long)?number_to_date?string['yyyy-MM-dd']+'T00:00:00')?datetime.iso?long)?then('true','false')}
  • TIME entity: For new and updated meetings, verify that the date and start time are on or after the current datetime.

    ${(((meetingSlot.value.date.date?number_to_date?string['yyyy-MM-dd']+'T'+meetingSlot.value.startTime.date?number_to_date?string['HH:mm:ss'])?datetime.iso?long) gte (.now?date?long - timezoneOffset?number))?then('true','false')}

    For all end times, verify that the end time is after the start time.

    ${(newEvent.value.startTime.date?number_to_time < newEvent.value.endTime.date?number_to_time)?then('true','false')}

To handle calendar-provider rejections gracefully, add your own global error handler. For example:

defaultTransitions:
  error: "globalErrorHandler"
  actions:
    system.authorizeUser: "userAuthN.performOAuth"

...

  globalErrorHandler:
    requiresAuthorization: false
    component: "System.Output"
    properties:
      text: "Sorry, we were unable to do the action that you requested."
    transitions:
      return: "done"

Alternatively, you can use the error transition to create error handlers that are appropriate for each case:

  setUpMeeting.performSchedule:
    component: "System.CreateCalendarEvent"
    properties:
      start: "${newEvent.value.date.date?number_to_date?string['yyyy-MM-dd']}T${newEvent.value.startTime.date?number_to_date?string['HH:mm:ss']}"
      end: "${newEvent.value.date.date?number_to_date?string['yyyy-MM-dd']}T${newEvent.value.endTime.date?number_to_date?string['HH:mm:ss']}"
      subject: "${newEvent.value.subject}"
      location: "${newEvent.value.location}"
      attendees: "${newEvent.value.attendees}"
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "setUpMeeting.printResults"
      error: "handleCreateEventError"

...

  handleCreateEventError:
    requiresAuthorization: false
    component: "System.Output"
    properties:
      text: "Sorry, there's a problem with the event that you wanted to create."
    transitions:
      return: "done"

System.CreateCalendarEvent

Use this component to add an event to an Outlook or Google calendar. Note that you can't create recurring or all-day events.

The user must be signed in to the calendar provider to access this component. You can use the "requires authorization" feature to manage user sign in, as described in Calendar Authorization.

To learn how to set the start and end values, see Working with Calendar Dates and Times.

Here's an example of how to use this component. In this example, a composite bag entity is used to get the date, start and end times, subject, location, and attendees.


  ####################
  # Create Meeting 
  ####################

  setUpMeeting:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      processUserMessage: true
      variable: "newEvent"
      nlpResultVariable: "iResult"     
      cancelPolicy: "immediate"
      transitionAfterMatch: "false"
      metadata:
        responseItems:       
          - type: "text"
            text: "${system.entityToResolve.value.prompt}"
            actions:
              - label: "${enumValue}"
                type: "postback"
                iteratorVariable: "system.entityToResolve.value.enumValues"
                payload:
                  variables:
                    newEvent: "${enumValue}"
        globalActions:
          - label: "Cancel"
            type: "postback"
            visible:
              onInvalidUserInput: false
            payload:
             action: "cancel"
    transitions:
      actions:
        cancel: "allDone"
      next: "setUpMeeting.askConfirm"       
  setUpMeeting.askConfirm:
    component: "System.CommonResponse"
    properties:
      processUserMessage: true
      metadata:
        responseItems:
          - type: "text"
            text: |
              Create ${newEvent.value.subject} meeting on ${newEvent.value.date.date?number_to_date?string['MMM d']}
              from ${newEvent.value.startTime.date?number_to_date?string['hh:mm a']} to ${newEvent.value.endTime.date?number_to_date?string['hh:mm a']}
              at ${newEvent.value.location} with ${newEvent.value.attendees}?
            name: "confirmCreate"
            separateBubbles: true
            actions:
              - label: "Yes"
                type: "postback"
                keyword: "yes"
                payload:
                  action: "yes"
                name: "Yes"
              - label: "No"
                keyword: "no"
                type: "postback"
                payload:
                  action: "no"
                name: "No"
    transitions:
      next: "intent"
      actions:
        yes: "setUpMeeting.performSchedule"
        no: "allDone"
        textReceived: "intent"      
  setUpMeeting.performSchedule:
    component: "System.CreateCalendarEvent"
    properties:
      start: "${newEvent.value.date.date?number_to_date?string['yyyy-MM-dd']}T${newEvent.value.startTime.date?number_to_date?string['HH:mm:ss']}"
      end: "${newEvent.value.date.date?number_to_date?string['yyyy-MM-dd']}T${newEvent.value.endTime.date?number_to_date?string['HH:mm:ss']}"
      subject: "${newEvent.value.subject}"
      location: "${newEvent.value.location}"
      attendees: "${newEvent.value.attendees}"
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "setUpMeeting.printResults"
      error: "handleCreateCalendarError"
  setUpMeeting.printResults:
    component: "System.Output"
    properties:
      text: "The ${newEvent.value.date.date?number_to_date?string['MMM d']} meeting is now on your calendar."
      keepTurn: true
    transitions:
      next: "setUpMeeting.getMeetings"
...
Note

This component is supported in Oracle Digital Assistant Version 21.02 and later.
Property Description Required?
provider The calendar provider. The allowed values are Google and Outlook. Yes
calendarOwner The user ID of the calendar owner. It must be a valid account ID for the calendar provider, such as the value of the variable that's identified by the System.OAuth2AccountLink component's authenticatedUserVariable property, which is set when the user authenticates. Yes
calendarId The name of the calendar. For the user's default calendar, set to the same value as the calendarOwner property. Yes
credential The provider's access token. This is the value of the variable that's identified by the System.OAuth2AccountLink component's accessTokenVariableName property, which is set when the user authenticates. Yes
start The meeting's start date and time in the format yyyy-MM-dd'T'HH:mm:ss For example, 2021-02-26T09:55:00. Yes
end The meeting's end date and time in the format yyyy-MM-dd'T'HH:mm:ss. For example, 2021-02-26T09:55:00. Yes
subject The subject of the meeting. Yes
attendees A comma separated list of attendees. Note that the calendar provider can't send a notification to an attendee if the ID isn't a valid account ID for that provider. Yes
timezoneOffset The amount of time in milliseconds to add to universal time (UTC) to get standard time in the user's time zone. For example, if the local time zone is UTC-2, then the timezoneOffset is -7200000. The default value is 0.
Note

You can derive the timezoneOffset property for the current user based on the value of the user context variable profile.timezoneOffset. However, if you do so, you must multiply profile.timezoneOffset by -1.

You can specify timezoneOffset or timezone but not both.

No
timezone

The local time zone's ID as identified by https://www.iana.org/time-zones. Also referred to as the TZ database name. For example: America/Los_Angeles. The default is UTC. You can specify timezoneOffset or timezone but not both.

No

System.DeleteCalendarEvent

Use this component to delete an event from an Outlook or Google calendar. Note that you can't delete recurring or all-day events.

The user must be signed in to the calendar provider to access this component. You can use the "requires authorization" feature to manage user sign in, as described in Calendar Authorization.

Here's an example of how to use this component.


  ####################
  # Cancel Meeting
  ####################
  
  # Want to select from deletable meetings

  cancelMeeting:
    component: "System.SetVariable"
    properties:
      variable: "stateAfterList"
      value: "cancelMeeting.confirmCancel"
    transitions:
      next: "cancelMeeting.setListType"
  cancelMeeting.setListType:
    component: "System.SetVariable"
    properties:
      variable: "listType"
      # Only show deletable meetings
      value: "DELETE"
    transitions:
      next: "cancelMeeting.setListPrompt"
  cancelMeeting.setListPrompt:
    component: "System.SetVariable"
    properties:
      variable: "listPrompt"
      value: "to cancel"
    transitions:
      next: "listMeetings.commonEntryPoint"

  # List meetings common code returns to this state
  cancelMeeting.confirmCancel:
    component: "System.ResetVariables"
    properties:
      variableList: "confirmAction"
    transitions:
      next: "cancelMeeting.askConfirm"      
  cancelMeeting.askConfirm:
    component: "System.CommonResponse"
    properties:
      processUserMessage: true
      metadata:
        responseItems:
          - type: "text"
            text: "Are you sure you want to cancel this meeting?"
            name: "confirmCcancel"
            separateBubbles: true
            actions:
              - label: "Yes"
                type: "postback"
                keyword: "yes"
                payload:
                  action: "yes"
                name: "Yes"
              - label: "No"
                keyword: "no"
                type: "postback"
                payload:
                  action: "no"
                name: "No"
    transitions:
      next: "intent"
      actions:
        yes: "cancelMeeting.performDelete"
        no: "allDone"
        textReceived: "intent"
  cancelMeeting.performDelete:
    component: "System.DeleteCalendarEvent"
    properties:
      eventId: "${eventId}"
      provider: "${system.config.calendarProvider}"
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "cancelMeeting.printSuccessMessage"
  cancelMeeting.printSuccessMessage:
    component: "System.Output"
    properties:
      text: "I've cancelled the meeting"
    transitions:
      return: "doneCancel"
  ...

  ############################
  # List Meetings Shared Code
  ############################
  
  listMeetings.commonEntryPoint:
    component: "System.SetVariable"
    properties:
      variable: "inputDate"
      value: "${iResult.value.entityMatches['DATE'][0]}"
    transitions:
      next: "listMeetings.setDate"
  listMeetings.setDate:
    component: "System.SetVariable"
    properties:
      variable: "start"
      value: "${inputDate.value?has_content?then(inputDate.value.date?number_to_date?string['yyyy-MM-dd'], (.now?date?long - timezoneOffset?number?long)?number_to_date?string['yyyy-MM-dd'])}T00:00:00"
    transitions:
      next: "listMeetings.clearInputDate"  
  listMeetings.clearInputDate:
    component: "System.ResetVariables"
    properties:
      variableList: "inputDate"
    transitions:
      next: "listMeetings.filterByAttendees"
  listMeetings.filterByAttendees:
    component: "System.CommonResponse"
    properties:
      processUserMessage: true
      metadata:
        responseItems:
          - type: "text"
            text: "Do you want to list only meetings with a particular attendee?"
            name: "confirmFilter"
            separateBubbles: true
            actions:
              - label: "Yes"
                type: "postback"
                keyword: "yes"
                payload:
                  action: "yes"
                name: "Yes"
              - label: "No"
                keyword: "no"
                type: "postback"
                payload:
                  action: "no"
                name: "No"
    transitions:
      next: "intent"
      actions:
        yes: "listMeetings.resolveAttendeesFilter"
        no: "listMeetings.clearAttendeesFilter"
        textReceived: "intent"

  # clear filter 
  
  listMeetings.clearAttendeesFilter:
    component: "System.ResetVariables"
    properties:
      variableList: "attendees"
    transitions:
      next: "listMeetings.performList"

  # resolve filter

  listMeetings.resolveAttendeesFilter:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      processUserMessage: true
      variable: "attendees"
      nlpResultVariable: "iResult"
      metadata:
        responseItems:
          - type: "text"
            text: "Who is the attendee?"
    transitions:
      next: "listMeetings.performAttendeesList"
      actions:
        textReceived: "listMeetings.performAttendeesList"

  # perform attendees list 

  listMeetings.performAttendeesList:
    component: "System.SelectCalendarEvent"
    properties:
      listType: "${listType}"
      start: "${start}"
      attendees: "${attendees}"
      prompt: "Choose the ${start?datetime.iso?long?number_to_date?string['MMM d']} meeting ${listPrompt}:"
      eventIdVariableName: "eventId"
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      actions:
        found: "${stateAfterList}"
        notfound: "listMeetings.printNotFoundMessage"
      next: "globalErrorHandler"

  # perform list 

  listMeetings.performList:
    component: "System.SelectCalendarEvent"
    properties:
      listType: "${listType}"
      start: "${start}"
      prompt: "Choose the ${start?datetime.iso?long?number_to_date?string['MMM d']} meeting ${listPrompt}:"
      eventIdVariableName: "eventId"
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      actions:
        found: "${stateAfterList}"
        notfound: "listMeetings.printNotFoundMessage"
      next: "globalErrorHandler"

  listMeetings.printNotFoundMessage:
    component: "System.Output"
    properties:
      text: "There are no meetings on ${start?datetime.iso?long?number_to_date?string['MMM d']}"
    transitions:
      return: "doneListMeetings"
...
Note

This component is supported in Oracle Digital Assistant Version 21.02 and later.
Property Description Required?
provider The calendar provider. The allowed values are Google and Outlook. Yes
calendarOwner The user ID of the calendar owner. It must be a valid account ID for the calendar provider, such as the value of the variable that's identified by the System.OAuth2AccountLink component's authenticatedUserVariable property, which is set when the user authenticates. Yes
calendarId The name of the calendar. For the user's default calendar, set to the same value as the calendarOwner property. Yes
credential The provider's access token. This is the value of the variable that's identified by the System.OAuth2AccountLink component's accessTokenVariableName property, which is set when the user authenticates. Yes
eventId The ID of the event to delete. You can use System.ListCalendarEvents or System.SelectCalendarEvent to get an eventId. Yes

System.GetCalendarEventDetails

Use this component to get an event's details from an Outlook or Google calendar.

The user must be signed in to the calendar provider to access this component. You can use the "requires authorization" feature to manage user sign in, as described in Calendar Authorization.

The details are returned in the variable that's specified by the eventDetailsVariableName property in the following JSON format:

{
  "isAllDay": boolean,
  "subject": string,
  "inviteResponse": string,
  "attendees": [
    "string",
      ...
  ],
  "start": format yyyy-MM-dd'T'HH:mm:ss.SSSZ,
  "end":  format yyyy-MM-dd'T'HH:mm:ss.SSSZ,
  "location": string,
  "isRecurring": boolean,
  "id": string
}

The start and end properties are UTC values. To learn how to convert the start and end values to local time, see Working with Calendar Dates and Times.

Here's an example of how to use this component.

  listMeetings.performGetDetails:
    component: "System.GetCalendarEventDetails"
    properties:
      eventId: "${eventId}"
      eventDetailsVariableName: "eventDetails"
      provider: "${system.config.calendarProvider}"
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "listMeetings.checkIfResults"
  # In case the eventId is no longer valid
  listMeetings.checkIfResults:
    component: "System.ConditionExists"
    properties:
      variable: "eventDetails"
    transitions:
      actions:
        exists: "listMeetings.printEventDetails"
        notexists: "globalErrorHandler" 
  listMeetings.printEventDetails:
    component: "System.Output"
    properties:
      text: |
        ${eventDetails.value.subject}
        ${(eventDetails.value.start?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['MMM d']}
        ${(eventDetails.value.start?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['hh:mm a']}-${(eventDetails.value.end?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['hh:mm a']}
        Location: ${eventDetails.value.location}        
        Attendees: ${eventDetails.value.attendees?join(', ')} 
    transitions:
      return: "doneGetDetails"
Note

This component is supported in Oracle Digital Assistant Version 21.02 and later.
Property Description Required?
provider The calendar provider. The allowed values are Google and Outlook. Yes
calendarOwner The user ID of the calendar owner. It must be a valid account ID for the calendar provider, such as the value of the variable that's identified by the System.OAuth2AccountLink component's authenticatedUserVariable property, which is set when the user authenticates. Yes
calendarId The name of the calendar. For the user's default calendar, set to the same value as the calendarOwner property. Yes
credential The provider's access token. This is the value of the variable that's identified by the System.OAuth2AccountLink component's accessTokenVariableName property, which is set when the user authenticates. Yes
eventId The ID of the event to retrieve. You can use System.ListCalendarEvents or System.SelectCalendarEvent to get an eventId. Yes
eventDetailsVariableName The name of the context variable in which to store the details. Yes

System.ListCalendarEvents

Use this component to get an array of Outlook or Google events for a named calender owner. You can filter the list by these attributes:

  • The event can be deleted
  • The event can be updated
  • The user was invited to the event
  • How the user has responded to an invitation
  • The event includes one or more named attendees
  • The meeting starts after a date and time
  • The meeting ends before a date and time

The user must be signed in to the calendar provider to access this component. You can use the "requires authorization" feature to manage user sign in, as described in Calendar Authorization.

The list is returned in the variable that's specified by the eventListVariableName property in the following JSON format:

[{
  "isAllDay": boolean,
  "subject": string,
  "inviteResponse": string,
  "start": format yyyy-MM-dd'T'HH:mm:ss.SSSZ,
  "end":  format yyyy-MM-dd'T'HH:mm:ss.SSSZ,
  "isRecurring": boolean,
  "id": string
}, …]

To learn how to set the start and end values, see Working with Calendar Dates and Times. That topic also shows how to convert the JSON start and end property values to local time.

Here's an example of how to use this component.

  ############################
  # List Invites
  ############################

  listInvites:
    component: "System.ListCalendarEvents"
    properties:
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
      listType: "INVITED"
      response: "PENDING,ACCEPTED,TENTATIVE,DECLINED"
      eventListVariableName: "eventList"
      start: "${(.now?date?long - timezoneOffset?number?long)?number_to_date?string['yyyy-MM-dd']}T00:00:00"
    transitions:
      next: "globalErrorHandler"
      actions:
        found: "listInvites.printMeetings"
        notfound: "listInvites.notFound"
  listInvites.printMeetings:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      metadata:
        responseItems:
        - type: "text"
          # display the local time
          text: |
            ${eventList.subject} [${eventList.inviteResponse}]
            ${(eventList.start?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['MMM d hh:mm a']} to ${(eventList.end?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['hh:mm a']}           
          name: "event"
          separateBubbles: true
          iteratorVariable: "eventList"
      processUserMessage: false
    transitions:
      return: "listInvitesDone"
  listInvites.notFound:
    component: "System.Output"
    properties:
      keepTurn: true
      text: "You don't have any invitations for the next 14 days"
    transitions:
      return: "listInvitesDone"      
Note

This component is supported in Oracle Digital Assistant Version 21.02 and later.
Property Description Required?
provider The calendar provider. The allowed values are Google and Outlook. Yes
calendarOwner The user ID of the calendar owner. It must be a valid account ID for the calendar provider, such as the value of the variable that's identified by the System.OAuth2AccountLink component's authenticatedUserVariable property, which is set when the user authenticates. Yes
calendarId The name of the calendar. For the user's default calendar, set to the same value as the calendarOwner property. Yes
credential The provider's access token. This is the value of the variable that's identified by the System.OAuth2AccountLink component's accessTokenVariableName property, which is set when the user authenticates. Yes
listType Indicates the type of list. Must be one of the following:
  • ALL: All types of the calender owner's meetings
  • DELETE: All of the meetings that the calender owner can delete
  • UPDATE: All of the meetings that the calender owner can update
  • INVITED: All of the meetings that the calender owner has been invited to
Yes
eventListVariableName The name of the context variable in which to store the events list. Yes
start The earliest date and time for which meetings should be included in the list (format: yyyy-MM-dd'T'HH:mm:ss). For example, 2021-02-26T09:55:00. Yes
end The latest date and time for which meetings should be included in the list (format: yyyy-MM-dd'T'HH:mm:ss). For example, 2021-02-26T09:55:00.

For list type INVITED the default is 14 days after the start date and time. For all other types, the default is 24 hours after the start date and time.

No
attendees A comma-separated, case-insensitive list of strings to use to filter the list by attendees. Only meetings where one or more attendee values contain one or more strings in the list are included in the output. No
response A comma-separated list of invitation statuses to filter the list on when the listType is INVITED. The allowable statuses are:
  • ACCEPTED
  • TENTATIVE
  • DECLINED
  • PENDING

The default is PENDING,TENTATIVE, which outputs only invitations which are waiting for a response or have been accepted tentatively.

No
timezoneOffset The amount of time in milliseconds to add to universal time (UTC) to get standard time in the user's time zone. For example, if the local time zone is UTC-2, then the timezoneOffset is -7200000. The default value is 0.
Note

You can derive the timezoneOffset property for the current user based on the value of the user context variable profile.timezoneOffset. However, if you do so, you must multiply profile.timezoneOffset by -1.

You can specify timezoneOffset or timezone but not both.

No
timezone The local time zone's ID as identified by https://www.iana.org/time-zones. Also referred to as the TZ database name. For example: America/Los_Angeles. The default is UTC. You can specify timezoneOffset or timezone but not both. No

This component can return the following actions:

Action Description
found One or more events were returned.
notfound There are no matching events.

System.SelectCalendarEvent

Use this component to display a list of Outlook or Google events that the user can select from. The component saves the ID of the selected event in the variable that's specified by the eventIdVariableName property.

You can filter the list to select from by these attributes:

  • The event can be deleted
  • The event can be updated
  • The user was invited to the event
  • How the user has responded to an invitation
  • The event includes one or more named attendees
  • The meeting starts after a date and time
  • The meeting ends before a date and time

The user must be signed in to the calendar provider to access this component. You can use the "requires authorization" feature to manage user sign in, as described in Calendar Authorization.

To learn how to set the start and end values, see Working with Calendar Dates and Times.

Here's an example of how to use this component.

  ############################
  # Respond Invites
  ############################
      
  respondInvites.performList:
    component: "System.SelectCalendarEvent"
    properties:
      listType: "INVITED"
      response: "${inviteFilter}"
      # Note: For list type INVITED the default end date is 14 days after the start date and time.
      start: "${(.now?date?long - timezoneOffset?number?long)?number_to_date?string['yyyy-MM-dd']}T00:00:00"
      prompt: "Select the invitation to send the response to:"
      eventIdVariableName: "eventId"
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "globalErrorHandler"
      actions:
        found: "respondInvites.resolveInviteResponse"
        notfound: "respondInvites.printNotFoundMessage"

  respondInvites.printNotFoundMessage:
    component: "System.Output"
    properties:
      text: "There are no meeting invites."
    transitions:
      return: "allDone"
  ...

Note

This component is supported in Oracle Digital Assistant Version 21.02 and later.
Property Description Required?
provider The calendar provider. The allowed values are Google and Outlook. Yes
calendarOwner The user ID of the calendar owner. It must be a valid account ID for the calendar provider, such as the value of the variable that's identified by the System.OAuth2AccountLink component's authenticatedUserVariable property, which is set when the user authenticates. Yes
calendarId The name of the calendar. For the user's default calendar, set to the same value as the calendarOwner property. Yes
credential The provider's access token. This is the value of the variable that's identified by the System.OAuth2AccountLink component's accessTokenVariableName property, which is set when the user authenticates. Yes
listType Indicates the type of list. Must be one of the following:
  • ALL: All types of the calender owner's meetings
  • DELETE: All of the meetings that the calender owner can delete
  • UPDATE: All of the meetings that the calender owner can update
  • INVITED: All of the meetings that are not organized by the calender owner but the owner is invited to attend.
Yes
eventIdVariableName The name of the context variable in which to store the event's ID. Yes
start The earliest date and time for which meetings should be included in the list (format: yyyy-MM-dd'T'HH:mm:ss). For example, 2021-02-26T09:55:00. Yes
end The latest date and time for which meetings should be included in the list (format: yyyy-MM-dd'T'HH:mm:ss). For example, 2021-02-26T09:55:00.

For list type INVITED the default is 14 days after the start date and time. For all other types, the default is 24 hours after the start date and time.

No
attendees A comma-separated, case-insensitive list of strings to use to filter the list by attendees. Only meetings where one or more attendee values contain one or more strings in the list are included in the output. No
response A comma-separated list of invitation statuses to filter the list on when the listType is INVITED. The allowable statuses are:
  • ACCEPTED
  • TENTATIVE
  • DECLINED
  • PENDING

The default is PENDING,TENTATIVE, which outputs only invitations which are waiting for a response or have been accepted tentatively.

No
prompt The text that appears before the list. The default is You have the following meeting(s): You don't need to include this property unless you want to override the default.

Tip:

In skills with platform version 21.04 and later, the default value is stored in the skill's resource bundle. To change the default, open the skill's Resources Bundle page, click Resource Bundles icon, select the Configuration tab, and change the message for the SelectCalendarEvent - prompt key.
No
allDayLabel The text to indicate all-day events. The default is All day. No
recurringLabel The text to indicate a recurring event. The default is Recurring. No
acceptedLabel The text to indicate that the calendar owner accepted the invitation. The default is Accepted. No
tentativeLabel The text to indicate that the calendar owner tentatively accepted the invitation. The default is Tentative. No
declinedLabel The text to indicate that the calendar owner declined the invitation. The default is Declined. No
pendingLabel The text to indicate that the calendar owner hasn't responded to the invitation. The default is Pending. No
timezoneOffset The amount of time in milliseconds to add to universal time (UTC) to get standard time in the user's time zone. For example, if the local time zone is UTC-2, then the timezoneOffset is -7200000. The default value is 0.
Note

You can derive the timezoneOffset property for the current user based on the value of the user context variable profile.timezoneOffset. However, if you do so, you must multiply profile.timezoneOffset by -1.

You can specify timezoneOffset or timezone but not both.

No
timezone The local time zone's ID as identified by https://www.iana.org/time-zones. Also referred to as the TZ database name. For example: America/Los_Angeles. The default is UTC. You can specify timezoneOffset or timezone but not both. No

This component can return the following actions:

Action Description
found One or more events were returned.
notfound There are no matching events.

System.SendInviteResponse

Use this component to accept, tentatively accept, or decline an invitation for an Outlook or Google calendar event.

The user must be signed in to the calendar provider to access this component. You can use the "requires authorization" feature to manage user sign in, as described in Calendar Authorization.

Here's an example of how to use this component.


  ############################
  # Respond Invites
  ############################
      
  respondInvites:
    component: "System.CommonResponse"
    properties:
      processUserMessage: true
      metadata:
        responseItems:
          - type: "text"
            text: "Which types of meeting invitations do you want to respond to?"
            name: "getInviteFilter"
            separateBubbles: true
            actions:
              - label: "Pending and tentatively accepted invitations"
                type: "postback"
                keyword: "PENDING,TENTATIVE"
                payload:
                  variables: 
                    inviteFilter: "PENDING,TENTATIVE"
              - label: "All invitations"
                keyword: "PENDING,ACCEPTED,TENTATIVE,DECLINED"
                type: "postback"                
                payload:
                  variables: 
                    inviteFilter: "PENDING,ACCEPTED,TENTATIVE,DECLINED"
              - label: "Cancel"
                keyword: "cancel"
                type: "postback"                
                payload:
                  action: "allDone" 
    transitions:
      actions:
        allDone: "allDone"
        textReceived: "intent" 
      next: "respondInvites.performList"
  respondInvites.performList:
    component: "System.SelectCalendarEvent"
    properties:
      listType: "INVITED"
      response: "${inviteFilter}"
      # Note: For list type INVITED the default end date is 14 days after the start date and time.
      start: "${(.now?date?long - timezoneOffset?number?long)?number_to_date?string['yyyy-MM-dd']}T00:00:00"
      prompt: "Select the invitation to send the response to:"
      eventIdVariableName: "eventId"
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "globalErrorHandler"
      actions:
        found: "respondInvites.resolveInviteResponse"
        notfound: "respondInvites.printNotFoundMessage"
  respondInvites.printNotFoundMessage:
    component: "System.Output"
    properties:
      text: "There are no meeting invites."
    transitions:
      return: "allDone"

  ############################
  # Invite Response
  ############################
      
  respondInvites.resolveInviteResponse:
    component: "System.CommonResponse"
    properties:
      processUserMessage: true
      metadata:
        responseItems:
          - type: "text"
            text: "Choose a response:"
            name: "getInviteResponse"
            separateBubbles: true
            actions:
              - label: "Accept"
                type: "postback"
                keyword: "ACCEPTED"
                payload:
                  variables: 
                    inviteResponse: "ACCEPTED"
              - label: "Tentatively accept"
                keyword: "TENTATIVE"
                type: "postback"                
                payload:
                  variables: 
                    inviteResponse: "TENTATIVE"
              - label: "Decline"
                keyword: "DECLINED"
                type: "postback"                
                payload:
                  variables: 
                    inviteResponse: "DECLINED"
              - label: "Don't send a response"
                keyword: "CANCEL"
                type: "postback"                
                payload:
                  action: "allDone" 
    transitions:
      actions:
        allDone: "allDone"
        textReceived: "intent" 
      next: "respondInvites.performRespond"
  respondInvites.performRespond:
    component: "System.SendInviteResponse"
    properties:
      eventId: "${eventId}"
      response: "${inviteResponse}"
      provider: "${system.config.calendarProvider}"
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions: 
      next: "respondInvites.printSuccessMessage"
  respondInvites.printSuccessMessage:
    component: "System.Output"
    properties:
      text: "I've sent the meeting invitation response"
    transitions:
      return: "doneSendInviteResponse"
Note

This component is supported in Oracle Digital Assistant Version 21.02 and later.
Property Description Required?
provider The calendar provider. The allowed values are Google and Outlook. Yes
calendarOwner The user ID of the calendar owner. It must be a valid account ID for the calendar provider, such as the value of the variable that's identified by the System.OAuth2AccountLink component's authenticatedUserVariable property, which is set when the user authenticates. Yes
calendarId The name of the calendar. For the user's default calendar, set to the same value as the calendarOwner property. Yes
credential The provider's access token. This is the value of the variable that's identified by the System.OAuth2AccountLink component's accessTokenVariableName property, which is set when the user authenticates. Yes
eventId The ID of the event to send the response to. You can use System.ListCalendarEvents or System.SelectCalendarEvent to get the ID of calender events to which the calendar owner was invited. Yes
response The response to send. The allowable responses are:
  • ACCEPTED
  • TENTATIVE
  • DECLINED
Yes

System.UpdateCalendarEvent

Use this component to make changes to an Outlook or Google calendar event. Note that you can't update recurring or all-day events.

The user must be signed in to the calendar provider to access this component. You can use the "requires authorization" feature to manage user sign in, as described in Calendar Authorization.

To learn how to set the start and end values, see Working with Calendar Dates and Times.

Here's an example of how to use this component. In this example, a composite bag entity is used to get the date, the start time, and the end time.


  ####################
  # Update Meeting 
  ####################
 
  updateMeeting:
    component: "System.SetVariable"
    properties:
      variable: "stateAfterList"
      value: "updateMeeting.performGetDetails"
    transitions:
      next: "updateMeeting.setListType"
  updateMeeting.setListType:
    component: "System.SetVariable"
    properties:
      variable: "listType"
      # Only show updateable meetings
      value: "UPDATE"
    transitions:
      next: "updateMeeting.setListPrompt"
  updateMeeting.setListPrompt:
    component: "System.SetVariable"
    properties:
      variable: "listPrompt"
      value: "to update"
    transitions:
      next: "listMeetings.commonEntryPoint"

  # List meetings common code returns to this state
  updateMeeting.performGetDetails:
    component: "System.GetCalendarEventDetails"
    properties:
      eventId: "${eventId}"
      eventDetailsVariableName: "eventDetails"
      provider: "${system.config.calendarProvider}"
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "updateMeeting.checkIfResults"      
  updateMeeting.checkIfResults:
    component: "System.ConditionExists"
    properties:
      variable: "eventDetails"
    transitions:
      actions:
        exists: "updateMeeting.printEventDetails"
        notexists: "globalErrorHandler"  
  updateMeeting.printEventDetails:
    component: "System.Output"
    properties:
      keepTurn: true
      text: |
        You selected:
        ${eventDetails.value.subject}
        ${(eventDetails.value.start?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['MMM d']}
        ${(eventDetails.value.start?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['hh:mm a']}-${(eventDetails.value.end?datetime.iso?long - timezoneOffset?number?long)?number_to_date?string['hh:mm a']}
        Location: ${eventDetails.value.location}        
        Attendees: ${eventDetails.value.attendees?join(', ')}     
    transitions:
      next: "updateMeeting.updateTime"

  # Change meeting time
      
  updateMeeting.updateTime:
    component: "System.ResolveEntities"
    properties:
      variable: "meetingSlot"
      nlpResultVariable: "iResult"      
      maxPrompts: 5
      cancelPolicy: "immediate" 
    transitions:
      actions:
        cancel: "allDone"
      next: "updateMeeting.setStart"      
  updateMeeting.setStart:
    component: "System.SetVariable"
    properties:
      variable: "start"
      value: "${meetingSlot.value.date.date?number_to_date?string['yyyy-MM-dd']}T${meetingSlot.value.startTime.date?number_to_date?string['HH:mm:ss']}"
    transitions:
      next: "updateMeeting.setEnd"
  updateMeeting.setEnd:
    component: "System.SetVariable"
    properties:
      variable: "end"
      value: "${meetingSlot.value.date.date?number_to_date?string['yyyy-MM-dd']}T${meetingSlot.value.endTime.date?number_to_date?string['HH:mm:ss']}"
    transitions:
      next: "updateMeeting.updateTime.performUpdate"
  updateMeeting.updateTime.performUpdate:
    component: "System.UpdateCalendarEvent"
    properties:
      eventId: "${eventId}"
      start: "${start}"
      end: "${end}"
      provider: "${system.config.calendarProvider}"
      #timezone: "${system.config.timezoneID}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      next: "updateMeeting.printSuccessMessage"
      error: "handleUpdateCalendarError"
  ...

  ############################
  # List Meetings Shared Code
  ############################
  
  listMeetings.commonEntryPoint:
    component: "System.SetVariable"
    properties:
      variable: "inputDate"
      value: "${iResult.value.entityMatches['DATE'][0]}"
    transitions:
      next: "listMeetings.setDate"
  listMeetings.setDate:
    component: "System.SetVariable"
    properties:
      variable: "start"
      value: "${inputDate.value?has_content?then(inputDate.value.date?number_to_date?string['yyyy-MM-dd'], (.now?date?long - timezoneOffset?number?long)?number_to_date?string['yyyy-MM-dd'])}T00:00:00"
    transitions:
      next: "listMeetings.clearInputDate"  
  listMeetings.clearInputDate:
    component: "System.ResetVariables"
    properties:
      variableList: "inputDate"
    transitions:
      next: "listMeetings.filterByAttendees"
  listMeetings.filterByAttendees:
    component: "System.CommonResponse"
    properties:
      processUserMessage: true
      metadata:
        responseItems:
          - type: "text"
            text: "Do you want to list only meetings with a particular attendee?"
            name: "confirmFilter"
            separateBubbles: true
            actions:
              - label: "Yes"
                type: "postback"
                keyword: "yes"
                payload:
                  action: "yes"
                name: "Yes"
              - label: "No"
                keyword: "no"
                type: "postback"
                payload:
                  action: "no"
                name: "No"
    transitions:
      next: "intent"
      actions:
        yes: "listMeetings.resolveAttendeesFilter"
        no: "listMeetings.clearAttendeesFilter"
        textReceived: "intent"

  # clear filter 
  
  listMeetings.clearAttendeesFilter:
    component: "System.ResetVariables"
    properties:
      variableList: "attendees"
    transitions:
      next: "listMeetings.performList"

  # resolve filter

  listMeetings.resolveAttendeesFilter:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      processUserMessage: true
      variable: "attendees"
      nlpResultVariable: "iResult"
      metadata:
        responseItems:
          - type: "text"
            text: "Who is the attendee?"
    transitions:
      next: "listMeetings.performAttendeesList"
      actions:
        textReceived: "listMeetings.performAttendeesList"

  # perform attendees list 

  listMeetings.performAttendeesList:
    component: "System.SelectCalendarEvent"
    properties:
      listType: "${listType}"
      start: "${start}"
      attendees: "${attendees}"
      prompt: "Choose the ${start?datetime.iso?long?number_to_date?string['MMM d']} meeting ${listPrompt}:"
      eventIdVariableName: "eventId"
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      actions:
        found: "${stateAfterList}"
        notfound: "listMeetings.printNotFoundMessage"
      next: "globalErrorHandler"

  # perform list 

  listMeetings.performList:
    component: "System.SelectCalendarEvent"
    properties:
      listType: "${listType}"
      start: "${start}"
      prompt: "Choose the ${start?datetime.iso?long?number_to_date?string['MMM d']} meeting ${listPrompt}:"
      eventIdVariableName: "eventId"
      provider: "${system.config.calendarProvider}"
      timezoneOffset: ${timezoneOffset?number * -1}
      calendarOwner: "${user.authenticatedUser}"
      calendarId: "${user.authenticatedUser}"
      credential: "${user.accessToken}"
    transitions:
      actions:
        found: "${stateAfterList}"
        notfound: "listMeetings.printNotFoundMessage"
      next: "globalErrorHandler"

  listMeetings.printNotFoundMessage:
    component: "System.Output"
    properties:
      text: "There are no meetings on ${start?datetime.iso?long?number_to_date?string['MMM d']}"
    transitions:
      return: "doneListMeetings"
...
Note

This component is supported in Oracle Digital Assistant Version 21.02 and later.
Property Description Required?
provider The calendar provider. The allowed values are Google and Outlook. Yes
calendarOwner The user ID of the calendar owner. It must be a valid account ID for the calendar provider, such as the value of the variable that's identified by the System.OAuth2AccountLink component's authenticatedUserVariable property, which is set when the user authenticates. Yes
calendarId The name of the calendar. For the user's default calendar, set to the same value as the calendarOwner property. Yes
credential The provider's access token. This is the value of the variable that's identified by the System.OAuth2AccountLink component's accessTokenVariableName property, which is set when the user authenticates. Yes
eventId The ID of the event to update. You can use System.ListCalendarEvents or System.SelectCalendarEvent to get an eventId. Yes
start The new start date and time in the format yyyy-MM-dd'T'HH:mm:ss For example, 2021-02-26T09:55:00. No
end The new end date and time in the format yyyy-MM-dd'T'HH:mm:ss For example, 2021-02-26T09:55:00. No
subject The new subject of the meeting. Yes
attendees A comma separated list of attendees. This list replaces the previous list. Note that the calendar provider can't send a notification to an attendee if the ID isn't a valid account ID for that provider. Yes
timezoneOffset The amount of time in milliseconds to add to universal time (UTC) to get standard time in the user's time zone. For example, if the local time zone is UTC-2, then the timezoneOffset is -7200000. The default value is 0.
Note

You can derive the timezoneOffset property for the current user based on the value of the user context variable profile.timezoneOffset. However, if you do so, you must multiply profile.timezoneOffset by -1.

You can specify timezoneOffset or timezone but not both.

No
timezone The local time zone's ID as identified by https://www.iana.org/time-zones. Also referred to as the TZ database name. For example: America/Los_Angeles. The default is UTC. You can specify timezoneOffset or timezone but not both. No

Footers

Use footers in System.List and System.CommonResponse for additional user guidance when your bot runs on text-only channels..
Runtime image of footer text.
This footer displays on all channels, even ones that support buttons like Facebook. However, you can configure channel-specific rendering for the footer. To do this:
  • Define the autoNumberPostbackActions variable using the system.message expression.
    setAutoNumbering:
      component: "System.SetVariable"
      properties:
        variable: "autoNumberPostbackActions" 
        value: "${(system.channelType=='facebook')?then('true','false')}" 
  • Define the footerText definition with an Apache FreeMarker if directive to display or hide the footer based on the channel type.
    footerText: <#if autoNumberPostbackActions.value>"Make your choice by entering the menu option number."</#if>
Note

On Facebook, the System.CommonResponse renders the footer text in its own text bubble that appears just before the global actions (the quick replies). The footer can’t display after these actions, because that requires a second footer text bubble that causes the actions to disappear.

The translate Property

YAML-based user interface and input components all have a translate property that overrides the global autoTranslate variable setting:
  • If you set the autoTranslate variable to false (the default), then no autotranslation occurs on the component unless you set the translate property to true.

  • If you set the autoTranslate variable to true, then the translate property is implicitly set to true as well, which means that the label, title, description, prompt and text strings will be translated.

For example, If you enabled autotranslate by setting it to true, then setting a component’s translate property to false excludes its prompt, title, description, label and text strings from translation. Conversely, if you don’t enable autotranslate, but a component's translate property is set to true, then the component’s prompt, title, description, label, and text string is translated into the detected user language using the configured translation service. (Input components translate the user input into English.)
autoTranslate is set to... ...and the component’s translate property is set to... ...then the user input, prompt, label, text, title, and description get translated
true not set yes
true true yes
true false no
false not set no
false false no
false true yes
Note

Flows designed with the Visual Flow Designer don't have the translate property or autoTranslatecontext variable. To configure translation for those skills you use the Translate User Input Message and Translate Bot Response Message properties.

System.Feedback

Note

This topic covers use of this component in YAML mode. For information on using it in the Visual Flow Designer, see User Feedback.

The System.Feedback component enables you to collect feedback data for Insights by presenting users with a rating scale after they've completed a transactional flow. If you're using the 21.10 SDK or later, this component outputs a horizontal star rating system. If you're using an earlier SDK, the component outputs this rating scale as a simple list that allows users to tap the button that corresponds with their rating.

While you can change the behavior of this component using the component properties, you can change its look and feel when you use the SDK (version 21.10 or later). For example, you can replace the default star icons used for the feedback buttons with another icon.

System.Feedback Component Properties

Property Description
maxRating The maximum rating that a user can submit. By default, the maximum value is 5. You can adjust this value downward.
enableTextFeedback A boolean, which if set to true, enables the user to submit text feedback if the rating is less than, or equal to, the threshold value. By default, this property is set to false (no feedback enabled).
threshold The value for evaluating the transition between the above and below actions. By default, the threshold between positive and negative feedback is set as 2 for the default maxRating value, which is 5.
footerText The text that displays at the bottom of the feedback dialog.

System.Feedback Component Transitions

Each transition action must name a state in the dialog flow that terminates the conversation with a return: "done" transition.
Action Description
above Set when the user input is a valid value that's above the threshold value.
below Set when user input is a valid value that's equal to, or below, the threshold value. ).
cancel Set when users decline the rating by clicking Skip.
You can use the following system variables for the messages output by the transition states:
  • system.userFeedbackRating – Returns the user's rating.
  • system.userFeedbackText – When enableTextFeedback is set to true, your skill can prompt for feedback when the ratings fall below the threshold value. system.userFeedbackText returns the user's input (${system.userFeedbackText.value}).
...
  getUserFeedback:
    component: "System.Feedback"
    properties: 
      threshold: 2
      maxRating: 5
      enableTextFeedback: true
    transitions:
      actions:
        above: "positiveFeedback"
        below: "negativeFeedback"
        cancel: "cancelFeedback"
  positiveFeedback:
    component: "System.Output"
    properties:
      text: "Thank you for your rating of ${system.userFeedbackRating.value}."
    transitions:
      return: "done"
  negativeFeedback:
    component: "System.Output"
    properties:
      text: "You gave us a score of ${system.userFeedbackRating.value} and entered ${system.userFeedbackText.value}. We appreciate your feedback."
    transitions:
      return: "done"
  cancelFeedback:
    component: "System.Output"
    properties:
      text: "Feedback canceled."
    transitions:
      return: "done"
...

System.Text

Note

This component is deprecated, and there is no longer a template available for it. Instead you can use one of the many templates based on the Common Response component that are offered in the User Messaging section of the Add Component dialog.

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 Sets the variable property with an entity value (when that entity value hasn’t already been set for the referenced variable). You can enable nlpResultVariable to return a value when you define it using a variable that holds the NLP results (such as iresult: "nlpresult" that’s used in our sample bots). By doing this, the nlpResultVariable property can still populate the value when it’s null if it finds a resolved entity that matches the one referenced by the variable. The dialog transitions to the next state when the nlpResultVariable sets the value. You can use this property in place of the System.SetVariable component. 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 Translation Services in Skills. No

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

How Do I Use the System.Text Component?

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 System.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:
      ...

System.List

Note

This component is deprecated, and there is no longer a template available for it. Instead you can use one of the many templates based on the Common Response component that are offered in the User Messaging section of the Add Component dialog.

The System.List component is designed to output a list of options. Depending on whether a variable value has been set (or even defined for this component), the navigation from the component can be triggered by the user's choice, or by the value set for the user or context variable.

Property Description Required?
options You can specify the options using comma-separated text strings, Apache FreeMarker expressions, and as a list of maps. The options Property and Action Lists both provide examples of the latter approach. Yes
prompt The text string that prompts the user. Yes
variable The name of the variable whose value is populated by the user input. The Dialog Engine skips this state if the variable value has already been set and doesn’t output the list options for the user. No
nlpResultVariable Sets the variable property with an entity value (when that entity value hasn’t already been set for the referenced variable). You can enable nlpResultVariable to return a value when you define it with the variable that holds the NLP results (such as iResult: "nlpresult" that’s used in our sample skills). By doing this, the nlpResultVariable property can still populate the value when it’s null if it finds a resolved entity that matches the one referenced by the variable. The dialog transitions to the next state when the nlpResultVariable sets the value. You can use this property in place of the System.SetVariable component. Action Lists describes how you can use the variable and nlpResultVariable properties to change the list display behavior. No—Use this property when the variable property names an entity-type variable.
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 Translation Services in Skills. No
autoNumberPostbackActions When set to true, this option prefixes numbers to options. Even when you haven’t set this option to true, auto-numbering can be enforced on list items when the digital assistant’s Enable Auto Numbering on Postback Actions configuration is set to true. Channel-specific auto-numbering can be applied to any skill that's registered to a digital assistant:${(system.channelType=='twilio')?then('true','false')} No
footerText Enhances the output on text-only channels. As described in Footers, you can use FreeMarker expressions to conditionalize the footer text for text-only channels. No
See Transitions for Common Response Components 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 Apache FreeMarker Template Language Syntax.

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:
     next: "size"
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 optional keyword 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 for Skills to find out more about using the dot notation. When users enter a value that matches one of the values specified in the keyword property, the bot reacts in the same way that it would if the user tapped the list option itself.
    askPizzaSize:
      component: "System.List" 
      properties:
        prompt: What size do you want?"
        options:
        - value: "small"
          label: "${rb.pizza_size_small}"
          keyword: "1"
        - value: "medium"
          label: "${rb.pizza_size_medium}"
          keyword: "2" 
        - value: "large"
          label: "${rb.pizza_size_large}"
          keyword: "3" 
       variable: "pizzaSize"
  • A text string of comma-separated options, like "small, medium, large" in the following snippet. You can’t add label and value properties when you define options as a string.
    askPizzaSize:
      component: "System.List"
      properties: 
        prompt: "What size do you want?"
        options: "small, medium, large"
        variable: "pizzaSize"
    
  • An Apache FreeMarker value expression that loops over either a list of strings, or a list of maps, where each map must contain both the label and value properties and optionally, a keyword property.
    askPizzaSize:
      component: "System.List" 
      properties:
        prompt: "What size do you want?"
        options: "${pizzaSize.value.enumValues}"
        variable: "pizzaSize"
Refer to the Apache FreeMarker Manual to find out more about the syntax.

Action Lists

Instead of using the System.Switch component for conditional navigation, you can use action lists. The System.List's optional variable and nlpResultVariable properties set the list display behavior and subsequent transition based on user input.
  • When you don't configure these properties, the transition action is based on the option selected by the skill user:
    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"
  • When you add the variable and nlpResultVariable properties, the list display gets bypassed when the user's input is matched. In the following snippet, the list of options gets bypassed when the nlpResultVariable, sets the size variable from user input like I want to order a large pizza. The transition appropriate to the value is then triggered.
    getPizzaSize:
      component: "System.List"
      properties:
        prompt: "What size of pizza"
        variable: "size"
        nlpResultVariable: "iResult"
        options:
    
        - label: "Small"
          value: "Small"
        - label: "Large"
          value: "Large"
        transitions:
          actions:
            Large: "Large"
            Small: "Small"

System.Output

Use the System.Output component to output a message that doesn't require a user response, or doesn't require your skill to process the user's response.
Note

This component is deprecated, and there is no longer a template available for it. Instead you can use one of the many templates based on the System.CommonResponse that are offered in the User Messaging section of the Add Component dialog.
Property Description Required?
text A text string Yes – This field requires a value.
keepTurn A boolean value for relinquishing (false) or retaining the skill’s control of the dialog flow (true). Use keepTurn: true when you want to output an unbroken sequence of skill messages wherein no interjections from the user are accepted. No
translate Use this property to override the boolean value that you’ve set for the autotranslate context variable. If you haven’t set that 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 to true, you can set this property to false to exclude this component from autotranslation. See Translation Services in Skills. No

How Do I Use the System.Output Component

The System.Output component requires the string definition for 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 skill. If you override this behavior, add the optional keepTurn property and set it to true to direct the Dialog Engine to the next state 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"

Defining Value Expressions for the System.Output Component

You can define one or more value expressions for the text property. For example, the following snippet 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" 
Each expression must always return a value. If even one expression returns a null value, then the skill outputs raw text for each expression in the string, leaving your users with ouput like this:
Your ${size.value} ${type.value} is on its way.

Description of value_expression_showing.png follows

It’s all or nothing. To make sure that your skill 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."

Description of default_text_display.png follows

Note

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 each time that you define a default value operation, or set off output text with double quotes. For example, the following System.Output component definition allows users to read the message as You said, “Cancel this order.”
confirmCancel:
    component: "System.Output"
    properties:
      text: "You said, \"Cancel this order.\""
    transitions:
      return: "cancelOrder"

Translating the Output Text

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 Translation Services in Skills.
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:
     ...