Skip to main content

Microsoft Teams Tab Application that uses the Graph API and Exchange FreeBusy Information

In my last post I went over the new Graph function called getSchedule and how this can be used to get the FreeBusy information for a User (or Meeting Room, Resource Mailbox etc) and display that as a table like the schedule assistant in Outlook.

In this post I'll show you how you can do the same thing in a Teams tab application which will give you an output something like the following

The steps this app takes to display this is firstly

Step 1.

Authentication - The app authenticates to the Microsoft Graph API using the javascript ADAL using the silent Authentication flow for tab applications which is explained in detail here .

Step 2

Get the Group Members - Once it has an Access-Token it then Gets the members of the current Team from the Graph by first getting the Id from the Context of the team currently in focus from the Teams Client SDK and then making a request to the Groups Endpoint


Schedule Request - Make a schedule request of the Members of the Team (note this operation is only in Beta at the moment). This returns the FreeBusy information for the members of the team in 30 minute timeslots for the working hours period I'm displaying. Note the Timezone from the browser (or Teams Client) is used here. Incorrect Time zone of timezone differences are something that can affect the results of this operation.


Build the HTML to Display- Build the above FreeBusy table from the Results


Get the UesrPhotos -   Backfill the user photos asynchronously using the Graph photos endpoint.

That's it for the rundown on the functional side of how this Tab app works for more of a description on how Tab apps work in general have a look at my last post which goes a bit more in depth on this. I've rewritten most of the code from that post so its now ES6 and implements both promises and async functions in JavaScript which eliminants a lot of clutter,logic fog and call-backs code the plagued the original (if you still using IE none this will work but if your still using IE your probably using Microsoft comic chat).

I've also implemented a config file in

So anything that needed to be hardcoded in the app is in this file which is basically

        clientId : "2cff1b6d-82d4-4dc0-9ac4-7f35b06cc64a"  - this the Azure App registration which you should create your own of that will list

        redirectUri : "/TeamsFB/app/silent-end.html" - From the Azure App registration

        authwindow :  "/TeamsFB/app/auth.html" - For the Slient Auth functions

        hostRoot: "" - For the relative references in the js files

this makes it easy if you want to change the host or use ngrok to host it, eg just change hostRoot, Azure RedirectURI to the ngrok address and you should be good to go.

Permissions for Azure App registration

Because this app accesses various graph endpoints different oauth Grants need to be allowed eg
  • Group members User.Read and Group.Read.All
  • FreeBusyInformation   Calendar.Read
  • UserPhotos User.ReadBasic.All
Installation and Pre-Req

Azure app registration - you need to have an app registration that is Authorised within you tenant (see my last post for more details)

Side Loading - To use custom tab applications you first need to enable side loading of Apps in the Office365 Admin portal ref .The important part is  "Sideloading is how you add an app to Teams by uploading a zip file directly to a team. Sideloading lets you test an app as it's being developed. It also lets you build an app for internal use only and share it with your team without submitting it to the Teams app catalog in the Office Store. "

As this is a custom application you need to use the "upload a custom app" link which is available when you click ManageTeam-Apps tab see

(Note if you don't see  the "upload a custom app" check that you have side loading of apps enabled in your tenant config)

What you upload here is a Zip file containing your manifest file and two images that you manifest refers to for eg
   "icons": {
    "outline": "Outline32.png",
    "color": "Colour192.png"

For this sample this is located in

These icons are what is used in the UI to represent your application.

All the code for this sample is available in GitHub here

Its also hosted in GitHub pages if you have a development tenant and want to test it (you will need to first use the admin consent URL listed above).

Popular posts from this blog

Downloading a shared file from Onedrive for business using Powershell

I thought I'd quickly share this script I came up with to download a file that was shared using One Drive for Business (which is SharePoint under the covers) with Powershell. The following script takes a OneDrive for business URL which would look like This script is pretty simple it uses the SharePoint CSOM (Client side object Model) which it loads in the first line. It uses the URI object to separate the host and relative URL which the CSOM requires and also the SharePointOnlineCredentials object to handle the Office365 SharePoint online authentication. The following script is a function that take the OneDrive URL, Credentials for Office365 and path you want to download the file to and downloads the file. eg to run the script you would use something like ./spdownload.ps1 '

Export calendar Items to a CSV file using EWS and Powershell

Somebody asked about this last week and while I have a lot of EWS scripts that do access the Calendar I didn't have a simple example that just exported a list of the Calendar events with relevant information to a CSV file so here it is. I've talked on this one before in this howto  but when you query the calendar folder using EWS you need to use a CalendarView which will expand any recurring appointments in a calendar. There are some limits when you use a calendarview in that you can only return a maximum of 2 years of appointments at a time and paging will limit the max number of items to 1000 per call. So if you have a calendar with a very large number of appointments you need to break your query into small date time blocks. In this example script I'm just grabbing the next 7 days of appointments if you want to query a longer period you need to adjust the following lines (keeping in mind what I just mentioned) #Define Date to Query $StartDate = (Get-Date) $EndDate

The MailboxConcurrency limit and using Batching in the Microsoft Graph API

If your getting an error such as Application is over its MailboxConcurrency limit while using the Microsoft Graph API this post may help you understand why. Background   The Mailbox  concurrency limit when your using the Graph API is 4 as per . This is evaluated for each app ID and mailbox combination so this means you can have different apps running under the same credentials and the poor behavior of one won't cause the other to be throttled. If you compared that to EWS you could have up to 27 concurrent connections but they are shared across all apps on a first come first served basis. Batching Batching in the Graph API is a way of combining multiple requests into a single HTTP request. Batching in the Exchange Mail API's EWS and MAPI has been around for a long time and its common, for email Apps to process large numbers of smaller items for a variety of reasons.  Batching in the Graph is limited to a m
All sample scripts and source code is provided by for illustrative purposes only. All examples are untested in different environments and therefore, I cannot guarantee or imply reliability, serviceability, or function of these programs.

All code contained herein is provided to you "AS IS" without any warranties of any kind. The implied warranties of non-infringement, merchantability and fitness for a particular purpose are expressly disclaimed.