Uma variável de automação é o que separa um "O seu chamado foi atualizado" genérico de um "Chamado 12345 - Impressora sem toner mudou para Em atendimento, com a técnica Ana Paula". No GLPI estas variáveis são as etiquetas de notificação: marcadores ##...## que o motor substitui pelo dado real no momento do envio. Parecem triviais até ao dia em que o nome do utilizador requerente sai em branco no e-mail e ninguém sabe porquê. Este guia é o mapa que usamos na sustentação de parques GLPI de clientes para acertar o modelo à primeira.
Onde vivem as variáveis: modelo não é notificação
Antes de escolher etiquetas, perceba a cadeia que o GLPI monta, porque a maioria dos "a variável não funciona" são, na verdade, erros de configuração, não de sintaxe. Uma mensagem só sai quando quatro peças estão alinhadas:
- Notificação (Configurar > Notificações): liga o evento - novo chamado, acompanhamento, solução, inquérito de satisfação.
- Modelo (Modelos de notificação): o corpo em texto e o corpo em HTML, onde escreve as etiquetas
##...##. - Destinatários: quem recebe - utilizador requerente, técnico atribuído, grupo, observador.
- Fila e envio: o GLPI não envia o e-mail de imediato; coloca-o em fila e a tarefa automática
queuednotificationdespacha-o.
Colocar a etiqueta certa num modelo que não está associado a nenhuma notificação ativa não produz e-mail nenhum - e a culpa não é da etiqueta.
As etiquetas que realmente usa
As etiquetas são contextuais: o conjunto disponível muda consoante o item (Ticket, Change, Problem). Para chamados, estas cobrem a maioria dos modelos - todas confirmadas diretamente no motor de notificação do GLPI 11:
| Etiqueta | O que devolve |
|---|---|
##ticket.id## | Número do chamado |
##ticket.title## | Título |
##ticket.description## | Descrição (conteúdo de abertura) |
##ticket.url## | Ligação direta ao chamado (exige sessão iniciada) |
##ticket.status## | Estado atual |
##ticket.priority## | Prioridade |
##ticket.category## | Categoria |
##ticket.creationdate## | Data de abertura |
##ticket.solvedate## | Data de solução |
##ticket.duedate## | Prazo de resolução (SLA) |
##ticket.authors## | Requerente(s) - lista separada por vírgulas |
##ticket.assigntousers## | Técnico(s) atribuído(s) - lista por vírgulas |
##ticket.assigntogroups## | Grupo(s) atribuído(s) |
##ticket.solution## | Texto da solução |
##followup.author## / ##followup.description## | Dentro de ##FOREACHfollowups## |
##task.author## / ##task.description## | Dentro de ##FOREACHtasks## |
##author.name## / ##author.email## | Dentro de ##FOREACHauthors## |
Repare que ##ticket.assigntousers## devolve uma lista já pronta, separada por vírgulas - o GLPI faz o implode internamente. Não é um ciclo, é texto simples: resolve o caso de "tenho dois técnicos e quero ambos no e-mail" sem qualquer truque.
O erro de campo mais comum: o requerente não é ##user.name##
Este é, de longe, o problema que mais reabrimos em auditoria de modelo: o nome do requerente chega em branco no e-mail. A causa é quase sempre a mesma - alguém copiou ##user.name## de um tutorial de recuperação de palavra-passe para dentro de uma notificação de chamado. Numa notificação de Ticket, ##user.name## simplesmente não existe: pertence às notificações do objeto Utilizador (reposição de palavra-passe, criação de conta). O GLPI não assinala erro - apenas substitui por vazio, e o técnico passa a tarde a caçar um bug que é, na verdade, de fonte de dados. O requerente de um chamado é ##ticket.authors## (lista pronta) ou, se quer nome e e-mail de cada um em separado, o bloco FOREACH a seguir.
FOREACH: a parte que quase ninguém conhece
Um chamado tem N acompanhamentos, N tarefas, N requerentes. Não existe uma etiqueta mágica que despeje tudo formatado: o GLPI expõe as coleções através de um bloco de repetição. Abre o ciclo, escreve o miolo uma vez com as etiquetas do item e fecha - e ainda pode limitar quantos itens quiser com FIRST ou LAST:
Ola ##ticket.authors##,
O seu chamado ##ticket.id## - ##ticket.title##
mudou para: ##ticket.status##
Tecnico(s): ##ticket.assigntousers##
Ultimo acompanhamento:
##FOREACH LAST 1 followups##
[##followup.date##] ##followup.author##:
##followup.description##
##ENDFOREACHfollowups##
Aceda: ##ticket.url##
O LAST 1 (também aceita FIRST e um número maior) é o que evita o e-mail quilométrico a repetir todo o histórico a cada novo acompanhamento - um pedido recorrente de cliente que a maioria "resolve" a cortar conteúdo à força, quando bastava o modificador. As coleções que aceitam FOREACH incluem followups, tasks, authors, actors, costs e as ligadas (linkedtickets, linkedchanges, linkedproblems).
Notificação multilingue de graça: as etiquetas ##lang.*##
Detalhe que só aparece quando abre a lista completa de etiquetas: cada etiqueta de valor tem uma companheira de rótulo. Para ##ticket.status## (o valor) existe ##lang.ticket.status##, que imprime o rótulo "Estado" traduzido para o idioma do destinatário. Ao montar o modelo com pares rótulo + valor, a mesma mensagem sai em português para um utilizador e em espanhol para outro, sem duplicar o modelo:
##lang.ticket.title##: ##ticket.title##
##lang.ticket.status##: ##ticket.status##
##lang.ticket.priority##: ##ticket.priority##
Num cliente com entidades em mais do que um país, isto reduz a manutenção de "um modelo por idioma" a um único modelo. O valor não traduz - o dado é o dado; o que muda é apenas o rótulo, e o ##lang.*## trata disso sozinho.
Diagnóstico: a variável está certa, mas o e-mail não sai
Quando o modelo está impecável e mesmo assim o e-mail desaparece, o problema não está na etiqueta - está na fila. O GLPI grava cada mensagem em glpi_queuednotifications e a tarefa automática queuednotification é quem envia de facto. Se a tarefa não corre (cron parado) ou o SMTP recusa, a mensagem acumula com sent_time nulo. É a primeira coisa que corremos num chamado de "notificação não chega":
-- Notificacoes em fila que ja deveriam ter saido:
-- sent_time NULL = ainda nao enviada; send_time no passado = atrasada.
SELECT id, name AS assunto, recipient, send_time, sent_try
FROM glpi_queuednotifications
WHERE sent_time IS NULL
AND send_time <= NOW()
ORDER BY send_time ASC
LIMIT 30;
Linhas a acumular com sent_try a subir significam SMTP a recusar; fila a crescer com sent_try a zero significa cron parado. Nos dois casos o modelo está certo - e acabou de poupar a tarde que ia gastar a reescrever etiquetas em vão.
Onde cada variável funciona (matriz de decisão)
A confusão que herdamos de quase todo o parque novo é achar que "modelo de chamado" e "modelo de notificação" são a mesma coisa. Não são - e só um dos dois faz substituição de ##tag##:
| Onde | Substitui ##tag##? | Para que serve |
|---|---|---|
| Modelo de notificação (corpo e assunto) | Sim - etiquetas, FOREACH e ##lang.*## | Corpo de e-mail dinâmico |
| Modelo de chamado (TicketTemplate) | Não | Predefinir, ocultar ou tornar obrigatórios campos na abertura |
| Modelo de tarefa / acompanhamento | Não | Texto-base reutilizável, sem substituição dinâmica |
| Assunto da notificação | Sim | As mesmas etiquetas do corpo, numa única linha |
Dica final que vale por todo o resto: ao editar um modelo de notificação, o GLPI mostra o separador de etiquetas disponíveis para aquele item específico. É a fonte da verdade - contextual e sempre alinhada com a versão instalada. Antes de copiar uma etiqueta de um blogue (este incluído), confirme que ela aparece ali.
Precisa de notificações que informem de verdade - multilingues, com o requerente certo e sem e-mail preso na fila? Conheça a sustentação de GLPI da NexTool.
Revisto pela equipa NexTool Solutions.