Une variable d'automatisation, c'est ce qui distingue un "Votre ticket a été mis à jour" générique d'un "Ticket 12345 - Imprimante sans toner passé en Traitement, pris par la technicienne Ana Paula". Dans GLPI, ces variables sont les balises de notification : des marqueurs ##...## que le moteur remplace par la donnée réelle au moment de l'envoi. Elles paraissent triviales jusqu'au jour où le nom du demandeur ressort vide dans le courriel et personne ne sait pourquoi. Ce guide est la carte que nous utilisons en maintien en condition de parcs GLPI clients pour réussir le modèle du premier coup.
Où vivent les variables : un modèle n'est pas une notification
Avant de choisir les balises, comprenez la chaîne que GLPI assemble, car la plupart des "la variable ne marche pas" sont en réalité des erreurs de configuration, pas de syntaxe. Un message ne part que lorsque quatre pièces sont alignées :
- Notification (Configuration > Notifications) : relie l'événement - nouveau ticket, suivi, solution, enquête de satisfaction.
- Modèle (Modèles de notification) : le corps texte et le corps HTML, où vous écrivez les balises
##...##. - Destinataires : qui le reçoit - demandeur, technicien affecté, groupe, observateur.
- File et envoi : GLPI n'envoie pas le courriel sur-le-champ ; il le met en file et l'action automatique
queuednotificationle distribue.
Mettre la bonne balise dans un modèle non relié à une notification active ne produit aucun courriel - et ce n'est pas la faute de la balise.
Les balises que vous utilisez vraiment
Les balises sont contextuelles : l'ensemble disponible change selon l'objet (Ticket, Change, Problem). Pour les tickets, celles-ci couvrent la plupart des modèles - toutes vérifiées directement dans le moteur de notification de GLPI 11 :
| Balise | Ce qu'elle renvoie |
|---|---|
##ticket.id## | Numéro du ticket |
##ticket.title## | Titre |
##ticket.description## | Description (contenu d'ouverture) |
##ticket.url## | Lien direct vers le ticket (connexion requise) |
##ticket.status## | Statut actuel |
##ticket.priority## | Priorité |
##ticket.category## | Catégorie |
##ticket.creationdate## | Date d'ouverture |
##ticket.solvedate## | Date de solution |
##ticket.duedate## | Échéance de résolution (SLA) |
##ticket.authors## | Demandeur(s) - liste séparée par des virgules |
##ticket.assigntousers## | Technicien(s) affecté(s) - liste par virgules |
##ticket.assigntogroups## | Groupe(s) affecté(s) |
##ticket.solution## | Texte de la solution |
##followup.author## / ##followup.description## | Dans ##FOREACHfollowups## |
##task.author## / ##task.description## | Dans ##FOREACHtasks## |
##author.name## / ##author.email## | Dans ##FOREACHauthors## |
Notez que ##ticket.assigntousers## renvoie une liste déjà prête, séparée par des virgules - GLPI fait l'implode en interne. Ce n'est pas une boucle, c'est du texte brut : cela résout "j'ai deux techniciens et je les veux tous les deux dans le courriel" sans aucune astuce.
L'erreur de terrain la plus fréquente : le demandeur n'est pas ##user.name##
C'est, de loin, le problème que nous rouvrons le plus lors des audits de modèle : le nom du demandeur arrive vide. La cause est presque toujours la même - quelqu'un a copié ##user.name## d'un tutoriel de réinitialisation de mot de passe dans une notification de ticket. Dans une notification de Ticket, ##user.name## n'existe tout simplement pas : elle appartient aux notifications de l'objet Utilisateur (réinitialisation de mot de passe, création de compte). GLPI ne lève aucune erreur - il substitue seulement une chaîne vide, et le technicien passe l'après-midi à traquer un bug qui est en fait un problème de source de données. Le demandeur d'un ticket, c'est ##ticket.authors## (liste prête) ou, si vous voulez le nom et le courriel de chacun séparément, le bloc FOREACH ci-dessous.
FOREACH : la partie que presque personne ne connaît
Un ticket a N suivis, N tâches, N demandeurs. Il n'existe pas de balise magique qui déverse tout formaté : GLPI expose les collections via un bloc de répétition. Vous ouvrez la boucle, écrivez le cœur une fois avec les balises de l'élément et la fermez - et vous pouvez même limiter le nombre d'éléments avec FIRST ou LAST :
Bonjour ##ticket.authors##,
Votre ticket ##ticket.id## - ##ticket.title##
est passe a : ##ticket.status##
Technicien(s) : ##ticket.assigntousers##
Dernier suivi :
##FOREACH LAST 1 followups##
[##followup.date##] ##followup.author## :
##followup.description##
##ENDFOREACHfollowups##
Acceder : ##ticket.url##
Le LAST 1 (accepte aussi FIRST et des nombres plus grands) évite le courriel kilométrique répétant tout l'historique à chaque nouveau suivi - une demande récurrente de client que la plupart "résolvent" en coupant du contenu à la main, alors que le modificateur suffisait. Les collections qui acceptent FOREACH incluent followups, tasks, authors, actors, costs et les liées (linkedtickets, linkedchanges, linkedproblems).
Notification multilingue gratuite : les balises ##lang.*##
Détail qui n'apparaît que lorsqu'on ouvre la liste complète des balises : chaque balise de valeur a une compagne d'étiquette. Pour ##ticket.status## (la valeur) il existe ##lang.ticket.status##, qui imprime l'étiquette "Statut" traduite dans la langue du destinataire. En construisant le modèle avec des paires étiquette + valeur, le même message part en portugais pour un utilisateur et en espagnol pour un autre, sans dupliquer le modèle :
##lang.ticket.title##: ##ticket.title##
##lang.ticket.status##: ##ticket.status##
##lang.ticket.priority##: ##ticket.priority##
Chez un client avec des entités dans plus d'un pays, cela ramène la maintenance de "un modèle par langue" à un seul modèle. La valeur, vous ne la traduisez pas - la donnée est la donnée ; seule l'étiquette change, et ##lang.*## s'en charge tout seul.
Diagnostic : la variable est bonne, mais le courriel ne part pas
Quand le modèle est impeccable et que le courriel disparaît quand même, le problème n'est pas la balise - c'est la file. GLPI écrit chaque message dans glpi_queuednotifications et l'action automatique queuednotification réalise l'envoi. Si l'action ne tourne pas (cron arrêté) ou que le SMTP refuse, le message s'accumule avec sent_time nul. C'est la première chose que nous exécutons sur un ticket "les notifications n'arrivent pas" :
-- Notifications en file qui auraient deja du partir :
-- sent_time NULL = pas encore envoyee ; send_time dans le passe = en retard.
SELECT id, name AS objet, recipient, send_time, sent_try
FROM glpi_queuednotifications
WHERE sent_time IS NULL
AND send_time <= NOW()
ORDER BY send_time ASC
LIMIT 30;
Des lignes qui s'accumulent avec un sent_try qui monte signifient que le SMTP rejette ; une file qui grossit avec sent_try à zéro signifie que le cron est arrêté. Dans les deux cas, le modèle est bon - et vous venez d'économiser l'après-midi que vous alliez passer à réécrire des balises pour rien.
Où fonctionne chaque variable (matrice de décision)
La confusion héritée de presque chaque nouveau parc, c'est de croire que "modèle de ticket" et "modèle de notification" sont la même chose. Ce n'est pas le cas - et un seul des deux fait la substitution de ##tag## :
| Où | Substitue ##tag## ? | À quoi ça sert |
|---|---|---|
| Modèle de notification (corps et objet) | Oui - balises, FOREACH et ##lang.*## | Corps de courriel dynamique |
| Modèle de ticket (TicketTemplate) | Non | Prédéfinir, masquer ou rendre des champs obligatoires à la création |
| Modèle de tâche / suivi | Non | Texte de base réutilisable, sans substitution dynamique |
| Objet (sujet) de la notification | Oui | Les mêmes balises que le corps, sur une seule ligne |
Conseil final qui vaut tout le reste : en éditant un modèle de notification, GLPI affiche l'onglet des balises disponibles pour cet élément précis. C'est la source de vérité - contextuelle et toujours alignée sur la version installée. Avant de copier une balise d'un blog (celui-ci compris), vérifiez qu'elle y figure.
Besoin de notifications qui informent vraiment - multilingues, avec le bon demandeur et sans courriel bloqué dans la file ? Découvrez le service de maintien GLPI de NexTool.
Révisé par l'équipe NexTool Solutions.