Microsoft Graph

A Lap around Microsoft Graph Toolkit Day 10 – Microsoft Graph Toolkit Teams Provider

Author: Simon Ågren, Microsoft Office Development MVP

@AgrenPointGitHub | LinkedIn 

Welcome to Day 10 of the Microsoft Graph Toolkit blog series!

Microsoft Teams plays an increasingly critical role in the remote collaboration and productivity work landscape. Teams applications can help you create collaboration and productivity solutions tailored to your organization’s needs. Microsoft Graph Toolkit (MGT) makes building Microsoft Teams solutions even easier.

In today’s blog, you will get more acquainted with the MGT Teams provider and we will show you how to create an MGT-powered personal tab in Microsoft Teams.

Setting things up

Let’s start by creating a simple HTML application, just as Elise showed you in the Day 2 post, and then build upon that scenario to make it work inside of Microsoft Teams.

Create the base HTML application

Start off by following all the steps in the post, and then come right back. I’ll just go grab a coffee meanwhile…

…now that you’ve registered an Azure AD application, created an HTML application, added Microsoft Graph Toolkit, the MSAL Provider and the components, you should have a page that looks something like this:

web app with mgt-login and mgt-agenda components
If you end up with an error stating that your reply-url is incorrect, make sure to check if your browser is running the application from http://localhost:3000 or http://localhost:3000/index.html. Since you configured the reply-url to work with the first case, you could add an additional reply-url or make a slight change to the MSAL provider and specify the redirect-uri:

<mgt-msal-provider 
        client-id="[YOUR-CLIENT-ID]"
        redirect-uri="http://localhost:3000">
</mgt-msal-provider>

Additional prerequisites

Now to continue, you will need to install the tools and manage the settings listed below.

Make some visual changes

If you followed this series during season one you learned about things like using templates, adding custom CSS and the power of mgt-get. Let’s apply some of that learning and incorporate some HTML and CSS.

First, remove the mgt-agenda component. In its place, add some HTML where we are using mgt-get in order to get all of your Microsoft Teams teams. Then, we use templates to display each Team with the display name and description. We also make use of the mgt-people component to display the users in the Team.

<mgt-get resource="/me/joinedTeams" scopes="User.Read.All">
    <template>
        <div class="header">
            <h1>My Joined Teams<h1>
            <h2>And  members</h2>
        </div>
        <div class="teams" data-for="team in value">
            <h3>{{ team.displayName }}</h3>
            <div data-if="team.description" class="description">
                {{ team.description }}
            </div>
            <div data-else class="description">
                Team description is empty
            </div>
            <h4>
                <mgt-people show-max="10" group-id={{team.id}}></mgt-people>
            </h4>
        </div>
    </template>
    <template data-type="loading">
        Loading...
    </template>
    <template data-type="error">
        {{ this }}
    </template>
</mgt-get>

Now add some CSS inside of style tags, in the header of the code:

<style>
    body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        background-color: #FFF;
    }

    .header {
        background-color: #6264A7;
        text-align: center;
        color: #F3F2F1;
        padding: 20px 10px;
        margin: 8px 4px;
        box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
    }

    .teams {
        background-color: #F3F2F1;
        padding: 10px;
        margin: 8px 16px;
    }

    .teams:hover {
        box-shadow: 0 3px 14px rgba(0, 0, 0, 0.3);
    }
</style>

Now, when you log into the application, it should look something like this when you hover over a user from the Team:

web application with user’s joined teams list

Turning your web app into a Teams Tab

Microsoft Teams tabs are webpages hosted outside of Teams that are embedded in an Iframe as a part of a channel, group chat or as a personal app for an individual user. They are context-aware and can grab some Teams-specific information based on where they are embedded.

Our goal today is to make the required changes that allows our HTML application to work both outside and inside of Microsoft Teams. The content surfaced in Teams must be hosted on a publicly available URL available using HTTPS.

In production scenarios we would host the application somewhere else, like an Azure web service, and instead use the URL to that application.

Step 1: Add the Teams SDK

The Microsoft Teams SDK is not included in MGT in case you want to run different versions of the SDK.

First, add a reference to the Microsoft Teams JavaScript Client SDK using script tags, before the Microsoft Graph Toolkit.

<script src="https://unpkg.com/@microsoft/teams-js/dist/MicrosoftTeams.min.js" crossorigin="anonymous"></script>

Step 2: Add the Teams Provider

We need a Microsoft Graph Toolkit provider to enable our components to call Microsoft Graph to retrieve and render data. The provider takes care of getting the necessary access token with the requested scopes, so we don’t need to write a bunch of code to implement all of the auth logic.

The Teams Provider, is a wrapper around the MSAL provider. It handles the Teams-specific logic, so you don’t have to create the necessary code to handle the interactions with the Teams SDK and all of the authentication redirects to authenticate the user. In true MGT spirit, you take care of the imports and configuration, and the Teams Provider does the heavy lifting.

Normally, we would need to make a call to microsoftTeams.initialize() in order to display the page in Microsoft Teams. In our case the MGT Teams Provider takes care of it.

As mentioned earlier, we want this application to work both inside and outside of Microsoft Teams. To do this we have two options.  The first option is to add the provider component mgt-teams-provider and keep the mgt-msal-provider with slight alterations. We can use the depends-on attribute in the MSAL provider to create a fallback chain. The MSAL provider will only be used if the Teams provider is not available in the current environment.

<mgt-teams-provider 
    client-id="[YOUR-CLIENT-ID]" 
    auth-popup-url="auth.html">
</mgt-teams-provider>

<mgt-msal-provider 
    client-id="[YOUR-CLIENT-ID]"
    depends-on="mgt-teams-provider" 
    redirect-uri="http://localhost:3000">
</mgt-msal-provider>

The other option is to use code.  We’ll do this because it gives us more control and we could use it (in a similar fashion) in more complex, code-based applications further down the road. We add a script tag with the code after all the components in the body:

<script>
    let provider;
    if (mgt.TeamsProvider.isAvailable) {
        provider = new mgt.TeamsProvider({
            clientId: "[YOUR-CLIENT-ID]",
            authPopupUrl: "/auth.html",
        });
    } else {
        provider = new mgt.MsalProvider({
            clientId: "[YOUR-CLIENT-ID]",
            redirectUri: "http://localhost:3000",
        });
    }
    mgt.Providers.globalProvider = provider;
</script>

Step 3: ADD ONE LINE OF CODE!

First, create the auth.html page in the root of the application (same level as index.html). This is the page that will handle the auth in the popup (authPopupUrl). Once again, we add script tag references to the Teams SDK and to MGT. Then we only need to add ONE line of code mgt.TeamsProvider.handleAuth() to make the Teams Provider handle everything for us:

<html>
  <head>
    <script src="https://unpkg.com/@microsoft/teams-js/dist/MicrosoftTeams.min.js" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/@microsoft/mgt/dist/bundle/mgt-loader.js"></script>
    <script>
      mgt.TeamsProvider.handleAuth();
    </script>
  </head>
  <body></body>
</html>

With all this time we are saving, maybe there’s time for another coffee.

Testing the app in Microsoft Teams

Step 1: Start the application in the browser

Start the application via Live Server by either right-clicking on the index.html file in the Explorer pane and click Open with Live Server, or using the shortcut ALT+L ALT+O.  The server will start and automatically open your index.html page in your default browser at http://localhost:3000.

You don’t need to log in or anything, just don’t close the browser tab.

Step 2: Start ngrok

Run this command:

ngrok http 3000 --host-header=localhost

forwarded ngrok address shown in terminal

Step 3: Add reply-url

Find the Azure AD application registration you created earlier in the Azure Portal. Move into Authentication and add the https URL from ngrok with trailing /auth.html.

redirect uri setup in Azure portal

Step 4:  Create app in App Studio

To create an app in Microsoft Teams you need an icon and a manifest file that points to the location where the actual application is hosted.  To build a manifest for our app we’ll use App Studio, which is very user-friendly.

First, start Microsoft Teams. I recommend using the web version, since you could use the browser debug tools. But using the desktop client is fine as well.

Launch App Studio from your apps, go into the Manifest editor tab and create a new app. Then fill in the required fields

app details view in Teams App Studio

In the left pane, click on Tabs and select to Add a personal tab and fill in the values (using the ngrok url)

 personal tab view in Teams App Studio

In the left pane, click on Test and distribute and then Download your app package. Then go back to Apps in Microsoft Teams, click on Upload a custom app and upload for <Tenant name>.

Select the .zip file that you just downloaded, and then add the tab.

Upload a custom app option in Teams

Remember, the manifest points to where the application is hosted. Right now, it points to the ngrok tunneling URL, and the application that runs locally. We don’t have to upload the .zip each time we make a code change, the changes will be reflected where it’s hosted.

If you have configured everything correctly, you should now be able to log in and see the application running inside of Microsoft Teams.

web app loaded within Teams as a tab

To summarize

Great job! It might seem like many steps, but after getting to know the workflow it’s quite easy.

Basically, the steps are:

  1. Register an Azure AD app and create the HMTL application with some MGT magic.
  2. Host the application somewhere. If locally, we spin up ngrok
  3. Create a Teams Application via App Studio and configure a personal tab.
  4. Make sure the reply-url in the Azure AD app, and the content url in the personal tab settings points to the correct URL.
  5. Install the application in Microsoft Teams

Next steps

Get the source code for this sample in the mgtLap repository. For simplicity, we only built a simple HTML application.

Try the Microsoft Teams Toolkit Visual Studio Code extension. It streamlines the development process, making it easier than ever to scaffold a new tab with your desired scope, then create and configure an app package (like App studio).

filter-icon