Reading Microsoft Teams presence information with Microsoft Graph and ESP32

Tags: Microsoft Graph, Microsoft Teams, ESP32, ExpressIf, Arduino, C++, Visual Studio Code, IoT

This long overdue blog post explains one of my small circuits which indicates Microsoft Teams presence information for a user from Microsoft Graph. Circuit is based on Expressif microcontroller ESP32 which reads a presence information for a user from Microsoft Graph and displays it as a color on RGB LED diode.

ESP32 with RGB LED

I started to explore microcontrollers again in spring of 2020 after a decade of not messing with electronics at all. I wanted to try something with Microsoft Graph, and ESP32 presented itself as an obvious choice for that purpose.

How it works

Circuit is quite simple, and consists only of 2 real electronic parts:

  1. ESP32 Dev Kit board (any other ESP32-based board should work)
  2. RGB LED diode

Circuit ESP32, RGB LED and wires

When the circuit is connected to the power supply, it connects itself to the configured WLAN access point and attempts to authenticate in Azure AD using device code flow. After successful authentication, the circuit calls the Microsoft Graph presence endpoint and turns on the RGB LED in same color as the obtained presence status for a user. That is repeated in the loop, every 30 seconds.

Necessary configuration

Circuit configuration consists of 2 sections:

  1. WLAN credentials
    • name of the WLAN access point and
    • the password to connect
  2. Microsoft Graph configuration
    • Tenant ID (GUID)
    • Client ID of the app registered in AAD (GUID)
    • User ID of the user for which we are reading presence (GUID)

Configuration parameters are defined in the file params.h which needs to be adjusted before the sketch is deployed to the ESP32 board. Configuration parameters for Microsoft Graph can be obtained from Azure portal, and User ID can be read using Graph Explorer.

const char *ssid = "<WiFi AP SSID GOES HERE>";
const char *pass = "<WIFI AP PASSWORD GOES HERE>";

String tenantId = "<AZURE AD TENANT ID GOES HERE>";
String clientId = "<AZURE AD APP CLIENT ID GOES HERE>";
String userId = "<MICROSOFT GRAPH USER ID GOES HERE>";

Authentication

For the authentication of calls to Microsoft Graph, I registered the app in Azure Active Directory which is configured with “Mobile and desktop application” client with Redirect URI for Native Client. API Permissions for the app are configured so that presence can be read from Microsoft Graph:

  • Presence.Read
  • Presence.Read.All

Application ID for this AAD app needs to be written as Client ID parameter in params.h

When device is powered on and connected to WiFi, it is necessary to perform authentication. I use device code flow for this purpose. The code will be written out to serial output of the microcontroller – and the easiest way to read it on Windows is to use TYPE command from Windows command prompt*.

Output on Serial Port

*Disclaimer: The driver for serial port of your board needs to be installed.

How I built it

The solution is built with C++ in Visual Studio Code with Arduino extension. Application logic consists of a sequence of HTTP calls and processing JSON responses from the endpoints. As an example, here is the code segment that reads presence information from Microsoft Graph:

String httpGETPresence(const char *targetUrl, String accessToken)

{

Serial.println("httpGETPresence(): ");

HTTPClient client;

client.begin(targetUrl);

client.addHeader("Authorization", "Bearer " + accessToken);

int httpResponseCode = client.GET();

String payload = "{}";

payload = client.getString();

client.end();

return payload;

}

As the application depends on successful authentication to obtain correct access tokens. Until the device is authenticated, the code tries to obtain correct tokens and will not attempt to retrieve presence information until valid access token is retrieved. Similar approach has been taken in case the access token is expired, but in this case I am executing the logic to renew the tokens. This code is executing in the loop with hard-coded delay of 30 seconds between calls.

After the device is successfully authenticated and valid access token is obtained, I am then calling presence endpoint on Microsoft Graph to obtain presence information. After presence information is obtained, the RGB LED diode is turned on in color that matches obtained presence from Microsoft Teams.

Here is the list of most important methods in the code sample with brief explanation of the functionality:

· httpAuthorizeDevice – initiates Device Code flow and obtains code that is used for device registration

· httpPopulateTokens – reads access and renew token after device is authenticated

· httpRenewTokens – renews tokens after access token is expired

· httpGETPresence – reads presence information

· lightLeds – lights RGB LED

Full code is available in a repository on GitHub: https://github.com/panjkov/esp32-msgraph-presence/

Conclusion

For a further reference, here are links to the documentation:

· Device Code Flow: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code

· Microsoft Teams Presence API: https://docs.microsoft.com/en-us/graph/api/resources/presence?view=graph-rest-1.0

What is the future of this solution?

This is a code sample showcasing connection to Microsoft Graph API endpoints using ESP32 and device authentication in C++, relevant at the time of writing this blog post (December 2020). I intend to create a version of the sample that reads only presence information for current user, which would simplify its configuration and to post it on same repository on GitHub. If you have questions or comments, feel free to get in touch with me on Twitter https://twitter.com/panjkov/ or posting an issue on GitHub Issues · panjkov/esp32-msgraph-presence (github.com).

Have fun playing with ESP32 and Microsoft Graph Smile

Until next time!

Dragan

No Comments

Add a Comment