Mettre en place un système de notifications sur Drupal 8

bûches d'arbre

Pour bon nombre de projets Drupal 8 qui disposent d'un minimum d'interactions avec ses utilisateurs, le besoin de mettre en place un système de notifications arrive rapidement sur le devant de la scène. Etre notifié d'un nouveau commentaire, d'une réponse à un commentaire, d'une nouvelle publication sur tel ou tel sujet, ou de tel utilisateur, sont des besoins récurrents.

Nous pouvons pour satisfaire ce type de besoin nous appuyer sur le module Message (et la stack liée à Message) qui peuvent nous permettre d'arriver à ce type de résultat avec l'aide du module Flag. Mais nous n'allons pas parler ici de ces deux modules somme toute génériques, et qui peuvent donc faire bien plus, mais d'un nouveau module Entity Activity dont l'unique vocation est de journaliser tout type d'action effectuée, par utilisateur selon ses abonnements, sur un projet.

Le module Entity Activity va nous permettre de générer tout type de message, sur tout type d'entité de contenu sur les 3 principales opérations du cycle de vie d'un contenu : sa création, sa mise à jour et sa suppression.

Configuration globale

La configuration initiale du module est assez rapide à mettre en place. La majorité de la configuration à faire se passe depuis le menu Configuration > Rédaction de contenu > Entity Activity

Dans un premier temps, il s'agit d'activer sur quels types d'entités vous souhaitez pouvoir générer des notifications. Et donc bien sûr permettre aux utilisateurs de s'abonner à ces entités.

Entity Activity Settings

Vous pouvez par la même occasion configurer si nécessaire une purge des différentes notifications (basées soit sur le temps de façon globale, soit un nombre maximum de notifications par utilisateur).

Support multilingue

Pour les projets multilingues, les abonnements sont également multilingues dans le sens où un utilisateur peut s'abonner à un contenu pour chacune de ses traductions disponibles de façon indépendante. Les messages des notifications sont alors générés dans la langue courante lorsque l'opération est effectuée. Vous pouvez forcer la génération d'un message de journal dans la langue préférée de l'utilisateur (si définie), en cochant l'option correspondante dans les paramètres généraux.

User preferred language option

Attention. cette option est coûteuse en performance du fait que chaque message de journal doit être regénéré pour chaque propriétaire d'un abonnement. Ne l'utilisez que si vous avez réellement besoin que les messages de journal soit générés dans la langue préférée de l'utilisateur.

Configuration des entités de contenu activées

Dans un second temps, nous allons configurer les modes d'affichages des entités que nous avons activées, pour afficher le composant Subscribe on qui va permettre aux utilisateurs de s'abonner (ou se désabonner) sur chacune des entités.

Article subscribe on

Vous pouvez alors afficher sur les différents modes d'affichages nécessaires, sur les différents types de contenu, ce bouton Subscribe on, comme ci-dessus avec l'exemple du type de contenu Article.

A partir de maintenant les utilisateurs, avec bien sûr la permission adéquate, vont pouvoir s'abonner et se désabonner sur chaque entité activée et paramétrée. Et ils vont pouvoir retrouver depuis leur compte un récapitulatif de tous leurs abonnements.

User's subscriptions

A noter que le bouton Remove sur chaque abonnement est présent du fait qu'il a été activé sur le mode d'affichage de l'entité Subscription depuis la page de configuration Configuration > Content Authoring > Entity Activity > Subscriptions settings > Manage display.

Configuration des générateurs de notifications.

Dans un troisième temps nous devons configurer quels messages seront générés depuis quelle opération et pour quels abonnements. A cette fin, nous pouvons créer autant de Générateurs que nécessaires selon les besoins d'un projet.

Entity Activity Generators

 

Chaque générateur de notification dispose de base de 4 types de plugin correspondant aux 4 types d'entités de contenu principal d'un projet Drupal 8, à savoir les contenus, les termes de taxonomie, les utilisateurs et les commentaires. Il est possible de rajouter autant de plugin que nécessaire pour des besoins spécifiques à un projet, mais nous aurons l'occasion de voir cela plus loin.

La configuration de ces Plugin est identique et suit la même logique.

Plugin log generator

Les options de configuration possible (en anglais) sont les suivantes.

  • Enable : si le plugin est actif ou non
  • Published : option pour ne générer une notification que si l'entité cible est publiée
  • Operation : le type d'opération depuis lequel le plugin doit générer une notification (création /  mises à jour / suppression)
  • Bundles : il est possible de limiter l'action d'un plugin à seulement un ou plusieurs paquets d'une entité de contenu. On peut laisser vide pour appliquer le plugin à tous les paquets indifférement.
  • Subscribed on : c'est ici l'option de configuration en quelque sorte maîtresse. Elle permet de définir à partir de quels abonnements le plugin va générer la notification. Les 2 options possibles sont Source Entity et Entity Referenced. La première (Source Entity) est la plus basique et permet de sélectionner les abonnements qui ont été réalisées sur l'entité elle-même (le contenu, l'utilisateur, etc.). La seconde option (Entity Referenced) va elle permettre de sélectionner les abonnements effectués sur une entité référencée (depuis un champs Entity Reference donc) par l'entité en cours. Le cas d'usage typique est de pouvoir générer une notification pour tous les utilisateurs abonnés à un thème Alpha (Terme de taxonomie) lorsque un nouveau contenu est publié sur ce thème, ou encore un autre cas d'usage est la génération d'une notification lors de la publication d'un commentaire relatif à un contenu. Mais les possibilités ici sont extrêmement variées et d'innombrables cas d'usage peuvent être couvert avec cette seconde option. Dans l'exemple ci-dessus nous avons choisi ici de générer une notification lors de la publication d'un contenu à tous les utilisateurs qui se sont abonnés à l'auteur du contenu.
  • Include parent term : cette option permet d'inclure tous les termes parents dans le cas où l'entité sur laquelle les abonnements sont recherchés est un terme de taxonomie. Utile si on souhaite qu'un utilisateur ayant souscrit au terme de taxonomie Fruit par exemple soit également notifié si un contenu est publié avec le terme de taxonomie Orange, qui serait un enfant du terme Fruit.
  • Log message : Il s'agit bien sûr ici du message qui sera généré et notifié aux utilisateurs. Vous pouvez configurer le format de texte à utiliser, et vous pouvez bien sûr utiliser tous les tokens relatifs à l'entité cible du plugin.
  • Use cron : cette option permet de débrayer la génération des notifications proprement dites de l'opération effectuée sur l'entité. En effet selon le nombre d'abonnements, la génération de toutes les notifications peut être un processus long et coûteux en performance. Cette option permet alors de déléguer aux taches planifiées la génération de ces notifications, permettant de ne pas pénaliser l'utilisateur qui effectue l'opération en question. Cette option est très vivement recommandée.

Vous pouvez alors créer et activer autant de générateurs de notifications pour couvrir tous les besoins métier de votre projet, chaque générateur de notifications pouvant lui-même disposer de plusieurs plugin en charge de la génération de la notification elle-même.

Configuration des notifications

Pour finaliser la mise en place de votre système de notification, vous pouvez alors configurer 2 éléments sur les entités Log du module qui portent ces notifications.

Depuis la page Configuration > Content authoring > Entity Activity > Log settings > Manage Display

Log manage display

Vous pouvez activer le champ extra Remove log, qui va exposer un bouton permettant au propriétaire de la notification (l'utilisateur qui s'est abonné) de supprimer cette notification (si il dispose de la permission adéquate).

Et vous pouvez également configurer le champ de base Read, avec le formateur de champs Log read / unread, ce qui aura pour effet d'exposer un bouton permettant au propriétaire de la notification de changer le statut de Non lu à Lu ou inversement.

Informer l'utilisateur de nouvelles notifications

Tout ceci n'est vraiment utile que si les utilisateurs peuvent être informés facilement de la présence de nouvelles notifications. A cette fin le module propose un block intitulé User log block, qui doit être placé et configuré dans la région adéquate du thème du projet.

User log block settings

Ce block a pour but d'afficher le nombre total de notifications non lues. A cette fin vous pouvez rajouter un (court) texte qui sera affiché à côté de ce nombre, vous pouvez utiliser une police d'icône pour afficher une icône à côté de ce chiffre (en utilisant les classes de cette police), mais aussi configurer le nombre maximum de notifications qui seront embarquées ainsi que le mode d'affichage utilisé pour les afficher, ainsi que rajouter un lien vers la page de l'utilisateur listant toutes ses notifications, quelque soit leur statut. Bien sûr vous pouvez surcharger le template Twig pour personnaliser à volonté le rendu de ce block. 

Extension du module Entity Activity

Du fait que les générateurs de notifications s'appuient sur un type de plugin, il est possible de créer son propre plugin pour rajouter une logique très spécifique à un projet, en surchargeant les méthodes de base utilisées, ou tout simplement pour supporter une nouvelle entité de contenu provenant d'un module contribué.

Les plugins doivent être placés sur le namespace Plugin/LogGenerator et peuvent ressembler à ceci par exemple si on souhaite surcharger et rajouter une logique très particulière sur une ou plusieurs des méthodes de ce type de Plugin:

/**
 * @LogGenerator(
 *   id = "my_custom_node",
 *   label = @Translation("My custom Node Log Generator"),
 *   description = @Translation("Generate custom log for the entity type Node or for related entities referenced."),
 *   source_entity_type = "node",
 *   bundles = {}
 * )
 */
class MyCustomNodeLogGenerator extends LogGeneratorBase {

  public function getEntitiesSubscribedOn(ContentEntityInterface $entity) {
    // Stuff.
  }
  
  public function preGenerateLog(ContentEntityInterface $entity, AccountProxyInterface $current_user = NULL) {
    // Stuff.
  }

  public function generateLog(array $settings) {
    // Stuff.
  }

}

Le module expose également deux paramètres qui peuvent être surchargés depuis le fichier settings.php d'un projet.

$settings['entity_activity_max_log'] = 100;

Ce paramètre permet de surcharger le nombre maximum de notifications (par défaut 50) qui peuvent être marquées comme lues en masse par un utilisateur. En effet celui-ci dispose d'un bouton sur sa page listant ses notifications qui permet de marquer en masse toutes ses notifications comme lues. Ce paramètre définit donc le nombre de notifications qui seront traitées par passe dans le processus de mise à jour qui sera alors lancé.

$settings['entity_activity_purge_user_always'] = TRUE;

Ce paramètre permet de forcer la purge par utilisateur (nombre maximum de notifications par utilisateur) à chaque execution d'une tache planifiée. En effet cette méthode de purge peut être très coûteuse en temps et en performances, selon le nombre d'utilisateur à traiter. Aussi par défaut, cette méthode n'est exécutée qu'une seule fois par jour, la nuit. Ce paramètre permet donc de passer outre ce comportement par défaut.

De plus, les notifications et les abonnements fournis par ce module sont elles-même des entités de contenu. A ce titre elles peuvent donc être personnalisées notamment par l'ajout de champs supplémentaires. Dans ce cas il revient alors au projet de définir la valeur de ces champs de façon programmatique en fonction des besoins métiers. A cette fin, des événements sont dispatchés pour chaque hook implémenté par Drupal sur le cycle du CRUD (presave, postsave, update, insert, delete, etc.).

Enfin les entités fournies par ce module (Log et Subscription) disposent d'un rendu de base pouvant convenir à de nombreux cas d'usage. Le rendu de ces entités s'appuie fortement sur un template Twig que vous pouvez alors surcharger pour répondre vos besoins.

Evolutions possibles

A ce jour Entity Activity permet donc de configurer rapidement un projet pour générer des notifications à destination des utilisateurs en fonction de leur abonnements. Il peut aussi être étendu aisément au moyen des Plugins pour rajouter des logiques métiers particulières si besoin. Une évolution naturelle serait de pouvoir générer et envoyer par mail (selon une fréquence choisie par l'utilisateur) une liste des dernières notifications non lues, même si pour l'instant cette fonctionnalité ne fait pas partie du périmètre fonctionnel du module. Mais un développeur Drupal 8 pourra aisément rajouter cette fonctionnalité (que ce soit dans le module lui-même ou un module contribué autre), les fondations posées ouvrant de nombreux possibles par rapport à cette thématique récurrente sur des projets à vocation communautaire.

Conclusion

En guise de conclusion, Entity Activity se veut un module simple de configuration, car centré exclusivement sur la génération de notifications, ou encore de journalisation d'événements se produisant sur un projet Drupal 8. Mais cette simplicité ne se fait pas au détriment de la modularité nécessaire quant à la génération (et leurs conditions sous-jacentes) des différentes notifications pour couvrir la plupart, si ce n'est pas tous, des cas d'usage et besoins récurrents.

 

Commentaires

Soumis par Ibrahima (non vérifié) le 10/05/2019 à 17:25 - Permalien

Bonjour, j'ai suivez votre tutoriel et au niveau de gestion de l'affichage...le bouton "Subscribe on" ne s'affiche pas.

Soumis par Mathieu (non vérifié) le 29/05/2019 à 09:52 - Permalien

Peut-on créer des options pour le lien Souscrire ? Comme dans mon drapeau J'aime :
https://imgur.com/a/sDfzXJt
Ou alors intégrer Flag à ce module, comme le fait Message Subscribe :
"Subscribing is naturally done using Flag module. There’s no assumption related to the amount of Flags you have - as long as you prefix your flag name with subscribe_ Message-subscribe treats it as a valid flag."

Y a t'il une fonctionnalité comme Message Digest ? Recevoir un email à chaque notification risque d'être lourd pour la personne qui a souscrit.

Pensez vous intégrer les notifications PUSH avec une PWA ?

Merci

Soumis par Christophe Natale (non vérifié) le 08/04/2020 à 16:50 - Permalien

Bonjour et merci pour ce module qui a l'air pratique.
J'ai toutefois un problème de js.
Lorsque je suis la procédure décrite plus haut, lorsque je vais sur un nœud
le bouton abonner apparaît.
Mais lorsque je clique dessus j'ai une erreur 404.
Je précise mon chemin vers le noeud est :
https://www.exemple.com/dev/digitalgreta/drupal8/web/test-11
dans la console de chrome j'ai :
jquery.min.js?v=3.4.1:2 POST https://www.exemple.com/ea/api/subscription/add 404
le chemin n'est pas respecté.
je me demande si c'est pas lié au fichier subscribe_on.js:
ligne 23 : $.ajax('/ea/api/subscription', {

Soumis par F. Victoire (non vérifié) le 09/06/2021 à 11:46 - Permalien

Bonjour,

J'ai activé le module, j'ai mis dans l'affichage d'un de mes type de contenu le champs "subscribe on", j'ai configurer 2 logs generators sur des noeuds (en update et en insert), j'ai désactivé 'use cron' pour avoir des logs immédiats, j'ai créé puis modifié trois noeuds; dans les journaux des logs, aucun log n'a été généré.
Qu'ai-je loupé dans la configuration ?
J'ai remarqué qu'il y a avait dans la page Entity Activity, il y avait les onglets 'Abonnement' (Subscriptions) et 'paramêtres d'abonnement'. A quoi servent-ils ?

Ajouter un commentaire