Integrando Node.js y Microsoft 365

Integrando Node.js y Microsoft 365

Integrar nuestras aplicaciones con otros servicios es sin duda uno de las formas más efectivas de extender la funcionalidad de las mismas y al mismo tiempo le da un valor agregado a nuestros usuarios.

Como muchas empresas, en mi empresa hacemos uso extensivo de un CRM para llevar el registro y seguimiento de nuestro portafolio de clientes. Sin embargo uno de los inconvenientes que se ha tenido por años es el hecho de que el CRM implementa su propio calendario sin opción de integrar de forma limpia con nuestros calendarios de Microsoft 365. La integración se limita a crear un calendario adicional que podemos importar a nuestro Outlook pero no deja de ser un agregado, un calendario externo. Esto despertó mi interés en explorar las opciones de integración que ofrece Microsoft 365 con aplicaciones externas y tal y como lo sospeché, existen formas muy convenientes de realizar una integración de este tipo.

Debo sin embargo hacer la salvedad que dicha integración es posible únicamente desde nuestra misma organización. Entendí que la incapacidad de todos los productos en el mercado para integrarse directamente con nuestro calendario principal y otros servicios de Microsoft 365 es debido a la misma forma en que está diseñado el servicio de Microsoft. Para hacer uso de todas las integraciones posibles es necesario tener control de nuestro portal de Azure como organización.

Vamos por pasos.

¿A quiénes va dirigido este tutorial?

Este tutorial va enfocado a quienes trabajan en un entorno de suscripción Microsoft 365 de tipo empresarial. Si bien Microsoft ofrece muchas opciones gratuitas para el usuario promedio, lo que acá vamos a describir aplica únicamente para organizaciones en algún plan pagado. Y como también existen varios niveles de suscripción, puedo confirmar que todo lo que voy a describir acá funciona con la suscripción estándar, sin necesidad de pagar los servicios adicionales de Azure.

Configuración inicial en Azure

Nuestro punto de partida será https://portal.azure.com. Previo a realizar cualquier tarea de integración debemos registrar nuestro aplicativo dentro de Azure para poder acceder a los permisos y recursos que necesitaremos. Para ello utilizamos la opción Azure Active Directory.

Una vez estamos dentro del Active Directory, buscamos siempre en la barra lateral izquierda la opción App registrations.

Finalmente seleccionamos la opción New registration para registrar un nuevo aplicativo y concederle permisos dentro de nuestra organización en Microsoft Azure. Acá debemos proveer un nombre para nuestro aplicativo, así como seleccionar la opción para el tipo de cuenta que estaremos utilizando. Para este tutorial utilizaremos la opción Single Tenant.

El parámetro Redirect URI es opcional pero usualmente pondremos aquí la URL de nuestra API o aplicativo desde donde estaremos realizando las llamadas a la API de Microsoft.

Hemos registrado nuestra aplicación para poder tener acceso a un Client ID, que es una llave única que nos permitirá realizar llamadas a la API de Microsoft. También desde aquí podemos asignar los permisos que necesitemos habilitar para que nuestro aplicativo pueda comunicarse adecuadamente con los endpoints de Microsoft con los que queremos integrarnos.

Generando un token de acceso desde Node.js

Ya hemos registrado nuestro aplicativo en Azure, ahora es momento de empezar a integrar nuestro aplicativo con Microsoft Graph. Microsoft Graph es una API que abre las puertas a una integración casi completa a todo el ecosistema de Microsoft de una manera muy conveniente con aplicativos externos. Si bien acá haremos únicamente un ejemplo sencillo de conexión de un aplicativo Node.js con el calendario de Outlook, es posible crear integraciones con OneDrive, MS Teams, Office y demás.

El primer paso para dicha conectividad empieza con la generación de un token de acceso. Debido a que se trata de una conexión entre aplicativos utilizaremos los siguientes 3 parámetros para autenticarnos en vez de utilizar credenciales de usuario: Client ID, Client Secret, Tenant ID y Resource. El Client ID lo obtenemos al registrar nuestro aplicativo en Azure tal y como lo describimos en la sección anterior. Nuestra clave secreta la generamos en el detalle de nuestro aplicativo registrado en Azure, en la sección Certificates & secrets.

Finalmente el Tenant ID lo podemos obtener directamente del Dashboard de Azure como el ID de nuestra organización:

Iniciamos por instalar el paquete curlrequest mediante el siguiente comando:

yarn add curlrequest

Con dicho paquete ya instalado armamos una petición de tipo POST de la siguiente manera:

const curl = require('curlrequest');
let opciones = {
    method: 'POST',
    url: `https://login.microsoftonline.com/${TENANT_ID}/oauth/token`,
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    data: {
        grant_type: 'client_credentials',
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET,
        resource: 'https://graph.microsoft.com/v1.0'
    }
};

curl.request(opciones, async (err, resultado) => {
    if (err) {
        // Manejo de error en la petición
    }
    
    // Acá podemos explorar la variable resultado para ver la respuesta
    let token = JSON.parse(resultado);
});

¿Qué es exactamente lo que viene en la petición de generación de un token?

El campo access_token es el que nos interesa, esta jerigonza de string es el que debemos almacenar en algún lado puesto que es la llave que debemos adjuntar a todas nuestras peticiones restantes. Veamos algunos ejemplos ya con nuestro token de acceso generado.

Crear evento en el calendario de Outlook

Puesto que acá estamos conectándonos con la API de Microsoft autenticados como un aplicativo registrado en Azure, para poder acceder a recursos de usuarios específicos es necesario conocer tanto su ID como el ID del recurso del usuario al que deseamos acceder. Con el token que ya hemos generado podemos obtener fácilmente el listado de usuarios de nuestra organización haciendo una petición GET a la URL https://graph.microsoft.com/v1.0/users. El token va como el Bearer del header de nuestra petición:

Y una vez tenemos el ID del usuario o usuarios, podemos obtener el ID de su calendario mediante una petición similar a la anterior, agregando al final de la URL el ID de usuario de la siguiente manera: https://graph.microsoft.com/v1.0/users/ID/calendar

Finalmente, el ID de nuestro calendario

Para uso continuo y confiable de todo este entorno es muy recomendable hacer una exploración inicial de los usuarios que estarán involucrados y almacenar en algúna estructura segura la información con los IDs de usuario y IDs de los recursos asociados a dichos usuarios que estaremos usando de forma continua. Acá estoy dejando los screenshots de las peticiones como una ayuda visual pero en la práctica esta información es muchísimo más conveniente tenerla ya previamente identificada.

Y finalmente, ya podemos hacer un método en Node.js que nos permita crear un evento en el calendario de un usuario:

const axios = require('axios');
const cliente = axios.create({ baseURL: 'https://graph.microsoft.com/v1.0' });

let opciones = {
    method: 'POST',
    url: `/users/${ID_USUARIO}/calendars/${ID_CALENDARIO}/events`,
    header: {
        Authorization: `Bearer ${TOKEN}`
    },
    data: {
        subject: 'Prueba de integración Node.js / MS365',
        body: {
            'contentType': 'HTML',
            'content': 'Contenido del evento'
        },
        start: {
            'dateTime': '2021-03-20T00:00:00',
            'timeZone': 'Eastern Standard Time'
        },
        end: {
            'dateTime': '2021-03-21T00:00:00',
            'timeZone': 'Eastern Standard Time'
        },
        isAllDay: true,
        showAs: 'free'
    }
};

cliente(opciones)
.then(respuesta => {
    // Procesamos la respuesta
})
.catch(error => {
    // Procesamos el error
});

Por practicidad estoy utilizando Insomnia como cliente REST para demostrar el resultado de estas peticiones. Si evaluamos la respuesta de dicha petición en la consola de nuestro aplicativo veremos algo igual a esto:

Y el resultado de tanto trabajo:

Las puertas abiertas al ecosistema de Microsoft

Si bien acá nos centramos únicamente en crear un evento en un calendario en una cuenta de usuario que pertenece a una organización con una suscripción de Microsoft 365, las posibilidades de integración para dicho ecosistema son enormes. Una vez dominamos la generación de tokens de acceso y contamos con el diccionario de usuarios y recursos asociados a estos usuarios, podemos integrar nuestros aplicativos de forma muy conveniente y efectiva con un ecosistema robusto y ya conocido por nuestros usuarios como lo es Microsoft.