Nous allons parler dans cet article de l’intégration des API Microsoft dans une application Web. Commençons d’abord par une mise en contexte :
Microsoft 365 est maintenant présent dans la majorité des entreprises, le télétravail tend à se démocratiser de plus en plus avec le contexte actuel, et Teams est de plus en plus utilisé. En effet, partager de l’information et chercher à améliorer nos manières de communiquer sont devenus de véritables enjeux.
Certains grands groupes développent ainsi des portails clients (B2B ou B2C) pour répondre à ces problématiques. Il s’agit là de mettre à disposition des clients diverses informations et services de manière centralisée sur un même portail.
La question qui s’est posée dans le cadre de notre mission est donc la suivante : comment pourrait-on faciliter les communications entres les clients de l’entreprise et leurs contacts commerciaux, que ce soit par chat, audio, vidéo ou bien l’organisation de meetings, le tout depuis ce portail ?
→ Et bien Microsoft met à disposition des outils répondant à ces besoins (API Microsoft Graph, deeplinks…)
Notre objectif a donc été de réaliser un POC pour tester ces API, voir ce qu’il était possible de faire, de ne pas faire, en trouver les limites, etc. Pour ensuite éventuellement transmettre ce qu’on aura appris à d’autres équipes.
Tout d’abord, qu’est-ce que Microsoft Graph ? “Microsoft Graph is the gateway to data and intelligence in Microsoft 365. It provides a unified programmability model that you can use to access the tremendous amount of data in Microsoft 365, Windows 10, and Enterprise Mobility + Security. Use the wealth of data in Microsoft Graph to build apps for organizations and consumers that interact with millions of users." (source)
Avant de pouvoir utiliser les API Microsoft Graph, il va falloir quelques prérequis.
Commençons par la notion de tenant, qui en fait représente une organisation dans Office 365, par exemple Talan. Il sera nécessaire d’avoir accès au compte admin de notre tenant, ou bien de travailler avec les personnes qui y ont accès.
Dans le cadre de notre POC, on nous a mis à disposition un tenant de test (avec de faux utilisateurs, de faux groupes, etc.) afin de faciliter nos recherches.
L’étape suivante a été d’enregistrer une nouvelle application dans le portail azure, afin d’être capable d’utiliser les API Microsoft.
→ Microsoft fournit un Quick Start pour configurer l’environnement de développement et ainsi lancer rapidement les développements dans le language que l’on souhaite. Dans notre cas, en Node.js.
A l’issu de ces étapes, nous avons un ID et un secret pour notre application, qu’il faudra renseigner dans les variables d’environnement.
Note : pour plus d’informations sur l’enregistrement d’applications dans le portail Azure, voici le lien !
Afin d’utiliser les API Microsoft Graph, il faut disposer d’un authentication token
en s’authentifiant en tant qu’utilisateur ou en tant que service.
Note : Microsoft Graph utilise l’authentification standard OIDC / OAuth2
Voici un exemple de requête de demande de token pour obtenir l’accès sans utilisateur :
POST: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=535fb089-9ff3-47b6...
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0Y...
&grant_type=client_credentials
Les paramètres passés dans le body de la requête client_id & client_secret sont les App ID et secret définis lors de l’enregistrement de l’application dans le portail azure.
Pour le paramètre scope : “La valeur transmise pour le paramètre scope dans cette demande doit être l’identificateur (URI de l’ID d’application) de la ressource souhaitée, avec le suffixe .default. Pour Microsoft Graph, la valeur est https://graph.microsoft.com/.default
. Cette valeur informe le point de terminaison de la Plateforme d’identités Microsoft que parmi toutes les autorisations que vous avez configurées pour votre application, un jeton doit être généré pour celles associées à la ressource que vous souhaitez utiliser." (https://docs.microsoft.com/fr-fr/graph/auth-v2-service)
Et enfin le paramètre grant_type doit prendre la valeur client_credentials
lorsqu’il s’agit d’une authentification en tant que service.
Voici donc le token que nous recevons en réponse à la requête:
{
"token_type": "Bearer",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1Ni..."
}
Pour résumer les 2 manières de s’authentifier:
Le scope d’utilisation des API Microsoft Graph dans l’application est régulé par l’administrateur via le portail azure, où il va devoir donner son consentement, lorsque cela est nécessaire, afin d’utiliser tel ou tel endpoint, et ce quelque soit l’authentification.
On pourra ainsi observer des différences de privilèges selon si la requête est au nom d’un utilisateur ou en tant que service.
Les permissions relatives à chaque endpoint de l’API sont décrites dans la documentation fournie par Microsoft. On y retrouve donc plusieurs types de permissions (déléguées et application). En voici un exemple sur les endpoints de lecture / écriture du calendrier :
Une fois toutes ces notions de tenant, d’authentification, de permissions comprises, il est relativement simple d’utiliser les API Microsoft Graph. De plus, Microsoft fournit une documentation claire et complète, ainsi qu’un set de requêtes Postman pour s’y familiariser (voici le lien).
Maintenant que nous avons vu comment utiliser les API Microsoft Graph, nous allons pouvoir parler du travail que nous avons réalisé dans le cadre du POC.
Pour reprendre la problématique du projet, que mettent concrètement à disposition les API Microsoft Graph pour faciliter les communications ? Y a t-il des endpoints de lecture / écriture de messagerie ? Y a t-il d’autres solutions ? Que recommande Microsoft pour ces cas d’utilisation ?
C’est ce à quoi nous allons tenter de répondre.
Pour commencer, nous avons fait quelques recherches sur la communication par chat et voici ce que nous en avons conclu :
→ Nous avons été confrontés à beaucoup de freins, que ce soit par la faisabilité, la pertinence ou la complexité des solutions.
Comment alors faire plus simplement ?
→ Azure Communication Services
Suite à la discussion que nous avons eue avec les équipes Microsoft Teams, nous avons été redirigés vers cette solution qui n’allait pas tarder à être lancée (à l’époque en tout cas) et qui répondrait à nos besoins en matière de communication. Cela étant, nous n’avons pas creusé l’idée plus que ça, bien qu’elle avait l’air assez intéressante.
Les équipes Microsoft Teams nous ont ensuite expliqué que leur vision de l’utilisation des services qu’ils proposent était différente de la nôtre. En effet, leur vision s’axe plus sur l’intégration d’applications externes dans l’environnement Teams que l’utilisation des API qu’ils mettent à disposition dans des applications externes.
Les deeplinks sont des liens intelligents capables de rediriger vers une url spécifique, inaccessible via un lien classique. Ce qui est le cas pour les urls de conversation Teams.
La structure des deeplinks vers une conversation est la suivante :https://teams.microsoft.com/l/call/0/0?users=<user1>,<user2>
. Elle nécessite donc uniquement les identifiants (emails) des utilisateurs concernés.
Cette solution nécessite effectivement que le client ait un compte Teams, et que nous en connaissions l’email.
De plus, selon la configuration du tenant et les restrictions d’accès que cela peut engendrer, il est possible que des utilisateurs d’un certain tenant ne puissent pas discuter avec des utilisateurs Teams d’un tenant externe au leur. Une solution existe : inviter des utilisateurs externes au tenant dans son tenant : ils auront alors un statut guest
, impliquant des restrictions sur l’utilisation de Teams, mais permettant de discuter avec les utilisateurs du tenant.
Après avoir accepté les conditions, le client pourra donc échanger avec son contact via l’interface Teams.
Nous avons finalement choisi l’utilisation des deeplinks, de par leur facilité d’utilisation et par la solution qu’ils apportent à notre besoin.
Cependant, nous avons vu là uniquement les solutions d’échanges instantanés. Mais les API Microsoft Graph permmettent aussi la planification de meetings, autrement dit la lecture / écriture dans les agendas des collaborateurs.
Nous avons découpé ce cas d’utilisation en 3 parties :
En voici la requête ainsi que la réponse :
POST https://graph.microsoft.com/v1.0/me/calendar/getSchedule
Prefer: outlook.timezone="Pacific Standard Time"
Content-Type: application/json
{
"schedules": ["adelev@contoso.onmicrosoft.com"],
"startTime": {
"dateTime": "2021-06-15T09:00:00",
"timeZone": "Pacific Standard Time"
},
"endTime": {
"dateTime": "2021-06-15T18:00:00",
"timeZone": "Pacific Standard Time"
},
"availabilityViewInterval": 60
}
HTTP/1.1 200 OK
Content-type: application/json
{
"value": [
{
"scheduleId": "adelev@contoso.onmicrosoft.com",
"availabilityView": "000220000",
"scheduleItems": [...],
"workingHours": {
"daysOfWeek": [...],
"startTime": "08:00:00.0000000",
"endTime": "17:00:00.0000000",
"timeZone": {
"name": "Pacific Standard Time"
}
}
},
]
}
Les éléments intéressants de la réponse à cette requête sont :
C’est donc ce dernier champs que l’on peut exploiter pour organiser des rendez-vous dans les créneaux disponibles du contact.
En voici la requête ainsi que la réponse :
POST https://graph.microsoft.com/v1.0/me/events
Prefer: outlook.timezone="Pacific Standard Time"
Content-type: application/json
{
"subject": "Let's go for lunch",
"body": {
"contentType": "HTML",
"content": "Does noon work for you?"
},
"start": {...},
"end": {...},
"location":{...},
"attendees": [...],
"allowNewTimeProposals": true,
"isOnlineMeeting": true,
"onlineMeetingProvider": "teamsForBusiness"
}
Comme on peut le voir, plusieurs champs sont à renseigner pour créer la réunion.
Mais ce sont les 2 champs isOnlineMeeting et onlineMeetingProvider qui vont permettre de créer une réunion Teams en ligne (si onlineMeetingProvider
vaut teamsForBusiness
) associée à la réunion et en générer le lien en réponse.
HTTP/1.1 201 Created
Content-type: application/json
{
"subject":"Let's go brunch",
"bodyPreview":"Does noon work for you?",
"webLink":"https://outlook.office365.com/...",
"isOnlineMeeting": true,
"onlineMeetingProvider": "teamsForBusiness",
"body":{...},
"start":{...},
"end":{...},
"attendees":[...],
"organizer":{
"emailAddress":{
"name":"Dana Swope",
"address":"danas@contoso.onmicrosoft.com"
}
},
"onlineMeeting": {
"joinUrl": "https://teams.microsoft.com/l/meetup-join/...",
"conferenceId": "conferenceId",
"tollNumber": "tollNumber"
}
}
Nous pouvons voir le champs onlineMeeting en réponse, qui fournit une url pour rejoindre le meeting ainsi que les informations nécessaires pour le rejoindre par téléphone.
Cette requête renvoit en réponse plus ou moins les mêmes informations que la réponse à la création de meeting, dont le lien vers la réunion Teams s’il s’agit d’une réunion en ligne, et toutes les informations dont on pourrait avoir besoin.
Ces fonctionnalités sont faciles à exploiter et peuvent apporter une vraie valeur à l’application.
Seulement, utiliser les API Teams dans notre application n’est pas le seul moyen d’utiliser les outils Microsoft. Il est également possible d’exposer notre application dans l’application Teams.
Une solution très intéressante est donc de créer une application et de l’intégrer dans l’environnement Teams. Il existe plusieurs types d’application que l’on peut ajouter : des bots, des webhooks, des outils de messagerie et des contenus web intégrés dans des onglets de Teams, comme le montre le schéma ci-dessous :
Pour notre POC, nous avons créé une application web intégrée dans un onglet de Teams en suivant ce tutoriel.
L’application aura besoin entre autres d’un fichier manifest.json pour la décrire et indiquer à Teams où est exposée l’application (voir le champs staticTabs
ci-dessous), ainsi qu’un grand nombre d’autres informations.
Voici une partie du manifest à fournir :
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.8/MicrosoftTeams.schema.json",
"manifestVersion": "1.8",
"id": "{{APPLICATION_ID}}",
"version": "{{VERSION}}",
"packageName": "{{PACKAGE_NAME}}",
"developer": {
"name": "<app_name>",
"websiteUrl": "https://{{HOSTNAME}}",
"privacyUrl": "https://{{HOSTNAME}}/privacy.html",
"termsOfUseUrl": "https://{{HOSTNAME}}/tou.html"
},
"staticTabs": [
{
"entityId": "<my_id>",
"name": "<display_name>",
"contentUrl": "https://{{HOSTNAME}}/<my_tab>/",
"scopes": [
"personal"
]
}
]
}
Une fois que tout est prêt, et afin de permettre aux développeurs de tester leur application, il va falloir autoriser le chargement d’une application locale dans Teams. Seul un administrateur peut activer cette option. Il sera alors possible d’ajouter l’application en tant qu’utilisateur dans Teams, afin de faire profiter à tous les collaborateurs de la nouvelle application !
Il est maintenant temps de faire un bilan de tout ce travail :