Intégration Microsoft Teams¶
Une intégration Microsoft Teams peut être ajoutée à votre installation de Drovio Server. Elle permet de démarrer et de rejoindre des sessions Drovio depuis Microsoft Teams, par la zone de rédaction ou par commande du bot. Elle se présente sous la forme d'un fichier JAR que vous ajoutez à Drovio Server puis configurez. Vous devrez créer un Azure Bot et une application dans Microsoft Entra ID.
Déclarer le bot dans Azure¶
La déclaration du bot peut se faire depuis le portail Azure, l'Azure CLI ou Terraform. Les trois aboutissent au même résultat : une inscription d'application, un secret client, et une ressource Azure Bot dont le canal Teams est activé.
Créer la ressource Azure Bot¶
Dans le portail Azure, choisissez Create a resource, cherchez Azure Bot, puis Create.
| Champ | Valeur |
|---|---|
| Bot handle | Un nom unique, par exemple Drovio |
| Subscription | L'abonnement à facturer |
| Resource group | Un nouveau groupe, par exemple Drovio |
| Pricing tier | Free (F0) |
| Type of app | Single Tenant |
| Creation type | Create new Microsoft App ID |
Faire pointer le bot vers votre serveur¶
Ouvrez la ressource, puis Settings et Configuration. Renseignez le Messaging endpoint avec :
https://<your server>/msteams/api/messages
Point d'accès public
La route /msteams/api/messages doit être joignable en HTTPS depuis les
serveurs de Microsoft. Si votre Drovio Server est derrière un pare-feu ou
un proxy inverse, veillez à ouvrir ce chemin sur Internet.
Appliquez, puis allez dans Settings et Channels, et ajoutez Microsoft Teams.
Relever les trois valeurs dont le plugin a besoin¶
Toujours sous Settings et Configuration, cliquez sur Manage Password à côté du Microsoft App ID. Cela ouvre l'inscription d'application dans Microsoft Entra ID.
Dans le volet Overview, relevez :
| Valeur dans Azure | Utilisée comme |
|---|---|
| Application (client) ID | client_id |
| Directory (tenant) ID | tenant_id |
Rendez-vous ensuite dans Certificates & secrets, onglet Client
secrets, et cliquez sur New client secret. Copiez aussitôt la colonne
Value : elle ne s'affiche qu'une fois, et il faut générer un nouveau secret
si vous la manquez. C'est le client_secret.
Exposer l'API et accorder l'accès à Graph¶
Sous Expose an API, cliquez sur Set à côté de l'Application ID URI, puis sur Save.
Sous API permissions, ajoutez une permission sur Microsoft Graph, choisissez Application permissions, et sélectionnez les deux permissions listées plus bas. Accordez-leur le consentement administrateur.
Déclarer l'URI de redirection¶
Utile seulement si vous comptez publier l'application depuis le panneau d'administration plutôt que de la déposer vous-même.
Sous Authentication, Add a platform, choisissez Web, et ajoutez l'URI de redirection :
https://<your server>/admin/access/msteams/publish/callback
Sans elle, la publication échoue sur AADSTS500113: No reply address is
registered for the application. Si l'accès à l'administration est restreint
par adresse IP sur ce serveur, l'adresse depuis laquelle le navigateur revient
doit également être autorisée, faute de quoi le retour est refusé par un
403.
Remplacez <your server> par l'URL publique de votre instance, et choisissez
votre propre groupe de ressources et votre région.
Ici l'application précède le bot
Le portail crée l'inscription d'application et le bot dans un seul
formulaire. La CLI ne le peut pas : az bot create exige l'identifiant
d'application comme argument obligatoire, l'inscription doit donc exister
d'abord. Le résultat final est identique.
Fixez d'abord les cinq noms, le reste des commandes pourra ensuite être collé tel quel :
| Variable | Ce qu'elle nomme |
|---|---|
SERVER |
L'URL publique de votre Drovio Server |
APP_NAME |
Le nom d'affichage de l'inscription d'application |
BOT_NAME |
La ressource bot, qui doit être libre à l'échelle d'Azure |
GROUP |
Le groupe de ressources qui porte le bot |
LOCATION |
La région du groupe de ressources |
Créez l'inscription d'application, son service principal, son Application ID URI et son secret client :
APP_ID=$(az ad app create \
--display-name "$APP_NAME" \
--sign-in-audience AzureADMyOrg \
--web-redirect-uris "$SERVER/admin/access/msteams/publish/callback" \
--query appId --output tsv)
TENANT_ID=$(az account show --query tenantId --output tsv)
az ad sp create --id "$APP_ID"
az ad app update --id "$APP_ID" --identifier-uris "api://$APP_ID"
CLIENT_SECRET=$(az ad app credential reset --id "$APP_ID" --append \
--display-name drovio-server --query password --output tsv)
La ligne az ad sp create correspond à l'étape que le portail vous masque.
Elle crée le service principal auquel les permissions sont accordées, et sans
lui le consentement administrateur échoue. L'URI d'identification est ce que
vise le manifest Teams. Le secret client ne s'affiche qu'une fois, veillez à
conserver ce que capture la dernière commande.
Demandez les deux permissions Graph, résolues par leur nom afin qu'aucun identifiant n'ait à être recopié. Le consentement viendra plus tard, à la fin de cet onglet :
GRAPH_ID=00000003-0000-0000-c000-000000000000
USER_READ=$(az ad sp show --id $GRAPH_ID \
--query "appRoles[?value=='User.Read.All'].id | [0]" --output tsv)
CATALOG_READ=$(az ad sp show --id $GRAPH_ID \
--query "appRoles[?value=='AppCatalog.Read.All'].id | [0]" --output tsv)
az ad app permission add --id "$APP_ID" --api $GRAPH_ID \
--api-permissions "$USER_READ=Role" "$CATALOG_READ=Role"
Cette commande affiche un message vous invitant à lancer
az ad app permission grant : ignorez-le, cette commande concerne les
permissions déléguées, alors que ces deux-ci sont des permissions
d'application.
Puis la ressource bot elle-même, et son canal Teams :
az group create --name "$GROUP" --location "$LOCATION"
az bot create \
--name "$BOT_NAME" \
--resource-group "$GROUP" \
--app-type SingleTenant \
--appid "$APP_ID" \
--tenant-id "$TENANT_ID" \
--endpoint "$SERVER/msteams/api/messages" \
--sku F0
az bot msteams create --name "$BOT_NAME" --resource-group "$GROUP"
echo "client_id $APP_ID (Application ID)"
echo "tenant_id $TENANT_ID (Directory ID)"
echo "client_secret $CLIENT_SECRET"
Accorder le consentement en dernier¶
Le consentement est la dernière étape, et il doit être vérifié. Microsoft Entra ID a besoin que l'inscription d'application, son service principal et les permissions demandées se soient propagés avant de pouvoir agir dessus. Lancée trop tôt, la commande ne signale aucune erreur et n'accorde rien :
az ad app permission admin-consent --id "$APP_ID"
SP_ID=$(az ad sp show --id "$APP_ID" --query id --output tsv)
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/servicePrincipals/$SP_ID/appRoleAssignments" \
--query "length(value)" --output tsv
La dernière commande doit afficher 2. Si elle affiche 0, attendez une
minute et rejouez les deux. Accorder le consentement demande le rôle
Privileged Role Administrator ou Global Administrator.
Le portail est le recours fiable
Si le compte reste à 0, ouvrez l'inscription d'application dans
Microsoft Entra ID, allez dans API permissions et cliquez sur Grant
admin consent for <votre tenant>. La colonne Status affiche alors
Granted, et la commande ci-dessus affiche 2.
La même mise en place, pour une infrastructure déjà décrite sous forme de
code. Elle réclame le fournisseur azuread en version 3 ou supérieure, où
sont apparues les petites ressources d'application composables. Les fichiers
ci-dessous forment un seul module racine.
resource "azuread_application_registration" "drovio" {
display_name = "Drovio"
sign_in_audience = "AzureADMyOrg"
}
resource "azuread_application_identifier_uri" "drovio" {
application_id = azuread_application_registration.drovio.id
identifier_uri = "api://${azuread_application_registration.drovio.client_id}"
}
resource "azuread_application_redirect_uris" "drovio" {
application_id = azuread_application_registration.drovio.id
type = "Web"
redirect_uris = ["${var.server_url}/admin/access/msteams/publish/callback"]
}
resource "azuread_application_api_access" "drovio" {
application_id = azuread_application_registration.drovio.id
api_client_id = data.azuread_application_published_app_ids.well_known.result["MicrosoftGraph"]
role_ids = [
data.azuread_service_principal.msgraph.app_role_ids["User.Read.All"],
data.azuread_service_principal.msgraph.app_role_ids["AppCatalog.Read.All"],
]
}
resource "azuread_application_password" "drovio" {
application_id = azuread_application_registration.drovio.id
}
resource "azuread_service_principal" "drovio" {
client_id = azuread_application_registration.drovio.client_id
}
# The two assignments below are the admin consent
resource "azuread_app_role_assignment" "user_read_all" {
app_role_id = data.azuread_service_principal.msgraph.app_role_ids["User.Read.All"]
principal_object_id = azuread_service_principal.drovio.object_id
resource_object_id = data.azuread_service_principal.msgraph.object_id
}
resource "azuread_app_role_assignment" "app_catalog_read_all" {
app_role_id = data.azuread_service_principal.msgraph.app_role_ids["AppCatalog.Read.All"]
principal_object_id = azuread_service_principal.drovio.object_id
resource_object_id = data.azuread_service_principal.msgraph.object_id
}
resource "azurerm_resource_group" "drovio" {
name = "Drovio"
location = "West Europe"
}
resource "azurerm_bot_service_azure_bot" "drovio" {
name = "Drovio"
resource_group_name = azurerm_resource_group.drovio.name
location = "global"
sku = "F0"
microsoft_app_id = azuread_application_registration.drovio.client_id
microsoft_app_type = "SingleTenant"
microsoft_app_tenant_id = data.azuread_client_config.current.tenant_id
endpoint = "${var.server_url}/msteams/api/messages"
}
resource "azurerm_bot_channel_ms_teams" "drovio" {
bot_name = azurerm_bot_service_azure_bot.drovio.name
location = azurerm_bot_service_azure_bot.drovio.location
resource_group_name = azurerm_resource_group.drovio.name
}
output "client_id" {
description = "Application (client) ID, for the plugin configuration"
value = azuread_application_registration.drovio.client_id
}
output "tenant_id" {
description = "Directory (tenant) ID, for the plugin configuration"
value = data.azuread_client_config.current.tenant_id
}
output "client_secret" {
description = "Client secret, for the plugin configuration"
value = azuread_application_password.drovio.value
sensitive = true
}
Trois choses à savoir avant d'appliquer :
- Le secret client atterrit dans l'état Terraform, qui détient alors un
identifiant vers votre tenant et doit être protégé comme tel. Retirez la
ressource
azuread_application_passwordet créez le secret à la main si cela n'est pas acceptable là où vous conservez votre état. - Les deux ressources
azuread_app_role_assignmentfont ce que réalise Grant admin consent dans le portail. L'identité qui exécute Terraform doit disposer du rôle Privileged Role Administrator ou Global Administrator pour les créer. azurerm_bot_service_azure_botest la ressource Azure Bot. N'utilisez pas l'ancienneazurerm_bot_channels_registration, qui décrit la génération précédente de déclaration de bot.
Un bot mono-tenant sert votre propre tenant, ce dont un déploiement autohébergé a besoin. La distribution multi-tenant vers les tenants de vos clients est un autre sujet, qui passe par AppSource.
Quelle que soit la méthode retenue, le nom du bot compte entre 4 et 42 caractères
et doit être libre à l'échelle d'Azure, si bien que Drovio seul peut être déjà
pris. La ressource bot elle-même vit à l'emplacement global, quelle que soit la
région de son groupe de ressources.
Le secret client expire
Le même secret authentifie le bot quand il répond dans Teams et le plugin quand il appelle Graph. À son expiration, l'application cesse de répondre et le panneau perd la vue du catalogue, jusqu'à ce qu'un nouveau secret soit saisi dans le panneau d'administration. Sa durée dépend de la façon dont vous l'avez créé :
| Méthode | Durée |
|---|---|
| Portail | À votre choix, 24 mois au maximum, Microsoft conseillant moins de 12 |
| Azure CLI | Un an, modifiable par --years sur az ad app credential reset |
| Terraform | Deux ans, la valeur par défaut appliquée par Microsoft Entra ID quand end_date_relative est omis |
Notez la date d'expiration quelque part et prévoyez la rotation : créez le nouveau secret d'abord, puis collez-le dans le panneau.
Free ou Standard
Le niveau Free (F0) autorise 10 000 messages par mois sur les canaux premium, ce qui suffit à la plupart des déploiements autohébergés. Passez en Standard (S1) si vous attendez des volumes supérieurs.
Permissions Graph¶
| Permission | Ce qu'elle apporte | Sans elle |
|---|---|---|
User.Read.All |
Les noms et les photos des participants | L'intégration fonctionne, les cartes n'affichent pas de photo |
AppCatalog.Read.All |
Le panneau lit le catalogue d'applications de votre organisation | Le panneau ne dit rien du catalogue, et son bouton propose de publier ou de mettre à jour sans savoir lequel |
Ce sont toutes deux des permissions d'application, et toutes deux demandent le consentement administrateur. Le plugin réclame un jeton neuf à chaque lecture du catalogue, si bien qu'un consentement accordé serveur en marche s'applique dès la lecture suivante, sans redémarrage.
La publication réclame une troisième permission, la déléguée
AppCatalog.ReadWrite.All, et elle fonctionne autrement. Elle n'est pas
déclarée sur l'inscription d'application : le panneau d'administration la
demande au moment où vous tentez de publier.
Installer le plugin¶
Copiez drovio-teams.jar dans le dossier des paquets du serveur, puis
déclarez-le dans settings.conf :
"plugin_management": {
"plugins": [
{
"classpath": "/opt/drovio-server/packages/drovio-teams.jar",
"path": "com.drovio.server.teams",
"ext": "java",
"base_address": "drovio.server.msteams"
}
]
}
La clé est plugin_management. Écrire plugin_manager donne un plugin qui ne se
charge jamais, sans qu'aucune erreur ne le signale. Le base_address vaut
drovio.server.msteams, adresse que l'application Drovio et le serveur emploient
tous deux dans leur code.
Redémarrez le serveur. Une entrée Microsoft Teams apparaît dans le panneau d'administration, et n'y apparaît que lorsque le plugin est chargé.
Pourquoi un redémarrage ici
La majeure partie de la configuration de Drovio Server s'applique à chaud,
mais les plugins ne sont chargés qu'au démarrage. Toute modification de
plugin_management, celle de ce plugin comprise, ne prend effet qu'au
redémarrage suivant.
Configurer l'intégration¶
Ouvrez l'entrée Microsoft Teams du panneau d'administration.
| Champ | D'où il vient |
|---|---|
| Status | Enabled ou Disabled |
| Application ID | Le client_id relevé dans Azure |
| Client secret | Le secret que vous avez copié |
| Tenant ID | Le tenant_id relevé dans Azure |
| Launch URI | Prérempli depuis l'URL du serveur |
| Join URI | Prérempli depuis l'URL du serveur |
L'enregistrement inscrit les valeurs dans la configuration du serveur et prend effet dès l'appel suivant, sans redémarrage. Le secret client ne s'affiche plus jamais : laisser le champ vide conserve celui qui est stocké.
Avant la 3.6.6, changer l'Application ID demandait un redémarrage
Les versions antérieures le lisaient une seule fois au démarrage du serveur.
Le bot continuait donc de vérifier les appels entrants contre l'ancienne
valeur et répondait 401 à chaque requête, en journalisant
Bot authentication failed: Invalid JWT audience.
Passer le statut à Disabled arrête le bot et les actions venant de l'application Drovio, tout en laissant ce panneau accessible pour configurer l'intégration.
Référence de configuration¶
Voici les clés de l'élément msteams de settings.conf, si vous préférez
l'éditer directement.
Le plugin écrit lui-même cet élément au premier démarrage qui n'en trouve aucun, si bien qu'un serveur peut être déployé avec le plugin puis configuré entièrement depuis le panneau.
| Clé | Défaut | Signification |
|---|---|---|
enabled |
false |
Active l'intégration. En son absence, la valeur retenue est false |
client_id |
Application (client) ID du bot | |
client_secret |
Secret client du bot | |
tenant_id |
Directory (tenant) ID. Vide, il désigne un bot multi-tenant, dont la création est abandonnée par Microsoft depuis juillet 2025 | |
launch_uri |
<url du serveur>/launch |
L'adresse vers laquelle une carte Teams envoie un utilisateur pour démarrer un appel |
join_uri |
<url du serveur>/join/app |
L'adresse vers laquelle une carte Teams envoie un utilisateur pour rejoindre un appel |
Construire et publier l'application Teams¶
L'application est une archive zip contenant le manifest et les icônes. La section App package du panneau d'administration permet de la construire.
| Champ | Remarques |
|---|---|
| Application ID | Prérempli depuis la configuration |
| Application ID URI | Prérempli avec api://<app id>. Ne le changez que si Entra ID en expose un autre |
| Version | Livrée avec le plugin, affichée à titre d'information. C'est la mise à jour du plugin qui publie une nouvelle version |
Download vous donne l'archive à déposer vous-même, depuis le centre d'administration Teams.
L'autre bouton vous connecte à Microsoft et place l'application directement dans
le catalogue de votre organisation. Son libellé suit ce que contient le
catalogue : Publish quand l'application n'y est pas, Update to x.y.z
quand il en contient une version plus ancienne, et Up to date quand il n'y a
rien à envoyer. C'est la lecture de cet état qu'apporte AppCatalog.Read.All.
Sans elle, le bouton affiche Publish or update et couvre les deux cas, ce qui
fonctionne tout aussi bien.
La publication exige un compte disposant du rôle d'administrateur Teams : tout autre compte ne peut que soumettre l'application à revue, laquelle attend ensuite une approbation dans le centre d'administration Teams. Rien de cette connexion n'est conservé : publier à nouveau reconnecte.
Le catalogue reflète les politiques de gestion d'applications du tenant, que Microsoft applique sous 24 à 48 heures après une publication. Une application publiée à l'instant peut donc ne pas encore y figurer, et le panneau peut continuer de proposer de la publier.
Autoriser l'application et la rendre facile à trouver¶
Dans le centre d'administration Teams, allez dans Teams apps puis Manage apps, cherchez Drovio, et passez son statut à Allowed.
L'application affiche la photo de profil des participants. Dans l'onglet Permissions, cliquez sur Review permissions et accordez-les.
Pour mettre l'application devant vos utilisateurs, allez dans Teams apps puis Setup policies. Modifiez la politique Global (Org-wide default), ou créez-en une et affectez-la à un groupe. Sous Pinned apps, ajoutez Drovio et ordonnez-la dans la portée Messaging extensions.
Ce qu'il faut savoir des politiques d'épinglage
- L'application s'ouvre depuis le
+de la zone de rédaction. Le client Teams actuel n'affiche plus les icônes d'extensions de message à côté de cette zone. Il n'y a donc aucune icône à épingler devant. La politique fixe l'ordre à l'intérieur du menu+, et c'est ce qui place Drovio en tête. - Un changement de politique met quelques heures à atteindre les clients, et un retour en arrière tout autant.
- Laisser User pinning désactivé supprime les épinglages que vos utilisateurs ont faits eux-mêmes.