Creating a scenario

Start a new scenario by selecting the Add button at the bottom of the Scenarios tab. To describe the basics of authoring with the Health Bot Service, let's use an example scenario with the Name Example scenario and the Description Hello world.

In this example, the Scenario Trigger is hello.

Note: Capitalization matters in the Scenario Trigger.

To add functions to the Example scenario, begin by dragging and dropping an object from the elements bar, described above in the table, onto the visual editor. The information fields associated with the object will appear in a pop-up window.

For this example, we are using a Statement .

In the Statement window, the display text is entered as Hello world.

Editing the label of an object is a good authoring practice. In this case, we have labeled it Greeting.

Note: The display text can be a string literal or a valid JavaScript expression.

You can open and edit the fields at any time by double-clicking on the object in the visual editor, or right-clicking and selecting Edit.

Web Chat pane

The Web Chat pane in the lower right of the Scenario editor allows you to run and test scenarios as you go.

To test our Example scenario, select Save. Then type "begin hello" in the Web Chat pane.


Tips Description
To quickly test and debug a scenario without mapping to intent

• Save the scenario.

• Enter begin + the scenario trigger in the Web Chat pane.

To test only a portion of your scenario Right-click the object where you would like to start running and select Make Start Step.

To stop a scenario Enter Stop in the Web Chat pane.

Run Scenario

You can run the currently edited scenario by clicking the Run button instead of typing "begin..." command. This will also allow you to pass arguments to the scenario you run. Doing so, will end any ongoing conversation and start executing the scenario from the Start Step. Arguments are accessible during runtime via the {scenarioArgs} variable.

To setup the arguments passed to the scenario, click the up arrow next to the Run button and click the Set Arguments menu option.

Arguments must be constants and can be one of the following types:

  • Number
  • Boolean
  • String (enclosed in double quotation marks)
  • JSON Object in valid JSON format.
  • Array of all the above types

Arguments syntax is validated while you type. In any case, error will be shown when badly formatted arguments are used to run a scenario.

Run From Here

You can start execution of a scenario from a specific step. This is useful when you want to focus on a certain path of the scenario without going through all the steps preceding it. Obviously, variables defined along the way will not be populated. You need to initiate any needed variable.

Right click any step you want to begin running from and select the "Run from here" option.

Debug Context

Use the Debug Context to evaluate the internal state of your scenario. You can inspect the state of your variables, scenario arguments, and the state of the Health Bot Service session.

The userData section provides user-specific data. The scenario author can choose to store any data about the user that will be useful for future interaction with that person, such as their age and gender. Users can delete this data by entering the "forget me" phrase during the chat. Users also have complete transparency regarding the data we store about them. They can get all this data by typing "what do you know about me."

For more information about variable types, see also Health Bot Instance variables.

The privateConversationData section is where to look to get information about the state of your scenario. Here you will see the state of the currently executing scenario, as well as any other scenarios that it involves. Included in the data are scenario arguments, scenario variables, and global variables.

Console Window

Trace Tab

The Trace tab can provide detailed information about the execution steps in the scenario. This information can be augmented by calling an action function with the session.trace() method, where the first parameter is what to display, described as a string or number, and the second argument is the severity level. Zero is the lowest severity level and will display the trace information with a green background. Three is the highest severity level and will display the trace with a red background. The trace window will return the trace of your code or executed steps.

In the Example scenario, we can trace the code with the following action function:

session.trace("notice", 0);

session.trace("warning", 1);

session.trace("error", 2);

session.trace("critical error", 3);

Running the code then returns the following results in the Trace window:

Note: Currently, the messages are delivered to the Trace window asynchronously, therefore they may appear out of order.

Immediate Expression Evaluation Tab

The Immediate tab allows you to run expression evaluation code while debugging the context of currently running scenario. This means that all the local and global variables are available to be inspected and modified. You can run any In-Line JavaScript expression that you would run anywhere. After typing the expression, press "Enter" key or F9 to evaluate the expression you just typed. The code will run in the context of the conversation, and the result will be displayed in the lower pane. Any changed value will be immediately reflected in the debug context window.

Health bot instance variables

During the scenario execution, the scenario author can store and retrieve variable values. There are also variables that are pre-populated by the framework. All variables are contained in our secure storage during the session of the conversation. This means that even if the connection is lost during the conversation or something happens to our servers, all the variables are restored when the conversation is resumed. User data is maintained between conversations.

There are three types of variables you can use inside the action and other expression fields:

  1. Conversation global variables denoted by @{myVar}. They persist throughout the lifespan of the conversation.

  2. Scenario variables denoted by ${myVar}. They live throughout the lifespan of a scenario. When a scenario ends and returns to the calling scenario, the variables are removed. This means you can write reusable scenarios.

  3. UserData variables denoted by &{myVar}. They live forever for the same user across all conversations.

All these notations (@, $, and &) are just abbreviation of the actual place this data is stored. They are expanded during runtime to the following objects:

Variable Real data location
@{myVar} session.privateConversationData.myVar
${myVar} session.privateConversationData.<current_scenario_name>.myVar
&{myVar} session.userData.myVar

Examples are visible in the Debug Context window shown above. In theory, you can write the long form of the variables (e.g., session.privateConversationData.myvar) but this is not recommended, especially for scenario variables.

Global Context

Using the Global Context element, you can set and get variables to use throughout your scenarios. Variables set in this way (unlike variables using the $, @, & notation) maintain their context and are persistent and available in all scenarios and for all users.

The context value can be a predefined object (e.g., ${myVar}) or a JSON notation object (as in the screenshot above). It can also be a simple type of object such as a string or an integer. After setting the context, you can retrieve it with a local variable, as shown below:

Once attached to a local variable, you can use it immediately as a JavaScript object.


Anytime you want to pause the conversation with the bot and ask the user for an input, you will need to use the Prompt step.

  • Display Text: Optional value presented to the user, prompting value entry.
  • Variable: Required: The name of the conversation variable that will hold the value after users responds
  • Data Type: Type of data you want to get back from the user. It can be a number, a string, a boolean response, a date or a time or a choice of values.
  • Is Active: Boolean expression that determines whether to show this step during runtime.
  • Maximum number of retries: In case user response is invalid according to the required data type, the bot will retry asking the same question number of times you specify in this field. Leaving this field empty will result in unlimited retries. Setting zero will not try to re-prompt even when validation fails. It's up to the scenario author to handle the result of the prompt in this case.

Prompt choice type

It's always preferable to present the user with a list of options to select from rather than prompting them to enter plain text, whenever possible. For this purpose, we use the Prompt element and select the choice data type, as shown below:

Once we do that, two new fields are revealed in the dropdown menu: Choice Array and Show Choices as. The array field can contain a valid JavaScript string array literal, for example: ["Red", "Blue", "Green"] or it can be a variable that contains a string array. With the second option, the content of choices can be determined in runtime.

You can select the way the choice is shown to the user. Be aware that not all the options will look good on all channels. For example, buttons will not appear in an SMS channel. You can select auto and let your health bot instance decided how to show it.

The user can either type the index of their choice in the input box or the text on the button. When the user selects a choice, the text will be sent to the health bot instance as the answer. If the choice the user types is not identified in the list, the prompt will be presented again. The result of the prompt will be available once the selection has been made and will be assigned to the variable defined for this prompt by the author.

Note: The value of the choice prompt is not a plain string or number but rather it is an object containing the following components:

  • score: The probability the choice was identified (0-1) (for example, if the user provided a textual answer which is almost identical to one of the options but not exactly, the score may be less than 1.

  • index: Index of the selection made -- zero based

  • entity: The context of the array item selected. For example, "Blue" if the "Blue" option is selected.

To insert a multi-way split following the Prompt in this example you would use the Switch element, as shown below:

Yes No Prompt

The Yes/No prompt is essentially a boolean prompt combined with a decision step. It allows you do ask boolean questions and branch according to the answer.

This will look like this:

Now you can connect the yes/no nodes to other steps in your flow.

Making Decisions

The basic logic element is the Decision object. Drag the step onto the canvas.

For the Decision object, write a Boolean expression, i.e., an expression that returns a Boolean value of true or false.

The flow of the script will branch according to the yes/no nodes of the Decision object.

If it will make your script more readable, you can flip the yes/no sides of the object by right-clicking the object and selecting Switch Yes/No Labels, as shown below:

Switch element

The Switch element defines a multi-way split in the flow of the scenario according to the evaluated expression. Instead of using a simple "branch element" that allows only two exit points, the Switch allows multiple exit points, simplifying the scenario flow.

The expression must be evaluated as a string because the case values are also treated as strings. The case values must also be string literals; they can not be expressions. In the example above, the level variable -- a number -- is converted into a string and compared with one of the string cases below it: 1, 2 or 3. After defining the expression and the cases, you can connect each of the cases to the next steps in the flow.

Note: There is a default case in each switch that will be executed if none of the other case values is matched.

Invoking a sub scenario

It is possible to create a scenario that can be called throughout the project. It can receive input parameters and return output to the calling scenario, making it reusable. The variables defined in such a scenario are local to the instance of the sub-scenario, so they will not affect other variables, even variables with the same name. To call a sub-scenario, drag the Begin Scenario step onto the canvas.

Define the Scenario Trigger by selecting one of your scenarios in the dropdown menu. Define the Arguments with either a literal or a variable object. Define the output Variable name with the return value from the called scenario, as shown in the example below:

Sub Scenario

The called scenario can access the argument passed from the calling scenario by using the ${scenarioArgs} variable. For example: ${scenarioArgs}.["varName"]

When you are ready to return from the called scenario, place an object from the End Scenario With Result element, as shown below:

Writing Action Code

Actions are snippets of JavaScript (ES5) code running in the context of the conversation session as part of a conversation dialog step. Actions offers enormous power to the scenario composer. Basically, it allows you to take control over the Bot Framework's APIs to be able to modify and extend your bot's functionality. You can add an Action object anywhere on the designer canvas by dragging the Action icon onto the canvas. An Action object has one entry point and one exit node.

Asynchronous actions

There are two types of actions: synchronous and asynchronous. In synchronous code, when the code snippets finish execution the next element is called automatically.

One the other hand, when writing asynchronous code, you must check the Asynchronous checkbox so that the automatic call to the next element will be canceled. The Health Bot Service framework can't assume when to call the next element, so you as the scenario author need to provide explicit instructions on when to move to the next element by using a next() expression. See an example of asynchronous action in the section Writing actions best practices.

Actions runtime context

Code written in an action runs in a special runtime sandbox called a NodeJS VM. When this context is created, it is empty of any objects -- a clean slate. We need to pass to this VM all the objects the author of the action might need to complete their task.

The author will want to pass their most used objects to the action, in addition to the require object -- the one that allows you to import other node objects as long as they exist in our package.json.

Below is a list of objects we pass to the action sandbox with links to more information:

Object Description
Session Bot framework's current running session.
Require Allows you to import node modules. This is a special version of require you can use to import only packages that are white listed
Builder Allows you to build bot messages, as well as attachments and cards, and send them to the client.
Moment Allows you to manipulate the date and time library.
Next next() is the function you should call when you want to progress to the next step in an asynchronous action.
request-promise Follow the link to view the request-promise library. This object is used to call rest APIs.
Config Configuration object allows access to the values of tenants’ configuration.
Underscore Follow the link to view a useful JavaScript library.

White Listed Packages

Below is a list of useful Node JS modules you can import with require:

Package Description
crypto Cryptographical functions
path Path utilities
string-decoder String utilities
querystring Query string parsing
url Url parsing
util NodeJS Utilities
jsonwebtoken JSON Web Token implementation (symmetric and asymmetric)
node-sha1 Exports a SHA1 function that uses node's crypto module under the hood
object-path Access deep object properties using a path
request-promise The simplified HTTP request client request with Promise support, powered by Bluebird
soap A minimal node SOAP client
strformat String formatting for Node.js and AngularJS
to-markdown HTML-to-Markdown converter
ttl Simple in-memory cache for JavaScript
underscore JavaScript's functional programming helper library
xml2js Simple XML to JavaScript object converter

Extending the session function

In addition to all the built-in functionality of the session function, the Health Bot Service has added custom programmatic functionality for you, the author.

Function Description
session.trace(message: string, level:number) Output trace string to the debug window
level: 0-3
session.saveFeedback(message: string) Write feedback string for this user

Writing actions best practices

The following is a brief list of best practices to keep in mind when authoring actions:

  • You can always press Ctrl + Space to get a list of variables and functions you can use in actions.

  • Be careful not to write infinite loops or overly heavy code in an action. Actions can't run for more than two seconds. After two seconds, the action will fail with a timeout error.

    Note: This does not mean that asynchronous operations can't run for more than two seconds.

  • You can access the arguments passed to the current scenario by using the ${scenarioArgs} variable.


See below for an example of an asynchronous action for saving feedback:

session.saveFeedback("This was a very good experience").then(function() {
}).catch(function(err) {
    session.trace("Error writing feedback " + err.message, 3 /*crtitical error*/);

Writing in-line expressions

Everything that is available to the action author is also available in in-line expressions in some steps. These expressions should be very simple -- for example, concatenating strings. If you want to write more complex code, use actions before you get to the step that needs the result from the expression.

The in-line expression will not be evaluated if there is only a literal string. The string "as-is" will be returned.

Attachments -- Hero/Thumbnail cards

You can attach Hero or Thumbnail cards to a prompt or statement to provide a richer experience, or to perform actions. When editing a prompt or statement, select the Attachment button and choose the type of card from the Attachment Type drop down list.

For Hero and Thumbnail cards, the fields below will be revealed to allow you to customize your card:

  • Image URL Allows you to display an optional thumbnail image on the card. If a Hero card is selected it will be shown as a bigger image in the center of the card.

  • Tile/Sub Title: Inputs for additional information at the top of the card.

  • Actions: Selecting the Add Action button opens an additional set of fields to define an action button. Each action button can have a different Action type that determines how it will function during the conversation. Each Action will also need to have an Action Title -- the text that will appear on the action button -- and an Action value -- the URL that will be invoked during the conversation.

Below are examples of a Thumbnail card attachment definition and of the corresponding output.

Adaptive cards

Adaptive cards allow a high level of flexibility for displaying information and providing interactivity to the end user chatting with a health bot instance.

The Health Bot Service enables the use of adaptive cards when authoring your scenario. Adaptive cards contain a simple JSON object and are treated by a health bot instance as attachments. When you want to display an adaptive card, you can attach it to either a statement or a prompt.

If the adaptive card does not require an input from the user---for example, in the case of a news or alert message -- you can attach it to a Statement.

If, on the other hand, you need an adaptive card with a form that pauses and accepts data from the user, then you must attach it to a Prompt.

The steps to adding an adaptive card are as follows:

  • Open the Statement or Prompt properties and select the Attachment button.

  • Select "Adaptive Card" from the "Attachment type" drop box and paste your adaptive card JSON into the JSON editor.

You can edit this JSON and parametrize it using the session variables. The JSON will be evaluated in runtime and a dynamically created adaptive card will be shown.

Getting data from forms

Adaptive cards also can be used to get form data. You will drag a prompt onto the canvas and define the variable to hold the form data. The type of the variable should be defined as a string. Later you will parse this value to access the form's data elements.

In the example scenario below, the adaptive card displays a form and outputs its content onto the next statement:

The code of the sample adaptive card is as follows:

    "$schema": "",
    "type": "AdaptiveCard",
    "version": "0.5",
    "body": [
            "type": "Container",
            "items": [
                    "type": "Input.Text",
                    "id": "age",
                    "placeholder": "age"
                    "type": "Input.ChoiceSet",
                    "id": "condition",
                    "isMultiSelect": true,
                    "style": "expanded",
                    "choices": [
                            "title": "Better",
                            "value": "better"
                            "title": "Worse",
                            "value": "worse"
                            "title": "Same",
                            "value": "same"
    "actions": [
            "type": "Action.Submit",
            "title": "Submit"

In runtime, pressing the Submit button on the card will collect all the form data and will pass it to the statement. The statement will print out the form data as shown below:

Exiting the editor

Select the Save and Exit button.

You will be returned to the Scenarios homepage and your saved scenario will be stored in the table as pictured below:

Managing scenarios

In the table of scenarios, you can enable and disable scenarios.

In addition to the Add button, buttons to Export, Import, and Refresh can also be found at the bottom of the Scenarios page.

Tips Description
Export your scenarios Use the Export button to export all the selected scenarios as JSON files for safekeeping, sharing, and to move from staging to production.
Import Use Import to import a JSON blob in to one or more scenarios.