Lab 2 - Bot Composer
Pre-Requirements
Create a new bot
The first step in creating a bot with the Composer is to create a new bot project. This will create a new folder on your local computer with all the files necessary to build, test and run the bot.
Start Composer.
In the Home page, select the New icon.
In the displayed Create from template or scratch? wizard, you'll be presented with different options to create your bot. For this tutorial, select Create from Scratch.
Select Next.
In the displayed Create a bot project form, enter the following information:
Name. Enter the name WeatherBot. Notice that spaces and special characters are not allowed in the bot's name.
Description. Enter A friendly bot who can talk about the weather.
Location. Select the location on your computer where to save the project.
Click OK.
After creating your bot, Composer will load the new bot's main dialog in the editor. It should look like this:
As you can see in the above picture, you have the Navigation pane (WeatherBot
) on the left, the Authoring canvas in the middle, and the Properties panel (Adaptive dialog) on the right.
Select the Greeting trigger in the Navigation pane on the left. In the Authoring canvas, the related conversation flow is displayed.
Note
A dialog contains one or more triggers that define the actions available to the bot while the dialog is active. When you create a new bot, an Activities trigger of type Greeting (ConversationUpdate activity) is automatically provisioned.
Triggers help your dialog capture events of interest and respond to them using actions.
To help keep bots organized, you can rename any trigger to something that better describes what it does. As an example, in the Properties panel on the right, rename the trigger from Greetings to Welcome User.
Now, it's time to make the bot do something. Let's instruct it to send a simple greeting to the user. In the Authoring canvas, select the existing Send a response action. Its properties will appear on the right in the Properties panel. This action has only one property: the text of the message to send.
Type a welcome message into this field such as:
Hi! I'm a friendly bot that can help with the weather. Try saying WEATHER or FORECAST.
It is always a good idea to have your bot introduce itself and explain it's main features.
We are not showing it here, but you can start adding functionality to your bot by adding Actions to the Welcome User trigger. You do this by selecting on the plus (+) icon in the Authoring canvas, at the desired location in the flow.
Tip
The bot's conversational flow for any given dialog is depicted in the Authoring canvas starting with the trigger name and a line going down from it to a plus (+) icon.
To add Actions to the conversational flow, select the plus (+) icon in the Authoring canvas then select the desired action from the drop down list that appears. Actions can be inserted any place in the conversational flow that has a plus (+) icon.
From the displayed list of actions, select the appropriate action.
Start your bot and test it
Now that your new bot has its first simple feature, you can launch it in the emulator and verify that it works.
Select Start bot in the upper right hand corner of the screen. This tells Composer to launch the bot's runtime, which is powered by the Bot Framework SDK.
Note
After selecting Start bot the text changes to Starting bot, then once the bot's runtime is running it will switch to Restart bot.
Once the bot's runtime has started, the Local bot runtime manager will open. You can also select the icon to the right of the text Restart bot, as highlighted in the following image, to open and close the Local bot runtime manager.
Select Test in Emulator in the Local bot runtime manager. This will open your bot in the Emulator.
Soon the Emulator will appear, and the bot should immediately greet you with the message you just configured:
When you are done, you can stop the bot by selecting the Stop Bot button in the Local bot runtime manager.
You now have a working bot, and you're ready to add some more substantial functionality!
Add dialogs to your bot
Note
It is useful to group functionality into different dialogs when building the features of your bot with the Composer. This helps keep the dialogs organized and allow sub-dialogs to be combined into larger and more complex ones.
A dialog contains one or more triggers. Each trigger consists of one or more actions which are the set of instructions that the bot will execute. Dialogs can also call other dialogs and can pass values back and forth between them.
What are you building?
The main function of the bot is to report current weather conditions.
To do this, you will create a dialog that:
Prompts the user to enter a zip code to use as location for weather lookup
Calls an external API to retrieve the weather data for a specific zip code
Create a new dialog
Start Composer.
Select the WeatherBot icon.
This opens the WeatherBot project.
In the Navigation pane select the three vertical dots associated with the WeatherBot dialog, then select Add a dialog.
In the drop-down menu, select Add new dialog.
In the displayed Create a dialog, enter the following information, then select OK:
Name. getWeather
Description. Get the current weather conditions
This will result in a new dialog with a pre-configured BeginDialog trigger. For now, you can just add a simple message to get started. You will learn more about this feature in a future tutorial.
In the Navigation pane on the left, select the BeginDialog trigger.
In the Authoring canvas, under the BeginDialog trigger, select the plus (+) icon.
In the drop-down menu, select the Send a response action.
In the Properties panel, enter the text Let's check the weather into the Language Generation section.
Connect the new dialog
You can break down a conversation flow into different dialogs and then chain them together. Let's see how it is done in Composer by connecting the newly created getWeather dialog to the main dialog.
In the Navigation pane, select WeatherBot
In the Properties panel, find the Language Understanding section.
Each dialog can have its own recognizer. A recognizer is a component of your bot that examines incoming messages to determine the users intention by evaluating all predefined intents. Each recognizer type uses a different technique to determine which intent, if any, best matches the user's input.
Select Regular expression recognizer from the Recognizer Type drop-down list.
In the Navigation pane select the three vertical dots associated with the WeatherBot dialog, then select Add a trigger.
In the Create a trigger dialog, enter the following information:
select Intent recognized from the What is the type of trigger drop-down list.
Enter weather into both the What is the name of this trigger (RegEx) and Please input regex pattern text boxes, then select Submit.
Note
This tells the bot to look for the word "weather" anywhere in an incoming message. Regular expression patterns are generally much more complicated, but this is adequate for the purposes of this example.
Next, create a new action for the Intent recognized trigger.
In the Authoring canvas, select the plus (+) icon beneath the trigger node.
From the drop-down menu, select Dialog management, then Begin a new dialog.
With the Begin a new dialog action active, select getWeather from the Dialog name drop down.
Now when a user enters weather, your bot will respond by activating the getWeather dialog.
In the next tutorial you will learn how to prompt the user for additional information, then query a weather service and return the results to the user, but first you need to validate that the functionality developed so far works correctly, you will do this using the Emulator.
Test bot in the Emulator
Select Start bot in the upper right hand corner of the screen.
Note
If the bot is still running from the previous tutorial, you can select Restart bot, this will update the bot runtime app with all the new content and settings.
Then select Test in Emulator. When the Emulator connects to your bot, it'll send the greeting you configured in the last section.
Send the bot a message that says weather. The bot should respond with your test message, confirming that your intent was recognized as expected, and the fulfilment action was triggered.
Add actions to your bot
A chatbot would not be intelligent if it can not take any actions. An action can be any REST call.
Getting the weather forecast
Before you can get the weather forecast you need to know the desired location. You can create a Text Input action to prompt the user for a zip code to pass to the weather service.
In the Navigation pane, select the the getWeather dialogs BeginDialog trigger.
In the Authoring canvas, select the plus (+) icon beneath the Send a response action, then select Text from the Ask a question menu.
See the Asking for user input article for more information about requesting and validating different data types.
After selecting Text from the Ask a question menu, you will notice that two new nodes appear in the flow. Each node corresponds to a tab in the Properties panel (See image below).
Bot Asks refers to the bots prompt to the user for information.
User Input enables you to assign the user input to a property that is saved in memory and can be used by the bot for further processing.
Other enables you to validate the user input and respond with a message if invalid input is entered.
In the properties panel, select the Bot Asks tab and enter What is your zip code? into the Prompt for text field.
This is the question that the bot will ask the user.
Select the User Input tab in the Properties panel. This section contains properties related to the user's response, including where to store the value and how to process it. Enter the following values:
Property. user.zipcode. The property used to store the user's answer.
Output Format. =trim(this.value). trim() is a prebuilt function in adaptive expressions. It trims any leading and trailing spaces in the user's input before it is validated and assigned to the property defined in the Property field, which is in this case user.zipcode.
Select the Other tab in the Properties panel. This is where you specify validation rules for the prompt, as well as error messages displayed to the user if they enter an invalid value based on the Validation Rules you create.
Expand the Recognizers section and enter the following in the Unrecognized Prompt field:
Sorry, I do not understand '${this.value}'. Please specify a 5 digit zip code in the format 12345.
Expand the Validation section and enter the following in the Validation Rules field:
length(this.value) == 5
This validation rule states that the user input must be 5 characters long. If the user input is shorter or longer than 5 characters your bot will send an error message, as defined in the Invalid prompt field.
Important
Make sure to press the enter key after entering the validation rule. If you don't press enter, the rule will not be added.
Enter the following in the Invalid prompt field:
Sorry, '${this.value}' is not valid. I'm looking for a 5 digit number as zip code. Please specify a 5 digit zip code in the format 12345.
Expand the Prompt Configurations section and set the Default value property to 98052.
Note
By default prompts are configured to ask the user for information Max turn count number of times (defaults to 3). When the max turn count is reached, the prompt will stop and the property will be set to the value defined in the Default value field before continuing the conversation.
You have created an action in your BeginDialog trigger that will prompt the user for their zip code and place it into the user.zipcode property. Next you will pass the value of that property in an HTTP request to a weather service, then if it passes your validation, display the weather report to the user.
Add an HTTP request
In this section, you will learn how to add an HTTP request, capture the results into a property, then determine what action to take depending on the results.
In the Authoring canvas, select the plus (+) icon under the last action, then select Send an HTTP request from the Access external resources menu.
In the Properties panel, select GET from the HTTP method drop-down list. Then enter the following in the Url field:
This will enable the bot to make an HTTP request to the specified URL. The reference to ${user.zipcode} will be replaced by the value from the bots' user.zipcode property. You can get an api_token for free from the OpenWeather website.
In the Result property field, enter the following:
dialog.api_response
Result property represents the property where the result of this action will be stored. The result can include any of the following 4 properties from the HTTP response:
statusCode. This can be accessed via
dialog.api_response.statusCode
.reasonPhrase. This can be accessed via
dialog.api_response.reasonPhrase
.content. This can be accessed via
dialog.api_response.content
.headers. This can be accessed via
dialog.api_response.headers
.
If the Response type is Json, it will be a deserialized object available via
dialog.api_response.content
property.After making an HTTP request, you need to test the status of the response and handle errors as they occur. You can use an If/Else branch for this purpose. To do this, select plus (+) icon that appears beneath the Send HTTP Request action you just created, then select Branch: if/else from the Create a condition menu.
In the Properties panel on the right, enter the following value into the Condition field:
dialog.api_response.statusCode == 200
This is the expression to evaluate for the if statement.
In the True branch select the plus (+) icon then select Set a Property from the Manage properties menu.
In the Properties panel on the right, enter dialog.weather into the Property field.
Next, enter =dialog.api_response.content into the Value field.
While still in the True branch, select the plus (+) icon that appears beneath the action created in the previous step, then select Send a response.
In the Properties panel on the right, enter the following response to send:
- The weather is ${dialog.weather.weather} and the temp is ${dialog.weather.temp}°
The flow should now appear in the Authoring canvas as follows:
You will now tell the bot what to do in the event that the status code returned is not 200.
Select the plus (+) icon in the False branch, then select Send a response and set the text of the message to:
I got an error: ${dialog.api_response.content.message}
For the purposes of this tutorial we will assume that if you are in this branch, it is because the zip code is invalid, and if it is invalid it should be removed so that the invalid value does not persist in the user.zipcode property. To remove the invalid value from this property, select the + button that follows the Send a response action you created in the previous step, then select Delete a property from the Manage properties menu.
In the Properties panel on the right, enter user.zipcode into the Property field.
The flow should appear in the Authoring canvas as follows:
You have now completed adding an HTTP request to your BeginDialog trigger. The next step is to validate that these additions to your bot work correctly. To do that you can test it in the Emulator.
Test in the Emulator
Select the Restart bot button in the upper right-hand corner of the Composer screen, then Test in Emulator.
After the greeting, send weather to the bot. The bot will prompt you for a zip code. Give it your home zip code, and seconds later, you should see the current weather conditions.
Add Help and Cancel
With even a simple bot, it is a good practice to provide help. You'll also want to provide a way for users to exit at any point in the flow.
Create a new dialog
Open the WheatherBot project.
In the upper menu bar, select + Add and from the drop-down menu select Add new dialog.
In the displayed Create a dialog form, enter the following values:
Name: help
Description: global help
Select OK.
Composer will create the new help dialog with a pre-configured BeginDialog trigger.
Select the help dialog's BeginDialog trigger in the Navigation pane.
Select the plus (+) icon in the Authoring canvas, then select Send a response from the list of actions.
In the Properties panel, enter the following text:
I am a weather bot! I can tell you the current weather conditions. Just say WEATHER.
Create an Intent recognized trigger
In the Navigation pane, select the main dialog (WeatherBot).
In the Properties panel, select Regular expression recognizer in the Recognizer Type drop-down list.
In the Navigation pane select the three vertical dots associated with the WeatherBot dialog, then select Add a trigger.
In the Create a trigger dialog, enter the following information:
select Intent recognized from the What is the type of trigger drop-down list.
Enter help into both the What is the name of this trigger (RegEx) and Please input regex pattern text boxes, then select Submit.
Select the plus (+) icon in the Authoring canvas, then select Begin a new dialog from the Dialog management drop-down list.
Next, specify the dialog to call when the help intent is recognized.
In the Properties panel, select help from the Dialog name drop-down list in
In addition to giving you the current weather, your bot should now also offer help. You can verify this using the Emulator.
Select Start bot in the upper right hand corner of the screen.
Note
If the bot is still running from the previous tutorial, you can select Restart bot, this will update the bot runtime app with all the new content and settings.
Then select Test in Emulator. When the Emulator connects to your bot, it'll send the greeting you configured in a previous tutorial, now you are able to call your new help dialog.
Notice that once you start the weather dialog by saying weather your bot doesn't know how to provide help since it is still trying to resolve the zip code. This is why you need to configure your bot to allow interruptions to the dialog flow.
Allowing interruptions
The getWeather dialog knows how to get the weather forecast, but does not know how to respond to requests for help. To enable the bot to respond to requests for help while in the getWeather dialog, you will need to configure it to handle interruptions. This will enable you to call the new help functionality from the getWeather dialog, then once done the conversational flow will seamlessly return to where it left off. The following steps demonstrate how to do this.
In the getWeather dialog, select the BeginDialog trigger.
In the Authoring canvas. Select the Prompt for text action.
In the Properties panel, select the Other tab. Set the Allow interruptions field to
true
.This tells Bot Framework to consult the parent dialog's recognizer, which will allow the bot to respond to help at the prompt as well.
Select Restart Bot and open it in the Emulator to verify you are able to call your new help dialog.
Say weather to your bot. It will ask for a zip code.
Then say help. It will now provide the global help response, even though that intent and trigger are defined in another dialog.
You have learned how to interrupt a flow to include help functionality to your bot. Next you will learn how to add a global cancel command that lets users exit out of a flow without completing it.
Global cancel
Follow the steps described in the create a new dialog section above to create a new dialog named cancel and add a Send a response action with the response of Canceling!.
In the Authoring canvas, add an action by selecting the plus (+) icon at the bottom of the flow.
Select Cancel all active dialogs from the Dialog management drop-down list.
When Cancel all dialogs is triggered, the bot will cancel all active dialogs, and send the user back to the main dialog.
Next you will add a cancel intent, the same way you added the help intent in the previous section.
Follow steps 1 to 5 described in the create an intent recognized trigger section above to create a cancel intent in the main dialog (weatherBot) and add a Begin a new dialog action in the cancel trigger. You also need to specify the dialog to call when the cancel intent is recognized. You do this by selecting cancel from the Dialog name drop-down list in the Properties panel.
Now, your users will be able to cancel out of the weather dialog at any point in the flow. You can verify this using the Emulator.
Select Restart Bot and open it in the Emulator to verify you are able to cancel.
Say weather to your bot. The bot will ask for a zip code.
Now say help. The bot will provide the global help response.
Now, say cancel. Notice that the bot doesn't resume the weather dialog but instead, it sends a response canceling!, then waits for your next message.
Language Generation
ow that your bot can perform its basic tasks it's time to improve your bot's conversational abilities. The ability to understand what your user means conversationally and contextually and responding with useful information is often the primary challenge for a bot developer. Bot Framework Composer integrates with the Bot Framework Language Generation library, a set of powerful templating and message formatting tools that let you include variation, conditional messages, and dynamic content. LG gives you greater control of how your bot responds to the user.
Let's start by adding some variation to the welcome message.
Go to the Navigation pane and select the WeatherBot dialogs WelcomeTheUser trigger.
Select the Send a response action in the Authoring Canvas.
Replace the response text in the Properties panel with the following:Bot responseCopy
Your bot will randomly select any of the above phrases when responding to the user. Each phrase must begin with the dash (-) character on a separate line. For more information see the Template and Anatomy of a template sections of the Language Generation article.
To test your new phrases click the Start Bot button on the top right and then click Test in Emulator. Click Restart conversation a few times to see the results of the greetings being randomly selected.
Currently, the bot reports the weather in a very robotic manner:
The weather is Clouds and it is 75°.
You can improve the language used when delivering the weather conditions to the user by utilizing two features of the Language Generation system: conditional messages and parameterized messages.
Select Bot Responses from the Composer menu.
You'll notice that every message you created in the flow editor also appears here and these LG template are grouped by dialogs. They're linked, and any changes you make in this view will be reflected in the flow as well.
Select getWeather in the navigation pane and select Show code in the upper right corner. This will enable a syntax-highlighted LG editor in the main pane. You can now edit LG templates in the selected dialog getWeather.
Scroll to the bottom of the editor and paste the following text:Bot responseCopy
This creates a new Language Generation template named
DescribeWeather
, seen below:The template lets the LG system use the data returned from the weather service in the
weather.weather
variable to generate a friendlier response.Select Design from the Composer Menu.
Select the getWeather dialog, and then click its BeginDialog trigger in the Navigation pane.
Scroll down in the Authoring Canvas and select the Send a response action that starts with The weather is....
Now replace the response with the following:
- ${DescribeWeather(dialog.weather)} and the temp is ${dialog.weather.temp}°
This syntax lets you nest the
DescribeWeather
template inside another template. LG templates can be combined in this way to create more complex templates.You are now ready to test your bot in the Emulator.
Click the Restart Bot button on the top right, and the click Test in Emulator to open your bot in the Emulator.
Now, when you say
weather
, the bot will send you a message that sounds much more natural than it did previously.
Adding cards and buttons
Adding buttons
Buttons are added as suggested actions. Your can add preset buttons to your bot that the user can select to provide input. Suggested actions improve the user experience by letting users answer questions or make selections with the tap of a button instead having to type responses.
First, update the prompt for the users zip code to include suggested actions for help and cancel actions.
Select the BeginDialog trigger in the getWeather dialog.
Select the Prompt for text action which is the second action in the flow.
Update the Prompt to include the suggested actions as shown below:Bot responseCopy
Click Start bot in the top right and then click Test in Emulator.
Now when you say weather to your bot, you will not only see that your bot asks you for zip code but also presents help and cancel button as suggested actions.
Adding cards
Now you can change the weather report to also include a card.
Scroll to the bottom of the Authoring canvas and select the Send a response node in the True branch that starts with
${DescribeWeather(dialog.weather)}...
Replace the response with this Thumbnail Card:Bot responseCopy
Click Restart Bot in the top right. Once your bot has restarted click Test in Emulator.
In the Emulator, go through the bot flow, say weather and enter a zip code. Notice that the bot now responds back with a card that contains the results along with a card title and image.
Add LUIS for language understanding
Up until this point in the tutorials we have been using the Regular Expression recognizer to detect user intent. One of the other recognizers currently available in Composer is the LUIS recognizer. The LUIS recognizer incorporates Language Understanding (LU) technology that is used by a bot to understand a user's response to determine what next to do in a conversation flow. Once the LUIS recognizer is selected you will need to provide training data in the dialog to capture the users intent that is contained in the message, which you will then pass on to the triggers which define how the bot will respond.
Update the recognizer type
Select the main dialog WeatherBot in the Navigation pane.
Select Default recognizer from the drop-down list in the Properties panel.
In the next section, you will learn to create three Intent recognized triggers using LUIS recognizer in WeatherBot. You can ignore or delete the Intent recognized triggers you created using regular expressions in the add help and cancel command tutorial.
Add language understanding data and conditions
You need to add trigger phrases for each of the three triggers (cancel, help, and weather) that LUIS will use as training data for your bot. You also need to set the Conditions for the help and weather dialogs.
Select the three dots next to the WeatherBot dialog. Then select Add new trigger.
Add the following language understanding training data in the Create a trigger form.
Select Intent recognized in the What is the type of this trigger? field.
Enter cancel in the What is the name of this trigger(LUIS)? field.
Enter example utterances using the .lu file format in the Trigger phrases field.Language understandingCopy
After you select Submit, you will see the trigger node in the authoring canvas.
In the Properties pane on the right, set the Condition property to =#Cancel.Score >= 0.8:
Select the arrow in the Condition property and set it to Write an expression. An = sign will appear.
Enter #Cancel.Score >= 0.8 in the field to set the condition, like in the following screenshot:
This tells your bot not to fire the cancel trigger if the confidence score returned by LUIS is lower than 80%. LUIS is a machine learning based intent classifier and can return a variety of possible matches, so you will want to avoid low confidence results.
Repeat steps 1 through 3 to create the weather trigger in the WeatherBot.Main dialog. Add the following LU training data phrases to the Trigger phrases field:Language understandingCopy
Repeat steps 1 through 3 to create the help trigger in the WeatherBot dialog. Set the Condition property to =#Help.Score >= 0.5 and add the following LU training data phrases to the Trigger phrases field:Language understandingCopy
Note
Read the .lu file format article for more information about .lu files.
Now you need to connect your bot to LUIS. First, follow the steps to create a LUIS resource in the Azure portal.
Once your resource has been created select the Go to resource button. Then select the Keys and Endpoint button on the left.
Select Show Keys to expose KEY 1 and KEY 2. Copy the value of your LUIS authoring key for either KEY 1 or KEY 2. Also copy the location value from the Location field. Both the LUIS authoring key and the location value will be used in the next step.
Now go back to Composer. You'll notice an error icon next to your WeatherBot bot project:
Select the icon, and then select Fix in bot settings. This will take you to the External services section in Project Settings.
Enter the value of the LUIS authoring key you copied in step 7 for LUIS authoring key and select the Location for the LUIS region.
You're now ready to test your bot!
Select Start bot on the top right, and then select Test in Emulator.
With LUIS, you no longer have to type in exact regex patterns to trigger specific scenarios for your bot. Try phrases like:
"How is the weather"
"Weather please"
"Cancel for me"
"Can you help me?"
Using LUIS for entity extraction
You can use LUIS to recognize entities. An entity is a word or phrase extracted from the users utterance that helps clarify their intent.
For example, the user could say "How is the weather in 98052?" Instead of prompting the user again for a zip code, your bot could respond with the weather. This is a very simple example of very powerful capabilities. For more information on how to use LUIS for entity extraction in Composer, read the How to define intent with entities article.
The first step is to add a regex entity extraction rule to the LUIS app.
Select User Input and then select WeatherBot in the navigation pane. Select Show code and in the Language Understanding editor add the following entity definition at the end of the LU content:Language understandingCopy
The next step is to create an action in the BeginDialog trigger to set the
user.zipcode
property to the value of thezipcode
entity.Select the getWeather dialog in the Navigation pane, then the BeginDialog trigger.
Select + in the Authoring Canvas to insert an action after the Send a response action (that has the prompt Let's check the weather). Then select Set a property from the Manage Properties menu.
In the Properties panel enter
user.zipcode
into the Property field and=@zipcode
in the Value field. Theuser.zipcode
property will now be set to the value of thezipcode
entity, and if entered by the user, they will no longer be prompted for it.Your bot is now ready to test.
Select the Restart Bot button on the top right and wait for the LUIS application to finish updating your changes. Then select Test in Emulator.
Now when you say "how is the weather in 98004", the bot will respond with the weather for that location instead of prompting you for a ZIP code.
Last updated