Integrazione Microsoft Teams¶
Un'integrazione Microsoft Teams può essere aggiunta alla vostra installazione di Drovio Server. Permette di avviare e di raggiungere sessioni Drovio da Microsoft Teams, tramite la casella di scrittura o tramite un comando del bot. Si presenta sotto forma di un file JAR che aggiungete a Drovio Server e poi configurate. Dovrete creare un Azure Bot e un'applicazione in Microsoft Entra ID.
Dichiarare il bot in Azure¶
La dichiarazione del bot può avvenire dal portale Azure, dall'Azure CLI o da Terraform. I tre metodi portano allo stesso risultato: una registrazione di applicazione, un secret client e una risorsa Azure Bot con il canale Teams attivato.
Creare la risorsa Azure Bot¶
Nel portale Azure, scegliete Create a resource, cercate Azure Bot, poi Create.
| Campo | Valore |
|---|---|
| Bot handle | Un nome univoco, per esempio Drovio |
| Subscription | L'abbonamento da fatturare |
| Resource group | Un nuovo gruppo, per esempio Drovio |
| Pricing tier | Free (F0) |
| Type of app | Single Tenant |
| Creation type | Create new Microsoft App ID |
Far puntare il bot al vostro server¶
Aprite la risorsa, poi Settings e Configuration. Compilate il Messaging endpoint con:
https://<your server>/msteams/api/messages
Punto di accesso pubblico
La rotta /msteams/api/messages deve essere raggiungibile in HTTPS dai
server di Microsoft. Se il vostro Drovio Server è dietro un firewall o
un proxy inverso, fate in modo che questo percorso sia aperto su
Internet.
Applicate, poi andate in Settings e Channels, e aggiungete Microsoft Teams.
Rilevare i tre valori di cui il plugin ha bisogno¶
Sempre sotto Settings e Configuration, fate clic su Manage Password accanto al Microsoft App ID. Si apre così la registrazione di applicazione in Microsoft Entra ID.
Nel riquadro Overview, rilevate:
| Valore in Azure | Usato come |
|---|---|
| Application (client) ID | client_id |
| Directory (tenant) ID | tenant_id |
Andate poi in Certificates & secrets, scheda Client secrets, e fate
clic su New client secret. Copiate subito la colonna Value: viene
mostrata una sola volta, e occorre generare un nuovo secret se la perdete.
È il client_secret.
Esporre l'API e concedere l'accesso a Graph¶
Sotto Expose an API, fate clic su Set accanto all'Application ID URI, poi su Save.
Sotto API permissions, aggiungete un'autorizzazione su Microsoft Graph, scegliete Application permissions, e selezionate le due autorizzazioni elencate più sotto. Concedete loro il consenso amministratore.
Dichiarare l'URI di reindirizzamento¶
Utile soltanto se intendete pubblicare l'applicazione dal pannello di amministrazione anziché caricarla voi stessi.
Sotto Authentication, Add a platform, scegliete Web, e aggiungete l'URI di reindirizzamento:
https://<your server>/admin/access/msteams/publish/callback
Senza di essa, la pubblicazione fallisce con AADSTS500113: No reply address
is registered for the application. Se l'accesso all'amministrazione è
limitato per indirizzo IP su questo server, anche l'indirizzo dal quale il
browser ritorna deve essere autorizzato, altrimenti il ritorno viene
rifiutato da un 403.
Sostituite <your server> con l'URL pubblica della vostra istanza, e
scegliete il vostro gruppo di risorse e la vostra regione.
Qui l'applicazione precede il bot
Il portale crea la registrazione di applicazione e il bot in un solo
modulo. La CLI non può farlo: az bot create richiede l'identificatore
di applicazione come argomento obbligatorio, quindi la registrazione
deve esistere prima. Il risultato finale è identico.
Fissate prima i cinque nomi, il resto dei comandi potrà poi essere incollato così com'è:
| Variabile | Ciò che nomina |
|---|---|
SERVER |
L'URL pubblica del vostro Drovio Server |
APP_NAME |
Il nome visualizzato della registrazione di applicazione |
BOT_NAME |
La risorsa bot, che deve essere libera su tutta Azure |
GROUP |
Il gruppo di risorse che ospita il bot |
LOCATION |
La regione del gruppo di risorse |
Create la registrazione di applicazione, il suo service principal, il suo Application ID URI e il suo 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 riga az ad sp create corrisponde al passaggio che il portale vi
nasconde. Crea il service principal al quale sono concesse le
autorizzazioni, e senza di esso il consenso amministratore fallisce. L'URI
di identificazione è ciò a cui punta il manifest Teams. Il secret client
viene mostrato una sola volta, conservate con cura quanto cattura l'ultimo
comando.
Chiedete le due autorizzazioni Graph, risolte per nome affinché nessun identificatore debba essere ricopiato. Il consenso arriverà più tardi, alla fine di questa scheda:
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"
Questo comando mostra un messaggio che vi invita a lanciare
az ad app permission grant: ignoratelo, quel comando riguarda le
autorizzazioni delegate, mentre queste due sono autorizzazioni di
applicazione.
Poi la risorsa bot stessa, e il suo canale 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"
Concedere il consenso per ultimo¶
Il consenso è l'ultimo passaggio, e deve essere verificato. Microsoft Entra ID ha bisogno che la registrazione di applicazione, il suo service principal e le autorizzazioni richieste si siano propagati prima di poter agire su di essi. Lanciato troppo presto, il comando non segnala alcun errore e non concede nulla:
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
L'ultimo comando deve mostrare 2. Se mostra 0, aspettate un minuto e
rilanciateli entrambi. Concedere il consenso richiede il ruolo Privileged
Role Administrator o Global Administrator.
Il portale è il ripiego affidabile
Se il conteggio resta a 0, aprite la registrazione di applicazione in
Microsoft Entra ID, andate in API permissions e fate clic su Grant
admin consent for <il vostro tenant>. La colonna Status mostra
allora Granted, e il comando qui sopra mostra 2.
La stessa configurazione, per un'infrastruttura già descritta sotto forma di
codice. Richiede il provider azuread in versione 3 o superiore, dove sono
comparse le piccole risorse di applicazione componibili. I file qui sotto
formano un unico modulo radice.
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
}
Tre cose da sapere prima di applicare:
- Il secret client finisce nello stato Terraform, che detiene allora una
credenziale verso il vostro tenant e deve essere protetto come tale.
Togliete la risorsa
azuread_application_passworde create il secret a mano se ciò non è accettabile là dove conservate il vostro stato. - Le due risorse
azuread_app_role_assignmentfanno ciò che realizza Grant admin consent nel portale. L'identità che esegue Terraform deve disporre del ruolo Privileged Role Administrator o Global Administrator per crearle. azurerm_bot_service_azure_botè la risorsa Azure Bot. Non usate la vecchiaazurerm_bot_channels_registration, che descrive la generazione precedente di dichiarazione del bot.
Un bot mono-tenant serve il vostro tenant, che è ciò di cui ha bisogno una distribuzione self-hosted. La distribuzione multi-tenant verso i tenant dei vostri clienti è un altro argomento, che passa da AppSource.
Qualunque sia il metodo scelto, il nome del bot conta tra 4 e 42 caratteri e
deve essere libero su tutta Azure, tanto che Drovio da solo può essere già
preso. La risorsa bot stessa vive nella posizione global, qualunque sia la
regione del suo gruppo di risorse.
Il secret client scade
Lo stesso secret autentica il bot quando risponde in Teams e il plugin quando chiama Graph. Alla sua scadenza, l'applicazione smette di rispondere e il pannello perde di vista il catalogo, finché un nuovo secret non viene inserito nel pannello di amministrazione. La sua durata dipende dal modo in cui l'avete creato:
| Metodo | Durata |
|---|---|
| Portale | A vostra scelta, 24 mesi al massimo, con Microsoft che consiglia meno di 12 |
| Azure CLI | Un anno, modificabile con --years su az ad app credential reset |
| Terraform | Due anni, il valore predefinito applicato da Microsoft Entra ID quando end_date_relative è omesso |
Annotate da qualche parte la data di scadenza e pianificate la rotazione: create prima il nuovo secret, poi incollatelo nel pannello.
Free o Standard
Il livello Free (F0) consente 10.000 messaggi al mese sui canali premium, il che basta alla maggior parte delle distribuzioni self-hosted. Passate a Standard (S1) se prevedete volumi superiori.
Autorizzazioni Graph¶
| Autorizzazione | Ciò che apporta | Senza di essa |
|---|---|---|
User.Read.All |
I nomi e le foto dei partecipanti | L'integrazione funziona, le schede non mostrano alcuna foto |
AppCatalog.Read.All |
Il pannello legge il catalogo di applicazioni della vostra organizzazione | Il pannello non dice nulla del catalogo, e il suo pulsante propone di pubblicare o di aggiornare senza sapere quale dei due |
Sono entrambe autorizzazioni di applicazione, ed entrambe richiedono il consenso amministratore. Il plugin chiede un token nuovo a ogni lettura del catalogo, tanto che un consenso concesso a server avviato si applica già dalla lettura successiva, senza riavvio.
La pubblicazione richiede una terza autorizzazione, la delegata
AppCatalog.ReadWrite.All, e funziona diversamente. Non è dichiarata sulla
registrazione di applicazione: il pannello di amministrazione la chiede nel
momento in cui tentate di pubblicare.
Installare il plugin¶
Copiate drovio-teams.jar nella cartella dei pacchetti del server, poi
dichiaratelo in 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 chiave è plugin_management. Scrivere plugin_manager dà un plugin che non
si carica mai, senza che alcun errore lo segnali. Il base_address vale
drovio.server.msteams, indirizzo che l'applicazione Drovio e il server usano
entrambi nel loro codice.
Riavviate il server. Una voce Microsoft Teams compare nel pannello di amministrazione, e vi compare soltanto quando il plugin è caricato.
Perché qui serve un riavvio
La maggior parte della configurazione di Drovio Server si applica a caldo,
ma i plugin sono caricati solo all'avvio. Qualsiasi modifica di
plugin_management, compresa quella di questo plugin, ha effetto solo al
riavvio successivo.
Configurare l'integrazione¶
Aprite la voce Microsoft Teams del pannello di amministrazione.
| Campo | Da dove viene |
|---|---|
| Status | Enabled o Disabled |
| Application ID | Il client_id rilevato in Azure |
| Client secret | Il secret che avete copiato |
| Tenant ID | Il tenant_id rilevato in Azure |
| Launch URI | Precompilato dall'URL del server |
| Join URI | Precompilato dall'URL del server |
Il salvataggio scrive i valori nella configurazione del server e ha effetto già dalla chiamata successiva, senza riavvio. Il secret client non viene più mostrato: lasciare il campo vuoto conserva quello memorizzato.
Prima della 3.6.6, cambiare l'Application ID richiedeva un riavvio
Le versioni precedenti lo leggevano una sola volta all'avvio del server. Il
bot continuava quindi a verificare le chiamate in entrata contro il valore
precedente e rispondeva 401 a ogni richiesta, registrando
Bot authentication failed: Invalid JWT audience.
Passare lo stato a Disabled ferma il bot e le azioni provenienti dall'applicazione Drovio, lasciando comunque accessibile questo pannello per configurare l'integrazione.
Riferimento di configurazione¶
Ecco le chiavi dell'elemento msteams di settings.conf, se preferite
modificarlo direttamente.
Il plugin scrive esso stesso questo elemento al primo avvio che non ne trova alcuno, tanto che un server può essere distribuito con il plugin e poi configurato interamente dal pannello.
| Chiave | Predefinito | Significato |
|---|---|---|
enabled |
false |
Attiva l'integrazione. In sua assenza, il valore adottato è false |
client_id |
Application (client) ID del bot | |
client_secret |
Secret client del bot | |
tenant_id |
Directory (tenant) ID. Vuoto, designa un bot multi-tenant, la cui creazione è abbandonata da Microsoft da luglio 2025 | |
launch_uri |
<url del server>/launch |
L'indirizzo verso il quale una scheda Teams manda un utente per avviare una chiamata |
join_uri |
<url del server>/join/app |
L'indirizzo verso il quale una scheda Teams manda un utente per raggiungere una chiamata |
Costruire e pubblicare l'applicazione Teams¶
L'applicazione è un archivio zip contenente il manifest e le icone. La sezione App package del pannello di amministrazione permette di costruirlo.
| Campo | Note |
|---|---|
| Application ID | Precompilato dalla configurazione |
| Application ID URI | Precompilato con api://<app id>. Cambiatelo solo se Entra ID ne espone un altro |
| Version | Fornita con il plugin, mostrata a titolo informativo. È l'aggiornamento del plugin a pubblicare una nuova versione |
Download vi dà l'archivio da caricare voi stessi, dal centro di amministrazione Teams.
L'altro pulsante vi connette a Microsoft e mette l'applicazione direttamente nel
catalogo della vostra organizzazione. La sua etichetta segue ciò che contiene il
catalogo: Publish quando l'applicazione non c'è, Update to x.y.z quando
ne contiene una versione più vecchia, e Up to date quando non c'è nulla da
inviare. È la lettura di questo stato che apporta AppCatalog.Read.All. Senza
di essa, il pulsante mostra Publish or update e copre i due casi, il che
funziona altrettanto bene.
La pubblicazione richiede un account che disponga del ruolo di amministratore Teams: qualsiasi altro account può solo sottoporre l'applicazione a revisione, la quale attende poi un'approvazione nel centro di amministrazione Teams. Nulla di questa connessione viene conservato: pubblicare di nuovo riconnette.
Il catalogo riflette le politiche di gestione delle applicazioni del tenant, che Microsoft applica entro 24 o 48 ore da una pubblicazione. Un'applicazione pubblicata poco fa può quindi non figurarvi ancora, e il pannello può continuare a proporre di pubblicarla.
Autorizzare l'applicazione e renderla facile da trovare¶
Nel centro di amministrazione Teams, andate in Teams apps poi Manage apps, cercate Drovio, e passate il suo stato a Allowed.
L'applicazione mostra la foto del profilo dei partecipanti. Nella scheda Permissions, fate clic su Review permissions e concedetele.
Per mettere l'applicazione davanti ai vostri utenti, andate in Teams apps poi Setup policies. Modificate la politica Global (Org-wide default), oppure createne una e assegnatela a un gruppo. Sotto Pinned apps, aggiungete Drovio e ordinatela nell'ambito Messaging extensions.
Ciò che occorre sapere sulle politiche di aggiunta
- L'applicazione si apre dal
+della casella di scrittura. Il client Teams attuale non mostra più le icone delle estensioni di messaggio accanto a questa casella. Non c'è quindi alcuna icona da aggiungere davanti. La politica fissa l'ordine all'interno del menu+, ed è questo che mette Drovio in testa. - Una modifica della politica impiega qualche ora a raggiungere i client, e altrettanto un ritorno indietro.
- Lasciare User pinning disattivato rimuove gli elementi che i vostri utenti hanno aggiunto da soli.