Skip to content

Commit

Permalink
Simplify the TS command bot template
Browse files Browse the repository at this point in the history
  • Loading branch information
therealjohn committed Jan 3, 2023
1 parent 9073fcc commit c0770c8
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 115 deletions.
44 changes: 43 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,47 @@
"cSpell.words": [
"kusto",
"logmining"
]
],
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
"[!t]*/**": true,
"t[!e]*/**": true,
"te[!m]*/**": true,
"tem[!p]*/**": true,
"temp[!l]*/**": true,
"templ[!a]*/**": true,
"templa[!t]*/**": true,
"templat[!e]*/**": true,
"template[!s]*/**": true,
"templates/[!b]*/**": true,
"templates/b[!o]*/**": true,
"templates/bo[!t]*/**": true,
"templates/bot/[!t]*/**": true,
"templates/bot/t[!s]*/**": true,
"templates/bot/ts/[!c]*/**": true,
"templates/bot/ts/c[!o]*/**": true,
"templates/bot/ts/co[!m]*/**": true,
"templates/bot/ts/com[!m]*/**": true,
"templates/bot/ts/comm[!a]*/**": true,
"templates/bot/ts/comma[!n]*/**": true,
"templates/bot/ts/comman[!d]*/**": true,
"templates/bot/ts/command[!-]*/**": true,
"templates/bot/ts/command-[!a]*/**": true,
"templates/bot/ts/command-a[!n]*/**": true,
"templates/bot/ts/command-an[!d]*/**": true,
"templates/bot/ts/command-and[!-]*/**": true,
"templates/bot/ts/command-and-[!r]*/**": true,
"templates/bot/ts/command-and-r[!e]*/**": true,
"templates/bot/ts/command-and-re[!s]*/**": true,
"templates/bot/ts/command-and-res[!p]*/**": true,
"templates/bot/ts/command-and-resp[!o]*/**": true,
"templates/bot/ts/command-and-respo[!n]*/**": true,
"templates/bot/ts/command-and-respon[!s]*/**": true,
"templates/bot/ts/command-and-respons[!e]*/**": true
}
}
5 changes: 3 additions & 2 deletions templates/bot/ts/command-and-response/.env.teamsfx.local
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# TeamsFx will overwrite the following variable values when running debug
# Teams Toolkit will overwrite the following variable when debugging
# The Bot Framework app ID and password automatically registered by Teams Toolkit
BOT_ID=
BOT_PASSWORD=

# Following variables can be customized or you can add your owns
# You can add additional environment variables that are used when debugging with Teams Toolkit
# FOO=BAR
60 changes: 23 additions & 37 deletions templates/bot/ts/command-and-response/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Overview of the Command bot template

This template showcases an app that responds to chat commands by displaying UI using an Adaptive Card. This enables your users to type in simple messages in Teams and your application can provide an appropriate response based on the contents of the message.
This project template helps you get started with a Teams app that can respond to customized chat messages. In the example code, you'll find a single `helloWorld` command defined that the bot responds to with UI that's created using an Adaptive Card - a JSON object and format that helps developers exchange UI content.

The app template is built using the TeamsFx SDK, which provides a simple set of functions over the Microsoft Bot Framework to implement this scenario.
The project template is a Node.js application that uses Restify to serve HTTP responses. It uses the `@microsoft/teamsfx` SDK to interact with Microsoft Bot Framework.

## Get Started with the Command bot

Expand All @@ -16,12 +16,12 @@ The app template is built using the TeamsFx SDK, which provides a simple set of
>
> **Note**
>
> Your app can be installed into a team, or a group chat, or as personal app. See [Installation and Uninstallation](https://aka.ms/teamsfx-command-response#customize-installation).
> Your app can be installed into a team, a group chat, or as a personal app. See [Installation and Uninstall](https://aka.ms/teamsfx-command-response#customize-installation).
>
1. First, select the Teams Toolkit icon on the left in the VS Code toolbar.
2. In the Account section, sign in with your [Microsoft 365 account](https://docs.microsoft.com/microsoftteams/platform/toolkit/accounts) if you haven't already.
3. Press F5 to start debugging which launches your app in Teams using a web browser. Select `Debug (Edge)` or `Debug (Chrome)`.
3. Press F5 to start debugging and launch your app in Teams using a web browser.
4. When Teams launches in the browser, select the Add button in the dialog to install your app to Teams.
5. Type or select `helloWorld` in the chat to send it to your bot - this is the default command provided by the template.

Expand All @@ -38,15 +38,6 @@ The bot will respond to the `helloWorld` command with an Adaptive Card:
| `bot` | The source code for the command and response Teams application |
| `templates` | Templates for the Teams application manifest and for provisioning Azure resources |

The following files can be customized and demonstrate an example implementation to get you started.

| File | Contents |
| - | - |
| `src/index.ts` | Application entry point and `restify` handlers for command and response |
| `src/adaptiveCards/helloworldCommand.json` | A generated Adaptive Card that is sent to Teams |
| `src/helloworldCommandHandler.ts` | The business logic to handle a command |
| `src/cardModels.ts` | The default Adaptive Card data model |

## Extend the command bot template with more commands and responses

Follow the steps below to add more commands and responses to extend the command bot:
Expand All @@ -66,7 +57,7 @@ You can edit the manifest template file `templates\appPackage\manifest.template.
"commands": [
{
"title": "helloWorld",
"description": "A helloworld command to send a welcome message"
"description": "A helloWorld command to send a welcome message"
},
{
"title": "doSomething",
Expand All @@ -79,7 +70,7 @@ You can edit the manifest template file `templates\appPackage\manifest.template.

### Step 2: Respond with an Adaptive Card

To respond with an Adaptive Card, define your card in its JSON format. Create a new file `src/adaptiveCards/doSomethingCommandResponse.json`:
To respond with an Adaptive Card, define your card in its JSON format. Create a new file `src/doSomethingCard.json`:

```json
{
Expand All @@ -93,7 +84,7 @@ To respond with an Adaptive Card, define your card in its JSON format. Create a
},
{
"type": "TextBlock",
"text": "Congratulations! Your hello world bot now includes a new DoSomething Command",
"text": "Congratulations! Your app now includes a new DoSomething Command",
"wrap": true
}
],
Expand All @@ -104,21 +95,20 @@ To respond with an Adaptive Card, define your card in its JSON format. Create a

You can use the [Adaptive Card Designer](https://adaptivecards.io/designer/) to help visually design your Adaptive Card UI.

> Please note:
> Note:
> - Respond with an Adaptive Card is optional, you can simply respond with plain texts.
> - If you'd like to send adaptive card with dynamic data, please refer to [this document](https://aka.ms/teamsfx-command-response#how-to-build-command-response-using-adaptive-card-with-dynamic-content).
> - Responding with an Adaptive Card is optional. You can also respond with plain text using `MessageFactory.text(message)`;.
> - Learn more about data binding and dynamic data with Adaptive Cards in the [documentation](https://aka.ms/teamsfx-command-response#how-to-build-command-response-using-adaptive-card-with-dynamic-content).
### Step 3: Handle the command

The TeamsFx SDK provides a convenient class, `TeamsFxBotCommandHandler`, to handle when an command is triggered from Teams conversation message. Create a new file, `bot/src/doSomethingCommandHandler.ts`:
Create a new file, `bot/src/doSomethingCommandHandler.ts`, to handle how the bot responds to the new command and implement the `TeamsFxBotCommandHandler` class.

```typescript
import { Activity, CardFactory, MessageFactory, TurnContext } from "botbuilder";
import { CommandMessage, TeamsFxBotCommandHandler, TriggerPatterns, MessageBuilder, } from "@microsoft/teamsfx";
import doSomethingCard from "./adaptiveCards/doSomethingCommandResponse.json";
import doSomethingCard from "./doSomethingCard.json";
import { AdaptiveCards } from "@microsoft/adaptivecards-tools";
import { CardData } from "./cardModels";

export class DoSomethingCommandHandler implements TeamsFxBotCommandHandler {
triggerPatterns: TriggerPatterns = "doSomething";
Expand All @@ -130,28 +120,24 @@ export class DoSomethingCommandHandler implements TeamsFxBotCommandHandler {
// verify the command arguments which are received from the client if needed.
console.log(`Bot received message: ${message.text}`);

const cardData: CardData = {
title: "doSomething command is added",
body: "Congratulations! You have responded to doSomething command",
};
// You can further customize what this command does like call an API, process data, etc.

const cardJson = AdaptiveCards.declare(doSomethingCard).render(cardData);
return MessageFactory.attachment(CardFactory.adaptiveCard(cardJson));
const adaptiveCard = AdaptiveCards.declare(doSomethingCard).render();
return MessageFactory.attachment(CardFactory.adaptiveCard(adaptiveCard));
}
}

```

You can customize what the command does here, including calling an API, process data, etc.

### Step 4: Register the new command

Each new command needs to be configured in the `ConversationBot`, which powers the conversational flow of the command bot template. Navigate to the `bot/src/internal/initialize.ts` file and update the `commands` array of the `command` property:
Each new command needs to be configured in the `ConversationBot`, which powers the conversational flow of the command bot template. Navigate to the `bot/src/index.ts` file and update the `commands` array of the `command` property:

```typescript
import { HelloWorldCommandHandler } from "../helloworldCommandHandler";
import { DoSomethingCommandHandler } from "../doSomethingCommandHandler";
import * as restify from "restify";
import { ConversationBot } from "@microsoft/teamsfx";
import { HelloWorldCommandHandler } from "./helloWorldCommandHandler";
import { DoSomethingCommandHandler } from "./doSomethingCommandHandler";

const commandBot = new ConversationBot({
//...
Expand All @@ -164,7 +150,7 @@ const commandBot = new ConversationBot({
});
```

Congratulations, you've just created your own command! To learn more about the command bot template, [visit the documentation on GitHub](https://aka.ms/teamsfx-command-response). You can find more scenarios like:
Congratulations, you've just created your own command! To learn more about the command bot template, [visit the documentation on GitHub](https://aka.ms/teamsfx-command-response) where you can learn more about:

- [Customize the trigger pattern](https://aka.ms/teamsfx-command-response#customize-the-trigger-pattern)
- [Customize the Adaptive Card with dynamic content](https://aka.ms/teamsfx-command-response#how-to-build-command-response-using-adaptive-card-with-dynamic-content)
Expand All @@ -174,15 +160,15 @@ Congratulations, you've just created your own command! To learn more about the c

## Extend command bot with other bot scenarios

Command bot is compatible with other bot scenarios like notification bot and workflow bot.
The Command bot project template is compatible with other bot scenarios like Notification bot and Workflow bot.

### Add notifications to your command bot

The notification feature adds the ability for your application to send Adaptive Cards in response to external events. Follow the [steps here](https://aka.ms/teamsfx-command-response#how-to-extend-my-command-and-response-bot-to-support-notification) to add the notification feature to your command bot. Refer [the notification document](https://aka.ms/teamsfx-notification) for more information.
The notification feature adds the ability for your application to send Adaptive Cards in response to external events. Follow the [steps here](https://aka.ms/teamsfx-command-response#how-to-extend-my-command-and-response-bot-to-support-notification) to add the notification feature to your command bot. Visit the [the notification bot documentation](https://aka.ms/teamsfx-notification) to learn more.

### Add workflow to your command bot

Adaptive cards can be updated on user action to allow user progress through a series of cards that require user input. Developers can define actions and use a bot to return an Adaptive Cards in response to user action. This can be chained into sequential workflows. Follow the [steps here](https://aka.ms/teamsfx-card-action-response#add-more-card-actions) to add workflow feature to your command bot. Refer [the workflow document](https://aka.ms/teamsfx-card-action-response) for more information.
Adaptive cards can be updated with user interactions to allow progress through a series of steps or sequential workflow. Learn more about adding these features to your command bot in the[documentation](https://aka.ms/teamsfx-card-action-response#add-more-card-actions).

## Additional information and references

Expand Down
2 changes: 1 addition & 1 deletion templates/bot/ts/command-and-response/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "command-response-bot",
"version": "1.0.0",
"description": "Microsoft Teams Toolkit Command and Response Bot Sample",
"description": "Microsoft Teams Toolkit Command and Response Bot Template",
"author": "Microsoft",
"license": "MIT",
"main": "./lib/index.js",
Expand Down

This file was deleted.

8 changes: 0 additions & 8 deletions templates/bot/ts/command-and-response/src/cardModels.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Activity, CardFactory, MessageFactory, TurnContext } from "botbuilder";
import { CommandMessage, TeamsFxBotCommandHandler, TriggerPatterns } from "@microsoft/teamsfx";
import { AdaptiveCards } from "@microsoft/adaptivecards-tools";
import helloWorldCard from "./adaptiveCards/helloworldCommand.json";
import { CardData } from "./cardModels";

/**
* The `HelloWorldCommandHandler` registers a pattern with the `TeamsFxBotCommandHandler` and responds
Expand All @@ -17,13 +16,36 @@ export class HelloWorldCommandHandler implements TeamsFxBotCommandHandler {
): Promise<string | Partial<Activity> | void> {
console.log(`Bot received message: ${message.text}`);

// Render your adaptive card for reply message
const cardData: CardData = {
title: "Your Hello World Bot is Running",
body: "Congratulations! Your hello world bot is running. Click the documentation below to learn more about Bots and the Teams Toolkit.",
// An example Adaptive Card that defines the response message of this helloWorld command.
const cardJson = {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "Hello, world!"
},
{
"type": "TextBlock",
"text": "Congratulations, your bot is running.",
"wrap": true
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "Learn More",
"url": "https://aka.ms/teamsfx-docs"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.4"
};

const cardJson = AdaptiveCards.declare(helloWorldCard).render(cardData);
return MessageFactory.attachment(CardFactory.adaptiveCard(cardJson));
// Parse the card JSON and render it as an HTML element
const adaptiveCard = AdaptiveCards.declare(cardJson).render();

return MessageFactory.attachment(CardFactory.adaptiveCard(adaptiveCard));
}
}
21 changes: 18 additions & 3 deletions templates/bot/ts/command-and-response/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import * as restify from "restify";
import { commandBot } from "./internal/initialize";
import { ConversationBot } from "@microsoft/teamsfx";
import { HelloWorldCommandHandler } from "./helloWorldCommandHandler";

// This template uses `restify` to serve HTTP responses.
// Create a restify server.
// The TeamsFx ConservationBot provides a simple way to configure how commands are handled.
export const commandBot = new ConversationBot({
// Configuration for the underlying BotFrameworkAdapter.
// By default, BOT_ID and BOT_PASSWORD are set by Teams Toolkit automatically when debugging locally or provisioning.
adapterConfig: {
appId: process.env.BOT_ID,
appPassword: process.env.BOT_PASSWORD,
},
command: {
enabled: true,
// Implement and add additional command handlers here as your bots' capabilities grow.
commands: [new HelloWorldCommandHandler()],
},
});

// This template uses restify to serve HTTP responses.
const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log(`\nBot Started, ${server.name} listening to ${server.url}`);
Expand Down
6 changes: 0 additions & 6 deletions templates/bot/ts/command-and-response/src/internal/config.ts

This file was deleted.

19 changes: 0 additions & 19 deletions templates/bot/ts/command-and-response/src/internal/initialize.ts

This file was deleted.

0 comments on commit c0770c8

Please sign in to comment.