Integração Microsoft Teams¶
Uma integração Microsoft Teams pode ser adicionada à sua instalação do Drovio Server. Permite iniciar e entrar em sessões Drovio a partir do Microsoft Teams, pela zona de redação ou por comando do bot. Apresenta-se sob a forma de um ficheiro JAR que adiciona ao Drovio Server e depois configura. Terá de criar um Azure Bot e uma aplicação no Microsoft Entra ID.
Declarar o bot no Azure¶
A declaração do bot pode fazer-se a partir do portal Azure, do Azure CLI ou do Terraform. Os três conduzem ao mesmo resultado: um registo de aplicação, um segredo de cliente, e um recurso Azure Bot cujo canal Teams está ativado.
Criar o recurso Azure Bot¶
No portal Azure, escolha Create a resource, procure Azure Bot, depois Create.
| Campo | Valor |
|---|---|
| Bot handle | Um nome único, por exemplo Drovio |
| Subscription | A subscrição a faturar |
| Resource group | Um novo grupo, por exemplo Drovio |
| Pricing tier | Free (F0) |
| Type of app | Single Tenant |
| Creation type | Create new Microsoft App ID |
Fazer o bot apontar para o seu servidor¶
Abra o recurso, depois Settings e Configuration. Preencha o Messaging endpoint com:
https://<your server>/msteams/api/messages
Ponto de acesso público
A rota /msteams/api/messages deve ser acessível em HTTPS a partir dos
servidores da Microsoft. Se o seu Drovio Server estiver atrás de uma
firewall ou de um proxy inverso, tenha o cuidado de abrir este caminho na
Internet.
Aplique, depois vá a Settings e Channels, e adicione Microsoft Teams.
Recolher os três valores de que o plugin precisa¶
Ainda sob Settings e Configuration, clique em Manage Password ao lado do Microsoft App ID. Isso abre o registo de aplicação no Microsoft Entra ID.
No painel Overview, recolha:
| Valor no Azure | Utilizado como |
|---|---|
| Application (client) ID | client_id |
| Directory (tenant) ID | tenant_id |
Vá em seguida a Certificates & secrets, separador Client secrets, e
clique em New client secret. Copie logo a coluna Value: só é
apresentada uma vez, e é preciso gerar um novo segredo se a perder. É o
client_secret.
Expor a API e conceder o acesso ao Graph¶
Sob Expose an API, clique em Set ao lado do Application ID URI, depois em Save.
Sob API permissions, adicione uma permissão sobre o Microsoft Graph, escolha Application permissions, e selecione as duas permissões listadas mais abaixo. Conceda-lhes o consentimento de administrador.
Declarar o URI de redirecionamento¶
Útil apenas se contar publicar a aplicação a partir do painel de administração em vez de a depositar você mesmo.
Sob Authentication, Add a platform, escolha Web, e adicione o URI de redirecionamento:
https://<your server>/admin/access/msteams/publish/callback
Sem ele, a publicação falha com AADSTS500113: No reply address is registered
for the application. Se o acesso à administração estiver restringido por
endereço IP neste servidor, o endereço a partir do qual o navegador regressa
deve igualmente ser autorizado, sem o que o regresso é recusado com um 403.
Substitua <your server> pelo URL público da sua instância, e escolha o seu
próprio grupo de recursos e a sua região.
Aqui a aplicação precede o bot
O portal cria o registo de aplicação e o bot num único formulário. O CLI
não o pode fazer: az bot create exige o identificador de aplicação como
argumento obrigatório, pelo que o registo deve existir primeiro. O
resultado final é idêntico.
Fixe primeiro os cinco nomes, podendo o resto dos comandos ser colado tal e qual:
| Variável | O que designa |
|---|---|
SERVER |
O URL público do seu Drovio Server |
APP_NAME |
O nome de apresentação do registo de aplicação |
BOT_NAME |
O recurso bot, que deve estar livre à escala do Azure |
GROUP |
O grupo de recursos que suporta o bot |
LOCATION |
A região do grupo de recursos |
Crie o registo de aplicação, o seu serviço principal, o seu Application ID URI e o seu segredo de cliente:
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)
A linha az ad sp create corresponde ao passo que o portal lhe oculta. Cria
o serviço principal ao qual as permissões são concedidas, e sem ele o
consentimento de administrador falha. O URI de identificação é aquilo que o
manifest do Teams visa. O segredo de cliente só é apresentado uma vez, tenha
o cuidado de conservar o que o último comando captura.
Peça as duas permissões Graph, resolvidas pelo seu nome para que nenhum identificador tenha de ser copiado. O consentimento virá mais tarde, no fim deste separador:
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"
Este comando apresenta uma mensagem convidando-o a lançar
az ad app permission grant: ignore-a, esse comando diz respeito às
permissões delegadas, ao passo que estas duas são permissões de aplicação.
Depois o próprio recurso bot, e o seu 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"
Conceder o consentimento em último lugar¶
O consentimento é o último passo, e deve ser verificado. O Microsoft Entra ID precisa de que o registo de aplicação, o seu serviço principal e as permissões pedidas se tenham propagado antes de poder agir sobre eles. Lançado demasiado cedo, o comando não assinala qualquer erro e nada concede:
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
O último comando deve apresentar 2. Se apresentar 0, aguarde um minuto e
repita os dois. Conceder o consentimento exige o papel Privileged Role
Administrator ou Global Administrator.
O portal é o recurso fiável
Se a contagem se mantiver em 0, abra o registo de aplicação no
Microsoft Entra ID, vá a API permissions e clique em Grant admin
consent for <o seu tenant>. A coluna Status apresenta então
Granted, e o comando acima apresenta 2.
A mesma instalação, para uma infraestrutura já descrita sob a forma de
código. Exige o fornecedor azuread na versão 3 ou superior, onde surgiram
os pequenos recursos de aplicação componíveis. Os ficheiros abaixo formam um
único módulo raiz.
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
}
Três coisas a saber antes de aplicar:
- O segredo de cliente vai parar ao estado do Terraform, que detém então uma
credencial para o seu tenant e deve ser protegido como tal. Retire o
recurso
azuread_application_passworde crie o segredo à mão se isso não for aceitável no local onde conserva o seu estado. - Os dois recursos
azuread_app_role_assignmentfazem o que realiza o Grant admin consent no portal. A identidade que executa o Terraform deve dispor do papel Privileged Role Administrator ou Global Administrator para os criar. azurerm_bot_service_azure_boté o recurso Azure Bot. Não utilize o antigoazurerm_bot_channels_registration, que descreve a geração anterior de declaração de bot.
Um bot monotenant serve o seu próprio tenant, o que é aquilo de que uma implantação autoalojada precisa. A distribuição multitenant para os tenants dos seus clientes é outro assunto, que passa pelo AppSource.
Seja qual for o método escolhido, o nome do bot tem entre 4 e 42 caracteres e deve
estar livre à escala do Azure, pelo que Drovio sozinho pode já estar tomado. O
próprio recurso bot vive na localização global, seja qual for a região do seu
grupo de recursos.
O segredo de cliente expira
O mesmo segredo autentica o bot quando este responde no Teams e o plugin quando este chama o Graph. Na sua expiração, a aplicação deixa de responder e o painel perde a visão do catálogo, até que um novo segredo seja introduzido no painel de administração. A sua duração depende da forma como o criou:
| Método | Duração |
|---|---|
| Portal | À sua escolha, 24 meses no máximo, aconselhando a Microsoft menos de 12 |
| Azure CLI | Um ano, modificável por --years em az ad app credential reset |
| Terraform | Dois anos, o valor predefinido aplicado pelo Microsoft Entra ID quando end_date_relative é omitido |
Anote a data de expiração nalgum lado e preveja a rotação: crie primeiro o novo segredo, depois cole-o no painel.
Free ou Standard
O nível Free (F0) autoriza 10 000 mensagens por mês nos canais premium, o que basta para a maioria das implantações autoalojadas. Passe a Standard (S1) se esperar volumes superiores.
Permissões Graph¶
| Permissão | O que traz | Sem ela |
|---|---|---|
User.Read.All |
Os nomes e as fotografias dos participantes | A integração funciona, os cartões não apresentam fotografia |
AppCatalog.Read.All |
O painel lê o catálogo de aplicações da sua organização | O painel nada diz do catálogo, e o seu botão propõe publicar ou atualizar sem saber qual |
São ambas permissões de aplicação, e ambas exigem o consentimento de administrador. O plugin pede um token novo a cada leitura do catálogo, pelo que um consentimento concedido com o servidor em funcionamento se aplica logo na leitura seguinte, sem reinício.
A publicação exige uma terceira permissão, a delegada
AppCatalog.ReadWrite.All, e funciona de outra forma. Não é declarada no
registo de aplicação: o painel de administração pede-a no momento em que tenta
publicar.
Instalar o plugin¶
Copie drovio-teams.jar para a pasta dos pacotes do servidor, depois declare-o em
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"
}
]
}
A chave é plugin_management. Escrever plugin_manager dá um plugin que nunca se
carrega, sem que qualquer erro o assinale. O base_address vale
drovio.server.msteams, endereço que a aplicação Drovio e o servidor empregam
ambos no seu código.
Reinicie o servidor. Uma entrada Microsoft Teams aparece no painel de administração, e só aí aparece quando o plugin está carregado.
Porquê um reinício aqui
A maior parte da configuração do Drovio Server aplica-se a quente, mas os
plugins só são carregados no arranque. Qualquer alteração ao
plugin_management, incluindo a deste plugin, só produz efeito no reinício
seguinte.
Configurar a integração¶
Abra a entrada Microsoft Teams do painel de administração.
| Campo | De onde vem |
|---|---|
| Status | Enabled ou Disabled |
| Application ID | O client_id recolhido no Azure |
| Client secret | O segredo que copiou |
| Tenant ID | O tenant_id recolhido no Azure |
| Launch URI | Pré-preenchido a partir do URL do servidor |
| Join URI | Pré-preenchido a partir do URL do servidor |
Guardar inscreve os valores na configuração do servidor e produz efeito logo na chamada seguinte, sem reinício. O segredo de cliente nunca mais é apresentado: deixar o campo vazio conserva aquele que está armazenado.
Antes da 3.6.6, mudar o Application ID exigia um reinício
As versões anteriores liam-no uma única vez no arranque do servidor. O bot
continuava, portanto, a verificar as chamadas recebidas contra o valor
anterior e respondia 401 a cada pedido, registando
Bot authentication failed: Invalid JWT audience.
Passar o estado a Disabled interrompe o bot e as ações vindas da aplicação Drovio, deixando este painel acessível para configurar a integração.
Referência de configuração¶
Eis as chaves do elemento msteams de settings.conf, caso prefira editá-lo
diretamente.
O próprio plugin escreve este elemento no primeiro arranque que não encontre nenhum, pelo que um servidor pode ser implantado com o plugin e depois configurado inteiramente a partir do painel.
| Chave | Predefinição | Significado |
|---|---|---|
enabled |
false |
Ativa a integração. Na sua ausência, o valor retido é false |
client_id |
Application (client) ID do bot | |
client_secret |
Segredo de cliente do bot | |
tenant_id |
Directory (tenant) ID. Vazio, designa um bot multitenant, cuja criação foi abandonada pela Microsoft desde julho de 2025 | |
launch_uri |
<url do servidor>/launch |
O endereço para o qual um cartão Teams envia um utilizador para iniciar uma chamada |
join_uri |
<url do servidor>/join/app |
O endereço para o qual um cartão Teams envia um utilizador para entrar numa chamada |
Construir e publicar a aplicação Teams¶
A aplicação é um arquivo zip que contém o manifest e os ícones. A secção App package do painel de administração permite construí-la.
| Campo | Observações |
|---|---|
| Application ID | Pré-preenchido a partir da configuração |
| Application ID URI | Pré-preenchido com api://<app id>. Só o altere se o Entra ID expuser outro |
| Version | Entregue com o plugin, apresentada a título informativo. É a atualização do plugin que publica uma nova versão |
O Download dá-lhe o arquivo para depositar você mesmo, a partir do centro de administração do Teams.
O outro botão liga-o à Microsoft e coloca a aplicação diretamente no catálogo da
sua organização. A sua etiqueta segue aquilo que o catálogo contém: Publish
quando a aplicação lá não está, Update to x.y.z quando contém uma versão mais
antiga, e Up to date quando não há nada a enviar. É a leitura desse estado que
o AppCatalog.Read.All traz. Sem ele, o botão apresenta Publish or update e
cobre os dois casos, o que funciona igualmente bem.
A publicação exige uma conta com o papel de administrador do Teams: qualquer outra conta só pode submeter a aplicação a revisão, a qual aguarda depois uma aprovação no centro de administração do Teams. Nada dessa ligação é conservado: publicar de novo volta a ligar.
O catálogo reflete as políticas de gestão de aplicações do tenant, que a Microsoft aplica em 24 a 48 horas após uma publicação. Uma aplicação publicada agora mesmo pode, portanto, ainda não lá figurar, e o painel pode continuar a propor publicá-la.
Autorizar a aplicação e torná-la fácil de encontrar¶
No centro de administração do Teams, vá a Teams apps e depois a Manage apps, procure Drovio, e passe o seu estado a Allowed.
A aplicação apresenta a fotografia de perfil dos participantes. No separador Permissions, clique em Review permissions e conceda-as.
Para colocar a aplicação à frente dos seus utilizadores, vá a Teams apps e depois a Setup policies. Altere a política Global (Org-wide default), ou crie uma e atribua-a a um grupo. Sob Pinned apps, adicione o Drovio e ordene-o no âmbito Messaging extensions.
O que é preciso saber sobre as políticas de afixação
- A aplicação abre-se a partir do
+da zona de redação. O cliente Teams atual já não apresenta os ícones de extensões de mensagem ao lado dessa zona. Não há, portanto, qualquer ícone a afixar à frente. A política fixa a ordem dentro do menu+, e é isso que coloca o Drovio à cabeça. - Uma alteração de política demora algumas horas a alcançar os clientes, e um regresso atrás outro tanto.
- Deixar o User pinning desativado remove as afixações que os seus utilizadores fizeram eles próprios.