How to create conversational bots for Microsoft Teams

In this workshop, we will learn how to create and add new bot to Microsoft Teams App and interact with Microsoft Teams Client. This article is targeted to provide step by step reference on workshop to be delivered as part of Global M365 Developer Bootcamp 2020, Pune.

Prerequisites

Note – Microsoft Teams must be configured to enable custom apps and allow custom apps to be uploaded to your tenant to build custom apps for Microsoft Teams. This step should have already been done if you have set up the tenant using this link. If not, you refer to this link to enable it.

On a very high level, below main steps will be followed.

  1. Register the bot with Microsoft Azure’s Bot Framework – Follow this link to complete this pre-step, this is required so that we have Bot App ID and Secret before creating Teams app.
  2. Create Teams app of type Bot.
  3. Test on Teams client

Create teams app of type Bot

Microsoft Teams app can be created in multiple ways, here we will be using Yeoman Generator for Microsoft Teams to scaffold our project.

Open a command prompt. Create a new directory and navigate.

md bot-demo
cd bot-demo

Run the below command to start creating new Teams app

yo teams

We will be asked a series of question which will be used to create the required project structure. You can select the below options

It will take a few minutes to create the project and then npm install will run to download the required dependencies. Once done we should be below the success message.

 

Now, the next step is to ensure we are using the latest version of Teams manifest and SDK

Run below command.

npm i @microsoft/teams-js

Open the project in your code editor(in my case it is visual studio code)

Open D:\SP\Samples\bot-demo\src\manifest\manifest.json

Open “D:\SP\Samples\bot-demo\gulp.config.js”

Add following line where all the manifest version are listed down

{
        version: "1.7",
        schema: "https://developer.microsoft.com/en-us/json-schemas/teams/v1.7/MicrosoftTeams.schema.json"
}

Now its time to change the default bot code to cover our use case.

open the ./src/app/bootcampBotDemoBot/BootcampBotDemo.ts

Add required Imports,

Add MessageFactory  to below line on top of the file.

import { StatePropertyAccessor, CardFactory, TurnContext, MemoryStorage, ConversationState, ActivityTypes, TeamsActivityHandler, MessageFactory } from "botbuilder";

Add below method to support One: One conversation between bot and user.

private async handleMessageMentionMeOneOnOne(context: TurnContext): Promise<void> {
  const mention = {
    mentioned: context.activity.from,
    text: `<at>${new TextEncoder().encode(context.activity.from.name)}</at>`,
    type: "mention"
  };

  const replyActivity = MessageFactory.text(`Hi ${mention.text} from a 1:1 chat.`);
  replyActivity.entities = [mention];
  await context.sendActivity(replyActivity);
}

Our BootcampBotDemo.ts file will have some event handles already added. An important one to understand is this.onMessage. Every time a message is sent by user this method will be called and here we will have to write our bot logic. This can be as simple as sending the user type message back to the user with some modification to calling any graph/SharePoint/custom API to perform some actions and send the custom message back to the user.  Below is the default method

 

Next, we will call this method when the bot receives the specific string MentionMe by doing the following:

  1. Locate the handler onMessage() within the constructor().
  2. replace the method with the below code
  3. Locate and add below above if (text.startsWith("hello")) { in the onMessage() handler with the following code:
this.onMessage(async (context: TurnContext): Promise<void> => {
            // TODO: add your own bot logic in here
            switch (context.activity.type) {
                case ActivityTypes.Message:
                    let text = TurnContext.removeRecipientMention(context.activity);
                    text = text.toLowerCase();
                    if (text.startsWith("mentionme")) {
                        await this.handleMessageMentionMeOneOnOne(context);
                        return;
                    } else if (text.startsWith("hello")) {
                        await context.sendActivity("Oh, hello to you as well!");
                        return;
                    } else if (text.startsWith("help")) {
                        const dc = await this.dialogs.createContext(context);
                        await dc.beginDialog("help");
                    } else {
                        await context.sendActivity(`I\'m terribly sorry, but my master hasn\'t trained me to do anything yet...`);
                    }
                    break;
                default:
                    break;
            }
            // Save state changes
            return this.conversationState.saveChanges(context);
        });

Here we just added an if condition and change the current if condition to else if

Now let us update the project environment variable. The project contains env variable file so store secure values like appid and add secret. This once hosted to Azure or anywhere will be reading from the Environment configuration of said framework.

Open ./.env

Find the following section in the file, and set the values of the below two properties that we copied when registering the bot from Azure Portal:

Register the bot in the Microsoft Teams app

Next we will register the bot in the Teams app, we can use App Studio for the same.

Go to https://teams.microsoft.com/ where you want to test this bot.

From the app navigation bar menu, search for App Studio.

 

Select the Manifest editor tab and then the Create a new app button:

 

Now we will be adding some information which will be required to generate manifest.json file for Teams app

 

Next from Capabilities on the left side, click on Bots.  Click on setup and the below popup will open.

As we are connecting to the existing Bot which we generated from Azure Portal.

We will select all three as Scope so that App supports all of the three conversations types.  Click on save.

Make sure you see the bot name as in the below section so that to confirm the Teams app was able to get the metadata of the App successfully.

 

Go to Test and Distribute on the left side and click on Download. It will download a zip file.

 

Unpack the zip and copy the manifest.json file in it to your project, updating the existing ./src/manifest/manifest.json file.

Copy this manifest.json file to Our project’s manifest.json file. Either you can replace the content or whole file,

In the ./src/manifest/manifest.json file, please verify icons property’s values, and update if necessary, file names to match what’s in the project

Find the property id. Change its value to match the GUID of the Azure AD app that was created when creating the bot in the Azure portal. Below is the screen shot from where we can find Azure AD app Id(don’t confuse this with Bot Azure App resource ID)

 

Test the Bot

The next thing for us to do is test the bot.

Navigate to the root folder of the project and run the below command.

gulp ngrok-serve

This gulp task will run many other tasks all displayed within the command-line console. The ngrok-serve task builds your project and starts a local web server (http://localhost:3007). It then starts ngrok with a random subdomain that creates a secure URL to your local webserver.

 

Update the Azure portal app to configure temporary ngrok api EndPoint.

Go to Azure Portal – Find the bot by selecting the Azure resource group and the Bot channel registratoin resource which we created before.

From Left navigation, select Bot management -> Settings.

Find the property Configuration ->Messageing endpoint and set the domain to the domain highlight in above screenshot.

Save the configuration

 

Install this custom app to Microsoft Teams

Now it’s time to install the custom app to test.

Go to https://teams.microsoft.com and sign in with the credentials of a Work and School account where you want to test, Please make sure you are testing this in your personal tenant and not MSFT community tenant.

Find option Upload a custom app at bottom of the page.

Below dialog box should appear. Click on Add for me.

Navigate to App from left navigation with name ‘Bootcamp Bot App demo 1’.

Type ‘hello’ and it should respond with ‘oh, hello to you as  well’

Type ‘mentionme’ and it should respond by mentioning logged in user with below message

So here we have a One:One conversation bot working for use, we can modify the bot code according to our need.

Add channel support and Group chat to a conversation bot

In the above exercise, our code was looking for a specific message MentionMe in order to respond. This works in a 1:1 personal chat because the bot isn’t mentioned in the conversation.

However, in a channel conversation or group chat, a user must @mention the bot to respond to a message. This is logical as channel and group chats can be happening between the users and bot not necessarily needs to respond to any message until it is asked for. This results in a message containing a reference to the bot, not just the message submitted.

For this, we will need to check the conversation type of message and then handle it accordingly.

Open ./src/app/conversationalBot/ConversationalBot.ts

 

Add a method to handle the channel or group conversation.

private async handleMessageMentionMeChannelConversation(context: TurnContext): Promise<void> {
  const mention = {
    mentioned: context.activity.from,
    text: `<at>${new TextEncoder().encode(context.activity.from.name)}</at>`,
    type: "mention"
  };

  const replyActivity = MessageFactory.text(`Hi ${mention.text}!`);
  replyActivity.entities = [mention];
  const followupActivity = MessageFactory.text(`*We are in a channel conversation*`);
  await context.sendActivities([replyActivity, followupActivity]);
}

Find onMessage method which we modified previously.  We will replace it below to call the above method when conversationType is not personal.

this.onMessage(async (context: TurnContext): Promise<void> => {
            // TODO: add your own bot logic in here
            switch (context.activity.type) {
                case ActivityTypes.Message:
                    let text = TurnContext.removeRecipientMention(context.activity);
                    text = text.toLowerCase();
                    if (text.startsWith("mentionme")) {
                        if (context.activity.conversation.conversationType === "personal") {
                          await this.handleMessageMentionMeOneOnOne(context);
                        } else {
                          await this.handleMessageMentionMeChannelConversation(context);
                        }
                        return;
                      } else if (text.startsWith("hello")) {
                        await context.sendActivity("Oh, hello to you as well!");
                        return;
                    } else if (text.startsWith("help")) {
                        const dc = await this.dialogs.createContext(context);
                        await dc.beginDialog("help");
                    } else {
                        await context.sendActivity(`I\'m terribly sorry, but my master hasn\'t trained me to do anything yet...`);
                    }
                    break;
                default:
                    break;
            }
            // Save state changes
            return this.conversationState.saveChanges(context);
        });

Once done, run the following command again

gulp ngrok-serve

Once it runs successfully, it will generate new ngrok url which we have to update in Azure Bot Channel registration endpoint.

Go to Azure Portal – Find the bot by selecting the Azure resource group and the Bot channel registration resource which we created before.

From Left navigation, select Bot management -> Settings.

Find the property Configuration ->Messageing endpoint and set the domain to the domain highlight in the above screenshot.

Save the configuration

 

We need to Install the custom app to Teams to add to Team.

Go to https://teams.microsoft.com and sign in with the credentials of a Work and School account where you want to test, Please make sure you are testing this in your personal tenant and not MSFT community tenant.

Find option Upload a custom app at bottom of the page.

Below dialog box should appear. Click on Add to a Team

It will ask us to select Channel. Select any channel and click on Setup bot

It will open the channel window, start typing @Bot and we should see suggestion like below

 

Below is how it should respond, I have included a default message scenario when user type something which bot code has not handled.

That’s it, the group chat also works in the same way.  The only thing while we install the app we need to select ‘Add to chat’ and it will give a list of group chats where we can set up a bot.

Summary

In this workshop/article we have seen how to create a conversation bot for Microsoft Teams and add it to 1:1 chat conversation as well as channel conversations. Though we have responded to it with simple reply messages we can also send adaptive cards etc.

Reference URL – https://docs.microsoft.com/en-us/learn/modules/msteams-conversation-bots/

(Visited 64 times, 2 visits today)