Carnet Wiki

Compléments trilogie mailshot

Version 17 — Mai 2020 JLuc

La trilogie c’est
-  mailshot : gestionnaire d’envois
-  mailsubscriber : gestionnaire de listes
-  newsletter : créateur de mails

Nouveautés (à reporter dans la doc officielle)

Forcer la synchronisation d’une liste dynamique

La synchronisation des listes dynamiques se fait automatiquement 1 fois toutes les 24h. Si vous avez laissé passer ce moment, que vous savez que votre liste à changé (par exemple parce que vous êtes en train de mettre au point sa fonction de définition dynamique), vous pouvez forcer la synchronisation en vous rendant dans la page Maintenance > Liste des travaux. Là vous trouverez une tâche mailsubscribers_synchro_lists dont vous pourrez forcer l’exécution en cliquant sur le bouton « Exécuter ». Cette tâche parcours alors toutes les listes dynamiques, et demande leur synchronisation... Cela se traduit par la création d’un nouveau job de synchronisation pour chacune des listes dynamiques définies. À ce moment, vous pouvez attendre que les synchronisations de toutes vos newsletters se fasse. Ou bien vous pouvez forcer l’actualisation immédiate de la newsletter de votre choix, en cliquant sur le bouton « exécuter » de cette tâche. Et par la suite, tant que cette tâche sera visible sur la page Liste des travaux, il vous sera possible de forcer à nouveau la synchronisation immédiate d’une liste.

La page Activité > Listes de diffusion montre le nombre d’abonnés à chaque liste et permet de savoir, au moins lors de la création de la liste, si la synchronisation s’est bien faite.

AJOUTÉ : un raccourci dans la page des listes de diffusions permet de forcer la resynchronisation. La resynchronisation se fait par le processus standard de tâches SPIP, et peut donc prendre quelques minutes avant d’être fait pour toutes les listes.

2 exemples du pipeline mailsubscriber_informations_liees définissant les segments

Par défaut, seuls les groupes de motclés qui s’appliquent sur la table spip_mailsubscribers des destinataires de mails peuvent générer une segmentation. Le 1er exemple utilise les motclés des auteurs pour qualifier les destinataires des listes et permettre leur segmentation selon les valeurs de ces motclés. Ici, les motclés des groupes 41 et 42 portant sur des auteurs sont utilisés pour qualifier les destinataires, lorsqu’il y a un auteur qui a ce même mail.

function premierexemple_mailsubscriber_informations_liees($flux){
	$id_groupes = array(41,42);
// Lorsqu'on est en train de qualifier un destinataire
	if (isset($flux['args']['email'])
	  and $id_mailsubscriber = $flux['args']['id_mailsubscriber']
	  and $email = $flux['args']['email']) {
// et s'il y a un auteur ayant son mail
		if ($id_auteur = sql_getfetsel('id_auteur','spip_mailsubscribers','id_mailsubscriber='.intval($id_mailsubscriber))) {
// On ajoute les mots associés à cet auteur figurant dans les groupes 41 et 42
			$mots = sql_allfetsel('M.id_mot,M.id_groupe','spip_mots as M JOIN spip_mots_liens as L on L.id_mot=M.id_mot','L.objet=\'auteur\' AND L.id_objet='.intval($id_auteur).' AND '.sql_in('M.id_groupe',$id_groupes));
			foreach($mots as $mot) {
				$id_groupe = $mot['id_groupe'];
				if (!isset($flux['data']['groupemots_'.$id_groupe])){
					$flux['data']['groupemots_'.$id_groupe] = array();
				}
				$flux['data']['groupemots_'.$id_groupe][] = $mot['id_mot'];
			}
	}
 
// Lorsqu'on est en train de déclarer les critères de définition d'un segment
// On déclare une saisie pour saisir un motclé de chacun de ces groupes
	if (isset($flux['args']['declarer'])) {
		$groupes = sql_allfetsel('id_groupe,titre','spip_groupes_mots',sql_in('id_groupe',$id_groupes));
		foreach($groupes as $groupe) {
			$flux['data']['groupemots_'.$groupe['id_groupe']] = array(
				'titre' => $groupe['titre'],
				'saisie' => 'mot',
				'options' => array(
					'id_groupe' => $groupe['id_groupe'],
					'forcer_select' => 'oui',
					'nom' => 'groupemots_'.$groupe['id_groupe'],
					'label' => $groupe['titre'],
					'class' => 'chosen',
				)
			);
		}
 
	}
 
	return $flux;
}

Dans le 2e exemple, on veut segmenter selon le code pays des destinataires, telque celui ci est défini par le plugin « Contacts et Organisation ». Là encore, c’est en fait l’auteur de même mail, lorsqu’il existe, qui est en fait référencé par « Contacts et Organisation ».

function deuxiemexemple_mailsubscriber_informations_liees($flux){
	$id_groupes = array(41,42);
// Lorsqu'on renseigne les caractèristiques des destinataires
	if (isset($flux['args']['email'])
	  and $id_mailsubscriber = $flux['args']['id_mailsubscriber']
	  and $email = $flux['args']['email']) {


$flux['data']['code_pays'] = array();
// S'il y a un auteur avec le même mail et que cet auteur est 'contact' avec le plugin "contacts et organisations", on va lui associer les codes pays de son contact et de ses organisations
		if ($id_auteur = sql_getfetsel('id_auteur','spip_mailsubscribers','id_mailsubscriber='.intval($id_mailsubscriber))
		  and $contact = sql_fetsel('*','spip_contacts','id_auteur='.intval($id_auteur))
		) {
// ib ajoute
			// deja le code_pays des mailings, par coherence
			if (!function_exists('contact_code_pays')) {
				include_spip('deuxiemexemple_fonctions');
			}
			if ($p = contact_code_pays($contact['id_contact'])) {
				$flux['data']['code_pays'][] = $p;
			}
			// puis tous les autres codes pays disponibles via les adresses et organisations
			if ($id_organisations = sql_allfetsel('id_organisation','spip_organisations_liens', "objet='contact' AND id_objet=" . intval($contact['id_contact']))) {
				$id_organisations = array_column($id_organisations, 'id_organisation');
				$id_auteurs = sql_allfetsel('id_auteur', 'spip_organisations', sql_in('id_organisation', $id_organisations));
				$id_auteurs = array_column($id_auteurs, 'id_auteur');
			}
			else {
				$id_auteurs = array();
			}
			$id_auteurs[] = $id_auteur;
			$id_adresses = sql_allfetsel('id_adresse', 'spip_adresses_liens', "objet='auteur' AND ".sql_in('id_objet', $id_auteurs));
			$id_adresses = array_column($id_adresses, 'id_adresse');
			$pays = sql_allfetsel('pays', 'spip_adresses', sql_in('id_adresse', $id_adresses));
			$pays = array_column($pays, 'pays');
			$flux['data']['code_pays'] = array_merge($flux['data']['code_pays'], $pays);
			$flux['data']['code_pays'] = array_filter($flux['data']['code_pays']);
			$flux['data']['code_pays'] = array_unique($flux['data']['code_pays']);
		}
	}


// Lorsqu'onn est en train de déclarer les saisies permettant de définir un segment,
// on ajoute la saisie d'un code pays
	if (isset($flux['args']['declarer'])) {


if ($pays = sql_allfetsel('code,nom','spip_pays','','','code')){
			$values = array_column($pays, 'nom', 'code');
			$flux['data']['code_pays'] = array(
				'titre' => $t=_T('pays:pays'),
				'valeurs' => $values,
				'saisie' => 'pays',
				'options' => array(
					'nom' => 'code_pays',
					'label' => $t,
					'class' => 'chosen',
					'champs_pays' => 'code',
					'code_pays' => 'oui',
					'multiple' => ' ',
					'size' => 10,
				)
			);
		}
	}
	return $flux;
}

Autre exemple de liste dynamique

/**
 * Mailing liste des auteurs abonnés
 * @return array
 **/
function mailsubscribers_synchro_list_newsletter_subscribers() {
	$id_auteurs = ids_auteurs_abonnes_valides_complets();
	$auteurs = sql_allfetsel(
		"DISTINCT(A.email),C.nom,C.prenom",
		"spip_auteurs AS A JOIN spip_contacts AS C ON (C.id_auteur=A.id_auteur)",
		array(
			sql_in('A.statut', array('1comite', '6forum')),
			sql_in('A.id_auteur', $id_auteurs),
			"A.email != ''"
		)
	);
	return $auteurs;
}

Autres modèles de Newsletter

- Le plugin [newsletters_modeles -> https://plugins.spip.net/newsletters_modeles.html ] propose des modèles de newsletter avec mise en page pleine largeur, en ligne ou en colonne.
- La page Autres modèles de NewsLetter recueille d’autres modèles de Newsletter.

Notification de désinscription

Les mails envoyés via mailshot par mailjet incluent un lien de désinscription. Lorsqu’un internaute clique ce lien, mailsubscriber le désinscrit et l’internaute reçoit un mail composé par l’assemblage des de chaines de langues définies par mailsubscriber, qu’il est possible de surcharger localement.

Embarquer des images

L’option « Embarquer les images » de facteur est surchargée par mailshot, si bien que les images ne sont jamais embarquées.

Il est toutefois possible d’embarquer les images avec mailjet + SMTP (mais pas avec l’API ni avec sparkpost) en créant dans mes_options.php une fonction bulkmailer_defaut qui reprend le code de bulkmailer_defaut_dist sauf pour la ligne qui force 'filtre_images' => false qui doit devenir 'filtre_images' => true .

Les segments

Il y a une doc maintenant : Utiliser les segments de listes. C’est donc juste là pour mémoire

Question : « j’ai des listes de destinataires "CA", "Adhérants", "intervenants", "presse" mais quand j’envoie une lettre à tous ces groupes, ceux qui font partie de plusieurs groupes la reçoivent en multiple exemplaires. Comment fonctionnent les segments et cela puis je m’en servir ? »

Edit 19/05/20 : depuis Mailshot V1.26.1, il y a une option qui evite d’envoyer la meme newsletter a un email qui l’a deja recue
cf https://git.spip.net/spip-contrib-extensions/mailshot/commit/669336e306b337e942bae95d3517b667695345d7

Réponse à confirmer et préciser : Le mieux est de commencer par créer un nouveau groupe de motclé. Les motclés de ce groupe serviront à qualifier les destinataires des listes, et lors de la création du groupe, il faut donc indiquer qu’il servira à qualifier les « inscrits aux listes de diffusion » (et pas les articles ou rubriques etc).

Par exemple on créera un groupe « statuts_associatif » et des motclés « CA », « Adhérant », « intervenant », « presse », etc et c’est cela qui servirait à distinguer les inscrits.
Du coup il n’y a qu’une seule liste de destinataire, mais tu attribuerais les motclés qui vont bien à chacun des membres. Evidemment tu peux aussi garder une liste « presse » à part (par exemple) et dans ce cas pas de motclé « presse ».

Rq : au lieu des motclés, ça peut être aussi des champs extras de la table spip_mailsubscribers, déclarés avec le plugin cextras.

Ensuite il faudrait créer les segments. Il y en aurait un en rapport avec chaque motclé du groupe segmentant. Ça se fait dans la page d’aministration de la liste. Le fait de créer le groupe de motclé associé aux destinataires de liste ajoute automatiquement un SELECT dans le formulaire de définition d’un segment pour indiquer « dans ce segment il y a les inscrits de la liste qui ont ce motclé ». Et il y a une case pour que les destinataires concernés par chaque segment soient raffraîchis automatiquement.

Ensuite, chaque segment est traité comme une liste, càd que quand on veut envoyer une newsletter, on peut choisir un segment en destinataire.

On peut donc avec une seule liste et les segments reproduire tout ce que tu fais avec plusieurs listes. Mais pour cela, dans ton cas avec un historique à gérer, il faudrait une moulinette php mysql pour convertir une fois pour toute l’appartenance à tes anciennes listes de chaque mailsubscriber en un ou plusieurs motclés qui lui serait affecté.

Et a priori, vu la structure des tables, avec les segments les envois ne sont pas doublonnés ensuite. Mais ça reste à vérifier.

Extension

Le fonctionnement de base des segments, décrit ci dessus, peut s’étendre au moyen d’un pipeline mailsubscriber_informations_liees dédié. Ce pipeline est appelé en 2 endroits
-  1) pour déclarer les saisies qui permettent de qualifier un mailsubscriber. Pour cela il reçoit l’argument

$flux = array( 'args' => array('declarer' => true),	
       'data' => $infos); 

.
Le pipeline doit retourner un tableau complétant (ou corrigeant) la déclaration des saisies par défaut qui se trouve déjà dans $infos.
-  2) pour décrire un mailsubscriber. Le pipeline reçoit alors l’argument

$flux = array('args' => array('email' => $email, 'id_mailsubscriber' => id_mailsubscriber),
		'data' => $infos );

où $infos est le tableau des couples (champs extra, valeur) et (groupemot, tableau des identifiants de motclés) décrivant le mailsubscriber, et qui doit être complété.

Bugs et points améliorerables

-  Difficulté rencontrée : j’avais choisi le modèle « Nouveauté » pour voir ce que ça donnait, et prévisualisé. Ce modèle utilise les derniers articles pour les insérer dans l’infolettre. Puis j’ai choisi « Typographique », mais tous les articles sont restés (temporairement) attaché, et je ne pouvais plus valider la newsletter (erreur de validation sans raison indiquée) et je ne savais comment sortir de cet état intermédiaire foireux. Après une frayeur certaine, F5 a rétabli une situation saine.

-  Dispersion des menus éparpillés dans plein de menus différents :

  • Edition > Infolettre
  • Publication > Suivi des envois de mails en nombre
  • Activité > Inscrits aux envois par mail
  • Activité > Listes de Diffusion

Ainsi que, dans une moindre mesure :

  • Configuration > Facteur
  • Configuration > Plugins > Mailshot > Configuration
  • Maintenance > Liste des travaux