CINXE.COM

Tutorial: Create a weather bot with Bot Framework Composer | Microsoft Learn

<!DOCTYPE html><html class="hasSidebar hasPageActions hasBreadcrumb conceptual has-default-focus theme-light" lang="en-us" dir="ltr" data-authenticated="false" data-auth-status-determined="false" data-target="docs" x-ms-format-detection="none"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta property="og:title" content="Tutorial: Create a weather bot with Bot Framework Composer" /> <meta property="og:type" content="website" /> <meta property="og:url" content="https://learn.microsoft.com/en-us/composer/tutorial-create-weather-bot" /><meta property="og:description" content="Learn the basics of bot building. Create a simple bot that uses the Open Weather API to get the latest weather forecast information and display it to users." /><meta property="og:image" content="https://learn.microsoft.com/en-us/media/open-graph-image.png" /> <meta property="og:image:alt" content="Microsoft Learn" /> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:site" content="@MicrosoftLearn" /> <meta name="color-scheme" content="light dark"><meta name="author" content="JonathanFingold" /> <meta name="breadcrumb_path" content="/composer/breadcrumb/toc.json" /> <meta name="depot_name" content="MSDN.composer-docs" /> <meta name="description" content="Learn the basics of bot building. Create a simple bot that uses the Open Weather API to get the latest weather forecast information and display it to users." /> <meta name="document_id" content="1636bda0-c8ee-5632-bb87-d7972f87e9d7" /> <meta name="document_version_independent_id" content="c8ab72b1-f10a-b0a7-1424-d86a6978621a" /> <meta name="feedback_help_link_type" content="" /> <meta name="feedback_help_link_url" content="" /> <meta name="feedback_product_url" content="" /> <meta name="feedback_system" content="None" /> <meta name="git_commit_id" content="7f7a00e4027ee87cef34ece948f203ea94018875" /> <meta name="gitcommit" content="https://github.com/MicrosoftDocs/composer-docs-pr/blob/7f7a00e4027ee87cef34ece948f203ea94018875/composer-docs/tutorial-create-weather-bot.md" /> <meta name="keywords" content="bot, composer, dialog" /> <meta name="locale" content="en-us" /> <meta name="manager" content="shellyha" /> <meta name="ms.author" content="iawilt" /> <meta name="ms.custom" content="evergreen" /> <meta name="ms.date" content="10/05/2021" /> <meta name="ms.reviewer" content="micchow" /> <meta name="ms.service" content="bot-composer" /> <meta name="ms.topic" content="tutorial" /> <meta name="original_content_git_url" content="https://github.com/MicrosoftDocs/composer-docs-pr/blob/live/composer-docs/tutorial-create-weather-bot.md" /> <meta name="page_type" content="conceptual" /> <meta name="pdf_url_template" content="https://learn.microsoft.com/pdfstore/en-us/MSDN.composer-docs/{branchName}{pdfName}" /> <meta name="schema" content="Conceptual" /> <meta name="site_name" content="Docs" /> <meta name="toc_rel" content="toc.json" /> <meta name="uhfHeaderId" content="Azure" /> <meta name="updated_at" content="2024-07-19 07:02 PM" /> <meta name="word_count" content="3406" /> <meta name="persistent_id" content="d3bcf713-552f-7a92-7cd0-5e29daf2eb46" /> <meta name="cmProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/8b896464-3b7d-4e1f-84b0-9bb45aeb5f64" data-source="generated" /> <meta name="cmProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/bcbcbad5-4208-4783-8035-8481272c98b8" data-source="generated" /> <meta name="cmProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/1ae5c491-970a-4062-8301-6336e69f9026" data-source="generated" /> <meta name="spProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/b1d2d671-9549-46e8-918c-24349120dbf5" data-source="generated" /> <meta name="spProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/43b2e5aa-8a6d-4de2-a252-692232e5edc8" data-source="generated" /> <meta name="spProducts" content="https://authoring-docs-microsoft.poolparty.biz/devrel/f2c3e52e-3667-4e8a-bf11-20b9eaccdc8c" data-source="generated" /> <meta name="github_feedback_content_git_url" content="https://github.com/MicrosoftDocs/composer-docs-pr/blob/live/composer-docs/tutorial-create-weather-bot.md" /><link href="https://learn.microsoft.com/en-us/composer/tutorial-create-weather-bot" rel="canonical"><title>Tutorial: Create a weather bot with Bot Framework Composer | Microsoft Learn</title><link rel="stylesheet" href="/static/assets/0.4.028726178/styles/site-ltr.css"> <script id="msdocs-script"> var msDocs = {environment: { supportLevel: 'production', accessLevel: 'online', reviewFeatures: false, systemContent: true, azurePortalHostname: 'portal.azure.com', legacyHosting: false, siteName: 'learn', },data: { timeOrigin: Date.now(), contentLocale: 'en-us', contentDir: 'ltr', userLocale: 'en-us', userDir: 'ltr', pageTemplate: 'Conceptual', brand: '', context: {}, hasBinaryRating: true, feedbackHelpLinkType:'', feedbackHelpLinkUrl:'', standardFeedback: false, showFeedbackReport: false, enableTutorialFeedback: false, feedbackSystem: 'None', feedbackGitHubRepo: '', feedbackProductUrl: '',extendBreadcrumb: true,isEditDisplayable: false, hideViewSource: false, hasPageActions: true, hasPrintButton: true, hasBookmark: true, hasShare: true, isPermissioned: false, isPrivateUnauthorized: false,hasRecommendations: true,contributors: [{ name: "JonathanFingold", url: "https://github.com/JonathanFingold" },{ name: "cyrilanderson", url: "https://github.com/cyrilanderson" },{ name: "damabe", url: "https://github.com/damabe" },{ name: "emgrol", url: "https://github.com/emgrol" },{ name: "v-alarioza", url: "https://github.com/v-alarioza" },{ name: "stevemunk", url: "https://github.com/stevemunk" },{ name: "MarcFromTerawe", url: "https://github.com/MarcFromTerawe" }],}, functions:{} }; </script><script src="https://wcpstatic.microsoft.com/mscc/lib/v2/wcp-consent.js"></script> <script src="https://js.monitor.azure.com/scripts/c/ms.jsll-4.min.js"></script><script src="/static/assets/0.4.028726178/global/deprecation.js"></script><script src="/static/assets/0.4.028726178/scripts/en-us/index-docs.js"></script></head> <body lang="en-us" dir="ltr"> <div class="header-holder has-default-focus"> <a href="#main" style="z-index: 1070" class="outline-color-text visually-hidden-until-focused position-fixed inner-focus focus-visible top-0 left-0 right-0 padding-xs text-align-center has-body-background" tabindex="1">Skip to main content</a><div hidden id="cookie-consent-holder" data-test-id="cookie-consent-container"></div> <div id="unsupported-browser" style=" background-color: white; color: black; padding: 16px; border-bottom: 1px solid grey;" hidden > <div style="max-width: 800px; margin: 0 auto;"> <p style="font-size: 24px">This browser is no longer supported.</p> <p style="font-size: 16px; margin-top: 16px;">Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.</p> <div style="margin-top: 12px;"> <a href="https://go.microsoft.com/fwlink/p/?LinkID=2092881 " style=" background-color: #0078d4; border: 1px solid #0078d4; color: white; padding: 6px 12px; border-radius: 2px; display: inline-block; ">Download Microsoft Edge</a> <a href="https://learn.microsoft.com/en-us/lifecycle/faq/internet-explorer-microsoft-edge" style=" background-color: white; padding: 6px 12px; border: 1px solid #505050; color: #171717; border-radius: 2px; display: inline-block; ">More info about Internet Explorer and Microsoft Edge</a> </div> </div> </div> <!-- liquid-tag banners global --> <!-- site header --> <header id="ms--site-header" data-test-id="site-header-wrapper" role="banner" itemscope="itemscope" itemtype="http://schema.org/Organization"> <div id="ms--mobile-nav" class="site-header display-none-tablet padding-inline-none gap-none" data-bi-name="mobile-header" data-test-id="mobile-header"></div> <div id="ms--primary-nav" class="site-header display-none display-flex-tablet" data-bi-name="L1-header" data-test-id="primary-header"></div> <div id="ms--secondary-nav" class="site-header display-none display-flex-tablet" data-bi-name="L2-header" data-test-id="secondary-header"></div> </header><div id="content-header" class="content-header uhf-container has-padding has-default-focus border-bottom-none" data-bi-name="content-header"> <div class="content-header-controls margin-xxs margin-inline-sm-tablet"> <button type="button" class="contents-button button button-sm margin-right-xxs" data-bi-name="contents-expand" aria-haspopup="true" data-contents-button> <span class="icon"><span class="docon docon-menu" aria-hidden="true"></span></span> <span class="contents-expand-title">Table of contents</span> </button> <button type="button" class="ap-collapse-behavior ap-expanded button button-sm" data-bi-name="ap-collapse" aria-controls="action-panel"> <span class="icon"><span class="docon docon-exit-mode" aria-hidden="true"></span></span> <span>Exit focus mode</span> </button> </div> </div><div id="disclaimer-holder" class="has-overflow-hidden has-default-focus"> <!-- liquid-tag banners sectional --> </div> </div> <div class="mainContainer uhf-container has-default-focus" data-bi-name="body"> <div class="columns has-large-gaps is-gapless-mobile "><div id="left-container" class="left-container is-hidden-mobile column is-one-third-tablet is-one-quarter-desktop"> <nav id="affixed-left-container" class="margin-top-sm-tablet position-sticky display-flex flex-direction-column" aria-label="Primary"></nav> </div><!-- .primary-holder --> <section class="primary-holder column is-two-thirds-tablet is-three-quarters-desktop"> <!--div.columns --> <div class="columns is-gapless-mobile has-large-gaps "><div id="main-column" class="column is-full is-8-desktop"> <main id="main" class="" role="main" data-bi-name="content" lang="en-us" dir="ltr"><!-- article-header --> <div id="article-header" class="background-color-body margin-top-sm-tablet margin-bottom-xs display-none-print"> <div class="display-flex align-items-center "><details id="article-header-breadcrumbs-overflow-popover" class="popover" data-for="article-header-breadcrumbs"> <summary class="button button-clear button-primary button-sm inner-focus" aria-label="All breadcrumbs"> <span class="icon"> <span class="docon docon-more"></span> </span> </summary> <div id="article-header-breadcrumbs-overflow" class="popover-content padding-none"> </div> </details> <bread-crumbs id="article-header-breadcrumbs" data-test-id="article-header-breadcrumbs" class="overflow-hidden flex-grow-1 margin-right-sm margin-right-md-tablet margin-right-lg-desktop margin-left-negative-xxs padding-left-xxs"></bread-crumbs><div id="article-header-page-actions" class="opacity-none margin-left-auto display-flex flex-wrap-no-wrap align-items-stretch"><a id="lang-link-tablet" class="button button-primary button-clear button-sm display-none display-inline-flex-tablet" title="Read in English" data-bi-name="language-toggle" data-read-in-link hidden> <span class="icon margin-none" aria-hidden="true" data-read-in-link-icon> <span class="docon docon-locale-globe"></span> </span> <span class="is-visually-hidden" data-read-in-link-text>Read in English</span> </a><button type="button" class="collection button button-clear button-sm button-primary display-none display-inline-flex-tablet" data-list-type="collection" data-bi-name="collection" title="Add to collection"> <span class="icon margin-none" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="collection-status is-visually-hidden">Save</span> </button><a data-contenteditbtn class="button button-clear button-sm text-decoration-none button-primary display-none display-inline-flex-tablet" aria-label="Edit" title="Edit This Document" data-bi-name="edit" hidden href="https://github.com/MicrosoftDocs/composer-docs-pr/blob/live/composer-docs/tutorial-create-weather-bot.md"> <span class="icon margin-none" aria-hidden="true"> <span class="docon docon-edit-outline"></span> </span> </a> <details class="popover popover-right" id="article-header-page-actions-overflow"> <summary class="justify-content-flex-start button button-clear button-sm button-primary" aria-label="More actions" title="More actions"> <span class="icon" aria-hidden="true"> <span class="docon docon-more-vertical"></span> </span> </summary> <div class="popover-content padding-xs"><button data-page-action-item="overflow-mobile" type="button" class="justify-content-flex-start button-block button-sm has-inner-focus button button-clear display-none-tablet" data-bi-name="contents-expand" data-contents-button data-popover-close> <span class="icon"> <span class="docon docon-editor-list-bullet" aria-hidden="true"></span> </span><span class="contents-expand-title">Table of contents</span></button><a id="lang-link-overflow" class="justify-content-flex-start button-sm has-inner-focus button button-clear button-block display-none-tablet" title="Read in English" data-bi-name="language-toggle" data-page-action-item="overflow-mobile" data-check-hidden="true" data-read-in-link hidden > <span class="icon" aria-hidden="true" data-read-in-link-icon> <span class="docon docon-locale-globe"></span> </span> <span data-read-in-link-text>Read in English</span> </a><button type="button" class="collection justify-content-flex-start button button-clear button-sm has-inner-focus button-block display-none-tablet" data-list-type="collection" data-bi-name="collection" title="Save" data-page-action-item="overflow-mobile" data-check-hidden="true" data-popover-close> <span class="icon" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="collection-status">Save</span> </button> <button type="button" class="collection justify-content-flex-start button button-clear button-sm has-inner-focus button-block display-none-tablet" data-list-type="plan" data-bi-name="plan" title="Add to Plan" data-page-action-item="overflow-mobile" data-check-hidden="true" data-popover-close hidden> <span class="icon" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="plan-status">Add to Plan</span> </button><a data-contenteditbtn class="button button-clear button-block button-sm has-inner-focus justify-content-flex-start text-decoration-none display-none-tablet" aria-label="Edit" title="Edit This Document" data-bi-name="edit" hidden href="https://github.com/MicrosoftDocs/composer-docs-pr/blob/live/composer-docs/tutorial-create-weather-bot.md"> <span class="icon" aria-hidden="true"> <span class="docon docon-edit-outline"></span> </span> <span>Edit</span> </a><div aria-hidden="true" class="margin-none" data-page-action-item="overflow-all"></div> <hr class="display-none-tablet margin-bottom-xxs margin-top-xxs" /> <h4 class="font-size-sm padding-left-xxs">Share via</h4> <a class="button button-clear button-sm button-block has-inner-focus text-decoration-none justify-content-flex-start share-facebook" data-bi-name="facebook" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-facebook-share font-size-md color-primary"></span> </span> <span class="margin-left-xxs">Facebook</span> </a> <a class="button button-clear button-sm has-inner-focus button-block text-decoration-none justify-content-flex-start share-twitter" data-bi-name="twitter" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-xlogo-share font-size-xxs"></span> </span> <span class="margin-left-xxs">x.com</span> </a> <a class="button button-clear button-sm has-inner-focus button-block text-decoration-none justify-content-flex-start share-linkedin" data-bi-name="linkedin" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-linked-in-logo font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">LinkedIn</span> </a> <a class="button button-clear button-sm button-block has-inner-focus text-decoration-none justify-content-flex-start margin-bottom-xxs share-email" data-bi-name="email" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-mail-message font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">Email</span> </a><hr /> <button class="button button-block button-clear button-sm justify-content-flex-start has-inner-focus margin-top-xxs" title="Print" type="button" aria-label="Print" data-bi-name="print" data-page-action-item="overflow-all" data-popover-close data-print-page data-check-hidden="true"> <span class="icon" aria-hidden="true"> <span class="docon docon-print font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">Print</span> </button> </div> </details> </div></div> </div> <!-- end article-header --><div> <button type="button" class="border contents-button button button-clear button-sm is-hidden-tablet has-inner-focus" data-bi-name="contents-expand" data-contents-button hidden> <span class="icon"> <span class="docon docon-editor-list-bullet" aria-hidden="true"></span> </span><span class="contents-expand-title">Table of contents</span></button> </div><!-- end mobile-contents button --> <div class="content "><h1 id="tutorial-create-a-weather-bot-with-composer">Tutorial: Create a weather bot with Composer</h1><div class="display-flex justify-content-space-between align-items-center flex-wrap-wrap page-metadata-container"> <div class="margin-right-xxs"> <ul class="metadata page-metadata" data-bi-name="page info" lang="en-us" dir="ltr"><li>Article</li><li class="visibility-hidden-visual-diff"><time class="is-invisible" data-article-date aria-label="Article review date" datetime="2023-07-19T19:01:00Z" data-article-date-source="calculated">07/19/2023</time> </li><li class="contributors-holder display-none-print"> <button aria-label="View all contributors" class="contributors-button link-button" data-bi-name="contributors" title="View all contributors">7 contributors</button> </li></ul> </div> <div id="user-feedback" class="margin-block-xxs display-none-print" data-hide-on-archived> <button id="user-feedback-button" data-test-id="conceptual-feedback-button" class="button button-sm button-clear button-primary" type="button" data-bi-name="user-feedback-button" data-user-feedback-button > <span class="icon" aria-hidden="true"> <span class="docon docon-like"></span> </span> <span>Feedback</span> </button> </div></div><nav id="center-doc-outline" class="doc-outline is-hidden-desktop display-none-print margin-bottom-sm" data-bi-name="intopic toc" aria-label="In this article"> <h2 id="ms--in-this-article" class="title is-6 margin-block-xs">In this article</h2> </nav><!-- <content> --><p><strong>APPLIES TO:</strong> Composer v2.x</p> <p>Follow the instructions in this tutorial to build a weather bot using Bot Framework Composer and the OpenWeather Weather API. When finished, you'll know how to navigate Composer's UI, and have an understanding of the core elements of bot building, like: dialogs, triggers, interruptions, and cards.</p> <p>In this tutorial, you'll learn how to:</p> <div class="checklist"> <ul> <li>Create a bot from a template</li> <li>Modify the Greeting</li> <li>Add a new dialog</li> <li>Connect a trigger</li> <li>Prompt a user for input</li> <li>Validate user inputs</li> <li>Make an HTTP request to an external API</li> <li>Enable interruptions for help and cancel requests</li> <li>Add a card to display weather</li> </ul> </div> <h2 id="prerequisites">Prerequisites</h2> <p>Before you get started, you'll need to:</p> <ul> <li><a href="install-composer" data-linktype="relative-path">Download and install Bot Framework Composer</a> for Windows, macOS, or Linux.</li> <li>Sign up for a <a href="https://openweathermap.org/price" data-linktype="external">free Weather API subscription</a> with OpenWeather. After you create your account and subscribe, you can get your API key by clicking your user name from the navigation bar and selecting <strong>My API keys</strong>.</li> </ul> <h2 id="a-quick-tour-of-composer">A quick tour of Composer</h2> <p>Before you jump in, it helps to understand which components make up the Composer's user interface. For this tutorial, you'll primarily use:</p> <ul> <li>The navigation pane: This is used to navigate Composer's options and features.</li> <li>The bot explorer: This displays the components that make up your project. This includes bots, dialogs, and the triggers associated with each dialog.</li> <li>The authoring canvas: This is where the logic for your bot lives. It shows all actions associated with the selected trigger.</li> <li>The properties pane: This is where you set properties for an explicit action, such as a prompt for text, sending an HTTP request, or clearing existing values from a group of properties.</li> </ul> <p><span class="mx-imgBorder"> <a href="media/introduction/composer-overview-image.png#lightbox" data-linktype="relative-path"> <img src="media/introduction/composer-overview-image.png" alt="A quick tour of the Composer Create page." data-linktype="relative-path"> </a> </span> </p> <h2 id="create-an-empty-bot-in-composer">Create an Empty Bot in Composer</h2> <p>To create a weather bot, you're going to start with the <strong>Empty Bot</strong> template. The <strong>Empty Bot</strong> template includes one dialog with two triggers.</p> <ol> <li>Open Composer.</li> <li>Select <strong>+ Create new</strong>.</li> <li>Select <strong>C#</strong>, then select <strong>Empty Bot</strong>. Review the description, then select <strong>Next</strong>.</li> <li>In the <strong>Create a bot project</strong> window, you'll need to provide some information about your bot. For this tutorial, you can use these values: <ul> <li><strong>Name</strong>: <code>weather_bot</code></li> <li><strong>Runtime</strong>: Azure Web App</li> <li><strong>Location</strong>: Select an existing folder, or create a new one to store your bot locally.</li> </ul> </li> <li>Select <strong>Create</strong>. After you select Create, Composer will get the template, create a project, build the runtime, and pull in any required packages. Setup can take a few minutes.</li> <li>When finished, you'll have a basic bot skeleton, with a dialog named <code>weather_bot</code>, and two triggers: <code>Greeting</code> and <code>Unknown intent</code>. <ul> <li><code>Greeting</code> - When a user connects to the bot, the user is sent a greeting.</li> <li><code>Unknown intent</code> - When the user sends a message or makes a request that the bot doesn't recognize, the bot sends a message telling the user it didn't understand the request. Here's a quick look at how your bot should look in the Composer UI. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-empty-bot-triggers.png" alt="Composition of a Composer bot." data-linktype="relative-path"> </span> </li> </ul> </li> </ol> <h3 id="check-point-did-you-create-an-empty-bot">Check point: Did you create an Empty Bot?</h3> <div class="nextstepaction"> <p><a href="#modify-the-greeting" data-linktype="self-bookmark">I created an empty bot</a> <a href="https://microsoft.qualtrics.com/jfe/form/SV_6D4KLPZc2jTIa2O?Product=Composer&amp;Page=tutorial-create-weather-bot&amp;Section=create-an-empty-bot-in-composer" data-linktype="external">I ran into an issue</a></p> </div> <h2 id="modify-the-greeting">Modify the Greeting</h2> <p>Now let's update your bot's <code>Greeting</code> message. This is a great opportunity to give your users an idea of how to communicate with your bot. Here we're going to welcome users and tell them that they can start by typing <strong>weather</strong>.</p> <ol> <li><p>Select the <code>Greeting</code> trigger in the bot explorer.</p> </li> <li><p>After you select <code>Greeting</code>, you'll see the authoring canvas. This is where you add logic to your bot. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-modify-greeting-authoring-canvas.png" alt="Authoring canvas for a trigger in Composer." data-linktype="relative-path"> </span> </p> </li> <li><p>In the authoring canvas, locate and select the action named <strong>Send a response</strong>.</p> </li> <li><p>In the properties pane, you'll see a few options. Locate <strong>Responses</strong>, then select <strong>Welcome to your bot</strong>. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-modify-greeting-send-response.png" alt="Update your bot's greeting message." data-linktype="relative-path"> </span> </p> </li> <li><p>Replace the text with:</p> <pre><code class="lang-lg">Welcome to Weather Bot! Type "weather" to get started. </code></pre> </li> </ol> <p>That's it, you've updated your bot's greeting message.</p> <h3 id="check-point-did-you-change-the-greeting">Check point: Did you change the Greeting?</h3> <ol> <li>Select <strong>Start bot</strong> or <strong>Restart bot</strong> in the upper right of the Composer window.</li> <li>In the Local bot runtime manager, select <strong>Open Web Chat</strong>.</li> <li>When the bot starts, you should see the updated Greeting message: Welcome to Weather Bot! Type "weather" to get started.</li> </ol> <div class="nextstepaction"> <p><a href="#create-a-new-dialog" data-linktype="self-bookmark">I updated the Greeting message</a> <a href="https://microsoft.qualtrics.com/jfe/form/SV_6D4KLPZc2jTIa2O?Product=Composer&amp;Page=tutorial-create-weather-bot&amp;Section=modify-the-greeting" data-linktype="external">I ran into an issue</a></p> </div> <h2 id="create-a-new-dialog">Create a new dialog</h2> <p>Every bot is built from a series of components called <a href="concept-dialog" data-linktype="relative-path">dialogs</a>. Each dialog encapsulates some bot functionality, such as sending a response, prompting a user for text, making an HTTP request, or maybe all of these. In this section, you're going to create a dialog to get the weather.</p> <ol> <li><p>Locate the <code>weather_bot</code> bot in the bot explorer. Select <strong>...</strong>, then select <strong>+ Add a dialog</strong>. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-create-new-dialog-add-dialog.png" alt="Add a new dialog to your bot." data-linktype="relative-path"> </span> </p> </li> <li><p><strong>Create a dialog</strong> will appear. When prompted, enter the following:</p> <ul> <li><strong>Name</strong> - <code>get_weather</code></li> <li><strong>Description</strong> - <code>Get the current weather conditions.</code></li> </ul> </li> <li><p>Select <strong>OK</strong>.</p> </li> <li><p>Locate the <code>get_weather</code> dialog in the bot explorer, then select the <code>BeginDialog</code> trigger.</p> </li> <li><p>In the authoring canvas, select <strong>+</strong>, then select <strong>Send a response</strong>. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-create-new-dialog-select-begin-dialog.png" alt="Send a response from your bot." data-linktype="relative-path"> </span> </p> </li> <li><p>You should see a new activity in the authoring canvas called <strong>Send a response</strong>.</p> </li> <li><p>In the properties pane on the right, locate the empty text box and enter the following text:</p> <pre><code class="lang-lg">Let's check the weather. </code></pre> <p><span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-create-new-dialog-add-text.png" alt="Add text to the response for get_weather." data-linktype="relative-path"> </span> </p> </li> </ol> <p>Let's recap what you just did. You created a new dialog called <code>get_weather</code>. This dialog has a trigger called <code>BeginDialog</code>, and within <code>BeginDialog</code>, you've added an <strong>activity</strong> called <strong>Send a response</strong>. This response is what is sent to users when the <code>get_weather</code> dialog is activated.</p> <p>Before you can test your new dialog, you need to create a trigger in the main <code>weather_bot</code> dialog, which allows you to start <code>get_weather</code>.</p> <h2 id="start-a-dialog-from-a-trigger">Start a dialog from a trigger</h2> <p>The conversation flow with a bot is broken down into different dialogs. In this section, you'll learn how to connect dialogs, specifically, how to connect the <code>get_weather</code> dialog to the <code>weather_bot</code> dialog (or main dialog for your bot).</p> <p>To learn more about dialog flow and design recommendations, see <a href="concept-best-practices" data-linktype="relative-path">Best practices for building bots using Composer</a>.</p> <ol> <li><p>Select the <code>weather_bot</code> dialog in the bot explorer.</p> </li> <li><p>Then, in the properties pane on the right, locate <strong>Recognizer Type/Dispatch type</strong> and select <strong>Change</strong>.</p> </li> <li><p>A window will appear, select <strong>Regular expression</strong>, then select <strong>Done</strong>. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-connect-trigger-regular-expression.png" alt="Change the recognizer/dispatch type to regular expression." data-linktype="relative-path"> </span> </p> </li> <li><p>Locate the <code>weather_bot</code> dialog and select the <strong>...</strong> to expand the menu, then select <strong>+ Add new trigger</strong>. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-connect-trigger-add-trigger.png" alt="Add a trigger to weather bot." data-linktype="relative-path"> </span> </p> </li> <li><p>When the <strong>Create a trigger</strong> menu appears, enter the following information and select <strong>Submit</strong>:</p> <ul> <li><strong>What is the type of this trigger?</strong> - <strong>Intent recognized</strong></li> <li><strong>What is the name of this trigger?</strong> - <code>weather</code></li> <li><strong>Please input the regEx pattern</strong> - <code>weather</code></li> </ul> <p>This trigger tells your bot to look for the word <em>weather</em> in any incoming message. In most cases, regular expressions (regEx) are more complex, however, in this tutorial, the goal is to demonstrate how it works. To learn more about pattern matching and built in evaluations, see <a href="/en-us/azure/bot-service/bot-builder-concept-adaptive-expressions" data-linktype="absolute-path">Adaptive expressions</a>. If you'd like to learn more about improving a bot with natural language processing (NLP), see <a href="concept-natural-language-processing" data-linktype="relative-path">Natural language processing in Composer</a>.</p> </li> <li><p>Make sure the <code>weather</code> trigger is selected. Then, in the authoring canvas, select <strong>+</strong>, then select <strong>Begin a new dialog</strong> from the <strong>Dialog management</strong> drop down menu. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-connect-trigger-authoring-canvas.png" alt="Begin a new dialog for the weather trigger." data-linktype="relative-path"> </span> </p> </li> <li><p>In the authoring canvas, select <strong>Begin a new dialog</strong>.</p> </li> <li><p>In the properties pane on the right, locate <strong>Dialog name</strong> and select <strong>get_weather</strong> from the drop-down menu. <span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-connect-trigger-begin-new-dialog.png" alt="Associate weather trigger with the get weather dialog." data-linktype="relative-path"> </span> </p> </li> </ol> <p>Let's recap what you accomplished. You've told your <code>weather_bot</code> to recognizer regular expressions. You created a trigger for <code>weather</code> and set its <strong>Trigger phrase</strong> to <strong>weather</strong>. Finally, you connected the <code>weather</code> trigger to the <code>get_weather</code> dialog.</p> <h3 id="check-point-did-you-connect-a-trigger-to-get_weather">Check point: Did you connect a trigger to get_weather?</h3> <ol> <li>Select <strong>Start bot</strong> or <strong>Restart bot</strong> in the upper right side of the Composer window.</li> <li>In the Local bot runtime manager, select <strong>Open Web Chat</strong>.</li> <li>After your bot has greeted you, type "weather". You should get this response: "Let's check the weather".</li> </ol> <div class="nextstepaction"> <p><a href="#prompt-a-user-for-input" data-linktype="self-bookmark">I created a new dialog and set up a trigger</a> <a href="https://microsoft.qualtrics.com/jfe/form/SV_6D4KLPZc2jTIa2O?Product=Composer&amp;Page=tutorial-create-weather-bot&amp;Section=connect-a-trigger-to-a-dialog" data-linktype="external">I ran into an issue</a></p> </div> <h2 id="prompt-a-user-for-input">Prompt a user for input</h2> <p>Before your bot can retrieve the weather, it needs the postal code for the location forecast. You can prompt a user for input with the <strong>Text input</strong> action.</p> <ol> <li><p>Locate <code>get_weather</code> in the bot explorer, then select <code>BeginDialog</code>.</p> </li> <li><p>In the authoring canvas, below the <strong>Send a response</strong> action, select <strong>+</strong>.</p> </li> <li><p>Select <strong>Ask a question</strong>, then select <strong>Text</strong>. Two nodes should appear in your authoring canvas: <strong>Prompt for text</strong> and <strong>User input</strong>. Each of these nodes corresponds to a tab in the properties pane, specifically <strong>Bot response</strong> and <strong>User input</strong>.</p> <ul> <li><strong>Bot response</strong> - The prompt from the bot asking the user for an input.</li> <li><strong>User input</strong> - Let's your bot assign the user input to a property that is saved in memory and can be used by your bot for additional processing.</li> <li><strong>Other</strong> - Offers options for validation and responses to user inputs.</li> </ul> <p><span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-text-input-ask-question.png" alt="Add text prompt to BeginDialog." data-linktype="relative-path"> </span> </p> </li> <li><p>In the properties pane, locate <strong>Bot response</strong> and select <strong>Add alternative</strong>. Then enter the following text.</p> <pre><code class="lang-lg">What's your postal code? </code></pre> <p><span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-text-input-bot-response.png" alt="Add a prompt asking the user for input." data-linktype="relative-path"> </span> </p> <p>This prompt is sent to users when the <code>get_weather</code> dialog is started.</p> </li> <li><p>Next, select <strong>User input</strong> in the properties pane.</p> </li> <li><p>Locate <strong>Property</strong> and set the value to:</p> <pre><code class="lang-text">user.postalcode </code></pre> </li> <li><p>Locate <strong>Output format</strong>, then update the value with this <a href="/en-us/azure/bot-service/bot-builder-concept-adaptive-expressions" data-linktype="absolute-path">adaptive expression</a>. <a href="/en-us/azure/bot-service/adaptive-expressions/adaptive-expressions-prebuilt-functions#trim" data-linktype="absolute-path"><code>trim()</code></a> is a prebuilt adaptive expression that removes preceding and trailing spaces from a value, this ensures that the value is accepted if someone accidentally adds a space before or after the postal code.</p> <pre><code class="lang-text">=trim(this.value) </code></pre> </li> </ol> <h2 id="validate-user-inputs">Validate user inputs</h2> <p>Now that you've set a prompt and created a property to save the user's response, let's learn how to set validation rules. Since you'll be using postal code to look up weather forecasts, you'll need to make sure that the user input is five characters (US postal codes). When the user provides a postal code greater or fewer than five characters, your bot should respond with an error message. In this section, you'll learn how to validate user input and respond with error messages.</p> <ol> <li><p>In the authoring canvas, make sure that <strong>User input</strong> is selected. Then select <strong>Other</strong> in the properties pane.</p> </li> <li><p>Expand <strong>Recognizers</strong> and select <strong>Add alternative</strong>. Then enter the following text:</p> <pre><code class="lang-lg">Sorry, I don't understand '${this.value}'. Please specify a 5 digit postal code in the format 12345. </code></pre> <p><span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-validation-recognizers.png" alt="Add an error message for an unrecognized input from the user." data-linktype="relative-path"> </span> </p> </li> <li><p>Expand <strong>Validation</strong>, then locate <strong>Validation rules</strong>. Select <strong>Add new</strong>, then from the drop-down menu select <strong>Write an expression</strong>. Enter the following text. This ensures that the user input equals five characters:</p> <div class="WARNING"> <p>Warning</p> <p>If Composer adds an <code>=</code> character to your expression, <strong>delete</strong> it. The expression should match what's in the example below.</p> </div> <pre><code class="lang-text">length(this.value) == 5 </code></pre> </li> <li><p>In the same menu, locate <strong>Invalid prompt</strong>. Below <strong>Responses</strong>, select <strong>Add alternative</strong>, then enter the following text. This is the message sent to the user if the postal code isn't equal to five characters:</p> <pre><code class="lang-lg">Sorry, '${this.value}' isn't valid. I'm looking for a 5 digit number as postal code. Please specify a 5 digit postal code in the format 12345. </code></pre> </li> <li><p>The last thing you'll want to do for validation, is set a default value for the postal code. Expand <strong>Prompt configuration</strong> and locate <strong>Default value</strong>, then enter the following text:</p> <pre><code class="lang-text">90210 </code></pre> </li> </ol> <p>Now, whenever a user types <strong>weather</strong>, they'll be prompted for their postal code, and that value will be stored in <code>user.postalcode</code>. If the user enters a postal code that isn't equal to five characters, an error message will be sent to the user.</p> <h3 id="check-point-did-you-validate-user-inputs">Check point: Did you validate user inputs?</h3> <ol> <li>Select <strong>Start bot</strong> or <strong>Restart bot</strong> In the upper right of the Composer window.</li> <li>In the Local bot runtime manager, select <strong>Open Web Chat</strong>.</li> <li>At the bottom of Composer, locate and select <strong>Watch</strong>. Then select <strong>Add property</strong>.</li> <li>Locate <strong>Name</strong> and select <code>user.postalcode</code>.</li> <li>In Web Chat, follow the prompts. When you enter a postal code, the value will be recorded in the <strong>Watch</strong> panel.</li> </ol> <div class="nextstepaction"> <p><a href="#make-an-http-request" data-linktype="self-bookmark">I prompted for text and validated the input</a> <a href="https://microsoft.qualtrics.com/jfe/form/SV_6D4KLPZc2jTIa2O?Product=Composer&amp;Page=tutorial-create-weather-bot&amp;Section=validate-user-inputs" data-linktype="external">I ran into an issue</a></p> </div> <h2 id="make-an-http-request">Make an HTTP request</h2> <p>Your bot is configured to prompt the user for their postal code, and send an error message when an invalid postal code is provided. In this section, you'll learn how to make an HTTP request to retrieve the current weather forecast from <a href="https://openweathermap.org/" data-linktype="external">OpenWeather</a>.</p> <p>Before you continue, you're going to need your API key for the Weather API. If you don't have an API key, please follow the instructions in <a href="#prerequisites" data-linktype="self-bookmark">prerequisites</a> to get one.</p> <ol> <li><p>Make sure that <code>BeginDialog</code> is selected in the bot explorer.</p> </li> <li><p>In the authoring canvas, select the <strong>+</strong> beneath all existing actions, then select <strong>Send an HTTP request</strong> from the <strong>Access external resources</strong> drop down menu.</p> <p><span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-http-request-add-request.png" alt="Add an HTTP request to BeginDialog for get_weather." data-linktype="relative-path"> </span> </p> </li> <li><p>Locate <strong>HTTP method</strong> in the properties pane and select <strong>GET</strong>.</p> </li> <li><p>Locate <strong>Url</strong> and set the value to the following text. Make sure to replace <code>YOUR_API_KEY</code> with your key from OpenWeather.</p> <pre><code class="lang-text">https://api.openweathermap.org/data/2.5/weather?zip=${user.postalcode},us&amp;appid=YOUR_API_KEY </code></pre> <p>The reference to <code>${user.postalcode}</code> will be replaced by the value from the bot's <code>user.postalcode</code> property.</p> </li> <li><p>The <strong>Result property</strong> is where the response of your HTTP request is stored. The response from OpenWeather will include the following response values: <code>statusCode</code>, <code>reasonPhrase</code>, <code>content</code>, <code>headers</code>. Locate <strong>Result property</strong> in the right panel, then enter the following value. We are storing the response in <code>dialog.api_response</code>. <code>dialog</code> is a scope that retains its properties until a dialog is ended.</p> <pre><code class="lang-text">dialog.api_response </code></pre> <p>You're storing the response in <code>dialog.api_response</code>. <code>dialog</code> is a scope that retains its properties for the duration of a dialog. To learn more about scopes and how properties are stored in memory, see <a href="concept-memory" data-linktype="relative-path">Conversation flow and memory</a>.</p> </li> <li><p>In the same menu, set <strong>Response type</strong> to <strong>json</strong>.</p> </li> <li><p>Next, you'll want to add some logic to your bot. You can do this with an <strong>If/else branch</strong>, using the HTTP response's <code>dialog.api_response.statusCode</code>. If the <code>statusCode</code> is <code>200</code>, you'll return the weather report. If the <code>statusCode</code> is anything else, you'll return an error message.</p> <p>In the authoring canvas, select <strong>+</strong>, then locate <strong>Create a condition</strong> and select <strong>Branch: If/else</strong>.</p> </li> <li><p>In the authoring canvas, locate and select <strong>Branch: If/else</strong>.</p> </li> <li><p>In the the properties pane, locate <strong>Condition</strong>, and from the drop-down menu select <strong>Write an expression</strong>. Enter the following text:</p> <pre><code class="lang-text">=dialog.api_response.statusCode == 200 </code></pre> </li> <li><p>Locate the <strong>True</strong> branch, then select <strong>+</strong>. Select <strong>Set properties</strong> from the <strong>Manage properties</strong> list.</p> </li> <li><p>Locate <strong>Assignments</strong> in the properties pane. For each property/value pair in the table below, select <strong>Add new</strong> and enter the following text:</p> <table> <thead> <tr> <th>Property</th> <th>Value</th> </tr> </thead> <tbody> <tr> <td><code>dialog.weather</code></td> <td><code>=dialog.api_response.content.weather[0].description</code></td> </tr> <tr> <td><code>dialog.icon</code></td> <td><code>=dialog.api_response.content.weather[0].icon</code></td> </tr> <tr> <td><code>dialog.city</code></td> <td><code>=dialog.api_response.content.name</code></td> </tr> <tr> <td><code>dialog.country</code></td> <td><code>=dialog.api_response.content.sys.country</code></td> </tr> <tr> <td><code>dialog.kelvin</code></td> <td><code>=dialog.api_response.content.main.temp</code></td> </tr> <tr> <td><code>dialog.celsius</code></td> <td><code>=round(dialog.kelvin-273.15)</code></td> </tr> <tr> <td><code>dialog.fahrenheit</code></td> <td><code>=round((dialog.celsius * 9/5) + 32)</code></td> </tr> </tbody> </table> <p>For more information about the Weather API, see <a href="https://openweathermap.org/current" data-linktype="external">Current weather data</a>.</p> </li> <li><p>In the <strong>True</strong> branch, below the <strong>Set properties</strong> action, select <strong>+</strong>, then select <strong>Send a response</strong>.</p> </li> <li><p>Locate <strong>Responses</strong> in the properties pane, then select <strong>Add alternative</strong>. Enter the following text:</p> <pre><code class="lang-lg">The weather is ${dialog.fahrenheit}F or ${dialog.celsius}C and ${dialog.weather}. </code></pre> </li> <li><p>Now, let's tell your bot what to do if the <code>statusCode</code> isn't <code>200</code>. In the <strong>False</strong> branch, select <strong>+</strong>, then select <strong>Send a response</strong>.</p> </li> <li><p>In the properties menu, locate <strong>Responses</strong>, then enter the following text:</p> <pre><code class="lang-lg">Something went wrong: ${dialog.api_response.content.message}. </code></pre> </li> <li><p>For the purpose of this tutorial it's assumed that if you're in this branch, it's because the postal code is invalid. If the postal code is invalid, it should be removed so that the invalid value doesn't persist in the <code>user.postalcode</code> property. In the <strong>False</strong> branch, below the <strong>Send a response</strong> action, select <strong>+</strong>. Then select <strong>Manage properties</strong> and <strong>Delete a property</strong>.</p> <p><span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-http-request-false-branch.png" alt="Delete postal code property value when request fails." data-linktype="relative-path"> </span> </p> </li> <li><p>In the properties pane on the right, update the value for <strong>Property</strong> with:</p> <pre><code class="lang-text">user.postalcode </code></pre> </li> </ol> <p>Let's recap what you just completed. You created an HTTP request to the Weather API, set up conditional branching, which uses the <code>statusCode</code> of the HTTP response, and added responses for a successful and failed request.</p> <h3 id="check-point-did-you-make-an-http-request">Check point: Did you make an HTTP request?</h3> <ol> <li>Select <strong>Start bot</strong> or <strong>Restart bot</strong> in the upper right of the Composer window.</li> <li>In the Local bot runtime manager, select <strong>Open Web Chat</strong>.</li> <li>When prompted to enter a postal code, type: "98052". This is the postal code for Redmond, WA.</li> <li>You should see a message like this: "The weather is 61F or 16C and partly cloudy".</li> </ol> <div class="nextstepaction"> <p><a href="#add-interruptions-to-the-conversation-flow" data-linktype="self-bookmark">I made an HTTP request and got the weather</a> <a href="https://microsoft.qualtrics.com/jfe/form/SV_6D4KLPZc2jTIa2O?Product=Composer&amp;Page=tutorial-create-weather-bot&amp;Section=make-an-http-request" data-linktype="external">I ran into an issue</a></p> </div> <h2 id="add-interruptions-to-the-conversation-flow">Add interruptions to the conversation flow</h2> <p>When building a bot, it's a good idea to allow your users to interrupt the conversation flow. Common interruptions include requests for help or to cancel the current dialog. In this section, you'll learn how to add help and cancel interruptions to your bot using <a href="concept-packages" data-linktype="relative-path"><strong>Package Manager</strong></a>.</p> <ol> <li><p>Select the <strong>Package Manager</strong> in the navigation pane. Make sure <strong>nuget</strong> is selected, then type <strong>help</strong> into the search bar and press <strong>Enter</strong>.</p> </li> <li><p>Select <code>Microsoft.Bot.Components.HelpAndCancel</code> in the package list. In the properties pane on the right, make sure the latest stable version is selected, as <code>rc</code> versions of packages may not function correctly. Then click <strong>Install</strong>.</p> <p><span class="mx-imgBorder"> <img src="media/tutorial-weatherbot/tutorial-package-manager-install.png" alt="Select Package Manager and install Microsoft.Bot.Components.HelpAndCancel package." data-linktype="relative-path"> </span> </p> </li> <li><p>Composer will let you know that the package is being installed. Installation may take a few minutes. When the <strong>Project Readme</strong> appears, review the content, then select <strong>OK</strong>.</p> </li> <li><p>Select the <strong>Create</strong> icon in the navigation pane to get back to the authoring canvas. You'll see two new dialogs: <code>CancelDialog</code> and <code>HelpDialog</code>. Each with a <code>BeginDialog</code> trigger.</p> </li> </ol> <h3 id="canceldialog">CancelDialog</h3> <ol> <li><p>Locate the <code>weather_bot</code> dialog and select <strong>...</strong>, then select <strong>+ Add a new trigger</strong>.</p> </li> <li><p>When the <strong>Create a trigger</strong> window appears, enter the following values, then select <strong>Submit</strong>:</p> <ul> <li><strong>What is the type of this trigger?</strong> - <strong>Intent recognized</strong></li> <li><strong>What is the name of this trigger (RegEx)</strong> - <code>cancel</code></li> <li><strong>Please input regEx pattern</strong> - <code>cancel|stop|quit</code></li> </ul> <p>This is a simple example of a regular expression that will recognize the cancel trigger if a user responds with: cancel, stop, or quit.</p> </li> <li><p>In the authoring canvas, select <strong>+</strong>.</p> </li> <li><p>Locate <strong>Dialog management</strong>, then select <strong>Begin a new dialog</strong>.</p> </li> <li><p>In the properties pane, locate <strong>Dialog name</strong>, then from the drop-down menu, select <strong>CancelDialog</strong>. Now the <code>cancel</code> trigger is connected to the <code>CancelDialog</code>.</p> </li> </ol> <h3 id="helpdialog">HelpDialog</h3> <ol> <li><p>Locate the <code>weather_bot</code> dialog and select <strong>...</strong>, then select <strong>+ Add a new trigger</strong>.</p> </li> <li><p>When the <strong>Create a trigger</strong> window appears, enter the following values, then select <strong>Submit</strong>:</p> <ul> <li><strong>What is the type of this trigger?</strong> - <strong>Intent recognized</strong></li> <li><strong>What is the name of this trigger (RegEx)</strong> - <code>help</code></li> <li><strong>Please input regEx pattern</strong> - <code>help|support|advice</code></li> </ul> <p>This is a simple example of a regular expression that will recognize the help trigger if a user responds with: help, support, or advice.</p> </li> <li><p>In the authoring canvas, select <strong>+</strong>.</p> </li> <li><p>Locate <strong>Dialog management</strong>, then select <strong>Begin a new dialog</strong>.</p> </li> <li><p>In the properties pane, locate <strong>Dialog name</strong>, then from the drop-down menu, select <strong>HelpDialog</strong>. Now the <code>help</code> trigger is connected to the <code>HelpDialog</code>.</p> </li> </ol> <h3 id="enable-interruptions">Enable interruptions</h3> <p>The <code>get_weather</code> dialog knows how to get the weather forecast, but it doesn't know how to respond to requests for help. To enable the bot to respond to requests for help while in the <code>get_weather</code> dialog, you'll need to configure it to handle interruptions. This will let you call the new help functionality from the <code>get_weather</code> dialog, and then once done the conversational flow will seamlessly return to where it left off.</p> <ol> <li>Locate the <code>get_weather</code> dialog in the bot explorer, then select the <code>BeginDialog</code> trigger.</li> <li>In the authoring canvas, locate and select the <strong>Prompt for text</strong> action.</li> <li>In the properties pane, select <strong>Other</strong>, then expand <strong>Prompt Configurations</strong>.</li> <li>Locate <strong>Allow interruptions</strong> and select <strong>true</strong>.</li> </ol> <p>Enabling interruptions in the <code>get_weather</code> dialog ensures that your bot consults the parent dialog's recognizer, which allows your bot to respond to help and cancel requests even when in the <code>get_weather</code> dialog.</p> <h3 id="check-point-did-you-enable-interruptions">Check point: Did you enable interruptions?</h3> <ol> <li>Select <strong>Start bot</strong> or <strong>Restart bot</strong> in the upper right of the Composer window.</li> <li>In the Local bot runtime manager, select <strong>Open Web Chat</strong>.</li> <li>Type "Cancel" or "Help".</li> </ol> <div class="nextstepaction"> <p><a href="#display-weather-information-with-cards" data-linktype="self-bookmark">I enabled help and cancel interruptions</a> <a href="https://microsoft.qualtrics.com/jfe/form/SV_6D4KLPZc2jTIa2O?Product=Composer&amp;Page=tutorial-create-weather-bot&amp;Section=add-interruptions-to-the-conversation-flow" data-linktype="external">I ran into an issue</a></p> </div> <h2 id="display-weather-information-with-cards">Display weather information with cards</h2> <p>Now, let's take the information that you're pulling from Open Weather and build a card to display the current weather in your bot.</p> <ol> <li><p>Locate the <code>get_weather</code> dialog in the bot explorer, then select the <code>BeginDialog</code> trigger.</p> </li> <li><p>Locate the <strong>True</strong> branch in the authoring canvas, then select <strong>Send a response</strong>.</p> </li> <li><p>In the properties pane on the right, select <strong>+</strong>, then select <strong>Attachments</strong>.</p> </li> <li><p>You should see a new tab called <strong>Attachments</strong>.</p> </li> <li><p>Select <strong>Add a new attachment</strong>. In the drop-down menu, select <strong>Create from template</strong>, then select <strong>Thumbnail card</strong>.</p> </li> <li><p>In the code editor that appears, replace the content with the following text:</p> <pre><code class="lang-lg">[ThumbnailCard title = Weather in ${dialog.city} in ${dialog.country} text = It is "${dialog.weather}" in ${user.postalcode} and the temperature is ${dialog.fahrenheit}&amp;deg;F or ${dialog.celsius}&amp;deg;C. Have a nice day. image = http://openweathermap.org/img/wn/${dialog.icon}@2x.png ] </code></pre> </li> </ol> <h3 id="check-point-did-you-add-a-weather-card">Check point: Did you add a weather card?</h3> <ol> <li>Select <strong>Start bot</strong> or <strong>Restart bot</strong> in the upper right of the Composer window.</li> <li>In the Local bot runtime manager, select <strong>Open Web Chat</strong>.</li> <li>When prompted to enter a postal code, type: "98052".</li> <li>You should see a card with the city, country/region, weather report, and icon for current weather conditions.</li> </ol> <div class="nextstepaction"> <p><a href="#next-steps" data-linktype="self-bookmark">I created a weather card</a> <a href="https://microsoft.qualtrics.com/jfe/form/SV_6D4KLPZc2jTIa2O?Product=Composer&amp;Page=tutorial-create-weather-bot&amp;Section=display-weather-information-with-cards" data-linktype="external">I ran into an issue</a></p> </div> <h2 id="next-steps">Next steps</h2> <ul> <li><a href="tutorial-improve-intent-recognition-language-understanding" data-linktype="relative-path">Improve your Composer bot's intent recognition with Natural Language Understanding (NLU)</a></li> </ul> </div><div id="ms--inline-notifications" class="margin-block-xs" data-bi-name="inline-notification"></div><div id="assertive-live-region" role="alert" aria-live="assertive" class="visually-hidden" aria-relevant="additions" aria-atomic="true"></div> <div id="polite-live-region" role="status" aria-live="polite" class="visually-hidden" aria-relevant="additions" aria-atomic="true"></div> <!-- </content> --> </main><!-- recommendations section --><!-- end recommendations section --> <!-- feedback section --><!-- end feedback section --> <!-- feedback report section --><!-- end feedback report section --><aside id="ms--additional-resources-mobile" aria-label="Additional resources" class="display-none-desktop display-none-print" > <hr class="hr" hidden /> <h2 id="ms--additional-resources-mobile-heading" class="title is-3" hidden>Additional resources</h2> <section id="right-rail-recommendations-mobile" data-bi-name="recommendations" hidden></section> <section id="right-rail-training-mobile" data-bi-name="learning-resources-card" hidden></section> <section id="right-rail-events-mobile" data-bi-name="events-card" hidden></section> <section id="right-rail-qna-mobile" data-bi-name="qna-link-card" hidden></section> </aside><div class="border-top is-visible-interactive has-default-focus margin-top-sm "><footer id="footer-interactive" data-bi-name="footer" class="footer-layout"><div class="display-flex gap-xs flex-wrap-wrap is-full-height padding-right-lg-desktop"><a data-mscc-ic="false" class="locale-selector-link button button-sm button-clear flex-shrink-0" href="#" data-bi-name="select-locale"> <span class="icon" aria-hidden="true"> <span class="docon docon-world"></span> </span> <span class="local-selector-link-text"></span></a><div class="ccpa-privacy-link" data-ccpa-privacy-link hidden> <a href="https://aka.ms/yourcaliforniaprivacychoices" class="button button-sm button-clear flex-shrink-0" data-mscc-ic="false" data-bi-name="your-privacy-choices" > <svg role="img" aria-label="California Consumer Privacy Act (CCPA) Opt-Out Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 14" xml:space="preserve" height="16" width="43" focusable="false" > <title>California Consumer Privacy Act (CCPA) Opt-Out Icon</title> <path d="M7.4 12.8h6.8l3.1-11.6H7.4C4.2 1.2 1.6 3.8 1.6 7s2.6 5.8 5.8 5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#fff"></path> <path d="M22.6 0H7.4c-3.9 0-7 3.1-7 7s3.1 7 7 7h15.2c3.9 0 7-3.1 7-7s-3.2-7-7-7zm-21 7c0-3.2 2.6-5.8 5.8-5.8h9.9l-3.1 11.6H7.4c-3.2 0-5.8-2.6-5.8-5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#06f"></path> <path d="M24.6 4c.2.2.2.6 0 .8L22.5 7l2.2 2.2c.2.2.2.6 0 .8-.2.2-.6.2-.8 0l-2.2-2.2-2.2 2.2c-.2.2-.6.2-.8 0-.2-.2-.2-.6 0-.8L20.8 7l-2.2-2.2c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0l2.2 2.2L23.8 4c.2-.2.6-.2.8 0z" style="fill:#fff"></path> <path d="M12.7 4.1c.2.2.3.6.1.8L8.6 9.8c-.1.1-.2.2-.3.2-.2.1-.5.1-.7-.1L5.4 7.7c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0L8 8.6l3.8-4.5c.2-.2.6-.2.9 0z" style="fill:#06f"></path> </svg> <span>Your Privacy Choices</span> </a> </div> <div class="flex-shrink-0"> <div class="dropdown has-caret-up"> <button class="dropdown-trigger button button-clear button-sm has-inner-focus theme-dropdown-trigger" aria-controls="theme-menu-interactive" aria-expanded="false" title="Theme" data-bi-name="theme"> <span class="icon"> <span class="docon docon-sun" aria-hidden="true"></span> </span> <span>Theme</span> <span class="icon expanded-indicator" aria-hidden="true"> <span class="docon docon-chevron-down-light"></span> </span> </button> <div class="dropdown-menu" id="theme-menu-interactive" role="menu"> <ul class="theme-selector padding-xxs" role="none"> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="light"> <span class="theme-light margin-right-xxs"> <span class="theme-selector-icon border display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Light</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="dark"> <span class="theme-dark margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Dark</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="high-contrast"> <span class="theme-high-contrast margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>High contrast</span> </button> </li> </ul> </div> </div> </div> </div> <ul class="links" data-bi-name="footerlinks"> <li class="manage-cookies-holder" hidden></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/previous-versions/" data-bi-name="archivelink">Previous Versions</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="https://techcommunity.microsoft.com/t5/microsoft-learn-blog/bg-p/MicrosoftLearnBlog" data-bi-name="bloglink">Blog</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/contribute/" data-bi-name="contributorGuide">Contribute</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://go.microsoft.com/fwlink/?LinkId=521839" data-bi-name="privacy">Privacy</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/legal/termsofuse" data-bi-name="termsofuse">Terms of Use</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://www.microsoft.com/legal/intellectualproperty/Trademarks/" data-bi-name="trademarks">Trademarks</a></li><li>&copy; Microsoft 2024</li> </ul> </footer></div></div><div id="ms--additional-resources" class="right-container column is-4-desktop display-none display-block-desktop" data-bi-name="pageactions" role="complementary" aria-label="Additional resources" > <div id="affixed-right-container" class="margin-top-sm-tablet" data-bi-name="right-column"> <h2 id="ms--additional-resources-heading" class="title is-6 margin-top-md" hidden>Additional resources</h2> <section id="right-rail-events" data-bi-name="events-card" hidden></section> <section id="right-rail-training" data-bi-name="learning-resources-card" hidden></section> <section id="right-rail-recommendations" data-bi-name="recommendations" hidden></section> <nav id="side-doc-outline" class="doc-outline" data-bi-name="intopic toc" aria-label="In this article"> <h3>In this article</h3> </nav> <section id="right-rail-qna" class="margin-top-xxs" data-bi-name="qna-link-card" hidden></section> </div> </div></div> <!--end of div.columns --> </section> <!--end of .primary-holder --> <!-- interactive container --> <aside id="interactive-container" class="interactive-container is-visible-interactive column has-body-background-dark "> </aside> <!-- end of interactive container --> </div> </div> <!--end of .mainContainer --> <section class="border-top has-default-focus is-hidden-interactive margin-top-sm "><footer id="footer" data-bi-name="footer" class="footer-layout uhf-container has-padding" role="contentinfo"><div class="display-flex gap-xs flex-wrap-wrap is-full-height padding-right-lg-desktop"><a data-mscc-ic="false" class="locale-selector-link button button-sm button-clear flex-shrink-0" href="#" data-bi-name="select-locale"> <span class="icon" aria-hidden="true"> <span class="docon docon-world"></span> </span> <span class="local-selector-link-text"></span></a><div class="ccpa-privacy-link" data-ccpa-privacy-link hidden> <a href="https://aka.ms/yourcaliforniaprivacychoices" class="button button-sm button-clear flex-shrink-0" data-mscc-ic="false" data-bi-name="your-privacy-choices" > <svg role="img" aria-label="California Consumer Privacy Act (CCPA) Opt-Out Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 14" xml:space="preserve" height="16" width="43" focusable="false" > <title>California Consumer Privacy Act (CCPA) Opt-Out Icon</title> <path d="M7.4 12.8h6.8l3.1-11.6H7.4C4.2 1.2 1.6 3.8 1.6 7s2.6 5.8 5.8 5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#fff"></path> <path d="M22.6 0H7.4c-3.9 0-7 3.1-7 7s3.1 7 7 7h15.2c3.9 0 7-3.1 7-7s-3.2-7-7-7zm-21 7c0-3.2 2.6-5.8 5.8-5.8h9.9l-3.1 11.6H7.4c-3.2 0-5.8-2.6-5.8-5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#06f"></path> <path d="M24.6 4c.2.2.2.6 0 .8L22.5 7l2.2 2.2c.2.2.2.6 0 .8-.2.2-.6.2-.8 0l-2.2-2.2-2.2 2.2c-.2.2-.6.2-.8 0-.2-.2-.2-.6 0-.8L20.8 7l-2.2-2.2c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0l2.2 2.2L23.8 4c.2-.2.6-.2.8 0z" style="fill:#fff"></path> <path d="M12.7 4.1c.2.2.3.6.1.8L8.6 9.8c-.1.1-.2.2-.3.2-.2.1-.5.1-.7-.1L5.4 7.7c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0L8 8.6l3.8-4.5c.2-.2.6-.2.9 0z" style="fill:#06f"></path> </svg> <span>Your Privacy Choices</span> </a> </div> <div class="flex-shrink-0"> <div class="dropdown has-caret-up"> <button class="dropdown-trigger button button-clear button-sm has-inner-focus theme-dropdown-trigger" aria-controls="theme-menu" aria-expanded="false" title="Theme" data-bi-name="theme"> <span class="icon"> <span class="docon docon-sun" aria-hidden="true"></span> </span> <span>Theme</span> <span class="icon expanded-indicator" aria-hidden="true"> <span class="docon docon-chevron-down-light"></span> </span> </button> <div class="dropdown-menu" id="theme-menu" role="menu"> <ul class="theme-selector padding-xxs" role="none"> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="light"> <span class="theme-light margin-right-xxs"> <span class="theme-selector-icon border display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Light</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="dark"> <span class="theme-dark margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Dark</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="high-contrast"> <span class="theme-high-contrast margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>High contrast</span> </button> </li> </ul> </div> </div> </div> </div> <ul class="links" data-bi-name="footerlinks"> <li class="manage-cookies-holder" hidden></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/previous-versions/" data-bi-name="archivelink">Previous Versions</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="https://techcommunity.microsoft.com/t5/microsoft-learn-blog/bg-p/MicrosoftLearnBlog" data-bi-name="bloglink">Blog</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/contribute/" data-bi-name="contributorGuide">Contribute</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://go.microsoft.com/fwlink/?LinkId=521839" data-bi-name="privacy">Privacy</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/legal/termsofuse" data-bi-name="termsofuse">Terms of Use</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://www.microsoft.com/legal/intellectualproperty/Trademarks/" data-bi-name="trademarks">Trademarks</a></li><li>&copy; Microsoft 2024</li> </ul> </footer> </section> <div id="action-panel" role="region" aria-label="Action Panel" class="action-panel has-default-focus" tabindex="-1"></div> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10