Microsoft Teams App With Blazor Made Easy Using Blazorade Teams
After I published my previous article about building a Microsoft Teams Tab App in Blazor, I decided to take it one step further. As you might have read on my blog, I have been writing component libraries for Blazor applications under the Blazorade umbrella. All of these are available on GitHub.
This time, I am happy to announce the first preview release of Blazorade Teams. The source code is now available on GitHub. You find the library published as a Nuget package too, so it’s dead simple to include in your application. The documentation is on the GitHub wiki for the Blazorade Teams repository.
So Blazorade Teams is all about building Teams apps in Blazor. To get a better understanding of how easy it is to build a Microsoft Teams Tab app with Blazor using Blazorade Teams, have a look at the code below.
@page "/contentpage" <TeamsApplication RequireAuthentication="true"> <ApplicationTemplate Context="ctx"> <h2>Teams Tab App for @ctx.AuthResult.IdTokenClaims["name"]</h2> </ApplicationTemplate> </TeamsApplication>
That is a complete and working tab application. If it was a personal tab application, then you would not even need anything else, like a configuration page. Just this page and a bit of configuration. That is all of the required stuff you need to have a properly working personal tab application in Microsoft Teams.
And, to top it all off, Blazorade Teams supports both Blazor Server and Blazor WebAssembly. And will always do so too. This means that if you pick the WebAssembly hosting model, you can host your applications for virtually nothing, money-wise I mean. If you got interested, please continue reading below.
The Easiest Way to Write a Microsoft Teams App With Blazor
So, what does Blazorade Teams actually do then? To put it short: A LOT! In the code snippet above, you have the TeamsApplication
component. That is where all the magic happens. Here’s a brief summary of all the things that component takes care of for you.
- Detects if your application was loaded as a standalone application or inside of Teams.
- Initializes your application with the Teams JavaScript SDK.
- Retrieves the Teams context in which the application is running.
- Authenticates the user specified in the retrieved context with the help of MSAL.js and Azure AD.
- Renders your application when all of the previous steps have been taken care of and provides this information through the
ApplicationTemplate
‘s context parameter. - Provides interop method to a selected set of Teams SDK endpoints so that you can work with the Teams SDK directly in C# (or any other language that you can use to build Blazor applications with).
The initial release of Blazorade Teams will focus on initialization and authentication. The interop parts are there to support the rest of the functionality, and will not be a complete set of the Teams SDK. Support for more interop with the Teams SDK will come in future versions. In many cases you don’t need to call the Teams SDK at all. Microsoft Graph provides you with a lot of functionality. Blazorade Teams will take care of authenticating the user, which includes also retrieving an access token to all the API’s you need to access in your application.
Getting Started With Blazorade Teams
This section outlines the different steps you need to take to start writing your first Microsoft Teams Tab App with Blazor using Blazorade Teams.
Register the Application With Azure AD
Usually you would want to authenticate your users properly. In many cases that would mean registering your application with Azure AD, and invoke some kind of authentication / authorization flow in your application.
Blazorade Teams does all of that for you in the TeamsApplication
component. You just have to set RequireAuthentication="true"
. Of course you need to register your application in Azure AD, and configure your application to use that information. But that’s pretty straight forward.
If you need to access APIs like Microsoft Graph in your application, then you just configure your application registration with the permissions your application needs. Stick to delegated permissions, since all of the authentication is done on the client. You can’t have any secrets embedded in your application. Authorization also becomes easier. When you use delegated permissions, your application can only do whatever the logged in user is allowed to do.
The only thing Blazorade Teams needs to know is the Client ID (Application ID) of your application, and the tenant in which you registered it. No need for client secrets or certificates or anything like that.
Not needing any client secrets or certificates is by design. I wanted to support both Blazor Server and Blazor WebAssembly, and having secrets in applications running only on the client is not possible.
Add Reference to Blazorade Teams
The easiest way for you to start using Blazorade Teams is using the Nuget package. At the time of writing (Early January 2021), the Blazorade.Teams Nuget package is still in preview, so be sure to include preview releases in your package manager to find the package.
For more information, see the Add Reference section on the Blazorade Teams wiki.
Configure Your Application
You configure Blazorade Teams through Dependency Injection (DI) like so many other things in ASP.NET applications these days. As I wrote above, Blazorade Teams only needs to know the Client ID and tenant ID, for authentication purposes. You can run your application without that too, if your application does not need any connections outside of Teams.
However, I have not tried what you can do with such an application. I guess it’s very common that you at least need to access Microsoft Graph from your application, so I haven’t spent too much time on worrying about this use case. But I guess it is a very valid use case anyway, which I need to come back to at some point.
So, to get your application configured properly and the Client ID and Tenant ID to your configuration file and add the following code to the ConfigureServices
method in your Startup
class.
services.AddBlazoradeTeams((provider, config) => { var myTeamsApp = provider .GetService<IConfiguration>() .GetSection("myTeamsApp"); config.ClientId = myTeamsApp.GetValue<string>("clientId"); config.TenantId = myTeamsApp.GetValue<string>("tenantId"); });
For more information on configuring your application, take a look at the Wiring Up section on the wiki.
Write Your Microsoft Teams App With Blazor
Currently, you can use Blazorade Teams to write personal tab applications and channel tab applications. Probably you can also write tab applications for group chats and meetings too, since they are very similar to channel tab applications. However, I haven’t tried that out yet, so I can’t say for sure. But, I’ve added both meeting tabs and group chat tabs to the backlog, so they will be properly supported in the future.
Anyway, as you saw in the beginning of this article, it is very easy to write tab applications for Microsoft Teams with Blazorade Teams. The simplest kind of applications, personal tab applications, require just a few lines of boilerplate code. Blazorade Teams takes care of so many tedious tasks for you. This means that you can focus on your application right away!
Channel Tab Applications
Channel tab applications require a bit more. They require a configuration page, that takes care of initializing the tab and application. Optionally, a channel tab application can have a removal page too, that takes care of things when the tab application is removed.
Blazorade Teams has you covered here too. With the source code for Blazorade Teams, you will also find a Blazor Server demo application. This demo application demonstrates both the configuration page and removal page.
The Configuration and Removal Pages
On the configuration page, you write code that runs after the user clicks the Save button on the configuration dialog, but before Teams actually creates the tab. There you can write whatever initialization code you need. Similarly, on the removal page, you can write code that runs after the user has hit the Remove button, but before Teams has actually removed the tab.
And remember, you use the TeamsApplication
component on both the configuration and removal page. That means that you have an access token to any APIs your Azure AD application registration defines. This means that you can for instance call into Microsoft Graph when a user configures or removes the application. Pretty cool, right?
To learn more about writing personal tab applications with Blazorade Teams, have a look at the personal tab application section on the wiki. When you have completed a personal tab application, you can go ahead to the channel tab application section.
Test and Deploy Your Application
OK, so now you have at least the initial parts of your application written. It’s time to test it with Teams. To help you with this, Microsoft has created the App Studio Teams application. This application will help you build the manifest for your application. You can then either download the manifest for later use, or directly deploy to Teams.
Directly deploying works great in development tenants where you want to run your application in your local development environment. Please note that you need to enable application side-loading in Teams in order to be able to deploy your Teams application directly from App Studio.
To learn more about using App Studio, have a look at the App Studio section on the Blazorade Teams wiki.
Summary
I’ve been wanting to build something that would make building a Microsoft Teams app with Blazor super easy. The setup is just so interesting. The Teams SDK is a pure JavaScript SDK, and Blazor is in many cases running on the server. And, I wanted to make sure that developers would not need to write any JavaScript unless they wanted to. There was just no time to spend on this, I thought. You know the usual story – Something else always came up.
But now, in the beginning of December 2020, I started working on Blazorade Teams. And I’m really happy I did. And I hope that I can contribute to the increasing popularity of both Blazor and Teams, two things I really enjoy working with.
10 Comments
John · January 26, 2021 at 18:28
Hi there,
Solution looks great. I was wondering if it is also possible to host app also outside of MS Teams. At least that’s what I’m trying to achieve. One web app that runs in and outside of MS Teams secured with AAD integration.
Thanks.
Mika Berglund · January 28, 2021 at 14:30
A Teams application is hosted anywhere. You can deploy it to Azure, AWS or any other hosting provider. Blazorade Teams is a library for Blazor applications that makes the necessary communication with Teams SDK much easier.
John · January 28, 2021 at 15:14
Yeah, I understand. But the idea is that people can run it outside of Teams, in a normal browser, or from within Teams.
However, when I run your code outside of Teams, it says its running outside of Teams “This application is designed to be run inside of Microsoft Teams.” and nothing else happens, hence my question.
Mika Berglund · January 28, 2021 at 19:02
Maybe I don’t understand what you are trying to achieve? Blazorade Teams is about building Teams applications that run in a tab inside of Teams using Blazor. What would be the point of running a Teams application outside of Teams?
All Teams applications, regardless of whether you run them in the desktop client or web client, are web applications that communicate with the Teams SDK to do certain things. And if you would run such an application outside of Teams, there would not be any Teams context to run the application in. That’s why I implemented that “This application is designed to run inside of Microsoft Teams” message.
Ronald Schutte · June 12, 2021 at 02:35
Hello Mika. Great project.
I was wondering if you plan to add support for include support for access to Dataverse for Teams as well.
PS: There are some broken links for the Blazor Server Demo.
Mika Berglund · June 12, 2021 at 07:45
Hi Ronald!
Currently, I don’t have any plans for Dataverse, neither to include support nor to exclude it in Blazorade Teams. I am trying to decide on how the implementation should actually be done before I release the initial version. This is mainly related to authentication, but there are also some issues related to running Blazorade Teams on a mobile device, at least with Android.
I found the broken links you pointed out. Thanks for that! I’ll fix those. Seems that I’ve just moved around the code a bit, which of course broke then links then.
Angelos · May 6, 2022 at 09:28
Blazorade looks great. Would this approch work on Mobile Teams as well?
Mika Berglund · May 9, 2022 at 08:41
Hi!
It was my intention to build the library into something that would work for any type of Teams application that Teams itself supports. However, since I begun working on the library there has been additional announcements from Microsoft, such as support for Blazor in [TeamsFx](https://docs.microsoft.com/microsoftteams/platform/get-started/get-started-overview).
So, I think that Blazorade Teams in its current form will not continue but rather focus on bringing added value to TeamsFx. That’s not anything that I’ve decided yet, and I need to take a closer look at building Teams applications with Blazor and TeamsFx, but that is how it looks right now.
Tom · October 25, 2023 at 11:53
I have been asked to investigate Blazor/Teams development and provided with a link to your original article. Having read this more recent article I then took a skim through the comments and noticed this last one regarding TeamsFX and possible change of direction for Blazorade Teams.
I note your reply is over a year ago, and that the last update to Blazorade in GitHub was 2 years ago. Where do things stand now? Has Microsoft’s TeamsFX and subsequent changes rendered Blazorade unnecessary, or have you take a different route with a new solution?
I don’t have much detail yet, but understand the interest from our side would be Blazor client that can access Azure functions
Mika Berglund · October 25, 2023 at 15:08
Hi Tom!
What comes to Teams applications built with Blazor, I would say that TeamsFX would be the best solution to go with, if you want to build your Teams applications using Blazor. Blazorade Teams was created at a time when the only option to write Teams applications was using a JavaScript library that was extremely hard to use in a Blazor application. That JS library required you to manage JavaScript interop both to and from JavaScript, which was taken care of by Blazorade Teams. Now with TeamsFX this is perhaps not that big of an issue anymore.
The design goal of all the different Blazorade libraries has been to fill in the gap between the supply and demand. When the supply changes that gap also changes. TeamsFX is a good example of that. If I start to design the next version of Blazorade Teams, it will definitely be built around TeamsFX, and provide extensions to that.
Another example of this is the first Blazorade library – Blazorade Bootstrap. If you are familiar with Bootstrap, you know that in many cases it requires a huge amount of HTML markup to properly implement a Bootstrap component. The idea behind Blazorade Bootstrap was to provide default behaviour that you could complete with just one line of markup, but then provide you with extension points where you could extend the components as you needed.
I admit that lately I have not been able to put down as much on Blazorade libraries as I would have liked. But I would not say that Blazorade as a family of Blazor libraries is unnecessary. There will always be a gap between supply and demand.
What comes to interest related to create a Blazor client application that would access an API developed as an Azure Functions app, you might want to look into using MSAL for authentication and authorization, and then use OIDC/OAuth to protect that API and get access tokens to it in your Blazor application using MSAL. There is a Blazoarde MSAL library that would help you do that. But, that library has been deprecated. The main reason for this is that the way Blazorade MSAL handles things is hard to get to work in MAUI applications when running on mobile devices. So, I have decided to create that library from scratch and make sure that it also works in any MAUI application built using Blazor. Currently, that repository is private while I’m building it for the first alpha release. The library will be called Blazorade Auth. If you are interested in that, just let me know.