Notificações em tempo real no GLPI com Smart Notify

No GLPI padrão, notificação é e-mail assíncrono que ninguém acompanha. O módulo gratuito Smart Notify põe um sino na navbar que faz polling do banco (modo delta ~93 bytes) e agrega dezesseis fontes de eventos ITIL. Veja como o poll funciona, o SQL de diagnóstico, a matriz de quais eventos deixar ligados e as armadilhas de campo - do autoplay do Chrome ao 1064 do MySQL 8.

No GLPI padrão, notificação é e-mail assíncrono: cai no spam, o técnico não mora no webmail e o followup fica horas sem resposta. O Smart Notify troca esse modelo por um sino na barra do próprio GLPI que faz polling no banco e agrega mais de uma dúzia de eventos ITIL em tempo quase real. Na sustentação de parques de clientes, aprendemos que o difícil não é ligar o sino - é calibrar o que ele mostra para não virar ruído. Este guia mostra como o poll funciona por baixo, um SQL de diagnóstico, a matriz de quais eventos deixar ligados e as armadilhas que mais derrubam a instalação.

Por que o e-mail nativo não resolve notificação operacional

As notificações nativas do GLPI dependem da fila queuednotification e de templates de e-mail. É um modelo assíncrono e fora da ferramenta: o técnico precisa alternar entre o GLPI e a caixa de entrada, e-mail transacional cai em spam corporativo, e ninguém acompanha o webmail em tempo real. O resultado clássico da operação é validação parada por horas e tarefa atribuída que ninguém viu.

O sino resolve isso para quem está logado no GLPI. Mas atenção à primeira armadilha: o sino não substitui o e-mail para o requerente. Ele notifica o técnico que está em sessão, não o cliente que abriu o chamado pelo self-service. O erro comum é desligar as notificações por e-mail achando que o sino cobre todo mundo - e o requerente para de ser avisado. Sino e e-mail são camadas complementares, não excludentes.

Como o sino funciona por baixo (polling + delta)

O JavaScript do sino faz um poll a cada 30 segundos (refresh_interval padrão) contra um endpoint AJAX. A cada ciclo, o backend varre até dezesseis fontes de evento, monta a lista, aplica a retenção (retention_days, padrão 90 dias), corta em max_notifications (padrão 50) e ordena por data decrescente. Cada notificação recebe um hash estável (sha1(tipo_id_timestamp)) - é ele que marca o item como lido sem depender de um campo novo no chamado.

O ponto que só quem opera percebe é o custo desse poll a cada 30s por técnico logado. Por isso o endpoint usa modo delta: o cliente devolve o hash do último estado (state=); se nada mudou, a resposta cai de cerca de 18 KB para ~93 bytes. E o read-check virou um único SELECT em lote - antes era um SELECT por notificação, chegando a ~700 por poll em usuários com backlog grande. O GET também faz session_write_close() logo no início, para não segurar o lock de sessão do PHP enquanto varre o banco.

# O sino faz polling a cada 30s neste endpoint (roteado pelo module_ajax):
GET /plugins/nextool/ajax/module_ajax.php?module=smartnotify&file=notifications.php&action=get&state=${HASH}

# Sem novidade desde o ultimo poll, a resposta e um delta de ~93 bytes:
{ "success": true, "unchanged": true, "state": "...md5...", "unread_count": 4 }

# So quando algo muda vem o payload completo (~18KB) com o array notifications[].

As fontes de evento e o que deixar ligado

A configuração global expõe dezesseis gatilhos e cada técnico ainda refina os seus no modal de preferências (acessível direto no dropdown do sino). Duas regras de targeting importam: o followup que você escreveu não te notifica (a query filtra users_id != usuário), e a notificação chega por envolvimento direto ou por grupo técnico (notify_group_involvement), sempre respeitando as entidades ativas da sessão.

Na sustentação, três gatilhos vêm desligados por padrão de propósito, e a experiência confirma a escolha: documentos anexados são ruído em parques com muito upload; novos problemas e novas mudanças são eventos menos frequentes que poluem o sino de quem só cuida de tickets. Ligar tudo é o caminho mais rápido para a fadiga de alerta - o técnico passa a ignorar o sino, e aí ele não serve para nada.

Família de eventoGatilho (config)PadrãoNota de campo
Followups (ticket, problema, mudança)notify_*_followupLigadoÉ o que mais move o backlog; mantenha
Validações e respostas de validaçãonotify_*_validation(_response)LigadoAprovação travada é gargalo silencioso
Tarefas atribuídasnotify_*_taskLigadoÉ a fila de trabalho do técnico
Soluções registradasnotify_solutionLigadoFecha o loop de quem acompanha
Documentos anexadosnotify_documentDesligadoRuidoso onde há muito anexo
Novos chamadosnotify_new_ticketLigadoSinal de entrada da fila
Novos problemas / mudançasnotify_new_problem / _changeDesligadoMenos comuns; ligue por perfil
Avisos manuais (broadcast)notify_manualLigadoManutenção, mudança de processo

Diagnóstico via SQL: quem silenciou o quê

Quando um cliente reclama que "o sino não avisa", o problema quase sempre é preferência individual ou entidade errada, não bug. Estas três consultas resolvem a triagem direto no banco (tabelas reais do módulo):

-- 1. Quantos tecnicos silenciaram cada tipo de evento (acha ruido/fadiga):
SELECT
  SUM(ticket_followups = 0) AS mudo_followup_ticket,
  SUM(solutions = 0)        AS mudo_solucao,
  SUM(documents = 0)        AS mudo_documento,
  SUM(sound_enabled = 0)    AS som_desligado
FROM glpi_plugin_nextool_smartnotify_preferences;

-- 2. Registros de leitura por usuario (backlog e ultima atividade):
SELECT users_id, COUNT(*) AS lidas_registradas, MAX(date_read) AS ultima_leitura
FROM glpi_plugin_nextool_smartnotify_read
GROUP BY users_id
ORDER BY ultima_leitura DESC;

-- 3. Broadcasts manuais ativos e seu alvo (all/user/group/entity):
SELECT id, title, priority, target_type, target_id, entities_id, date_creation
FROM glpi_plugin_nextool_smartnotify_manual
WHERE is_active = 1
ORDER BY date_creation DESC;

Sons por prioridade e a armadilha do autoplay

Notificações emitem som via Web Audio API, com quatro timbres mapeados por prioridade. O técnico ouve, antes de olhar a tela, se o que chegou é rotina ou urgência:

PrioridadeSomTimbre (aprox.)
BaixasubtleCurto e grave (440 Hz)
NormaldefaultPadrão (523 Hz)
AltaalertMédio (659 Hz)
UrgentealarmLongo e agudo (880 Hz)

A armadilha aqui não é do módulo, é do navegador: a política de autoplay do Chrome só permite criar o AudioContext depois do primeiro gesto do usuário. Na prática, o primeiro som de uma sessão só sai depois do primeiro clique na tela. Todo mês alguém abre chamado dizendo "o som não funciona" - a resposta é clicar uma vez na página. Não é bug, é a Web Audio API respeitando o navegador.

Broadcasts manuais e limpeza automática

Administradores enviam avisos manuais com targeting preciso: todos, um usuário, um grupo ou uma entidade (a coluna target_type na tabela _manual). É o canal certo para janela de manutenção ou mudança de processo, sem disparar e-mail para a base inteira. A retenção é cuidada por uma CronTask diária (smartnotify_cleanup), registrada no install como MODE_EXTERNAL. Isso importa: em MODE_INTERNAL a tarefa roda por web-hit e pode travar em state=2. Dispare o cron do GLPI por fora (no GLPI 11, front/cron.php) e a limpeza acontece sozinha conforme retention_days e logs_retention_days.

# CronTask registrada no install (idempotente), 1x/dia, MODE_EXTERNAL:
#   Nome: smartnotify_cleanup   Frequencia: DAY_TIMESTAMP (86400s)
# Dispare o cron do GLPI por fora (nunca dependa do MODE_INTERNAL via web-hit):
* * * * * www-data /usr/bin/php /var/www/html/front/cron.php >/dev/null 2>&1

A armadilha que derruba a instalação: MySQL 8 x MariaDB

Um caso real de sustentação (junho/2026, cliente em MySQL 8.0.46): o install do módulo virava HTTP 500 e o parque ficava sem o sino. A causa raiz não estava no GLPI, estava no SQL: um bloco ALTER TABLE ... ADD COLUMN IF NOT EXISTS - sintaxe exclusiva do MariaDB. No MySQL 8 esse IF NOT EXISTS em coluna não existe e o statement falha com erro 1064, derrubando o install inteiro. A lição vale para qualquer plugin GLPI: DDL condicional não é portável entre MariaDB e MySQL. A correção (versão 2.2.1+) foi tirar o DDL condicional do .sql e mover as migrações para PHP com helpers portáveis do plugin base. Se você roda MySQL 8, garanta o módulo em 2.2.1 ou superior.

Na NexTool implantamos e sustentamos ambientes GLPI de ponta a ponta. Se o seu time convive com chamado esquecido e notificação por e-mail que ninguém abre, o Smart Notify é gratuito e liga em minutos pelo catálogo de módulos NexTool - e a nossa equipe de sustentação ajuda a calibrar o que cada perfil recebe para o sino virar sinal, não ruído.


Este conteúdo foi produzido com auxílio de inteligência artificial e revisado pela equipe Nextool Solutions.

Perguntas Frequentes

Não. O GLPI nativo depende da fila queuednotification e de templates de e-mail, um modelo assíncrono e fora da ferramenta. O módulo gratuito Smart Notify adiciona um sino na navbar que faz polling no banco a cada 30 segundos e agrega dezesseis fontes de eventos ITIL (followups, validações, tarefas, soluções, documentos, novos chamados e avisos manuais), com sons por prioridade.

Não, são camadas complementares. O sino avisa quem está logado no GLPI - tipicamente o técnico em sessão. O requerente que abriu o chamado pelo self-service continua dependendo do e-mail. O erro comum é desligar as notificações por e-mail achando que o sino cobre todo mundo; aí o cliente para de ser avisado.

Pouco, por causa do modo delta. O cliente devolve o hash do último estado (state=) e, se nada mudou, a resposta cai de cerca de 18 KB para ~93 bytes - a maioria dos polls não tem novidade. O read-check foi consolidado em um único SELECT em lote (antes era um por notificação) e o GET libera o lock de sessão com session_write_close(). O intervalo é configurável em refresh_interval.

Calibrando o que cada perfil recebe. Três gatilhos já vêm desligados por padrão (documentos anexados, novos problemas e novas mudanças) porque são ruidosos ou pouco frequentes. Cada técnico refina no modal de preferências, e o SQL da tabela _preferences mostra quem silenciou o quê. Ligar tudo leva à fadiga de alerta e o técnico passa a ignorar o sino.

É a política de autoplay do Chrome, não um bug. O navegador só permite criar o AudioContext depois do primeiro gesto do usuário, então o primeiro som de cada sessão sai apenas após o primeiro clique na página. A partir daí os sons por prioridade tocam normalmente.

Funciona em ambos a partir da versão 2.2.1. Versões anteriores traziam um ALTER TABLE ... ADD COLUMN IF NOT EXISTS no install.sql, sintaxe exclusiva do MariaDB que no MySQL 8 falha com erro 1064 e derruba a instalação (HTTP 500). A correção moveu as migrações para PHP com helpers portáveis. Em MySQL 8, use 2.2.1 ou superior.

Precisa de ajuda?