O GLPI 11 tem webhook nativo: a cada ticket aberto, alterado ou eliminado, avisa outro sistema por HTTP, com assinatura e novas tentativas. Testámos no nosso GLPI de suporte e a primeira configuração não entregou nada. O motivo não estava em nenhum ecrã: o GLPI recusa qualquer URL com porta, como :8080 ou a :5678 predefinida do n8n. Este guia mostra como configurar, o que o teste mediu e os três detalhes que bloqueiam a integração.
Precisa de ir além do webhook de saída, com condições, várias etapas ou receção de dados externos? Veja Automações e webhooks no GLPI com o NexTool.
O que o webhook nativo faz (e o que não faz)
O webhook do GLPI 11 é de saída: quando algo acontece num item, o GLPI compõe uma mensagem e envia-a para um URL. Serve para avisar um ERP, abrir um cartão no Teams, alimentar um painel ou desencadear um fluxo no n8n.
- Eventos: novo, atualização e eliminação.
- Itens: os mesmos da nova API do GLPI 11, como tickets, problemas, alterações, ativos e utilizadores.
- Mensagem: por predefinição, o item no formato da API (estado, requerente, equipa, entidade, datas), editável com variáveis.
Não recebe nada. Para outro sistema criar ou alterar tickets no GLPI, o caminho é a API.
Onde configurar
Em Configurar > Webhooks > Adicionar:
| Campo | Para que serve |
|---|---|
| Entidade e recursivo | Só dispara para itens dessa entidade (e das entidades-filhas, se recursivo) |
| Tipo de item e evento | Ex.: Ticket + Novo |
| URL | Destino. Aceita variáveis, como o ID do item no caminho |
| Método HTTP | POST, PUT, PATCH ou GET |
| Número de tentativas | Quantas vezes reenviar se o destino falhar |
| Log no histórico do item | Regista cada envio no histórico do ticket |
| Salvar corpo da resposta | Guarda o que o destino respondeu (tem de ser permitido na configuração do servidor) |
E nos separadores:
- Critérios: filtra os itens que disparam o envio, com os mesmos critérios da pesquisa. Ex.: só tickets da categoria "Compras".
- Editor de carga: substitui a mensagem predefinida por um modelo seu, com pré-visualização.
- Segurança: segredo da assinatura, desafio de validação do URL e autenticação OAuth.
- Cabeçalhos personalizados: como
AuthorizationouContent-Type.
O teste: o que medimos
Criámos dois webhooks na entidade de testes do nosso GLPI de suporte (empresa fictícia Acme) e abrimos tickets. Um apontava para um destino que responde 200; o outro, para um destino que responde com erro 500.

| O que verificámos | Resultado |
|---|---|
URL com porta (http://destino:8080/...) |
Recusado como "unsafe", nada é enviado |
| O mesmo URL sem porta | Aceite |
| Tempo entre abrir o ticket e a entrega | 8 segundos (próxima execução do cron) |
| Destino com erro 500 e "Número de tentativas" = 2 | 3 envios, um por minuto, e o GLPI desiste |
Assinatura X-GLPI-signature |
Confere: HMAC-SHA256 do corpo + X-GLPI-timestamp |
Cabeçalho Content-Type |
Não é enviado |
| Corpo | {"event": "new", "item": {...}} com 2,1 KB para um ticket simples |
Os três detalhes que bloqueiam a integração
1. URL com porta é recusado
O GLPI 11 só chama URL que passem numa lista de permissões (proteção contra utilização indevida do servidor). A regra predefinida aceita domínio, IP e caminho, mas não aceita porta. O erro não aparece no ecrã: fica no webhook.log, como "Webhook target URL ... is unsafe".
Testámos a função do próprio GLPI:
| URL | Resultado |
|---|---|
https://n8n.empresa.com.br/webhook/abc |
aceite |
https://n8n.empresa.com.br:5678/webhook/abc |
recusado |
http://localhost:5678/webhook/abc |
recusado |
http://localhost/webhook/abc |
aceite |
Solução: publique o destino na porta predefinida (443 ou 80), normalmente atrás de um proxy inverso. Isto também resolve o HTTPS. É possível alargar a lista com a constante GLPI_SERVERSIDE_URL_ALLOWLIST, mas esta aplica-se a todos os acessos do servidor a URL externos, por isso altere-a com cuidado.
2. Sem Content-Type, o destino pode não entender o JSON
O GLPI envia o corpo em JSON, mas sem o cabeçalho Content-Type. Ferramentas como o n8n e muitos frameworks só leem o corpo como JSON quando o cabeçalho o indica.
Solução: em Cabeçalhos personalizados, adicione Content-Type: application/json.
3. Sem cron, nada sai
O webhook não é enviado de imediato: vai para uma fila, e a ação automática queuedwebhook envia a cada minuto, até 50 de cada vez. Se o cron do GLPI não estiver a correr, a fila só cresce.
Solução: cron por linha de comandos a cada minuto (veja o passo 6 de como instalar o GLPI 11) e, de vez em quando, uma vista de olhos em Configurar > Webhooks > Fila de webhooks (Webhook queue).
Como validar a assinatura no destino
Cada envio traz dois cabeçalhos: X-GLPI-timestamp (momento do evento) e X-GLPI-signature. A assinatura é o HMAC-SHA256 do corpo seguido do timestamp, com o segredo do webhook. Em Python:
import hmac, hashlib
def assinatura_valida(corpo: bytes, timestamp: str, assinatura: str, segredo: str) -> bool:
calc = hmac.new(segredo.encode(), corpo + timestamp.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(calc, assinatura)
Dois cuidados: - O timestamp é do evento, não do envio. Nas novas tentativas repete-se. Se recusar mensagens "antigas", deixe uma janela que cubra as tentativas (alguns minutos). - Use o corpo em bruto, tal como chegou. Se o seu código descodificar e voltar a codificar o JSON, a assinatura não coincide.
Para quem precisa de mais garantias, o separador Segurança tem o desafio de validação: antes de enviar, o GLPI chama o URL com um crc_token, e o destino tem de responder com o HMAC desse token. Há também OAuth (client credentials): o GLPI obtém um token no servidor de autorização e envia-o como Bearer.
Quando o webhook nativo não chega
- Receber dados de outro sistema: é preciso a API.
- Lógica com várias condições e etapas, como "se a categoria for X e o requerente for da direção, avisa um canal e abre uma tarefa": os Critérios filtram, mas não encadeiam ações.
- Ver num só ecrã o que falhou e reenviar com um clique. A fila mostra o estado, mas o diagnóstico está no
webhook.log.
Nestes casos, entram um orquestrador como o n8n ou o módulo Automações do NexTool.
Checklist antes de ativar em produção
- Destino em HTTPS, na porta predefinida, sem
:portano URL. - Cabeçalho
Content-Type: application/json. - Assinatura validada no destino, com o corpo em bruto e uma janela de tempo para as tentativas.
- Critérios para não disparar em tudo.
- "Número de tentativas" de acordo com a importância (3 é um bom começo).
- Cron do GLPI a correr a cada minuto.
- "Log no histórico do item" ativado, para o técnico ver o que foi enviado.
- Teste com um ticket fictício antes de abrir a todos.
Teste da NexTool em 3 de outubro de 2026, no GLPI 11.0.7 do nosso suporte, entidade de testes com dados fictícios. Os webhooks e tickets de teste foram eliminados depois. Comportamentos verificados também no código-fonte do GLPI 11.