🙋🤖 Place your order! - Build bots for Microsoft Teams to automate repetitive workflows using Teams Toolkit for VS Code
Tags: microsoft365dev, microsoftteams, bots, typescript
Published: 2022-12-06 12:20:00

---
title: 🙋🤖 Place your order! - Build bots for Microsoft Teams to automate repetitive workflows using Teams Toolkit for VS Code
published: true
description: In this tutorial, I'm going to walk you through the steps of how to use Teams Toolkit for Visual Studio Code to create a Microsoft Teams app containing a bot that the employees can use to place orders at the company restaurant.
tags: microsoft365dev,microsoftteams,bots,typescript
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87da99vxuu5f6hz9k3j7.png
published_at: 2022-12-06 12:20 +0000
---

Imagine the scenario that your organisation wants to make it easier for employees to place orders at the company restaurant.

As your organisation 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.

Placing an order at a restaurant is a simple repetitive task. Typically, the process goes like this:

1. Employee asks to make an order.
2. Restaurant responds with the menu.
3. Employee places their order based on the menu options.
4. Restaurant confirms and works on the order.

Developing a bot for Microsoft Teams, rather than a traditional web application, is a great way of implementing this type of workflow inside Microsoft Teams through a conversational interface.

In this tutorial, I'm going to walk you through the steps of how to use [Teams Toolkit for Visual Studio Code](https://learn.microsoft.com/microsoftteams/platform/toolkit/teams-toolkit-fundamentals?WT.mc_id=m365-79415-garrytrinder) to create a Microsoft Teams app that contains a bot that the employees can use to place orders with the restaurant.

![Order command response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k27a1jkdwl57k6cgkp04.png)

If you want to see the finished version, checkout the sample in the gallery, or the [final source code](https://github.com/OfficeDev/TeamsFx-Samples/tree/dev/place-your-order-workflow-bot) on the TeamsFx GitHub repository.

> 🎥 A recording from the weekly [Microsoft 365 Platform Community](https://pnp.github.io) call is available, [Build your first Workflow bot for Microsoft Teams with Teams Toolkit for Visual Studio Code](https://youtu.be/rQIXOo0BevM), which covers the steps discussed in this tutorial.

## Table of Contents

- [Teams Toolkit for Visual Studio Code](#ttk)
- [Prerequisites](#prereqs)
- [Install Teams Toolkit for Visual Studio Code](#install)
- [Scaffold and run the project](#scaffold)
- [Clean the project](#clean)
- [Create the Adaptive Card templates](#adaptive-cards)
- [Create the order command](#command)
- [Create the order card action](#action)
- [Place your order](#place-order)
- [What next?](#what-next)
- [Learn more](#learn-more)

<h2 id="ttk">🛠 Teams Toolkit for Visual Studio Code</h2>

[Teams Toolkit for Visual Studio Code](https://learn.microsoft.com/microsoftteams/platform/toolkit/teams-toolkit-fundamentals?WT.mc_id=m365-79415-garrytrinder) enables you to create, debug and deploy Microsoft Teams apps to a Microsoft 365 tenant fast using a no configuration approach.

In a recent release of Teams Toolkit for Visual Studio Code, a new scenario-based app capability has been released called *Initiate sequential workflows*.

This new capability makes it easy for developers to respond to actions invoked from Adaptive Cards, which is ideal for our restaurant order scenario.

Using this new capability, we will create a bot that uses the below workflow.

1. The employee sends a message containing the word *order* to the bot chat.
2. The bot returns an Adaptive Card containing a simple form.
3. The employee submits the form. 
4. The bot captures the form data and replaces the form with a confirmation message.

![Contoso Restaurant sample project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5somg2qiv7fmff6dm2w.png)

<h2 id="prereqs">🏁 Prerequisites</h2>

To follow this guide successfully you will need.

 - **Microsoft 365 Tenant**, which has been [enabled for developing custom applications with](https://learn.microsoft.com/microsoftteams/platform/m365-apps/prerequisites#prepare-a-developer-tenant-for-testing?WT.mc_id=m365-81147-garrytrinder). 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 [joining the Microsoft 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program?WT.mc_id=m365-81147-garrytrinder). It is pre-configured for Microsoft Teams app development right out of the box.
 - **Visual Studio Code**, if you do not have it installed, [download it for free](https://code.visualstudio.microsoft.com)!

With the prerequisites done, let’s begin!

<h2 id="install">🛠 Install Teams Toolkit for Visual Studio Code</h2>

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.

1. Open *Visual Studio Code*.
2. Open the *Extensions panel* from the Side Bar.
3. *Search for Teams Toolkit* in the marketplace.
4. Select *Teams Toolkit* in the search results.
5. Click the *Install button* to install the extension.

Once the extension has been successfully installed, you will see a Microsoft Teams icon in the Side Bar.

<h2 id="scaffold">👷 Scaffold and run the project</h2>

After installing the extension, let’s create our project.

1. Open the Teams Toolkit extension by clicking on the *Microsoft Teams icon* in the Side Bar
2. Click the *Create a new Teams app* button to start the project scaffolding wizard
3. Select *Create a new Teams app* in the first step
4. Select *Initiate sequential workflows* in the Capabilities step
5. Select *TypeScript* in the Programming Language step
6. Select a folder of your choice in the Workspace folder step, this is the location of where the project will be created.
7. Enter *ContosoRestaurant* in the application name step. 

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.

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.

The scaffolded project contains some boilerplate code which provides some basic workflow functionality, containing a command and action.

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.

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.

Click the *Sign In* button 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.

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.

> The first time you run your app, Teams Toolkit will perform an *npm install* to install all the required packages, so it might take a few moments depending on your network and machine resources.
>
> This would be a good time to grab a ☕️

When complete, a browser window will be launched and you will be navigated to the web version of Microsoft Teams. You may be prompted for authentication again, if you are, just complete the steps using the same account as you signed in previously.

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. 

Type `helloWorld` into the chat box and send your message, this will invoke the bot command which returns an Adaptive Card with a button. 

Selecting the button will update the Adaptive Card with confirmation of that action.

<h2 id="clean">👷 Clean the project</h2>

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't get in the way and we can start from a clean slate.

Don't worry about what we are removing for now, I'll explain all this as we go through the steps.

If your debug session is still running, just close down the browser window or stop the debugging session in Visual Studio Code.

To remove the default code, you can [use a script](https://gist.github.com/garrytrinder/1911550e3511ec2c0cfe551fd2c120af) or do it manually.

To manually remove the code

- Delete all files in the following folders 
  - `bot\src\AdaptiveCards`
  - `bot\src\cardActions`
  - `bot\src\commands`
- Clear contents of `bot\src\cardModels.ts`
- Update `/bot/src/internal/initialize.ts`
  - Clear `commands` array 👉 `commands: []`
  - Clear `actions` array 👉 `actions: []`
  - Remove the unused `imports`
- Update `templates/appPackage/manifest.template.json`
  - Clear the `commands` array 👉 `commands: []`

To use the script to remove the code

- Create a `scripts` folder in the root
- Download the file and add it to the `scripts` folder
- Open terminal prompt, change to root directory
- Execute `node scripts\ttk_workflowbot_clean.js`

Now that we have a clean project, let's start building out our scenario.

<h2 id="#adaptive-cards">🧑‍💻 Create the Adaptive Card templates</h2>

The first thing we will do is implement Adaptive Cards templates, these cards represent our user interface that employees will interact with.

> [Adaptive Cards](https://learn.microsoft.com/adaptive-cards/) are an open card exchange format enabling developers to exchange UI content in a common and consistent way.

[Templating](https://learn.microsoft.com/adaptive-cards/templating/) enables the separation of data from the layout in an Adaptive Card, by using data binding syntax `${data}` we can add placeholders into our templates that can be populated data when we use the Adaptive Card SDK to render the card.

The first template will be sent back to the employee when they request to make an order with menu options.

Let's create a new file in the `bot\src\AdaptiveCards` folder called `orderCommandResponse.json` with the following contents.

```json
{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.4",
    "body": [
        {
            "type": "TextBlock",
            "text": "${FormInfo.title}",
            "size": "Large",
            "wrap": true,
            "weight": "Bolder"
        },
        {
            "type": "Input.ChoiceSet",
            "id": "EntreeSelectVal",
            "label": "${Order.questions[0].question}",
            "style": "filtered",
            "isRequired": true,
            "errorMessage": "This is a required input",
            "placeholder": "Please choose",
            "choices": [
                {
                    "$data": "${Order.questions[0].items}",
                    "title": "${choice}",
                    "value": "${value}"
                }
            ]
        },
        {
            "type": "Input.ChoiceSet",
            "id": "SideVal",
            "label": "${Order.questions[1].question}",
            "style": "filtered",
            "isRequired": true,
            "errorMessage": "This is a required input",
            "placeholder": "Please choose",
            "choices": [
                {
                    "$data": "${Order.questions[1].items}",
                    "title": "${choice}",
                    "value": "${value}"
                }
            ]
        },
        {
            "type": "Input.ChoiceSet",
            "id": "DrinkVal",
            "label": "${Order.questions[2].question}",
            "style": "filtered",
            "isRequired": true,
            "errorMessage": "This is a required input",
            "placeholder": "Please choose",
            "choices": [
                {
                    "$data": "${Order.questions[2].items}",
                    "title": "${choice}",
                    "value": "${value}"
                }
            ]
        }
    ],
    "actions": [
        {
            "type": "Action.Execute",
            "verb": "order",
            "title": "Place Order"
        }
    ]
}
```

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. 

> 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 `{ "DrinkVal": "value" }`.

![Order command response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k27a1jkdwl57k6cgkp04.png)

The second template will be displayed to the employee when they have submitted their order to the restaurant.

Let's create a new file in the `bot\src\AdaptiveCards` folder called `orderActionResponse.json` with the following contents.

```json
{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.4",
  "body": [
    {
      "type": "TextBlock",
      "text": "${title}",
      "wrap": true,
      "style": "heading"
    },
    {
      "type": "Container",
      "items": [
        {
          "type": "FactSet",
          "facts": [
            {
              "title": "Entree",
              "value": "${actionData.EntreeSelectVal}"
            },
            {
              "title": "Side",
              "value": "${actionData.SideVal}"
            },
            {
              "title": "Drink",
              "value": "${actionData.DrinkVal}"
            }
          ]
        }
      ]
    }
  ],
  "actions": [
    {
      "type": "Action.Execute",
      "title": "Edit Order",
      "verb": "order-edit"
    }
  ]
}
```

When this card is rendered, it will display the selected options submitted in the first card and an action button.

![Order action response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1s6v4vmd8cck3p4iohll.png)

Now that we have our templates in place, let'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.

Open the `bot/src/cardModels.ts` file.

Add the following interfaces which describes the data shape for the `bot\src\AdaptiveCards\orderCommandResponse.json` card.

```ts
export interface OrderData {
  FormInfo: FormInfo;
  Order: Order;
}

export interface FormInfo {
  title: string;
}

export interface Order {
  questions: Question[];
}

export interface Question {
  question: string;
  items: Item[];
}

export interface Item {
  choice: string;
  value: string;
}
```

Add the following interfaces which describes the data shape for the `bot\src\AdaptiveCards\orderCommandResponse.json` card. 

```ts
export interface OrderResponseData {
  title: string;
  actionData: OrderActionData;
}

export interface OrderActionData {
  EntreeSelectVal: string;
  SideVal: string;
  DrinkVal: string;
}
```

The `OrderActionData` interface also provides the shape of the data which is returned to our bot when the first card is submitted.

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.

<h2 id="command">📝 Create the order command</h2>

To create a new command we need to perform three tasks

- Create the command handler
- Update the bot configuration
- Update the app manifest

### Create the command handler

With our user interface defined, let's create the `order` command which our employees will use to start the order process.

Let's create a new file in the `bot\src\commands` folder called `orderCommandHandler.ts` with the following contents.

```ts
export class OrderCommandHandler implements TeamsFxBotCommandHandler { }
```

The `OrderCommandHandler` class will represent the handler for when the `order` command is sent in the bot chat. 

We will use the `TeamsFxBotCommandHandler` interface from the `@microsoft/teamsfx` library to implement the handler functionality.

Let's import the `CommandMessage`, `TeamsFxBotCommandHandler` and `TriggerPatterns` classes from the `@microsoft/teamsfx` library, the TurnContext class and Activity interface from `botbuilder` library, and implement the `TeamsFxBotCommandHandler` interface.

> You can use the [Quick Fix](https://code.visualstudio.com/docs/editor/refactoring#_code-actions-quick-fixes-and-refactorings) menu in Visual Studio Code to import packages and implement interfaces quickly

```ts
import { CommandMessage, TeamsFxBotCommandHandler, TriggerPatterns } from "@microsoft/teamsfx";
import { TurnContext, Activity } from "botbuilder";

export class OrderCommandHandler implements TeamsFxBotCommandHandler {

  triggerPatterns: TriggerPatterns;

  async handleCommandReceived(context: TurnContext, message: CommandMessage): Promise<string | void | Partial<Activity>> {
    throw new Error("Method not implemented.");
  }

}
```

Let's update the `triggerPatterns` property with the value `order`. This property defines the keyword that the bot will listen out for when it is sent messages.

```ts
triggerPatterns: TriggerPatterns = "order";
```

Next, let's add the logic to the `handleCommandReceived` method that will be executed when the handler is invoked.

First, add the `async` keyword to the method declaration as the method will return a `Promise`.

```ts
async handleCommandReceived(context: TurnContext, message: CommandMessage): Promise<string | void | Partial<Activity>> {
```

Next we will create a new object that we will use populate the template in the shape of the `OrderData` model that we defined earlier. This object will represent the menu options that the employee can choose from in the form.

Import the `OrderData` interface using an import statement at the top of the file.

```ts
import { OrderData } from "../cardModels";
```

Create a new constant called `orderData` using the `OrderData` interface as its type, replacing the `throw` statement. 

```ts
const orderData: OrderData = {
      "FormInfo": {
        "title": "Malt & Vine Order Form"
      },
      "Order": {
        "questions": [
          {
            "question": "Which entree would you like?",
            "items": [
              {
                "choice": "Steak",
                "value": "Steak"
              },
              {
                "choice": "Chicken",
                "value": "Chicken"
              },
              {
                "choice": "Tofu",
                "value": "Tofu"
              }
            ]
          },
          {
            "question": "Which side would you like?",
            "items": [
              {
                "choice": "Baked Potato",
                "value": "Baked Potato"
              },
              {
                "choice": "Rice",
                "value": "Baked Potato"
              },
              {
                "choice": "Vegetables",
                "value": "Baked Potato"
              },
              {
                "choice": "Noodles",
                "value": "Baked Potato"
              },
              {
                "choice": "No Side",
                "value": "Baked Potato"
              }
            ]
          },
          {
            "question": "Which drink would you like?",
            "items": [
              {
                "choice": "Water",
                "value": "Water"
              },
              {
                "choice": "Soft Drink",
                "value": "Soft Drink"
              },
              {
                "choice": "Coffee",
                "value": "Coffee"
              },
              {
                "choice": "Natural Juice",
                "value": "Natural Juice"
              },
              {
                "choice": "No Drink",
                "value": "No Drink"
              }
            ]
          }
        ]
      }
    }
```

Now we have our data, we need to populate our template with `orderData` to 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.

Import the template and SDK by adding import statements at the top of the file.

```ts
import orderCard from "../adaptiveCards/orderCommandResponse.json";
import { AdaptiveCards } from "@microsoft/adaptivecards-tools";
```

Add the following line after you initialise the `orderData` constant, where we will use the Adaptive Cards SDK to parse the template and passing the data object to it to render the card.

```ts
const cardJson = AdaptiveCards
  .declare<OrderData>(orderCard)
  .render(orderData);
```

We now have a card populated with data and ready to be sent, so let's do that.

Import the `MessageFactory` and `CardFactory` classes from the `botbuilder` library by updating the existing import statement.

```ts
import { TurnContext, Activity, MessageFactory, CardFactory } from "botbuilder";
```

Add the following line after you initialise the `cardJson` constant to send the populated Adaptive Card to the bot chat.

```ts
return MessageFactory.attachment(
  CardFactory.adaptiveCard(cardJson)
);
```

### Update the bot configuration

After implementing the command handler, the next step is to update the bot configuration to tell our bot about our new handler.

Open the `bot\src\internal\initialize.ts` file which contains our bot configuration and import the `OrderCommandHandler` class at the top of the file.

```ts
import { OrderCommandHandler } from "../commands/orderCommandHandler";
```

Update the `commands` array, including a new instance of the `OrderCommandHandler` class in the array.

```ts
command: {
  enabled: true,
  commands: [new OrderCommandHandler()],
},
```

### Update the app manifest

The final step is to add our order command to the list of suggestions that the bot can recommend to employees who use it.

Open the `templates\manifest.template.json` app manifest file, which describes how our app integrates into Microsoft Teams.

Update the `commands` array, including a new command object in the array.

```json
"commands": [
  {
    "title": "order",
    "description": "Place an order"
  }
]
```

![Bot Suggestions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ig2lp6x0q1338ys02dvp.png)

<h2 id="order-action">⚡️ Create the order card action</h2>

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.

To create a new action handler we need to perform two tasks

- Create the action handler
- Update the bot configuration

### Create the action handler

Let's create a new file in the `bot\src\cardActions` folder called `orderActionHandler.ts` with the following contents.

```ts
export class OrderActionHandler implements TeamsFxAdaptiveCardActionHandler { }
```

The `OrderActionHandler` class will represent the handler for when an Adaptive Card action that uses the `Action.Execute` type passing the `order` verb. 

We will use the `TeamsFxAdaptiveCardActionHandler` interface from the `@microsoft/teamsfx` library to implement the handler functionality.

Let's import the `AdaptiveCardResponse` enum and `TeamsFxAdaptiveCardActionHandler` class from the `@microsoft/teamsfx` library, the `TurnContext` class and `InvokeResponse` interface from `botbuilder` library, and implement the `TeamsFxAdaptiveCardActionHandler` interface.

```ts
import { AdaptiveCardResponse, TeamsFxAdaptiveCardActionHandler } from "@microsoft/teamsfx";
import { TurnContext, InvokeResponse } from "botbuilder";

export class OrderActionHandler implements TeamsFxAdaptiveCardActionHandler {

  triggerVerb: string;

  adaptiveCardResponse?: AdaptiveCardResponse;
  
  handleActionInvoked(context: TurnContext, actionData: any): Promise<InvokeResponse<any>> {
    throw new Error("Method not implemented.");
  }

}
```

Let's update the `triggerVerb` property with the value `order`. This property defines the verb that the bot will listen out for when it is sent data as a result of an `Action.Execute` action invoked from an Adaptive Card.

```ts
triggerVerb: string = "order";
```

Next, let's add the logic to the `handleActionInvoked` method that will be executed when the handler is invoked.

Add the `async` keyword to the method declaration as the method will return a `Promise`.

```ts
async handleActionInvoked(context: TurnContext, actionData: any): Promise<InvokeResponse<any>> {
```

You may have noticed that `handleActionInvoked` method returns an `actionData` parameter, this will contain the data submitted from our Adaptive Card. 

As we have already defined the model for this data, let's replace `any` with our own type.

Import the `OrderActionData` interface using an import statement at the top of the file.

```ts
import { OrderActionData } from "../cardModels";
```

Update `actionData` parameter type.

```ts
async handleActionInvoked(context: TurnContext, actionData: OrderActionData): Promise<InvokeResponse<any>> {
```

Next we will create a new object that we will use populate the template in the shape of the `OrderResponseData` model that we defined earlier. This object will represent the menu options selected by the employee and includes a title to display in the confirmation.

Import the `OrderResponseData` interface using an import statement at the top of the file.

```ts
import { OrderResponseData } from "../cardModels";
```

Create a new constant called `orderResponseData` using the `OrderResponseData` interface as its type, replacing the `throw` statement. 

```json
const orderResponseData: OrderResponseData = {
  title: "✅ [ACK] Order Placed",
  actionData
};
```

Now we have our data, we need to populate our template with `orderResponseData` to 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.

Import the template and SDK by adding import statements at the top of the file.

```ts
import orderActionResponseCard from "../adaptiveCards/orderActionResponse.json";
import { AdaptiveCards } from "@microsoft/adaptivecards-tools";
```

Add the following line after you initialise the `orderResponseData` constant, where we will use the Adaptive Cards SDK to parse the template and passing the data object to it to render the card.

```ts
const cardJson = AdaptiveCards
  .declare<OrderResponseData>(orderActionResponseCard)
  .render(orderResponseData);
```

We now have a card populated with data and ready to be sent, so let's do that.

Import the `InvokeResponseFactory` class from the `@microsoft/teamsfx` library by updating the existing import statement.

```ts
import { AdaptiveCardResponse, InvokeResponseFactory, TeamsFxAdaptiveCardActionHandler } from "@microsoft/teamsfx";
```

Add the following line after you initialise the `cardJson` constant to send the populated Adaptive Card to the bot chat, replacing the existing Adaptive Card.

```ts
return InvokeResponseFactory.adaptiveCard(cardJson);
```

### Update the bot configuration

After implementing the action handler, the next step is to update the bot configuration to tell our bot about our new handler.

Open the `bot\src\internal\initialize.ts` file which contains our bot configuration and import the `OrderActionHandler` class at the top of the file.

```ts
import { OrderCommandHandler } from "../commands/orderCommandHandler";
```

Update the `actions` array, including a new instance of the `OrderActionHandler` class in the array.

```ts
cardAction: {
  enabled: true,
  actions: [new OrderActionHandler()]
},
```

<h2 id="place-order">🙋 Place your order</h2>

Now it's time to run our bot and test it out.

You can do this easily, either by opening the Debug panel and selecting the green play button or by pressing F5 on your keyboard. 

Follow the steps to side load your application, when the bot chat is visible, submit `order` in the chat to start the workflow.

![Order placed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84c8ot8ako6hvmdv1ywk.png)

> 🎉 Congratulations! You'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.

<h2 id="what-next">⏭ What next?</h2>

Want to make more updates? Here are a few things you can try.

- **Edit order**, implement the _Edit Order_ button that is displayed when the order is confirmed.
- **Expand the menu**, add more options to the order form.
- **Update the app icons**, currently the app uses stock icons, update the icons in the `templates/appPackage/resources` directory with new, more relevant icons.
- **Restrict supported Teams scopes**, 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.

<h2 id="learn-more">📚 Learn more</h2>

- [Microsoft Teams Developer Center](https://developer.microsoft.com/microsoft-teams?WT.mc_id=m365-79415-garrytrinder)
- [Teams Toolkit Documentation](https://docs.microsoft.com/en-us/microsoftteams/platform/overview?WT.mc_id=m365-79415-garrytrinder)
- [Teams Toolkit Overview](https://learn.microsoft.com/microsoftteams/platform/toolkit/teams-toolkit-fundamentals?WT.mc_id=m365-79415-garrytrinder)
- [Workflow bot in Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/workflow-bot-in-teams?tabs=JS&WT.mc_id=m365-79415-garrytrinder)
- [Build workflow bot](https://learn.microsoft.com/microsoftteams/platform/sbs-gs-workflow-bot?tabs=vscode?WT.mc_id=m365-79415-garrytrinder)

> 👋 Happy coding!

> Banner image generated using DALL·E 2 text to image API, _a robot placing an order at a restaurant_