Microsoft Graph es la puerta de entrada para interactuar programáticamente con Microsoft 365. Entre sus capacidades, podemos acceder a la información de reuniones online en Teams: detalles, enlaces, organizadores, asistentes, grabaciones y más.
En este artículo vamos a ver cómo usar el endpoint GET /onlineMeetings para obtener la información de una reunión específica, qué permisos son necesarios, ejemplos prácticos y algunas limitaciones que conviene conocer antes de empezar.
🏃♂️ TL;DR (para los ansiosos)
-
Registrá una app en Azure AD y otorgale permisos OnlineMeetings.Artifact.Read.All.
-
Obtené un token de acceso (delegado o de aplicación).
-
Hacé una llamada GET a https://graph.microsoft.com/v1.0/{userId}/onlineMeetings/{meetingId}/attendanceReport
-
Recibí los datos en formato JSON con información de la reunión.
Hacé una llamada GET a https://graph.microsoft.com/v1.0/{userId}/onlineMeetings/{meetingId}/attendanceReport/{reportId}/attendanceRecords
Recibí los datos en formato JSON. Vas a tener que iterar en el modelo de datos porque la información no está 100% aplanada en un valor.
En este artículo te voy a explicar paso a paso como obtener la información relacionada a una llamada de teams y algunas consideraciones a tener en cuenta:
1- Registrar una App en Microsoft entra ID
En Microsoft Entra ID necesitas registrar una nueva aplicación. No importa el nombre. Lo importante es, luego, asignarle los permisos de api necesarios. En el ejemplo que vamos a ver en este artículo, le vamos a conceder permisos de acceso a la api de Graph como aplicación y no como servicio delegado.
💡 Diferencias entre acceso delegado o app-only:
- Delegado: la app actúa en nombre de un usuario y solo accede a lo que ese usuario tiene permitido.
- App-only: la app actúa por sí sola, con permisos propios, sin intervención de un usuario.
Para darle los permisos como aplicación, debes ir a "Permisos de Api" > agregar > Microsoft Graph > como aplicación
Luego, buscar en los permisos lo siguiente
OnlineMeetings.Artifact.ReadAll
Este es el mínimo acceso requerido para leer los reportes de asistencias de las reuniones.
⚠️ IMPORTANTE: Asegurarse de que el Global Admin acepte el permiso luego de otorgarlo
Asi es como debería verse luego de "Conceder por admin"
Este ultimo paso es importante, de lo contrario no va a funcionar. Además de registrar la aplicación y concederle los permisos. El administrador debe crear un secreto (Secret) para la aplicación. Esto es muy importante. Y luego de crear el secreto, debe guardarse en un lugar seguro.
2- Crear una policy en el tenant para esta nueva aplicación (New-CsApplicationAccessPolicy)
Registrar la aplicación y concederle los permisos a la api de Graph son pasos fundamentales. Pero esto no va a funcionar si el administrador no crea una policy específica para esta nueva aplicación.
New-CsApplicationAccessPolicy es un cmdlet de PowerShell que se usa en Microsoft Teams para crear una nueva política de acceso a aplicaciones. Esta política define qué aplicaciones (identificadas por sus ID de cliente) están autorizadas a acceder a reuniones en línea o eventos virtuales en nombre de un usuario específico.
A continuación, estos son los comandos necesarios para crear la policy que deben ser ejecutados en una terminal logueado como administrador:
New-CsApplicationAccessPolicy -Identity [Nombre para tu nueva policy] -AppIds [Id de tu aplicación / GUID] -Description [Una descripción general del permiso otorgado. Por ejemplo: Acceder a las reuniones de Teams]
Luego de haber ejecutado exitósamente dicho comando, ejecutar el siguiente otro:
Grant-CsApplicationAccessPolicy -PolicyName [Nombre de la policy creada en el paso anterior] -Global
Ejemplo de una policy:
New-CsApplicationAccessPolicy -Identity Policy-Para-App-Eze -AppIds "ee5fcec2-XXXX-4zl7-9gdv-XXXc55aaXXXX" -Description "Permitir a la appA App-Eze poder acceder a la información de las reuniones de teams."
Grant-CsApplicationAccessPolicy -PolicyName "Policy-Para-App-Eze" -Global
3- Probar la Graph Api
Luego de la configuración inicial, vamos a probar si esto funciona. Para ello, vamos a probar que nuestra aplicación puede acceder a los artefactos de teams. Para ello los pasos son:
- Obtener token
- Obtener el AttendanceReport basado en un ID de meeting
- Obtener el AttendanceRecords basado en el Reporte obtenido en el paso anterior
Obtener token 🔑
Como paso inicial, siempre es necesario obtener un token ya que es un parámetro obligatorio en cualquiera de los otros métodos que queramos consumir.
Tipo de llamada: Post
URI: https://login.microsoftonline.com/
{Tenant ID}/oauth2/v2.0/token
Body: grant_type=client_credentials&
client_id={Id de la aplicación registrada}&
client_secret={Secret generado para la aplicación}&
scope=https://graph.microsoft.com/.default
⚠️
IMPORTANTE: El scope es muy importante porque define en el token el acceso a los recursos necesarios, al margen de que la aplicación ya tenga concedido los accesos.
Si esto funcionó correctamente, como resultado podemos ver que obtenemos un "access_token". Podemos validar el contenido del mismo desde esta página:
https://jwt.io/. Copiamos y pegamos el JWT en la misma y podemos ver los valores que obtuvimos.
Obtener el AttendanceReport basado en un ID de meeting 📚
En este paso me quiero deterner a explicar algo que puede ser algo "tricky" con respecto al ID de la meeeting.
La URL de una reunión de Teams tiene esta forma: https://teams.microsoft.com/l/meetup-join/19%3ameeting_APG1NGQwOKEtYjg0OS00MTNoLWE1MjktNGSjVDZkYTYiOWE5%40thread.v2/0?...
El ID de la meeting se compone de: Owner.Id_Segmento de la URL.
Pasando en limpio:
El segmento de la URL de la meeting que es parte del ID es el siguiente: https://teams.microsoft.com/l/meetup-join/19%3ameeting_APG1NGQwOKEtYjg0OS00MTNoLWE1MjktNGSjVDZkYTYiOWE5%40thread.v2/0?...
Suponiendo que el owner de la meeting es mi usuario y mi Microsoft Entra ID obect id es: f3a9c2d0-7b4e-4e8a-9c6f-1d2a5b8e3c9f (por poner un ejemplo ficticio).
Entonces, el ID de la meeting sería: f3a9c2d0-7b4e-4e8a-9c6f-1d2a5b8e3c9f_9%3ameeting_APG1NGQwOKEtYjg0OS00MTNoLWE1MjktNGSjVDZkYTYiOWE5%40thread.v2
Es importante mencionar que, la URL de la meeting está en formato URL Encoded eso debe mantenerse y no se debe convertir a string por mas que parezca tentador.
Ahora si, luego de establecer el ID de la meeting y de conocer el ID del owner de la meeting, podemos obtener los reportes de asistencia de dicha meeting:
Tipo de llamada: GetURI: https://graph.microsoft.com/v1.0/users/{
ID del Owner de la meeting}/onlineMeetings/
{ID de la meeting}/attendanceReports
Siguiendo el ejemplo:
GET https://graph.microsoft.com/v1.0/users/f3a9c2d0-7b4e-4e8a-9c6f-1d2a5b8e3c9f/onlineMeetings/f3a9c2d0-7b4e-4e8a-9c6f-1d2a5b8e3c9f_9%3ameeting_APG1NGQwOKEtYjg0OS00MTNoLWE1MjktNGSjVDZkYTYiOWE5%40thread.v2/attendanceReports
Header:
- Authorization: Bearer {Token obtenido en el paso anterior}
Si todos los valores fueron configurados correctamente, deberíamos obtener una respuesta como figura a continuación:
Vamos a obtener una colección de reportes asociados a la meeting. Y, ¿Por qué una colección de reportes y no uno solo?. Bueno, la respuesta simple es que Microsoft genera varias "fotos" (snapshots) de las reuniones virtuales dependendiendo distintos eventos:
- Cada vez que se inicia la reunión
- Si se trata de una reunión recurrente
- Si alguien inició la reunión luego de haber culminado
Cada una de estas situaciones genera un reporte nuevo y no se suma al existente. Por default se puede considerar el último reporte como el mas nuevo. O bien, se puede procesar esta información e ir un nivel mas allá recorriendo los distintos reportes, iterando entre todos los invitados que el reporte contiene y agregar la información en un único reporte. Pero eso ya está por fuera de esta demostración.
Obtener el AttendanceRecords basado en el Reporte obtenido en el paso anterior 🧑💻
Los Attendance Records son la instancia de cada asistente en cada uno de los reportes generados en la reunión. Esta instancia contiene información como por ejemplo:
- Duración total en la reunión (en minutos)
- Una colección de interacciones que contiene cada vez que se sumó y se bajó de la llamada.
Es decir, con este método puedo obtener información pormenorizada de la asistencia de la persona en la llamada. Veamos cómo se consume este método:
Tipo de llamada: Get
URI: https://graph.microsoft.com/v1.0/users/
{ID del Owner de la meeting}/onlineMeetings/
{ID de la meeting}/attendanceReports/
{ID del reporte obtenido en el paso anterior}/attendanceRecords
Siguiendo el ejemplo:
GET https://graph.microsoft.com/v1.0/users/f3a9c2d0-7b4e-4e8a-9c6f-1d2a5b8e3c9f/onlineMeetings/f3a9c2d0-7b4e-4e8a-9c6f-1d2a5b8e3c9f_9%3ameeting_APG1NGQwOKEtYjg0OS00MTNoLWE1MjktNGSjVDZkYTYiOWE5%40thread.v2/attendanceReports/c3a9f2d0-2a8v-3z5s-2g9j-1d2a5b8e3p6a
Header:
- Authorization: Bearer {Token}
Si todos los valores fueron configurados correctamente, deberíamos obtener una respuesta como figura a continuación:
Como se puede ver, se obtiene un registro por cada asistente a la meet, el email (en caso de haber ingresado anónimamente ese valor será null), y luego una colección de "Intervalos" donde el asistente ingresó a la reunión y luego se bajó. Si eso ocurre mas de una vez durante la duración de la llamada, veremos mas de un registro de "Intervalos" con la duración parcial de cada una de ellas.
Resumen:
- Registrar aplicación, darle acceso a los artefactos de las meetings y crear una policy específica.
- Obtener token
- Establecer ID de la meeting y el ID del owner de la meeting
- Get attendaceReport
- Get attendanceRecords basado en el ID de un Report
Comentarios
Publicar un comentario