Notifications avancées

Une API générique pour créer des notifications.

Description

Ce plugin est avant tout un outil de développement, qui permet de déclarer des notifications possibles et fournit des moyens pour gérer des abonnements et des désistements pour celles-ci.

On part du principe qu’une notification c’est :

  • un contenu, possiblement en plusieurs format (texte brut, HTML, court)
  • des destinataires par défaut, choisis par la notification elle-même
  • des destinataires explicites, qui se sont abonnés
  • des rabats-joie qui veulent bloquer une notification
  • optionnellement des préférences qui conditionnent l’envoi ou pas pour un destinataire
  • des modes d’envoi (email, jabber, sms, pigeon...)

Tous ces éléments sont alors programmables lors du développement de la notification, de manière assez fines, et toujours optionnelle. On peut donc déclarer une notification avec juste un squelette SPIP, ou bien imaginer des choses plus complexes.

Appeler une notification

Tout d’abord, pour utiliser une notification, il faut qu’elle soit appelée quelque part. C’est la fonction classique de SPIP :

// Chargement de la fonction
$notifications = charger_fonction('notifications', 'inc/');

// Appel générique
$notifications('truc', $id, $options);

// Exemple
$notifications('patate_instituer', $id_patate, array('avant' => $statut_avant, 'apres' => $statut_apres));

Contenu de la notification

Une notification sans contenu, c’est comme une mouche sans ailes. Plusieurs moyens sont proposés pour indiquer ce qui sera envoyé.

Uniquement en créant des squelettes

  • notifications/truc.html correspond au texte brut de la notification, c’est le minimum à fournir pour l’envoi par email
  • notifications/truc_html.html correspond à la version HTML
  • notifications/truc_court.html correspond au format court, de type SMS ou Microblog (limité en caractères, donc)

Ces trois squelettes reçoivent diverses informations utiles en contexte :

  • quoi : le nom de la notification
  • id : l’identifiant passé en paramètre
  • options : l’éventuel tableau d’options
  • mode : le mode d’envoi pour lequel on est en train de générer le contenu
  • destinataire : un id_auteur (souvent) ou bien une information de contact (adresse email par exemple)
  • contact : toujours l’information de contact en rapport avec le mode d’envoi utilisé
  • objet, id_objet, id_truc : les informations sur l’objet concerné par la notification en utilisant le même principe que pour les modèles : le premier mot du nom de la notification est le type de l’objet (article_instituer, patate_supprimer, etc).

En passant par PHP

Vous pouvez aussi créer une fonction notifications_truc_contenu_dist($id, $options, $destinataire, $mode) dans le fichier notifications/truc.php. Cela permet parfois plus de possibilités ou de lisibilité.

Cette fonction prend en paramètre l’identifiant et le tableau d’options qui ont pu être passé dans la notification, mais aussi le destinataire à qui est en train d’être envoyé le message (un id_auteur ou une info de contact, comme précédemment), ainsi que le mode d’envoi (« email » par exemple).

La fonction peut soit renvoyer directement un texte, ce qui correspondra au texte brut de la notification, soit renvoyer un tableau avec trois clés optionnelles :

  • texte : le texte brut du message
  • html : la version HTML
  • court : la version courte

Pour chaque possibilité, si la clé n’existe pas dans le tableau, alors le plugin cherchera le squelette correspondant dans la première méthode, sinon rien.

Destinataires

Désormais, votre notification existe. Mais elle ne sera jamais envoyée à personne si elle n’a pas de destinataires ! Le plugin permet trois sources d’où peuvent provenir les malheureux spammés. :) :

  1. Une liste définie lors du développement de la notification.
  2. Des gens abonnés explicitement, stockés dans une table de la base.
  3. Ces deux sources s’additionnent, et une fois la liste constituée, elle passe dans le pipeline notifications_destinataires, et peut donc être étendue.

Destinataires par défaut

Vous pouvez définir les destinataires d’une notification en créant la fonction notifications_truc_destinataires_dist($id, $options) dans le fichier notifications/truc.php.

La liste est un tableau donc chaque élément est un destinataire. Ce dernier peut être décrit de trois manières différentes suivant vos besoins ou infos à votre disposition :

  • un id_auteur : c’est le cas le plus courant et le plus générique, car il permet ensuite d’envoyer par plusieurs modes d’envoi
  • une adresse de courriel : dans ce cas seul le mode d’envoi « email » pourra être utilisé, c’est un cas possible pour des forums publics par exemple où les gens ne sont pas inscrits
  • un tableau explicite des modes d’envoi : enfin on peut décrire explicitement comment sera envoyé le message à un destinataire, avec un tableau dont chaque clé est le nom d’un mode d’envoi, et la valeur de la clé est l’information de contact pour ce mode d’envoi

Exemple :

function notifications_truc_destinataires_dist($id, $options){
	return array(
		16, 38,12,  // des id_auteur
		'paul@personne.fr', 'livarot@fromage.com', // des emails
		array( // un tableau explicite pour UN destinataire
			'email'=>'truc@bidule.net',
			'sms'=>'0606060606',
			'jabber'=>'truc@jabber.fr'
		),
	);
}

Destinataires abonnés

La deuxième méthode consiste à fournir à vos utilisateurs des moyens pour s’abonner explicitement à une notification. Le plugin contient donc une table dédiée à cela, ainsi que des actions.

La table des abonnements contient :

  • id_auteur : l’utilisateur concerné par cet abonnement, peut valoir 0 si on utilise plutôt l’information de contact
  • contact : une information de contact si ce n’est pas pour un utilisateur inscrit (par exemple une adresse email)
  • quoi : le nom de la notification
  • id : l’identifiant éventuel pour cette notification
  • preferences : un éventuel tableau (sérialisé pour le stockage) contenant les préférences de l’abonné, si la notification en utilise
  • modes : un tableau (sérialisé aussi) contenant la liste des modes d’envoi à utiliser pour cet abonné ; si cette liste est vide, cela signifie que l’utilisateur ne veut PAS recevoir cette notification (blacklist)
  • actif : 1 pour activer l’abonnement, 0 pour le désactiver

Action « abonner_notification »

Cette action permet d’abonner peut être utilisée soit telle quelle pour un abonnement très simple, soit dans le traitement d’un formulaire.

Par défaut, elle abonne l’utilisateur actuellement connecté, uniquement par email, en prenant en paramètre la notification « quoi-id » :
#URL_ACTION_AUTEUR{abonner_notification, truc-32}

Mais on peut aussi l’appeler en PHP :

$abonner = charger_fonction('abonner_notification', 'action/');
$abonner('truc-32', $modes, $preferences);

On peut donc optionnellement passer deux tableaux $modes et $preferences, qui seront utilisés pour cet abonnement.

L’action sait aussi récupérer les POST contact pour l’information de contact si ce n’est pas pour un utilisateur, modes et preferences qui seront utilisés si on ne les fournit pas à la fonction.
On peut donc facilement utiliser cette fonction comme traitement d’un formulaire.

À terme le but est de savoir générer automatiquement des formulaires pour s’abonner ou pour configurer des abonnements.

Programmer des préférences

Une notification complexe peut définir une fonction qui indiquera pour chaque destinataire abonné (ceux qui sont dans la table) s’il doit recevoir ou pas le message suivant des préférences qu’il aurait.

Pour cela il faut définir une fonction notifications_truc_preferences_dist($id, $options, $preferences) dans le fichier notifications/truc.php.

En plus des informations classique de la notification, la fonction reçoit les préférences d’un destinataire. Normalement ces dernières ne sont jamais vides puisque la fonction n’est justement appelée que s’il y a des préférences.

On doit renvoyer « true » ou « false », suivant que le destinataire doit être ajouté ou pas.

Ne plus recevoir une notification

Le système d’abonnements explicites permet de s’assurer que vos utilisateurs veulent vraiment recevoir une notification. Mais comme nous l’avons vu, certaines notifications définissent elles-mêmes leur liste de destinataires, et ces derniers n’ont donc pas leur mot à dire.

Avec la même table, on permet donc la désinscription explicite à une notification. Vous pouvez donc proposer à vos utilisateurs de ne surtout pas recevoir telle ou telle notification.

Pour cela, il faut les abonner à une notification avec une liste de modes d’envoi vide. Cela signifiera qu’ils sont blacklistés pour cette notification.

Modes d’envoi

Les modes d’envoi sont un ensemble de fonctions PHP placées dans notifications/modes/bidule.php.

Pour implémenter un nouveau mode d’envoi, il faut deux fonctions :

  • notifications_modes_bidule_envoyer_dist($contact, $contenu) qui va envoyer le contenu au contact par le mode bidule
    • $contact contient une information de contact déjà vérifiée et cohérente avec le mode
    • $contenu est un tableau pouvant contenir « texte », « html » et « court », les trois formats de message
  • notifications_modes_bidule_contact_dist($destinataire) qui doit renvoyer une information de contact cohérente avec le mode en question (une adresse email pour le mode « email », un numéro pour le mode « sms », etc) par rapport au destinataire passé en paramètre
    • $destinataire peut être une information de contact à vérifier et si c’est bon la garder, sinon renvoyer « null »
    • ou bien cela peut être un id_auteur, et dans ce cas la fonction doit essayer de trouver une information de contact valable pour ce mode en rapport avec cet id_auteur, sinon renvoyer « null »

Il faut ensuite créer un fichier bidule.yaml au même endroit, afin de déclarer ce mode d’envoi. Le fichier doit contenir :

titre: 'Nom du mode'
description: 'Une description un peu plus longue'

# On peut utiliser des chaînes de langue simple
titre: '<:truc:bidule_titre:>'

Encore à faire

Le noyau des fonctionnalités est normalement assez complet. Maintenant ce qu’il manque, ce sont les interfaces et formulaires prêt-à-l’emploi pour gérer les notifications.

Il faudrait donc faire :

  • un formulaire de configuration pour les admins qui liste automatiquement toutes les notifications déclarées afin de les activer ou pas pour l’ensemble du site
  • un formulaire pour gérer les abonnements d’un auteur (un début simple existe) listant ses abonnements actuels et permettant de les modifier
  • un formulaire permettant de créer ou modifier un abonnement et sachant automatiquement générer les champs pour les préférences qui auraient été décrites dans le fichier de déclaration de la notification (en YAML)

Discussion

15 discussions

  • 4

    Bonjour,

    Dans le cadre d’un plugin perso, j’utilise les notifs avancées. mais je me confronte à un souci d’incompréhension depuis 2jours. Je m’explique :

    Mon plugin utilise un formulaire CVT. Dans Traiter j’institue l’objet via action/intituer_objet qui lui meme inclue un action/editer_objet. Au passage (changement statut, et autres fonctions) j’envoie une notification à l’auteur. Jusque là tout va bien.

    La ou je coince, c’est que je souhaiterai envoyer un champs supplémentaire aux $options de ma notification depuis une de mes variable de formulaire.
    Genre dans traiter : $options[perso] = _request(’perso’) ;
    mais comment l’envoyer dans la notification ? une aide serait la bienvenue svp :)

    merci d’avance

    • Je ne suis pas sûr de comprendre la question. Si c’est toi qui appelle la notification dans ton code, alors tu peux mettre ce que tu veux dans le tableau en troisième argument de la fonction, non ? Ce troisième paramètre est complètement libre et sert justement à mettre ce qu’on veut.

    • Il est vrai que j’ai du mal a m’expliquer correctement :)

      La notification est bien appelée dans le code de action/editer_objet utilisé dans mon action/instituer_objet. Et en effet je peux tout a fait faire un $options[perso]= $perso ;
      Mais cette fonction instituer_objet générique est utilisée soit en dur dans mon form_traiter, soit dans un pipeline (en fonction des traitements). j’essaye de trouver une solution pour brancher depuis le formulaire traiter cette fameuse variable $perso dans action/editer_objet.

      sinon autre solution peut etre, passer par le pipeline notifications_truc_contenu_dist($id, $options, $destinataire, $mode) ? Mes notifs avancées ont des squelettes :
      -  notifications/objet.html
      -  notifications/objet_html.html
      -  notifications/objet_court.html
      c’est soit le pipeline, soit les squelettes ? ou bien le pipeline surcharge les squelettes ?

      Sinon existe t il un moyen d’ajouter à $options[] avec un pipeline depuis n’importe où ?

      j’essaye d’être clair mais je reconnais qu il est compliqué de comprendre la question.

    • Tout ce plugin ne fait que se brancher, utiliser, les appels à la fonction notifications() de SPIP qui existe déjà. Toutes les fonctions de ce plugin reçoivent en paramètre ce qui a été défini une fois pour toute lors de l’appel de la notification.

      Ce que je ne comprends pas c’est si c’est TOI qui appelle la notification dans TON code. Ou si c’est appelé dans un code générique de SPIP que toi tu appelles (ça a l’air d’être ça). Si ce n’est pas TOI qui appelle la notification, et bien forcément t’as pas la main sur l’appel et donc tu peux pas modifier les paramètres.

      C’est en SPIP 2 ou 3 ? (editer_objet et instituer_objet c’est en 3 à priori)

      Par contre tu peux ne pas utiliser cette notification par défaut et ajouter TA notification dans ton code, en appelant par exemple notifications('patate_instituer', $id_patate, $optionsquetuveux)

    • C’est bien un spip 3, apres j’ai mis ’objet’ mais il ne s’agit pas des fonctions du core.

      Ma notification est bien appelée dans mon editer_’objet’ sous la forme $notifications(’objet_relou’, $id_commande, $options) ;
      mais je me demandais si il y avait une solution pour envoyer via un pipeline entre mon formulaire et la partie instituer.

      Au final solution simple : j’ai simplement inséré un champ supplémentaire dans ma base et au moment d’instituer si celui ci est plein je le rajoute à $options[]
      Ainsi je peux contextualiser mon message dans mon notifications/objet_html.html en testant la valeur de [(#ENVoptions|table_valeurperso)]

      Merci beaucoup pour ton aide :)

    Répondre à ce message

  • 2

    Bonjour à nouveau.
    Un doute, ce code pourrait « intercepter » qui a ete publié un article, et quelle rubrique il appartient, pour envoyer une notification à un array d’e-mails ?
    Il est très compliqué ?
    Merci

    • C’était déjà possible avant ce plugin, il y a déjà une notification appelée lors du changement de statut d’un article.

      Exactement ici :
      http://core.spip.org/projects/spip/repository/entry/branches/spip-2.1/ecrire/action/editer_article.php#L267

      Ce plugin permet de faciliter l’écriture des notifications en découpant les différentes étapes. Tu peux donc définir un squelette du nom de cette notification + une fonction PHP renvoyant un tableau de destinataires, comme l’indique la documentation, et alors ce squelette sera envoyé à cette liste.

    • Merci. Cela peut me donner des indices. J’avais essayé de modifier instituerarticle.php pris le id_rubrique pour sélectionner les auteurs attachés par le plugin acces restreint et utiliser mon propre array $destinataires, mais ne fonctionne pas :-( J’espère que cela va m’aider à suivre.

    Répondre à ce message

  • 2

    Hola
    Je vous remercie pour vos nombreuses contributions à la communauté SPIP !
    J’ai un besoin urgent d’un plugin comme celui-ci d’envoyer des mises à jour des sections différentes à différents visiteurs choisissant parmi une liste de sections et de visiteurs, mais je ne sais pas de programmation.
    J’écrire pour demander si vous avez déjà une interface en version bêta à tester dans l’action et de voir si il peut être utile pour moi parce que je ne pouvais pas le faire fonctionner sans interface :-(
    Merci.

    • Malheureusement, il n’y a pas encore de vraie interface déjà toute prête pour les utilisateurs. :(

      J’avais commencé un peu, mais c’est loin d’être terminé, et pour l’instant je n’ai plus le temps d’avancer sur ce plugin.

    • Merci pour votre réponse. Salut !

    Répondre à ce message

  • 7

    Hello

    Je bloque sur l’utilisation de ce plugin, au niveau de l’envoi... J’ai regardé des exemples d’utilisation des notifications. Ce que j’ai compris :

    Dans le fichier notifications/commande_instituer.php, j’ai une fonction notifications_commande_instituer_dist.

    En gros elle crée les destinataires via le pipeline destinataires :

    $destinataires = pipeline('notifications_destinataires',  array(
      'args'=>array('quoi'=>$quoi,'id'=>$id_commande,'options'=>$options),
      'data'=>$destinataires)
     );

    Puis nettoyage : notifications_nettoyer_emails($destinataires) ;

    Dans les exemples qui utilisent les notifications du core ou le plugin notifications, on appelle ensuite notifications_envoyer_mails($destinataires, $msg_mail,$sujet_mail) qui accepte un tableau de destinataires.

    Mais cette fonction n’existe pas dans Notifications Avancées. Je pensais appeler notifications_envoyer(), mais elle n’accepte qu’un destinataire...

    Où j’ai pas bon ?

    Merci

    • Je ne comprends pas ce que tu essayes de faire.

      La doc me parait pourtant claire et bien séparée en chapitre : si tu veux définir des destinataires explicitement, tu crées une fonction notifications_truc_destinataires_dist(). Je ne répète pas ici ce que ça doit renvoyer, c’est écrit plus haut.

    • Je ne suis pas clair, car je n’ai sans doute pas compris le principe des notifications ?

      Bref, je pige comme on definit les destinataire et j’ai bien un contenu dans notifications/truc.html, truc_html.html et truc_court.html...

      C’est la 3e étape qui coince... Comment déclenche t’on l’envoi ? Dans les exemples que j’ai vu, faut appeler la fonction notifications_envoyer_mails() que je ne trouve pas dans ce plugin.

    • Mais ya jamais eu rien à faire. Ça s’envoie tout seul du moment que ya au moins un mail.

      Mais tu appelles la fonction notifications() un jour ? :)
      L’appel qui déclenche une notification comme toujours :

      $notifications = charger_fonction('notifications', 'inc/');
      $notifications('commande_instituer', $id_commande, $options);
    • Mais je te répète qu’il n’y a rien à faire, il faut juste qu’il y ait au moins un destinataire dans la liste et un contenu existant fournit soit pas un squelette soit par la fonction PHP « truc_contenu ».

      Tu vois bien là :
      http://zone.spip.org/trac/spip-zone/browser/_plugins_/notifications_avancees/trunk/notifavancees_pipelines.php#L6

      que la fonction « notifications_envoyer » est automatiquement appelée par le plugin dès lors qu’il y a au moins un destinataire.

    • Et en plus dans ce nouveau système ya PAS du tout « notifications_commande_instituer_dist » !

    • Ayé, compris... Je n’avais pas vu l’appel du pipeline avant l’appel classique dans ecrire/inc/notifications.php dans la fonction inc_notifications_dist. Peut-être peut-on rajouter ce texte dans le paragraphe « Appeler une notification » :

      C’est le seul appel nécessaire par le plugin utilisateur. Celui-ci doit juste ensuite fournir des éléments utiles à la constitution de la liste des destinataires et du contenu sous forme de squelettes ou de fonctions php correctement nommées et rangées dans un dossier notifications (Cf ci-dessous). Contrairement au fonctionnement des notifications du core ou du plugin Notifications, c’est le plugin Notifications Avancées (via son pipeline notifications_envoyer()) qui s’occupe de rassembler tous ces éléments afin de créer et d’envoyer la notification (il n’est plus nécessaire d’écrire une fonction php dans le plugin appelant pour le faire)

      Ca fonctionne bien et c’est plus facile a mettre en oeuvre (maintenant que j’ai pigé). Bravo.

      Pour le plugin commandes, on peut donc rajouter un « utilise ». Et spécifier que les notifications de commandes ne fonctionnent que si ce plugin est installé ?

    Répondre à ce message

  • 2

    Hello

    Pour continuer la demo Z-Commerce, je suppose qu’il vaut mieux utiliser ce plugin que l’ancien notifications ? Isn’t it ?

    • Ben j’en sais rien parce que pour l’instant ça ferait une dépendance en plus du coup.

      Parce que l’ancien c’est juste un plugin qui ajoute des notifications, mais la fonction notifications elle est dans le core. Là ce plugin il modifie la façon dont on crée les notifications, c’est encore autre chose.

      J’ai pas vraiment d’avis pour l’instant.

    • En fait je n’avais pas encore compris le fonctionnement et donc pas vu que la fonction est dans le core. Donc effectivement, pas besoin de plugin.

      Du coup si je déplace ces notifications de zcommerce à Commandes, le paramétrage éventuel du vendeurs (tous les admins ou uniquement webmestres) à notifier peut se faire dans le formulaire de config de Commandes.

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom