{"id":12437,"date":"2022-12-14T08:51:44","date_gmt":"2022-12-14T16:51:44","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/?p=12437"},"modified":"2022-12-14T08:53:27","modified_gmt":"2022-12-14T16:53:27","slug":"build-bots-to-automate-repetitive-workflows-using-teams-toolkit-for-visual-studio-code","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/build-bots-to-automate-repetitive-workflows-using-teams-toolkit-for-visual-studio-code\/","title":{"rendered":"Build bots to automate repetitive workflows using Teams Toolkit for Visual Studio Code"},"content":{"rendered":"<p>Imagine the scenario that your organization wants to make it easier for employees to place orders at the company restaurant.<\/p>\n<p>As your organization is already a heavy user of Microsoft Teams, it makes sense to build an app and surface it where your employees spend most of their working day.<\/p>\n<p>Placing an order at a restaurant is a simple repetitive task. Typically, the process goes like this:<\/p>\n<ol>\n<li>Employee asks to make an order.<\/li>\n<li>Restaurant responds with the menu.<\/li>\n<li>Employee places their order based on the menu options.<\/li>\n<li>Restaurant confirms and works on the order.<\/li>\n<\/ol>\n<p>Developing a bot for Microsoft Teams, rather than a traditional web application, is a great way to implement this type of workflow inside Microsoft Teams through a conversational interface.<\/p>\n<p>In this tutorial, I walk you through the steps of how to use <a href=\"https:\/\/learn.microsoft.com\/microsoftteams\/platform\/toolkit\/teams-toolkit-fundamentals?WT.mc_id=m365-79415-garrytrinder\">Teams Toolkit for Visual Studio Code<\/a> to create a Microsoft Teams app that contains a bot employees can use to place orders with the restaurant.<\/p>\n<p><a class=\"article-body-image-wrapper\" href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--4KBtnQ4_--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/k27a1jkdwl57k6cgkp04.png\"><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--4KBtnQ4_--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/k27a1jkdwl57k6cgkp04.png\" alt=\"Order command response\" width=\"880\" height=\"495\" \/><\/a><\/p>\n<p>If you want to see the finished version, checkout the sample in the gallery, or the\u00a0<a href=\"https:\/\/github.com\/OfficeDev\/TeamsFx-Samples\/tree\/dev\/place-your-order-workflow-bot\">final source code<\/a>\u00a0on the TeamsFx GitHub repository.<\/p>\n<blockquote><p>\ud83c\udfa5 A recording from the weekly\u00a0<a href=\"https:\/\/pnp.github.io\/\">Microsoft 365 Platform Community<\/a>\u00a0call is available,\u00a0<a href=\"https:\/\/youtu.be\/rQIXOo0BevM\">Build your first Workflow bot for Microsoft Teams with Teams Toolkit for Visual Studio Code<\/a>, which covers the steps discussed in this tutorial.<\/p><\/blockquote>\n<h2><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#table-of-contents\" name=\"table-of-contents\"><\/a>Table of contents<\/h2>\n<ul>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#ttk\">Teams Toolkit for Visual Studio Code<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#prereqs\">Prerequisites<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#install\">Install Teams Toolkit for Visual Studio Code<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#scaffold\">Scaffold and run the project<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#clean\">Clean the project<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#adaptive-cards\">Create the Adaptive Card templates<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#command\">Create the order command<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#action\">Create the order card action<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#place-order\">Place your order<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#what-next\">What next?<\/a><\/li>\n<li><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#learn-more\">Learn more<\/a><\/li>\n<\/ul>\n<h2 id=\"ttk\">\ud83d\udee0 Teams Toolkit for Visual Studio Code<\/h2>\n<p><a href=\"https:\/\/learn.microsoft.com\/microsoftteams\/platform\/toolkit\/teams-toolkit-fundamentals?WT.mc_id=m365-79415-garrytrinder\">Teams Toolkit for Visual Studio Code<\/a>\u00a0enables you to create, debug and deploy Microsoft Teams apps to a Microsoft 365 tenant fast using a no configuration approach.<\/p>\n<p>In a recent release of Teams Toolkit for Visual Studio Code, a new scenario-based app capability has been released called\u00a0<em>Initiate sequential workflows<\/em>.<\/p>\n<p>This new capability makes it easy for developers to respond to actions invoked from Adaptive Cards, which is ideal for our restaurant order scenario.<\/p>\n<p>Using this new capability, we will create a bot that uses the below workflow.<\/p>\n<ol>\n<li>The employee sends a message containing the word\u00a0<em>order<\/em>\u00a0to the bot chat.<\/li>\n<li>The bot returns an Adaptive Card containing a simple form.<\/li>\n<li>The employee submits the form.<\/li>\n<li>The bot captures the form data and replaces the form with a confirmation message.<\/li>\n<\/ol>\n<p><a class=\"article-body-image-wrapper\" href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--_H1f3CP8--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/n5somg2qiv7fmff6dm2w.png\"><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--_H1f3CP8--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/n5somg2qiv7fmff6dm2w.png\" alt=\"Contoso Restaurant sample project\" width=\"880\" height=\"495\" \/><\/a><\/p>\n<h2 id=\"prereqs\">\ud83c\udfc1 Prerequisites<\/h2>\n<p>To follow this guide successfully you will need.<\/p>\n<ul>\n<li><strong>Microsoft 365 Tenant<\/strong>, which has been\u00a0<a href=\"https:\/\/learn.microsoft.com\/microsoftteams\/platform\/m365-apps\/prerequisites#prepare-a-developer-tenant-for-testing?WT.mc_id=m365-81147-garrytrinder\">enabled for developing custom applications with<\/a>. If you do not have a tenant, I highly recommend that you use a Microsoft 365 Developer Tenant, which you can obtain for free by\u00a0<a href=\"https:\/\/developer.microsoft.com\/microsoft-365\/dev-program?WT.mc_id=m365-81147-garrytrinder\">joining the Microsoft 365 Developer Program<\/a>. It is pre-configured for Microsoft Teams app development right out of the box.<\/li>\n<li><strong>Visual Studio Code<\/strong>, if you do not have it installed,\u00a0<a href=\"https:\/\/code.visualstudio.microsoft.com\/\">download it for free<\/a>!<\/li>\n<\/ul>\n<p>With the prerequisites done, let\u2019s begin!<\/p>\n<h2 id=\"install\">\ud83d\udee0 Install Teams Toolkit for Visual Studio Code<\/h2>\n<p>Our first step is to install Teams Toolkit into Visual Studio Code, you can do this several ways, however the easiest is way is to search for and install the extension using the Extensions panel from the Side Bar within Visual Studio Code.<\/p>\n<ol>\n<li>Open\u00a0<em>Visual Studio Code<\/em>.<\/li>\n<li>Open the\u00a0<em>Extensions panel<\/em>\u00a0from the Side Bar.<\/li>\n<li><em>Search for Teams Toolkit<\/em>\u00a0in the marketplace.<\/li>\n<li>Select\u00a0<em>Teams Toolkit<\/em>\u00a0in the search results.<\/li>\n<li>Click the\u00a0<em>Install button<\/em>\u00a0to install the extension.<\/li>\n<\/ol>\n<p>Once the extension has been successfully installed, you will see a Microsoft Teams icon in the Side Bar.<\/p>\n<h2 id=\"scaffold\">\ud83d\udc77 Scaffold and run the project<\/h2>\n<p>After installing the extension, let\u2019s create our project.<\/p>\n<ol>\n<li>Open the Teams Toolkit extension by clicking on the\u00a0<em>Microsoft Teams icon<\/em>\u00a0in the Side Bar<\/li>\n<li>Click the\u00a0<em>Create a new Teams app<\/em>\u00a0button to start the project scaffolding wizard<\/li>\n<li>Select\u00a0<em>Create a new Teams app<\/em>\u00a0in the first step<\/li>\n<li>Select\u00a0<em>Initiate sequential workflows<\/em>\u00a0in the Capabilities step<\/li>\n<li>Select\u00a0<em>TypeScript<\/em>\u00a0in the Programming Language step<\/li>\n<li>Select a folder of your choice in the Workspace folder step, this is the location of where the project will be created.<\/li>\n<li>Enter\u00a0<em>ContosoRestaurant<\/em>\u00a0in the application name step.<\/li>\n<\/ol>\n<p>When you complete the last step, Teams Toolkit will create a project in a folder with the same name in the Workspace folder location you selected in the previous step.<\/p>\n<p>After the project scaffolding is complete, Teams Toolkit will re-open Visual Studio Code in the project folder and open a Readme file for the project.<\/p>\n<p>The scaffolded project contains some boilerplate code which provides some basic workflow functionality, containing a command and action.<\/p>\n<p>You can run the bot to see how it works by opening the debug side panel, select your browser of choice in the dropdown, and start debugging by either clicking the green play icon or by pressing F5 on your keyboard.<\/p>\n<p>If this is the first time you have used Teams Toolkit for Visual Studio Code, when you first launch your app using Debug, you will be prompted to sign into your Microsoft 365 tenant.<\/p>\n<p>Click the\u00a0<em>Sign In<\/em>\u00a0button in the prompt, this will open your primary browser and navigate you to a Microsoft 365 login screen. Enter your account details to complete the authentication flow, once successful you can close the browser window and return to Visual Studio Code.<\/p>\n<p>Teams Toolkit will setup all the required resources and services for your bot to run locally inside Microsoft Teams, and also provide debugging and hot reload functionality.<\/p>\n<blockquote><p>The first time you run your app, Teams Toolkit will perform a <em>npm install<\/em>\u00a0to install all the required packages, so it might take a few moments depending on your network and machine resources.<\/p>\n<p>This would be a good time to grab a \u2615\ufe0f<\/p><\/blockquote>\n<p>When complete, a browser window will launch, and you will be navigated to the web version of Microsoft Teams. You may be prompted for authentication again. If you are, complete the steps using the same account as you signed in previously.<\/p>\n<p>When Microsoft Teams loads, a dialog box will appear which enables you to side load your app. Click the Add button to add the app as a personal app and open the bot chat.<\/p>\n<p>Type\u00a0<code>helloWorld<\/code> into the chat box and send your message. This will invoke the bot command which returns an Adaptive Card with a button.<\/p>\n<p>Selecting the button will update the Adaptive Card with confirmation of that action.<\/p>\n<h2 id=\"clean\">\ud83d\udc77 Clean the project<\/h2>\n<p>This is entirely optional, but to help follow along with the rest of this tutorial, I recommend that you remove the default code, so it doesn&#8217;t get in the way and we can start from a clean slate.<\/p>\n<p>Don&#8217;t worry about what we are removing for now, I&#8217;ll explain all this as we go through the steps.<\/p>\n<p>If your debug session is still running, just close down the browser window or stop the debugging session in Visual Studio Code.<\/p>\n<p>To remove the default code, you can\u00a0<a href=\"https:\/\/gist.github.com\/garrytrinder\/1911550e3511ec2c0cfe551fd2c120af\">use a script<\/a>\u00a0or do it manually.<\/p>\n<p>To manually remove the code<\/p>\n<ul>\n<li>Delete all files in the following folders\n<ul>\n<li><code>bot\\src\\AdaptiveCards<\/code><\/li>\n<li><code>bot\\src\\cardActions<\/code><\/li>\n<li><code>bot\\src\\commands<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Clear contents of\u00a0<code>bot\\src\\cardModels.ts<\/code><\/li>\n<li>Update\u00a0<code>\/bot\/src\/internal\/initialize.ts<\/code>\n<ul>\n<li>Clear\u00a0<code>commands<\/code>\u00a0array \ud83d\udc49\u00a0<code>commands: []<\/code><\/li>\n<li>Clear\u00a0<code>actions<\/code>\u00a0array \ud83d\udc49\u00a0<code>actions: []<\/code><\/li>\n<li>Remove the unused\u00a0<code>imports<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Update\u00a0<code>templates\/appPackage\/manifest.template.json<\/code>\n<ul>\n<li>Clear the\u00a0<code>commands<\/code>\u00a0array \ud83d\udc49\u00a0<code>commands: []<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>To use the script to remove the code<\/p>\n<ul>\n<li>Create a\u00a0<code>scripts<\/code>\u00a0folder in the root<\/li>\n<li>Download the file and add it to the\u00a0<code>scripts<\/code>\u00a0folder<\/li>\n<li>Open terminal prompt, change to root directory<\/li>\n<li>Execute\u00a0<code>node scripts\\ttk_workflowbot_clean.js<\/code><\/li>\n<\/ul>\n<p>Now that we have a clean project, let&#8217;s start building out our scenario.<\/p>\n<h2 id=\"#adaptive-cards\">\ud83e\uddd1\u200d\ud83d\udcbb Create the Adaptive Card templates<\/h2>\n<p>The first thing we will do is implement Adaptive Cards templates, these cards represent our user interface that employees will interact with.<\/p>\n<blockquote><p><a href=\"https:\/\/learn.microsoft.com\/adaptive-cards\/\">Adaptive Cards<\/a>\u00a0are an open card exchange format enabling developers to exchange UI content in a common and consistent way.<\/p><\/blockquote>\n<p><a href=\"https:\/\/learn.microsoft.com\/adaptive-cards\/templating\/\">Templating<\/a>\u00a0enables the separation of data from the layout in an Adaptive Card, by using data binding syntax\u00a0<code>${data}<\/code>\u00a0we can add placeholders into our templates that can be populated data when we use the Adaptive Card SDK to render the card.<\/p>\n<p>The first template will be sent back to the employee when they request to make an order with menu options.<\/p>\n<p>Let&#8217;s create a new file in the\u00a0<code>bot\\src\\AdaptiveCards<\/code>\u00a0folder called\u00a0<code>orderCommandResponse.json<\/code>\u00a0with the following contents.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight json\"><code><span class=\"p\">{<\/span>\r\n    <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"AdaptiveCard\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nl\">\"$schema\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"http:\/\/adaptivecards.io\/schemas\/adaptive-card.json\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nl\">\"version\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"1.4\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nl\">\"body\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n        <span class=\"p\">{<\/span>\r\n            <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"TextBlock\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"text\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${FormInfo.title}\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"size\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Large\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"wrap\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"weight\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Bolder\"<\/span>\r\n        <span class=\"p\">},<\/span>\r\n        <span class=\"p\">{<\/span>\r\n            <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Input.ChoiceSet\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"id\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"EntreeSelectVal\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"label\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${Order.questions[0].question}\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"style\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"filtered\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"isRequired\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"errorMessage\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"This is a required input\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"placeholder\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Please choose\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"choices\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n                <span class=\"p\">{<\/span>\r\n                    <span class=\"nl\">\"$data\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${Order.questions[0].items}\"<\/span><span class=\"p\">,<\/span>\r\n                    <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${choice}\"<\/span><span class=\"p\">,<\/span>\r\n                    <span class=\"nl\">\"value\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${value}\"<\/span>\r\n                <span class=\"p\">}<\/span>\r\n            <span class=\"p\">]<\/span>\r\n        <span class=\"p\">},<\/span>\r\n        <span class=\"p\">{<\/span>\r\n            <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Input.ChoiceSet\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"id\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"SideVal\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"label\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${Order.questions[1].question}\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"style\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"filtered\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"isRequired\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"errorMessage\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"This is a required input\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"placeholder\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Please choose\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"choices\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n                <span class=\"p\">{<\/span>\r\n                    <span class=\"nl\">\"$data\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${Order.questions[1].items}\"<\/span><span class=\"p\">,<\/span>\r\n                    <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${choice}\"<\/span><span class=\"p\">,<\/span>\r\n                    <span class=\"nl\">\"value\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${value}\"<\/span>\r\n                <span class=\"p\">}<\/span>\r\n            <span class=\"p\">]<\/span>\r\n        <span class=\"p\">},<\/span>\r\n        <span class=\"p\">{<\/span>\r\n            <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Input.ChoiceSet\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"id\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"DrinkVal\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"label\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${Order.questions[2].question}\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"style\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"filtered\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"isRequired\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"errorMessage\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"This is a required input\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"placeholder\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Please choose\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"choices\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n                <span class=\"p\">{<\/span>\r\n                    <span class=\"nl\">\"$data\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${Order.questions[2].items}\"<\/span><span class=\"p\">,<\/span>\r\n                    <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${choice}\"<\/span><span class=\"p\">,<\/span>\r\n                    <span class=\"nl\">\"value\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${value}\"<\/span>\r\n                <span class=\"p\">}<\/span>\r\n            <span class=\"p\">]<\/span>\r\n        <span class=\"p\">}<\/span>\r\n    <span class=\"p\">],<\/span>\r\n    <span class=\"nl\">\"actions\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n        <span class=\"p\">{<\/span>\r\n            <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Action.Execute\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"verb\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"order\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Place Order\"<\/span>\r\n        <span class=\"p\">}<\/span>\r\n    <span class=\"p\">]<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>When this card is rendered, it will display a mini form with three drop downs and an action button. When the action button is selected, the form data is sent to the bot along with a verb, which represents the action that was performed.<\/p>\n<blockquote><p>Note that the drop downs are given ID property values, when the form is submitted the data sent to bot as key\/value pairs, e.g\u00a0<code>{ \"DrinkVal\": \"value\" }<\/code>.<\/p><\/blockquote>\n<p><a class=\"article-body-image-wrapper\" href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--4KBtnQ4_--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/k27a1jkdwl57k6cgkp04.png\"><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--4KBtnQ4_--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/k27a1jkdwl57k6cgkp04.png\" alt=\"Order command response\" width=\"880\" height=\"495\" \/><\/a><\/p>\n<p>The second template will be displayed to the employee when they have submitted their order to the restaurant.<\/p>\n<p>Let&#8217;s create a new file in the\u00a0<code>bot\\src\\AdaptiveCards<\/code>\u00a0folder called\u00a0<code>orderActionResponse.json<\/code>\u00a0with the following contents.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight json\"><code><span class=\"p\">{<\/span>\r\n  <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"AdaptiveCard\"<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nl\">\"$schema\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"http:\/\/adaptivecards.io\/schemas\/adaptive-card.json\"<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nl\">\"version\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"1.4\"<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nl\">\"body\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n    <span class=\"p\">{<\/span>\r\n      <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"TextBlock\"<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"text\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${title}\"<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"wrap\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"style\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"heading\"<\/span>\r\n    <span class=\"p\">},<\/span>\r\n    <span class=\"p\">{<\/span>\r\n      <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Container\"<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"items\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n        <span class=\"p\">{<\/span>\r\n          <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"FactSet\"<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nl\">\"facts\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n            <span class=\"p\">{<\/span>\r\n              <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Entree\"<\/span><span class=\"p\">,<\/span>\r\n              <span class=\"nl\">\"value\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${actionData.EntreeSelectVal}\"<\/span>\r\n            <span class=\"p\">},<\/span>\r\n            <span class=\"p\">{<\/span>\r\n              <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Side\"<\/span><span class=\"p\">,<\/span>\r\n              <span class=\"nl\">\"value\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${actionData.SideVal}\"<\/span>\r\n            <span class=\"p\">},<\/span>\r\n            <span class=\"p\">{<\/span>\r\n              <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Drink\"<\/span><span class=\"p\">,<\/span>\r\n              <span class=\"nl\">\"value\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"${actionData.DrinkVal}\"<\/span>\r\n            <span class=\"p\">}<\/span>\r\n          <span class=\"p\">]<\/span>\r\n        <span class=\"p\">}<\/span>\r\n      <span class=\"p\">]<\/span>\r\n    <span class=\"p\">}<\/span>\r\n  <span class=\"p\">],<\/span>\r\n  <span class=\"nl\">\"actions\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n    <span class=\"p\">{<\/span>\r\n      <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Action.Execute\"<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Edit Order\"<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"verb\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"order-edit\"<\/span>\r\n    <span class=\"p\">}<\/span>\r\n  <span class=\"p\">]<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>When this card is rendered, it will display the selected options submitted in the first card and an action button.<\/p>\n<p><a class=\"article-body-image-wrapper\" href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--T623pv8Y--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/1s6v4vmd8cck3p4iohll.png\"><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--T623pv8Y--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/1s6v4vmd8cck3p4iohll.png\" alt=\"Order action response\" width=\"880\" height=\"495\" \/><\/a><\/p>\n<p>Now that we have our templates in place, let&#8217;s create the data models to define the correct data shape to use with our template when we render the card using the Adaptive Cards SDK.<\/p>\n<p>Open the\u00a0<code>bot\/src\/cardModels.ts<\/code>\u00a0file.<\/p>\n<p>Add the following interfaces which describes the data shape for the\u00a0<code>bot\\src\\AdaptiveCards\\orderCommandResponse.json<\/code>\u00a0card.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">export<\/span> <span class=\"kr\">interface<\/span> <span class=\"nx\">OrderData<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">FormInfo<\/span><span class=\"p\">:<\/span> <span class=\"nx\">FormInfo<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"nl\">Order<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Order<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"kr\">interface<\/span> <span class=\"nx\">FormInfo<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">title<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"kr\">interface<\/span> <span class=\"nx\">Order<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">questions<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Question<\/span><span class=\"p\">[];<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"kr\">interface<\/span> <span class=\"nx\">Question<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">question<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"nl\">items<\/span><span class=\"p\">:<\/span> <span class=\"nx\">Item<\/span><span class=\"p\">[];<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"kr\">interface<\/span> <span class=\"nx\">Item<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">choice<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"nl\">value<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Add the following interfaces which describes the data shape for the\u00a0<code>bot\\src\\AdaptiveCards\\orderCommandResponse.json<\/code>\u00a0card.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">export<\/span> <span class=\"kr\">interface<\/span> <span class=\"nx\">OrderResponseData<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">title<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"nl\">actionData<\/span><span class=\"p\">:<\/span> <span class=\"nx\">OrderActionData<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"kr\">interface<\/span> <span class=\"nx\">OrderActionData<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">EntreeSelectVal<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"nl\">SideVal<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"nl\">DrinkVal<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>The\u00a0<code>OrderActionData<\/code>\u00a0interface also provides the shape of the data which is returned to our bot when the first card is submitted.<\/p>\n<p>Take a moment to look at the data binding syntax used in the templates and the shape of the data defined in the data models.<\/p>\n<h2 id=\"command\">\ud83d\udcdd Create the order command<\/h2>\n<p>To create a new command we need to perform three tasks<\/p>\n<ul>\n<li>Create the command handler<\/li>\n<li>Update the bot configuration<\/li>\n<li>Update the app manifest<\/li>\n<\/ul>\n<h3><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#create-the-command-handler\" name=\"create-the-command-handler\"><\/a>Create the command handler<\/h3>\n<p>With our user interface defined, let&#8217;s create the\u00a0<code>order<\/code>\u00a0command which our employees will use to start the order process.<\/p>\n<p>Let&#8217;s create a new file in the\u00a0<code>bot\\src\\commands<\/code>\u00a0folder called\u00a0<code>orderCommandHandler.ts<\/code>\u00a0with the following contents.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">export<\/span> <span class=\"kd\">class<\/span> <span class=\"nx\">OrderCommandHandler<\/span> <span class=\"k\">implements<\/span> <span class=\"nx\">TeamsFxBotCommandHandler<\/span> <span class=\"p\">{<\/span> <span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>The\u00a0<code>OrderCommandHandler<\/code>\u00a0class will represent the handler for when the\u00a0<code>order<\/code>\u00a0command is sent in the bot chat.<\/p>\n<p>We will use the\u00a0<code>TeamsFxBotCommandHandler<\/code>\u00a0interface from the\u00a0<code>@microsoft\/teamsfx<\/code>\u00a0library to implement the handler functionality.<\/p>\n<p>Let&#8217;s import the\u00a0<code>CommandMessage<\/code>,\u00a0<code>TeamsFxBotCommandHandler<\/code>\u00a0and\u00a0<code>TriggerPatterns<\/code>\u00a0classes from the\u00a0<code>@microsoft\/teamsfx<\/code>\u00a0library, the TurnContext class and Activity interface from\u00a0<code>botbuilder<\/code>\u00a0library, and implement the\u00a0<code>TeamsFxBotCommandHandler<\/code>\u00a0interface.<\/p>\n<blockquote><p>You can use the\u00a0<a href=\"https:\/\/code.visualstudio.com\/docs\/editor\/refactoring#_code-actions-quick-fixes-and-refactorings\">Quick Fix<\/a>\u00a0menu in Visual Studio Code to import packages and implement interfaces quickly<\/p><\/blockquote>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">CommandMessage<\/span><span class=\"p\">,<\/span> <span class=\"nx\">TeamsFxBotCommandHandler<\/span><span class=\"p\">,<\/span> <span class=\"nx\">TriggerPatterns<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">@microsoft\/teamsfx<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">TurnContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Activity<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">botbuilder<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"kd\">class<\/span> <span class=\"nx\">OrderCommandHandler<\/span> <span class=\"k\">implements<\/span> <span class=\"nx\">TeamsFxBotCommandHandler<\/span> <span class=\"p\">{<\/span>\r\n\r\n  <span class=\"nl\">triggerPatterns<\/span><span class=\"p\">:<\/span> <span class=\"nx\">TriggerPatterns<\/span><span class=\"p\">;<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"nx\">handleCommandReceived<\/span><span class=\"p\">(<\/span><span class=\"nx\">context<\/span><span class=\"p\">:<\/span> <span class=\"nx\">TurnContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">message<\/span><span class=\"p\">:<\/span> <span class=\"nx\">CommandMessage<\/span><span class=\"p\">):<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"kr\">string<\/span> <span class=\"o\">|<\/span> <span class=\"k\">void<\/span> <span class=\"o\">|<\/span> <span class=\"nb\">Partial<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Activity<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nb\">Error<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">Method not implemented.<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Let&#8217;s update the\u00a0<code>triggerPatterns<\/code>\u00a0property with the value\u00a0<code>order<\/code>. This property defines the keyword that the bot will listen out for when it is sent messages.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"nx\">triggerPatterns<\/span><span class=\"p\">:<\/span> <span class=\"nx\">TriggerPatterns<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">order<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Next, let&#8217;s add the logic to the\u00a0<code>handleCommandReceived<\/code>\u00a0method that will be executed when the handler is invoked.<\/p>\n<p>First, add the\u00a0<code>async<\/code>\u00a0keyword to the method declaration as the method will return a\u00a0<code>Promise<\/code>.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">async<\/span> <span class=\"nx\">handleCommandReceived<\/span><span class=\"p\">(<\/span><span class=\"nx\">context<\/span><span class=\"p\">:<\/span> <span class=\"nx\">TurnContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">message<\/span><span class=\"p\">:<\/span> <span class=\"nx\">CommandMessage<\/span><span class=\"p\">):<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"kr\">string<\/span> <span class=\"o\">|<\/span> <span class=\"k\">void<\/span> <span class=\"o\">|<\/span> <span class=\"nb\">Partial<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">Activity<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"p\">{<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Next we will create a new object that we will use populate the template in the shape of the\u00a0<code>OrderData<\/code>\u00a0model that we defined earlier. This object will represent the menu options that the employee can choose from in the form.<\/p>\n<p>Import the\u00a0<code>OrderData<\/code>\u00a0interface using an import statement at the top of the file.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">OrderData<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/cardModels<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Create a new constant called\u00a0<code>orderData<\/code>\u00a0using the\u00a0<code>OrderData<\/code>\u00a0interface as its type, replacing the\u00a0<code>throw<\/code>\u00a0statement.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">orderData<\/span><span class=\"p\">:<\/span> <span class=\"nx\">OrderData<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"dl\">\"<\/span><span class=\"s2\">FormInfo<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"dl\">\"<\/span><span class=\"s2\">title<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Malt &amp; Vine Order Form<\/span><span class=\"dl\">\"<\/span>\r\n      <span class=\"p\">},<\/span>\r\n      <span class=\"dl\">\"<\/span><span class=\"s2\">Order<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"dl\">\"<\/span><span class=\"s2\">questions<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n          <span class=\"p\">{<\/span>\r\n            <span class=\"dl\">\"<\/span><span class=\"s2\">question<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Which entree would you like?<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"dl\">\"<\/span><span class=\"s2\">items<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Steak<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Steak<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Chicken<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Chicken<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Tofu<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Tofu<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">}<\/span>\r\n            <span class=\"p\">]<\/span>\r\n          <span class=\"p\">},<\/span>\r\n          <span class=\"p\">{<\/span>\r\n            <span class=\"dl\">\"<\/span><span class=\"s2\">question<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Which side would you like?<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"dl\">\"<\/span><span class=\"s2\">items<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Baked Potato<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Baked Potato<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Rice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Baked Potato<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Vegetables<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Baked Potato<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Noodles<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Baked Potato<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">No Side<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Baked Potato<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">}<\/span>\r\n            <span class=\"p\">]<\/span>\r\n          <span class=\"p\">},<\/span>\r\n          <span class=\"p\">{<\/span>\r\n            <span class=\"dl\">\"<\/span><span class=\"s2\">question<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Which drink would you like?<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"dl\">\"<\/span><span class=\"s2\">items<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Water<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Water<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Soft Drink<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Soft Drink<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Coffee<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Coffee<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Natural Juice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Natural Juice<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">},<\/span>\r\n              <span class=\"p\">{<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">choice<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">No Drink<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"dl\">\"<\/span><span class=\"s2\">value<\/span><span class=\"dl\">\"<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">No Drink<\/span><span class=\"dl\">\"<\/span>\r\n              <span class=\"p\">}<\/span>\r\n            <span class=\"p\">]<\/span>\r\n          <span class=\"p\">}<\/span>\r\n        <span class=\"p\">]<\/span>\r\n      <span class=\"p\">}<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Now we have our data, we need to populate our template with\u00a0<code>orderData<\/code>\u00a0to render a card that we can then send to the bot chat as our response. To do this we need to import our template and the Adaptive Cards SDK.<\/p>\n<p>Import the template and SDK by adding import statements at the top of the file.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"nx\">orderCard<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/adaptiveCards\/orderCommandResponse.json<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">AdaptiveCards<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">@microsoft\/adaptivecards-tools<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Add the following line after you initialise the\u00a0<code>orderData<\/code>\u00a0constant, where we will use the Adaptive Cards SDK to parse the template and passing the data object to it to render the card.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">cardJson<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">AdaptiveCards<\/span>\r\n  <span class=\"p\">.<\/span><span class=\"kr\">declare<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">OrderData<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">(<\/span><span class=\"nx\">orderCard<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"p\">.<\/span><span class=\"nx\">render<\/span><span class=\"p\">(<\/span><span class=\"nx\">orderData<\/span><span class=\"p\">);<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>We now have a card populated with data and ready to be sent, so let&#8217;s do that.<\/p>\n<p>Import the\u00a0<code>MessageFactory<\/code>\u00a0and\u00a0<code>CardFactory<\/code>\u00a0classes from the\u00a0<code>botbuilder<\/code>\u00a0library by updating the existing import statement.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">TurnContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Activity<\/span><span class=\"p\">,<\/span> <span class=\"nx\">MessageFactory<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CardFactory<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">botbuilder<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Add the following line after you initialise the\u00a0<code>cardJson<\/code>\u00a0constant to send the populated Adaptive Card to the bot chat.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">return<\/span> <span class=\"nx\">MessageFactory<\/span><span class=\"p\">.<\/span><span class=\"nx\">attachment<\/span><span class=\"p\">(<\/span>\r\n  <span class=\"nx\">CardFactory<\/span><span class=\"p\">.<\/span><span class=\"nx\">adaptiveCard<\/span><span class=\"p\">(<\/span><span class=\"nx\">cardJson<\/span><span class=\"p\">)<\/span>\r\n<span class=\"p\">);<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<h3><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#update-the-bot-configuration\" name=\"update-the-bot-configuration\"><\/a>Update the bot configuration<\/h3>\n<p>After implementing the command handler, the next step is to update the bot configuration to tell our bot about our new handler.<\/p>\n<p>Open the\u00a0<code>bot\\src\\internal\\initialize.ts<\/code>\u00a0file which contains our bot configuration and import the\u00a0<code>OrderCommandHandler<\/code>\u00a0class at the top of the file.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">OrderCommandHandler<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/commands\/orderCommandHandler<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Update the\u00a0<code>commands<\/code>\u00a0array, including a new instance of the\u00a0<code>OrderCommandHandler<\/code>\u00a0class in the array.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"nx\">command<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">enabled<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">commands<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"k\">new<\/span> <span class=\"nx\">OrderCommandHandler<\/span><span class=\"p\">()],<\/span>\r\n<span class=\"p\">},<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<h3><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#update-the-app-manifest\" name=\"update-the-app-manifest\"><\/a>Update the app manifest<\/h3>\n<p>The final step is to add our order command to the list of suggestions that the bot can recommend to employees who use it.<\/p>\n<p>Open the\u00a0<code>templates\\manifest.template.json<\/code>\u00a0app manifest file, which describes how our app integrates into Microsoft Teams.<\/p>\n<p>Update the\u00a0<code>commands<\/code>\u00a0array, including a new command object in the array.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight json\"><code><span class=\"nl\">\"commands\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n  <span class=\"p\">{<\/span>\r\n    <span class=\"nl\">\"title\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"order\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nl\">\"description\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"Place an order\"<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"p\">]<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p><a class=\"article-body-image-wrapper\" href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--hCCtPYCg--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/ig2lp6x0q1338ys02dvp.png\"><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--hCCtPYCg--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/ig2lp6x0q1338ys02dvp.png\" alt=\"Bot Suggestions\" width=\"880\" height=\"495\" \/><\/a><\/p>\n<h2 id=\"order-action\">\u26a1\ufe0f Create the order card action<\/h2>\n<p>With our user interface and command handler defined, we now need to create an action handler which will be triggered when the employee submits the order.<\/p>\n<p>To create a new action handler we need to perform two tasks<\/p>\n<ul>\n<li>Create the action handler<\/li>\n<li>Update the bot configuration<\/li>\n<\/ul>\n<h3><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#create-the-action-handler\" name=\"create-the-action-handler\"><\/a>Create the action handler<\/h3>\n<p>Let&#8217;s create a new file in the\u00a0<code>bot\\src\\cardActions<\/code>\u00a0folder called\u00a0<code>orderActionHandler.ts<\/code>\u00a0with the following contents.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">export<\/span> <span class=\"kd\">class<\/span> <span class=\"nx\">OrderActionHandler<\/span> <span class=\"k\">implements<\/span> <span class=\"nx\">TeamsFxAdaptiveCardActionHandler<\/span> <span class=\"p\">{<\/span> <span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>The\u00a0<code>OrderActionHandler<\/code>\u00a0class will represent the handler for when an Adaptive Card action that uses the\u00a0<code>Action.Execute<\/code>\u00a0type passing the\u00a0<code>order<\/code>\u00a0verb.<\/p>\n<p>We will use the\u00a0<code>TeamsFxAdaptiveCardActionHandler<\/code>\u00a0interface from the\u00a0<code>@microsoft\/teamsfx<\/code>\u00a0library to implement the handler functionality.<\/p>\n<p>Let&#8217;s import the\u00a0<code>AdaptiveCardResponse<\/code>\u00a0enum and\u00a0<code>TeamsFxAdaptiveCardActionHandler<\/code>\u00a0class from the\u00a0<code>@microsoft\/teamsfx<\/code>\u00a0library, the\u00a0<code>TurnContext<\/code>\u00a0class and\u00a0<code>InvokeResponse<\/code>\u00a0interface from\u00a0<code>botbuilder<\/code>\u00a0library, and implement the\u00a0<code>TeamsFxAdaptiveCardActionHandler<\/code>\u00a0interface.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">AdaptiveCardResponse<\/span><span class=\"p\">,<\/span> <span class=\"nx\">TeamsFxAdaptiveCardActionHandler<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">@microsoft\/teamsfx<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">TurnContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">InvokeResponse<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">botbuilder<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"kd\">class<\/span> <span class=\"nx\">OrderActionHandler<\/span> <span class=\"k\">implements<\/span> <span class=\"nx\">TeamsFxAdaptiveCardActionHandler<\/span> <span class=\"p\">{<\/span>\r\n\r\n  <span class=\"nl\">triggerVerb<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span><span class=\"p\">;<\/span>\r\n\r\n  <span class=\"nl\">adaptiveCardResponse<\/span><span class=\"p\">?:<\/span> <span class=\"nx\">AdaptiveCardResponse<\/span><span class=\"p\">;<\/span>\r\n\r\n  <span class=\"nx\">handleActionInvoked<\/span><span class=\"p\">(<\/span><span class=\"nx\">context<\/span><span class=\"p\">:<\/span> <span class=\"nx\">TurnContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">actionData<\/span><span class=\"p\">:<\/span> <span class=\"kr\">any<\/span><span class=\"p\">):<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">InvokeResponse<\/span><span class=\"o\">&lt;<\/span><span class=\"kr\">any<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nb\">Error<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">Method not implemented.<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Let&#8217;s update the\u00a0<code>triggerVerb<\/code>\u00a0property with the value\u00a0<code>order<\/code>. This property defines the verb that the bot will listen out for when it is sent data as a result of an\u00a0<code>Action.Execute<\/code>\u00a0action invoked from an Adaptive Card.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"nx\">triggerVerb<\/span><span class=\"p\">:<\/span> <span class=\"kr\">string<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">order<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Next, let&#8217;s add the logic to the\u00a0<code>handleActionInvoked<\/code>\u00a0method that will be executed when the handler is invoked.<\/p>\n<p>Add the\u00a0<code>async<\/code>\u00a0keyword to the method declaration as the method will return a\u00a0<code>Promise<\/code>.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">async<\/span> <span class=\"nx\">handleActionInvoked<\/span><span class=\"p\">(<\/span><span class=\"nx\">context<\/span><span class=\"p\">:<\/span> <span class=\"nx\">TurnContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">actionData<\/span><span class=\"p\">:<\/span> <span class=\"kr\">any<\/span><span class=\"p\">):<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">InvokeResponse<\/span><span class=\"o\">&lt;<\/span><span class=\"kr\">any<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"p\">{<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>You may have noticed that\u00a0<code>handleActionInvoked<\/code>\u00a0method returns an\u00a0<code>actionData<\/code>\u00a0parameter, this will contain the data submitted from our Adaptive Card.<\/p>\n<p>As we have already defined the model for this data, let&#8217;s replace\u00a0<code>any<\/code>\u00a0with our own type.<\/p>\n<p>Import the\u00a0<code>OrderActionData<\/code>\u00a0interface using an import statement at the top of the file.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">OrderActionData<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/cardModels<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Update\u00a0<code>actionData<\/code>\u00a0parameter type.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">async<\/span> <span class=\"nx\">handleActionInvoked<\/span><span class=\"p\">(<\/span><span class=\"nx\">context<\/span><span class=\"p\">:<\/span> <span class=\"nx\">TurnContext<\/span><span class=\"p\">,<\/span> <span class=\"nx\">actionData<\/span><span class=\"p\">:<\/span> <span class=\"nx\">OrderActionData<\/span><span class=\"p\">):<\/span> <span class=\"nb\">Promise<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">InvokeResponse<\/span><span class=\"o\">&lt;<\/span><span class=\"kr\">any<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"p\">{<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Next we will create a new object that we will use populate the template in the shape of the\u00a0<code>OrderResponseData<\/code>\u00a0model that we defined earlier. This object will represent the menu options selected by the employee and includes a title to display in the confirmation.<\/p>\n<p>Import the\u00a0<code>OrderResponseData<\/code>\u00a0interface using an import statement at the top of the file.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">OrderResponseData<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/cardModels<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Create a new constant called\u00a0<code>orderResponseData<\/code>\u00a0using the\u00a0<code>OrderResponseData<\/code>\u00a0interface as its type, replacing the\u00a0<code>throw<\/code>\u00a0statement.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight json\"><code><span class=\"err\">const<\/span> <span class=\"err\">orderResponseData:<\/span> <span class=\"err\">OrderResponseData<\/span> <span class=\"err\">=<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"err\">title:<\/span> <span class=\"s2\">\"\u2705 [ACK] Order Placed\"<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"err\">actionData<\/span>\r\n<span class=\"p\">}<\/span><span class=\"err\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Now we have our data, we need to populate our template with\u00a0<code>orderResponseData<\/code>\u00a0to render a card that we can then replace the submitted Adaptive Card with. To do this we need to import our template and the Adaptive Cards SDK.<\/p>\n<p>Import the template and SDK by adding import statements at the top of the file.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"nx\">orderActionResponseCard<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/adaptiveCards\/orderActionResponse.json<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">AdaptiveCards<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">@microsoft\/adaptivecards-tools<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Add the following line after you initialise the\u00a0<code>orderResponseData<\/code>\u00a0constant, where we will use the Adaptive Cards SDK to parse the template and passing the data object to it to render the card.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">cardJson<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">AdaptiveCards<\/span>\r\n  <span class=\"p\">.<\/span><span class=\"kr\">declare<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">OrderResponseData<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">(<\/span><span class=\"nx\">orderActionResponseCard<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"p\">.<\/span><span class=\"nx\">render<\/span><span class=\"p\">(<\/span><span class=\"nx\">orderResponseData<\/span><span class=\"p\">);<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>We now have a card populated with data and ready to be sent, so let&#8217;s do that.<\/p>\n<p>Import the\u00a0<code>InvokeResponseFactory<\/code>\u00a0class from the\u00a0<code>@microsoft\/teamsfx<\/code>\u00a0library by updating the existing import statement.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">AdaptiveCardResponse<\/span><span class=\"p\">,<\/span> <span class=\"nx\">InvokeResponseFactory<\/span><span class=\"p\">,<\/span> <span class=\"nx\">TeamsFxAdaptiveCardActionHandler<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">@microsoft\/teamsfx<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Add the following line after you initialise the\u00a0<code>cardJson<\/code>\u00a0constant to send the populated Adaptive Card to the bot chat, replacing the existing Adaptive Card.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">return<\/span> <span class=\"nx\">InvokeResponseFactory<\/span><span class=\"p\">.<\/span><span class=\"nx\">adaptiveCard<\/span><span class=\"p\">(<\/span><span class=\"nx\">cardJson<\/span><span class=\"p\">);<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<h3><a href=\"https:\/\/dev.to\/microsoft365\/place-your-order-build-bots-for-microsoft-teams-to-automate-repetitive-workflows-using-teams-toolkit-for-vs-code-13l8#update-the-bot-configuration\" name=\"update-the-bot-configuration\"><\/a>Update the bot configuration<\/h3>\n<p>After implementing the action handler, the next step is to update the bot configuration to tell our bot about our new handler.<\/p>\n<p>Open the\u00a0<code>bot\\src\\internal\\initialize.ts<\/code>\u00a0file which contains our bot configuration and import the\u00a0<code>OrderActionHandler<\/code>\u00a0class at the top of the file.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">OrderCommandHandler<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">..\/commands\/orderCommandHandler<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<p>Update the\u00a0<code>actions<\/code>\u00a0array, including a new instance of the\u00a0<code>OrderActionHandler<\/code>\u00a0class in the array.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"nx\">cardAction<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nl\">enabled<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">actions<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"k\">new<\/span> <span class=\"nx\">OrderActionHandler<\/span><span class=\"p\">()]<\/span>\r\n<span class=\"p\">},<\/span>\r\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\"><\/div>\n<\/div>\n<\/div>\n<h2 id=\"place-order\">\ud83d\ude4b Place your order<\/h2>\n<p>Now it&#8217;s time to run our bot and test it out.<\/p>\n<p>You can do this easily, either by opening the Debug panel and selecting the green play button or by pressing F5 on your keyboard.<\/p>\n<p>Follow the steps to side load your application, when the bot chat is visible, submit\u00a0<code>order<\/code>\u00a0in the chat to start the workflow.<\/p>\n<p><a class=\"article-body-image-wrapper\" href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--45wyxYrj--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/84c8ot8ako6hvmdv1ywk.png\"><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--45wyxYrj--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/84c8ot8ako6hvmdv1ywk.png\" alt=\"Order placed\" width=\"880\" height=\"495\" \/><\/a><\/p>\n<blockquote><p>\ud83c\udf89 Congratulations! You&#8217;ve just created your first bot that implements a simple workflow to automate a repetitive task enabling an employee to place an order with the company restaurant.<\/p><\/blockquote>\n<h2 id=\"what-next\">\u23ed What next?<\/h2>\n<p>Want to make more updates? Here are a few things you can try.<\/p>\n<ul>\n<li><strong>Edit order<\/strong>, implement the\u00a0<em>Edit Order<\/em>\u00a0button that is displayed when the order is confirmed.<\/li>\n<li><strong>Expand the menu<\/strong>, add more options to the order form.<\/li>\n<li><strong>Update the app icons<\/strong>, currently the app uses stock icons, update the icons in the\u00a0<code>templates\/appPackage\/resources<\/code>\u00a0directory with new, more relevant icons.<\/li>\n<li><strong>Restrict supported Teams scopes<\/strong>, by default the bot can be installed into a personal, chat or channel context, to restrict where the bot can be used, update the scopes array in the app manifest.<\/li>\n<\/ul>\n<h2 id=\"learn-more\">\ud83d\udcda Learn more<\/h2>\n<ul>\n<li><a href=\"https:\/\/developer.microsoft.com\/microsoft-teams?WT.mc_id=m365-79415-garrytrinder\">Microsoft Teams Developer Center<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/microsoftteams\/platform\/overview?WT.mc_id=m365-79415-garrytrinder\">Teams Toolkit Documentation<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/microsoftteams\/platform\/toolkit\/teams-toolkit-fundamentals?WT.mc_id=m365-79415-garrytrinder\">Teams Toolkit Overview<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/microsoftteams\/platform\/bots\/how-to\/conversations\/workflow-bot-in-teams?tabs=JS&amp;WT.mc_id=m365-79415-garrytrinder\">Workflow bot in Teams<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/microsoftteams\/platform\/sbs-gs-workflow-bot?tabs=vscode?WT.mc_id=m365-79415-garrytrinder\">Build workflow bot<\/a><\/li>\n<\/ul>\n<blockquote><p>\ud83d\udc4b Happy coding!<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to use Teams Toolkit for Visual Studio Code to create a Microsoft Teams app that contains a bot employees can use to place restaurant orders.<\/p>\n","protected":false},"author":100385,"featured_media":12451,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[128],"tags":[23,44],"class_list":["post-12437","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-teams","tag-teams-toolkit","tag-visual-studio-code"],"acf":[],"blog_post_summary":"<p>Learn how to use Teams Toolkit for Visual Studio Code to create a Microsoft Teams app that contains a bot employees can use to place restaurant orders.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/12437","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/100385"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=12437"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/12437\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/12451"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=12437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=12437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=12437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}