Building a Windows Presentation Foundation (WPF) Microsoft Teams App

Author: Alessandro Avila, a Microsoft Apps Consultant developer Today’s guest blog post comes from Alessandro Avila, a Microsoft Apps Consultant developer, and his experiences with app development, cloud migration, and overall digital transformation at ABB – a global leader in robotics, power, heavy electrical equipment, and automation technology based in Europe.

Introduction

Teams is the hub for teamwork in Microsoft 365 – bringing together people, chat, content, calls and apps in a central space for collaboration and productivity. Enterprises across the globe rely on the rich features provided by the platform to build powerful workspaces and provide valuable feedback to the Teams product group to further enhance those experiences. This post covers my recent experience with an enterprise customer, ABB – a global digital transformation leader, helping their marketing organization through their Teams adoption, as well as custom app solution development to address some of their process automation needs. ABB’s marketing organization was an early adopter of Teams – and heavily used the Microsoft Planner app integration in Teams to organize activities and tasks in a systematic and structured fashion and assign them to staff across different divisions and geos. For those unfamiliar with the app, Microsoft Planner is a project management application that allows teams to create, assign and organize work visually to better facilitate teamwork and monitor progress. With the high usage of Teams and the Planner integration, our customer needed a solution that would be able to automate the capability of copying Planner plans (including tasks/activities/content) in bulk across different Teams teams – eliminating the time-consuming manual copy process that it was performing currently. In this post we’ll walk you through our custom app solution demo we built for ABB to address their need and requirements. We’ll cover knowledge areas spanning across Teams app development, Graph APIs, C#, and Azure.

Planner app integration in Teams

Teams extends content and web services through ‘apps’ that enable one or more capabilities teams can use in their daily work for collaboration and productivity. You can take advantage of the many Microsoft and 3 rd -party app integrations available in the Teams store or you can even build your own custom app for your organization or widely-available to the public. Screenshot of different apps available in Teams for addition as a tab in a Teams channelWith the Microsoft Planner app integration in Teams, teams can create custom plans, create tasks, and assign work item all within a Teams channel. Tasks are organized in Buckets (Kanban) by default and enhanced with contextual details (Task progress, Start Date, Due Date, Checklist) that fosters teamwork, collaboration, and productivity. Screenshot of Planner plan’s boards viewScreenshot of Planner’s task details paneThe Planner app integration in Teams, provides the ability to copy an existing Planner plan as a tab. However, there are a couple limitations which impact the user experience for these migration scenarios:

  1. Provides only an ‘intra-team’ copy (i.e., you can create a copy of an existing plan only within the same Team where the source plan resides);
  2. By selecting an existing plan and adding it as a tab, the copied plan is actually a pointer to the previous one: any changes made to the newly created plan would affect the source plan; in other words, it’s a shallow copy, not a deep copy.

Screenshot of copy plan option

To address these limitations that was impacting our client’s experience, we built a custom app solution (“TeamsApp”) which enables an inter-Teams copy of Planner Plans, with full copy of underlying Buckets and Tasks and gives IT Admins a tool that can be used to set up tasks within a new team.

Prerequisites

Before we dive into the demo, we’ll walk through some of the prerequisites you’ll need to complete.

We’ll be leveraging Microsoft Graph APIs, so a Microsoft 365 tenant is needed. We recommend using a developer tenancy for this and you can get one if you register for the Microsoft 365 Developer Program here. An Azure AD App needs to be registered in the Azure Portal, as well.

Having these set up will enable communication between ‘TeamsApp’ and the Microsoft Identity Platform of the specific tenant and establishes the information that it uses to get OAuth Access Tokens. Through the registered Azure AD App, the ‘TeamsApp’ can access Microsoft 365 organization resources.

Azure AD App Registration

(For a detailed description, follow the steps explained in the Microsoft Docs).

  1. Sign into the Azure Portal with a Work or School / Personal Account.
  2. If the specified account gives access to more than one tenant, select the desired tenant.
  3. From the left-menu: Azure Active Directory -> App registrations -> New registration.

Azure Registration Window

4. Fill in the mandatory fields:

a. Name: the app name (e.g.: “TeamsApp”).

b. Supported account types: it depends on which accounts will access TeamsApp and Graph APIs through the AD v2.0 application. You can choose between:

i. (default) Accounts in this organizational directory : this option maps to Azure AD only single tenant; select this option if you’re building a line-of-business application;

ii. Accounts in any organizational directory: this option maps to Azure AD only multi-tenant;

iii. Accounts in any organizational directory and personal Microsoft accounts (e.g. Skype, Xbox, Outlook.com); this option maps to Azure AD multi-tenant and personal Microsoft accounts; this option targets the widest set of customers. Note: This was the option we used.

c. Redirect URI: it’s URI AD will return the authentication response to, after successfully authenticating the user.

ii. Set the value to “urn:ietf:wg:oauth:2.0:oob” in the textbox.

5. Click on Register.

App registration window

6. On the application page, take note of the Application (client) ID field, we’ll need it when it comes to properly setting the authentication properties in our app;

7. Since we are using NET as .NET authentication library (v4.9.0) to get tokens from the AD identity platform, we need to get back to our application and change the Redirect URI field.

8. From the Suggested Redirect URIs section, select the URI in the form:

9. Take note of the new Redirect URI as well.

App Permissions

Since ‘TeamsApp’ integrates with Microsoft Identity Platform, it follows an authorization model that gives users control over how data can be accessed; see Microsoft Docs for more information about permissions and consent.

Specifying the app’s permissions (or scopes), we have fine-grained control over data our APIs can access to perform their functions.

For our purposes, we need to setup two permissions:

  1. Read.All: Sign in and read user profile
  2. ReadWrite.All: Read and write all groups

Here are the permissions already granted for the demo AD App:

Permissions screen

Let’s add a new permission:

  1. Click on “Add a permission” button;
  2. Select “Microsoft Graph” as Microsoft APIs, then Delegated permissions as type of permissions, since ‘TeamsApp’ needs to access the API as the signed-in user.
  3. Look for “Group.ReadWrite.All”, check it and click on Add permissions button.

Permissions screen

4. Since Admin consent is required for this permission, click on “Grant Admin consent for Contoso”.

Consent screen

The ‘TeamsApp’ Solution

Solution Architecture

We developed ‘TeamsApp’ with Visual Studio, and it contains the following two projects:

Project structure

Project structure

Either two projects are built using .NET Framework 4.7.2 (even though some C# 8.0 Preview 2 features are used – the inline using, to mention the most recurrent).

Authentication and access

To interact with Microsoft Graph REST APIs, a JSON-like access token is required and is provided by the Microsoft Identity Platform (Azure AD v2.0). It’s needed to validate the caller (the Azure AD App) and check that it has the proper permissions to access Graph resources (each API endpoint will expose different resources, each of them requires different permissions, as you can discover in more details through this link).

‘TeamsApp’ uses MSAL.NET (Microsoft Authentication Library for .NET) to easily get tokens and allow users to sign in with their work or school accounts (it depends on how you configured the Azure AD App in Azure AD App Registration (4.b).

The class responsible for authentication is AuthenticationHelper (Helpers\AuthenticationHelper.cs in TeamsApp.Lib). This class implements the Singleton design pattern to expose a single instance of an authentication provider that’d be used for the entire application’execution; ClientID and ReturnUrl must be set in the App.xaml file (TeamsApp.WPF) before running the application, with the values provided during the App registration in the Azure Portal (see Azure AD App Registration for details); replace placeholders in the tags ida:ClientID and ida:ReturnUrl:

Graph APIs

Microsoft Graph exposes several endpoints to access Microsoft Cloud service resources. After getting the authentication token (see previous section), you can access resources through HTTP calls that look like the following:

The components of a requests are: