Documentação oficial desta página · v0.20.6
Microsoft Teams
Conecte o Hermes Agent ao Microsoft Teams como um bot. Diferente do Socket Mode do Slack, o Teams entrega mensagens chamando um webhook HTTPS público, então a sua instância precisa de um endpoint acessível pela internet — um túnel de desenvolvimento (dev local) ou um domínio de verdade (produção).
Precisa de resumos de reunião a partir de eventos do Microsoft Graph, em vez de conversas normais de bot? Use a página de configuração dedicada: Reuniões do Teams.
Rode
hermes gateway setupe escolha Microsoft Teams para um passo a passo guiado.
Como o bot responde
| Contexto | Comportamento |
|---|---|
| Conversa pessoal (DM) | O bot responde a toda mensagem. Não precisa de @menção. |
| Conversa em grupo | O bot só responde quando é @mencionado. |
| Canal | O bot só responde quando é @mencionado. |
O Teams entrega @menções como mensagens comuns com marcações <at>BotName</at>, que o Hermes remove automaticamente antes de processar.
Em instalações a partir do código-fonte ou locais, inclua o extra do Teams para que o adaptador embutido consiga importar o SDK do Microsoft Teams:
uv sync --extra teams
# ou, para instalações editáveis:
uv pip install -e ".[teams]"
Passo 1: Instale a CLI do Teams
A @microsoft/teams.cli automatiza o registro do bot — sem precisar do portal do Azure.
npm install -g @microsoft/teams.cli@preview
teams login
Para conferir o login e descobrir o seu próprio object ID do AAD (necessário para TEAMS_ALLOWED_USERS):
teams status --verbose
Passo 2: Exponha a porta do webhook
O Teams não consegue entregar mensagens para localhost. No desenvolvimento local, use qualquer ferramenta de túnel para obter uma URL HTTPS pública. A porta padrão é 3978 — troque com TEAMS_PORT se precisar.
# devtunnel (Microsoft)
devtunnel create hermes-bot --allow-anonymous
devtunnel port create hermes-bot -p 3978 --protocol http # troque 3978 pela TEAMS_PORT se mudou
devtunnel host hermes-bot
# ngrok
ngrok http 3978 # troque 3978 pela TEAMS_PORT se mudou
# cloudflared
cloudflared tunnel --url http://localhost:3978 # troque 3978 pela TEAMS_PORT se mudou
Copie a URL https:// da saída — você vai usá-la no passo seguinte. Deixe o túnel rodando enquanto desenvolve.
A URL pública do túnel usa HTTPS, mas o listener local de webhook do Hermes usa HTTP puro. O túnel termina o TLS e encaminha HTTP para a porta 3978; não configure a porta local do túnel como HTTPS.
Em produção, aponte o endpoint do bot para o domínio público do seu servidor (veja Implantação em produção).
Passo 3: Crie o bot
teams app create \
--name "Hermes" \
--endpoint "https://<url-do-seu-tunel>/api/messages"
A CLI imprime o seu CLIENT_ID, o CLIENT_SECRET e o TENANT_ID, além de um link de instalação para o Passo 6. Guarde o client secret — ele não é mostrado de novo.
Passo 4: Configure as variáveis de ambiente
Acrescente ao ~/.hermes/.env:
# Obrigatórias
TEAMS_CLIENT_ID=<seu-client-id>
TEAMS_CLIENT_SECRET=<seu-client-secret>
TEAMS_TENANT_ID=<seu-tenant-id>
# Restrinja o acesso a usuários específicos (recomendado)
# Use os object IDs do AAD que aparecem em `teams status --verbose`
TEAMS_ALLOWED_USERS=<seu-aad-object-id>
Passo 5: Suba o gateway
Docker (rode a partir do diretório que contém o docker-compose.yml — normalmente o clone do repositório hermes-agent, não ~):
cd /caminho/do/hermes-agent
HERMES_UID=$(id -u) HERMES_GID=$(id -g) docker compose up -d gateway
Instalação nativa / systemd (o instalador hermes de uma linha, em ~/.hermes/hermes-agent):
hermes gateway restart
# ou em primeiro plano: hermes gateway run
O SDK do Teams é opcional; quando o Teams está habilitado, o gateway o instala sob demanda no venv do próprio Hermes na primeira inicialização (não use o pip install do sistema no Ubuntu 24.04 — isso esbarra no externally-managed-environment da PEP 668). Para instalar manualmente no venv do Hermes:
~/.hermes/hermes-agent/venv/bin/pip install microsoft-teams-apps aiohttp
# ou, a partir de um clone do agente: uv sync --extra teams
A porta padrão do webhook é 3978 (mude com TEAMS_PORT). Confira se está no ar:
curl http://localhost:3978/health # deve devolver: ok
# Docker:
docker logs -f hermes
# Nativo:
hermes gateway status -l
Procure por:
[teams] Webhook server listening on * (all interfaces, IPv4+IPv6):3978/api/messages
Passo 6: Instale o app no Teams
teams app get <teamsAppId> --install-link
Abra o link impresso no navegador — ele abre direto no cliente do Teams. Depois de instalar, mande uma mensagem direta para o bot — está pronto.
Referência de configuração
Variáveis de ambiente
| Variável | Descrição |
|---|---|
TEAMS_CLIENT_ID | ID do app (client) do Azure AD |
TEAMS_CLIENT_SECRET | Client secret do Azure AD |
TEAMS_TENANT_ID | ID do tenant do Azure AD |
TEAMS_ALLOWED_USERS | Object IDs do AAD, separados por vírgula, autorizados a usar o bot |
TEAMS_ALLOW_ALL_USERS | Defina true para ignorar a lista de permissão e liberar para todo mundo |
TEAMS_HOME_CHANNEL | ID da conversa para entrega de mensagens do cron e proativas |
TEAMS_HOME_CHANNEL_NAME | Nome de exibição do canal principal |
TEAMS_PORT | Porta do webhook (padrão: 3978) |
config.yaml
Como alternativa, configure pelo ~/.hermes/config.yaml:
platforms:
teams:
enabled: true
extra:
client_id: "seu-client-id"
client_secret: "seu-secret"
tenant_id: "seu-tenant-id"
port: 3978
Recursos
Cartões interativos de aprovação
Quando o agente precisa rodar um comando potencialmente perigoso, ele manda um Adaptive Card com quatro botões, em vez de pedir que você digite /approve:
- Allow Once — aprova este comando específico
- Allow Session — aprova esse padrão pelo resto da sessão
- Always Allow — aprova esse padrão de forma permanente
- Deny — rejeita o comando
Clicar num botão resolve a aprovação ali mesmo e substitui o cartão pela decisão.
Entrega de resumos de reunião (pipeline de reuniões do Teams)
Quando o plugin de pipeline de reuniões do Teams está habilitado, este adaptador também cuida da entrega de saída dos resumos de reunião — uma única superfície de integração com o Teams, não duas. Depois que a transcrição da reunião é resumida, o escritor publica o resumo no destino do Teams que você escolheu.
A entrega de resumos do pipeline é configurada na entrada da plataforma teams, junto com a configuração do bot:
platforms:
teams:
enabled: true
extra:
# configuração existente do bot (client_id, client_secret, tenant_id, port) ...
# Entrega de resumos de reunião (só é usada quando o plugin teams_pipeline está habilitado)
delivery_mode: "graph" # ou "incoming_webhook"
# Para delivery_mode: graph — escolha UM destes:
chat_id: "19:meeting_..." # publicar em uma conversa do Teams
# team_id: "..." # OU publicar em um canal
# channel_id: "..."
# access_token: "..." # opcional; recorre às credenciais de app MSGRAPH_*
# Para delivery_mode: incoming_webhook:
# incoming_webhook_url: "https://outlook.office.com/webhook/..."
| Modo | Use quando | Contrapartida |
|---|---|---|
incoming_webhook | O caso simples de "publicar um resumo neste canal", com uma URL estática gerada pelo Teams. | Sem thread de respostas, sem reações, aparece com a identidade configurada no webhook. |
graph | Publicações em thread no canal ou em conversas 1:1 e de grupo, sob a identidade do bot, via Microsoft Graph. | Exige o registro de app no Graph com as permissões de aplicação ChannelMessage.Send (canal) ou Chat.ReadWrite.All (conversa). |
Se o plugin teams_pipeline não estiver habilitado, essas configurações ficam inertes — elas só entram em ação quando o runtime do pipeline se liga à entrada de webhook do Graph.
Implantação em produção
Num servidor permanente, termine o TLS num proxy reverso e encaminhe as requisições para o listener HTTP puro do Hermes, normalmente http://127.0.0.1:3978. Registre no Teams o endpoint HTTPS público do proxy:
teams app create \
--name "Hermes" \
--endpoint "https://seu-dominio.com/api/messages"
Se você já criou o bot e só precisa atualizar o endpoint:
teams app update --id <teamsAppId> --endpoint "https://seu-dominio.com/api/messages"
Garanta que o endpoint HTTPS público seja acessível pela internet e use um certificado TLS válido. O Teams rejeita certificados autoassinados. Mantenha o listener do Hermes atrás do proxy; a porta 3978 não serve HTTPS por conta própria.
Resolução de problemas
| Problema | Solução |
|---|---|
Can't find a suitable configuration file vindo do docker compose | Você não está no repositório que tem o docker-compose.yml, ou está numa instalação nativa — use hermes gateway restart no lugar, ou entre no clone antes com cd |
requirements not met / Teams SDK missing / No adapter available for teams | Reinicie o gateway para a instalação sob demanda rodar, ou instale no venv do Hermes: ~/.hermes/hermes-agent/venv/bin/pip install microsoft-teams-apps aiohttp. O pip do sistema falha no Ubuntu 24.04 (PEP 668) e de todo modo não afetaria o serviço |
O endpoint health funciona, mas o bot não responde | Confira se o seu túnel continua rodando e se o endpoint de mensagens do bot bate com a URL do túnel |
Os logs mostram "UNKNOWN / HTTP/1.0" 400 quando o Teams manda uma mensagem | O túnel ou o proxy reverso está encaminhando HTTPS para o listener HTTP puro do Hermes. Termine o TLS no proxy e encaminhe HTTP para a porta 3978 |
KeyError: 'teams' nos logs | Reinicie o contêiner — isso já foi corrigido na versão atual |
| O bot responde com erros de autenticação | Verifique se TEAMS_CLIENT_ID, TEAMS_CLIENT_SECRET e TEAMS_TENANT_ID estão todos definidos corretamente |
No inference provider configured | Confira se a ANTHROPIC_API_KEY (ou a chave de outro provedor) está definida no ~/.hermes/.env |
| O bot recebe mensagens, mas ignora | Talvez o seu object ID do AAD não esteja em TEAMS_ALLOWED_USERS. Rode teams status --verbose para descobri-lo |
| A URL do túnel muda a cada reinício | URLs do devtunnel são persistentes se você usar um túnel nomeado (devtunnel create hermes-bot). O ngrok e o cloudflared geram uma URL nova a cada execução, a menos que você tenha plano pago — atualize o endpoint do bot com teams app update quando ela mudar |
| O Teams mostra "This bot is not responding" | O webhook devolveu erro. Veja docker logs hermes / hermes gateway status -l em busca de tracebacks |
[teams] Failed to connect nos logs | O SDK não conseguiu se autenticar. Confira as credenciais e se o tenant ID bate com a conta que você usou no teams login |
Segurança
Sempre defina TEAMS_ALLOWED_USERS com os object IDs do AAD dos usuários autorizados. Sem isso, qualquer pessoa que encontre ou instale o seu bot consegue interagir com ele.
Trate o TEAMS_CLIENT_SECRET como uma senha — gire-o periodicamente pelo portal do Azure ou pela CLI do Teams.
- Guarde as credenciais no
~/.hermes/.envcom permissão600(chmod 600 ~/.hermes/.env) - O bot só aceita mensagens de usuários que estejam em
TEAMS_ALLOWED_USERS; mensagens não autorizadas são descartadas em silêncio - O seu endpoint público (
/api/messages) é autenticado pelo Bot Framework do Teams — requisições sem JWT válido são rejeitadas