Jan 29, 2022 3 min read

Get full meeting details in a Teams meetings app, without Bot SDK

You can get meeting details in a Microsoft Teams meeting app through the Bot SDK, but what if you prefer to not use the Bot SDK?

Get full meeting details in a Teams meetings app, without Bot SDK

Imagine you are developing a Microsoft Teams meetings application and for some of your desired functionality you need the details of the meeting your app is running in context of. Doesn't sound like an exceptional requirement for an in-meeting app, right? Unfortunately, it's way harder and a lot more complex than it should be.

A custom Microsoft Teams meetings application is created using the Microsoft Teams JavaScript SDK, and is essentially just a web application that uses the SDK to lighten up or interact with Teams features.
The JavaScript SDK provides contextual information for your app and where it is running. There is one method that caught my eye: microsoftTeams.meeting.getMeetingDetails(). It has no documentation and it is unclear how it should be used, as such I have not been able to figure out how it is supposed to work. It always returns with App doesn't have sufficient permission to use this API. A Google search brings me to TechCommunity and learns me that this method is not available to third-party developers:

Microsoft Graph has the /me/onlineMeetings/{meetingId} endpoint that allows you to get meeting details of the passed in meeting id. The JavaScript SDK on the other hand has another promising property: microsoftTeams.context.meetingId. 1 and 1 equals 2, right? But yet again it's not that simple as both are not compatible with each other 🙄. The meeting id from the JS SDK is meant to be sent to the Get Meeting Details method from Bot Framework, and it has a "weird" format: MCMxOTptZWV0aW5nX05XTTJZMlkzTjJRdFpEUTNPUzAwTWpneExXRTNaV1V0WW1WbU1UUTJOMlUzT0dReEB0aHJlYWQudjIjMA==.

Adding a bot to your meetings application is the only documented way to get full meeting details. Having to create a bot JUST for this feels is overkill, but the format of the meetingId made me dig a little deeper... A string that ends with == is a sign of it being base64 encoded, so as a last resort I decided to decode it and that was the eureka moment!
Let's go through it step by step.

  1. Get the meetingId from the context in the Teams JS SDK.
let meetingId = microsoftTeams.context.meetingId;

2. Base64 decode that value:

let decodedMeetingId = Buffer.from(meetingId, "base64").toString("ascii");
// 0#19:meeting_NWM2Y2Y3N2QtZDQ3OS00MjgxLWE3ZWUtYmVmMTQ2N2U3OGQx@thread.v2#0

3. That value (minus the 0# and #0 padding) looks a lot like a Teams meeting chat id (😲), so let's strip them off:

let chatId = decodedMeetingId.replace(/^0#|#0$/g, "");
// 19:meeting_NWM2Y2Y3N2QtZDQ3OS00MjgxLWE3ZWUtYmVmMTQ2N2U3OGQx@thread.v2

4. Use the chatId with Microsoft Graph get chat endpoint to fetch some info:

GET https://graph.microsoft.com/beta/chats/{chatId}

It gives the following result:

When the provided chatId is of a chat associated with a Microsoft Teams meeting, the returned object contains an onlineMeetingInfo object (at the time of writing: only in the beta/ endpoint of Graph).
It still doesn't have the proper meetingId included but it does have the joinWebUrl property!

5. Use the Microsoft Graph /onlineMeetings endpoint with some filtering on joinWebUrl to find the right meeting:

GET https://graph.microsoft.com/beta/me/onlineMeetings?$filter=joinWebUrl eq '{joinWebUrl}'

It should return an array with only 1 object, as only 1 meeting should match the joinWebUrl:

And there you go, all the meeting details WITHOUT using the Bot SDK! You can argue if this really is a simpler solution, but at least it is one less component to maintain. If your meeting application uses/needs a bot anyways, that's of course still the preferred way 😉.

It's been 4 months since I figured it out. I never got around to blog about it, and I only briefly mentioned it in my Meeting Bingo App session at Commsverse. Sorry to those who needed this sooner!
Thanks to Vardhaman Deshpande for asking this exact question on an internal Microsoft forum, it triggered me to finally write it down.
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Yannick Reekmans.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.