Preview Release of .Net Teams Bot Builder v4 SDK

Microsoft Teams team

We’re excited to announce the preview release of the .NET Teams Bot Builder v4 SDK. This has consistently been a top ask from our bot builders and we’re very happy to begin expanding our support for bots built on Bot Framework to include the newest version. This preview release is just the beginning; over the next few months we’ll be adding new documentation, samples and releasing our SDKs for both .NET and Node.js.

Some key concepts to keep in mind

First and foremost, its important to realize that everything you can do in Bot Framework v4, you can do in v3 (and vice-versa), it’s just different. The new version does some important work in aligning the Bot Framework SDKs across languages, aligns very closely with the design philosophy of ASP.NET Core, and deals more cleanly with the concepts of dependency injection and middleware, but under the hood the wire protocol remains the same. This means that if you have a v3 bot, it will continue to work for the foreseeable future.

If you’ve never worked with ASP.NET before, Bot Framework v4 can be a bit difficult to get used to at first. Just keep in mind which layer of the application is responsible for what, and don’t mix responsibilities.

A brief introduction to Bot Framework v4 for .NET

If you haven’t worked with Bot Framework v4 I highly recommend reading through the Concept section of their documentation. You’ll get a great introduction to the platform, how it is structured, and what pieces you’ll need to focus on as you design your bot.

The core concept underlying Bot Framework is the idea of a turn, which represents a complete question-and-response interaction with your bot. The below diagram shows a typical interaction with your bot. You receive an HTTP Post message containing JSON from the client. The Adapter creates an Activity object, initiates the OnTurn pipeline and passes the Activity to any middleware you’ve registered. After performing it’s logic, the middleware passes the Activity to your bot to perform your OnTurn logic, and if necessary you read/write to your state through a state property accessor. Once your logic finishes the Activity is handed back to the middleware for any final processing, and finally your response is returned to the client.

Overview of the Microsoft Teams Bot Builder SDK for .NET

Our SDK extends the core Bot Builder SDK with Microsoft Teams specific functionality allowing you to create a rich experiences for your users. In addition to adding Teams specific extensions to the Bot Builder libraries, we add five middleware classes and a Teams-specific conversation state.

  • TeamsMiddleware – This is the core middleware that creates a TeamContext object which adds Teams specific information to the Activity.
  • DropChannelActivitiesMiddleware & DropChatActivitiesMiddleware – Both allow you to restrict interactions to a particular kind of channel. For example, if your bot doesn’t support one-on-one chat you can drop all chat activities.
  • TeamsTenantFilteringMiddleware – Allows you to restrict to a particular tenant Id
  • DropNonTeamsActivitiesMiddleware – Allows you to short-circuit the OnTurn pipeline if the activity didn’t originate from Teams
  • TeamSpecificConversationState – This allows you to make use of a state storage accessor that is scoped across an entire Team (two separate interactions with your bot from two members of the same Team can access the same bot state)

Getting started using the Microsoft Teams Bot Builder SDK for .NET

1. Setup the environment

For this we’ll be using the Bot Builder extension for Visual Studio. You’ll need both installed to follow along completely. Once you’ve got those installed open up Visual Studio and go File > New Project > Visual C# > BotFramework > EchoBot and click OK.

Once you have the bot scaffolded out using the template, we’ll need to add the Microsoft.Bot.Builder.Teams NuGet package. In the Package Manager console type:

PM > Install-Package Microsoft.Bot.Builder.Teams -version 4.0.0-beta1

2. Wire up the middleware

We’re going to be building a fairly basic bot that will reply to interactions with some information about the Team used to contact the bot, an integer keeping track of how many times the bot has been contacted from a particular Team, and also echo back the message it received. To do that we’ll need to connect our Teams middleware and make use of the Teams conversation state.

Open up the Startup.cs file and add the following using statements:

using Microsoft.Bot.Builder.Teams.Middlewares;
using Microsoft.Bot.Builder.Teams.StateStorage;
using Microsoft.Bot.Builder.BotFramework;

In the ConfigureServices method in the AddBot lambda expression, change the type of the ConversationState:

var conversationState = new TeamSpecificConversationState(dataStore);

options.State.Add(new TeamSpecificConversationState(dataStore));

Next we’ll add the Teams middleware:

options.Middleware.Add(new DropNonTeamsActivitiesMiddleware());
options.Middleware.Add(new TeamsMiddleware(
    new ConfigurationCredentialProvider(Configuration)));

Finally, we need to change the ConverstationState type in the singleton registration as well. In the AddSingleton lambda expression make the change below:

var conversationState = options.State.OfType<TeamSpecificConversationState>()
                               .FirstOrDefault();

Since we’ve changed the type of the conversation state, we’ll need to change the state storage accessor. Open the EchoBotAccessors.cs class. Change the type passed into the constructor as well as the public property:

using Microsoft.Bot.Builder.Teams.StateStorage;
...

public EchoBotAccessors(TeamSpecificConversationState conversationState)
        {
            ConversationState = conversationState ?? throw new 
                ArgumentNullException(nameof(conversationState));
        }
...
public TeamSpecificConversationState ConversationState { get; }

3. Add our bot logic

OK, we’ve finally got everything wired up, and we can now start adding some logic to our bot. Open up the EchoBotBot.cs file and add the following using statements:

using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Schema.Teams;
using Microsoft.Bot.Connector.Teams;

The OnTurnAsync function is the starting point for your bot’s logic. Add the following to that function inside the if statement:

// Before doing Teams specific stuff, get hold of the TeamsContext
ITeamsContext teamsContext = turnContext.TurnState.Get<ITeamsContext>();

// From there we can get the Team ID, Channel ID, and Tenant ID off of the incoming activity
string incomingTeamId = teamsContext.Team.Id;
string incomingChannelid = teamsContext.Channel.Id;
string incomingTenantId = teamsContext.Tenant.Id;

// Using those IDs, we can make an operation call to fetch the list of channels in the team, and print count of channels.
ConversationList channels = await teamsContext.Operations.FetchChannelListAsync(incomingTeamId);
await turnContext.SendActivityAsync($"You have {channels.Conversations.Count} channels in this team");

// We can also make an operation call to fetch details of the team where the activity was posted, and print it.
TeamDetails teamInfo = await teamsContext.Operations.FetchTeamDetailsAsync(incomingTeamId);
await turnContext.SendActivityAsync($"Name of this team is {teamInfo.Name} and group-id is {teamInfo.AadGroupId}");

That’s it! All that is left is to package and deploy your bot. The easiest way to do this is to use the App Studio app to help you register your bot and create your manifest file. If you need help on this you can find detailed guidance in our documentation.

Echo bot response

Roadmap for expanding Bot Framework v4 support

  • Mid February – Node SDK preview release
  • March – GA for Node & .Net SDKs
  • March – Doc library and some samples updated to BF v4

Additional resources

Feedback usabilla icon