Skip to content

Using Power Apps and Graph API to show who is available at a specific office

Have you ever wondered who is available on Microsoft Teams at a specific office location in your organization? You may have multiple offices across the country and you need to reach out to someone who is not currently in any meeting but could rather chat/talk to you.

In this blog post, I’ll show you how to create a simple and useful Power Apps app that lets you see who is online on Teams at any office location, using Power Apps, Power Automate, and Microsoft Graph API. You will learn how to:

  • Use SharePoint to store and manage the office locations and their users
  • Use Power Automate to create a cloud flow that retrieves the availability status of the users from Teams using Microsoft Graph API
  • Use Power Apps to create a canvas app that displays the office locations and their users, including their availability status, and allows you to start a conversation with them
  • Understand the licensing options for the solution.

By following the steps in this blog post, you will have a working Power App that shows who is available on Team, using your own Microsoft 365 tenant’s data. You will then be able to customize it to suit your needs, by adding more features or including the office, user and live presence information as part of your existing app. Let’s get started!

SharePoint list for offices locations and groups

The first thing we need to know is who works at which office. It is assumed that for each location there is an Entra ID or Office 365 group containing its users. Information like this could often be found in your organization’s Active Directory.

A new SharePoint list is created in which the offices and the IDs of their corresponding groups are stored:

This way, the user does not have to know which group corresponds to which office. He is only interested in the offices and who is available at which office at any given time.

Flow: users’ status information

Next, we want to find out which users in the selected group are showing up as green in Microsoft Teams – meaning their presence state is “available”.

Let’s create a Power Automate cloud flow that starts from Power Apps and receives the group ID from Power Apps as a parameter. Then the users of that group are searched (List group members).

All sorts of information about group members is returned from this action. However, we only need a list of user identifiers. Let’s create that list with the Select function that grabs the output value from the “List group members” step and maps the “User Id” parameter.

Looking good! Now we have just the GUID values in the response Body:

Next, we will find out the current status of these users in Teams. For this we need to call the Graph API. There you will find an endpoint with which you can check the status information of several users with a single call:

POST https://graph.microsoft.com/v1.0/communications/getPresencesByUserId

But could the query be performed with some standard connector? For example with this one:

Or this one:

Unfortunately, no:

Error: URI path is not a valid Graph endpoint, path is neither Absolute nor relative or resource/object is not supported for this connector. Resources: me, users, groups, sites, search, planner, teams, chat

This was to be expected, yet I had to try if the standard connectors included in Microsoft 365 licenses would have been sufficient. Now we need to proceed to using a premium licensed connector.

Next, we will try to make a Graph API call using the “Invoke an HTTP request” function of the HTTP with Azure AD connector. This way we could avoid registering our own Entra ID application.

No luck. Retrieving status information is not included here either:

The traditional option remains: making the raw HTTP request and handling the authentication. But is the API call executed as an application or as a user with delegated rights?

The choice is easy because the application cannot use this API (at least not yet):

Let’s register an Entra ID application that is given the Graph API delegated “Presence.Read.All” permissions.

After this, we can apply for a token with a username and password. Naturally, the service ID is used, not anyone’s personal Entra ID.

Finally, the actual Graph API call is made using the received token:

We are interested in employees who are available according to Teams presence status. Let’s filter them out:

Let’s return a list of people to Power Apps with the Response function. This is how we can include the JSON schema:

The complete flow looks like the following:

Power Apps

The last step is to create Power Apps, which shows the employees who are available (according to Teams) at the selected location.

A combo box is added to the application, from which you can select the desired office. Locations are retrieved from the SharePoint list:

Next, the flow we just made is added to the app (Add flow):

When the user selects a location, the available users of the location are searched with flow and stored in the collection (colAvailableUsers):

OnChange: ClearCollect(colAvailableusers,'PA-Getgroupmembersavailability'.Run(Self.Selected.GroupId));

This time there was only one user available at the location we were interested in:

Let’s add a gallery to the screen showing the available users (colAvailableusers):

With the Office 365 Users connector, we can show users’ photos in the gallery:

Using the same connector, we retrieve the user’s profile information. We show their name and titles. We want to show the name in bold and retrieve the user’s information only once. This can be done using the With function and the HtmlText control:

HtmlText = With({varUser: Office365Users.UserProfileV2(ThisItem.id)},
                 "<div style=font-weight:600>"&varUser.displayName &"</div>
                 <div>"&varUser.jobTitle &"</div>"
                )

After a light cleaning the application looks like this:

Calling/opening a conversation

It should be possible to directly open a Teams call or chat with a free person from the application.

Let’s add icons for these functions to the gallery:

When the application’s only screen is opened (OnVisible event), information is retrieved on whether the application is used in a browser or something else (within the Teams application, or on a phone):

UpdateContext({locIsHostClientWeb:Param("hostClientType")="web"})

Finally, the necessary commands for the icons’ OnSelect events are added.

To open a chat:

Select(Parent);
If(
    locIsHostClientWeb,
    Launch(
        "https://teams.microsoft.com/l/chat/0/0?users="& 
          Office365Users.UserProfileV2(ThisItem.id).mail,
        {},
        LaunchTarget.New
    ),
    Launch(
        "msteams://teams.microsoft.com/l/chat/0/0?users="& 
          Office365Users.UserProfileV2(ThisItem.id).mail,
        {},
        LaunchTarget.New
    )
)

Making a call:

Select(Parent);
If(
    locIsHostClientWeb,
    Launch(
        "https://teams.microsoft.com/l/call/0/0?users="& 
          Office365Users.UserProfileV2(ThisItem.id).mail,
        {},
        LaunchTarget.New
    ),
    Launch(
        "msteams://teams.microsoft.com/l/call/0/0?users="&
         Office365Users.UserProfileV2(ThisItem.id).mail,
        {},
        LaunchTarget.New
    )
)

Handy!

What licenses does this require?

The solution’s Power App does not contain premium features, but the Power Automate cloud flow it starts does (HTTP connector). An Office 365 / Microsoft 365 license alone is therefore not enough to use the application. Although the automation uses a service account, we’d be doing multiplexing if we tried to avoid licensing the actual end users who receive value from the premium feature.

Users of the app can be licensed in several different ways:

  • Power Apps Premium license for the users (formerly “Power Apps Per User”) to cover unlimited apps.
  • Power Apps per App license for the users of this app only.
  • The application can be installed in a Pay-as-you-go environment. In this case the license is not tied to users, but usage is billed based on the number of monthly active users.

Alternatively, we can license the specific cloud flow used by the application, to allow its usage by the entire organization. This would be done with the new Power Automate Process licenses, which my colleague Jukka Niiranen has explained in his recent blog post.

Canvas Power AppsFlowGraph APIMicrosoft TeamsPower AppsPower Automate

Leave a Reply

Your email address will not be published. Required fields are marked *