Reading Microsoft Teams presence information with Microsoft Graph and ESP32
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.
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:
ESP32 Dev Kit board (any other ESP32-based board should work)
RGB LED diode
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:
WLAN credentials
name of the WLAN access point and
the password to connect
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 = "
"; const char *pass = " "; String tenantId = "
"; String clientId = " "; String userId = " ";
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*.
*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
Until next time!
Dragan