
Avec l'augmentation de l'utilisation des e-mails dans les environnements réglementaires, j'ai décidé qu'il est temps de commencer un nouveau projet qui rassemble tout cela avec des exemples de code sur la façon de stocker le corps de l'e-mail et toutes ses données associées.
Il y a environ un an, j'ai écrit un blog sur comment récupérer des copies d'emails pour archivage et consultation, mais je n’ai pas abordé le stockage réel de l'email ou des données associées, et récemment j'ai écrit un blog sur le stockage de toutes les données d'événements (c'est-à-dire quand l'email a été envoyé, ouvert, cliqué, rebondi, désinscrit, etc.) d'un email à des fins d'audit, mais j'ai choisi de ne pas créer de code de support.
Avec l'augmentation de l'utilisation des emails dans les environnements réglementaires, j'ai décidé qu'il était temps de commencer un nouveau projet qui réunit tout cela avec des exemples de code sur la façon de stocker le corps de l'email et toutes ses données associées. Au cours de l'année prochaine, je vais continuer à développer ce projet dans le but de créer une application de stockage et de visualisation fonctionnelle pour les emails archivés et toutes les informations de journal produites par SparkPost. SparkPost n'a pas de système qui archive le corps des emails mais permet de créer une plateforme d'archivage assez facilement.
Dans cette série de blogs, je décrirai le processus que j'ai suivi pour stocker le corps de l'email sur S3 (Amazon’s Simple Store Service) et toutes les données de journal pertinentes dans MySQL pour un référencement croisé facile. Pour les systèmes d'archivage de production qui nécessitent des stratégies de sauvegarde de base de données robustes, envisagez de mettre en œuvre un processus complet de sauvegarde et de restauration PostgreSQL pour garantir que vos données d'archivage sont correctement protégées. En fin de compte, c'est le point de départ pour construire une application qui permettra une recherche facile des emails archivés, puis d'afficher ces emails avec les données d'événements (journal). Le code pour ce projet peut être trouvé dans le dépôt GitHub suivant : https://github.com/jeff-goldstein/PHPArchivePlatform
Cette première entrée de la série de blogs va décrire le défi et exposer une architecture pour la solution. Le reste des blogs détaillera des parties de la solution ainsi que des exemples de code.
La première étape de mon processus a été de comprendre comment j'allais obtenir une copie de l'email envoyé au destinataire original. Pour obtenir une copie du corps de l'email, vous devez soit :
Capturer le corps de l'email avant d'envoyer l'email
Faire en sorte que le serveur email stocke une copie
Demander au serveur email de créer une copie à stocker pour vous
Si le serveur email ajoute des éléments comme le suivi de lien ou le suivi d'ouverture, vous ne pouvez pas utiliser le n°1 car il ne reflètera pas les modifications de suivi d'ouverture/clic.
Cela signifie que soit le serveur doit stocker l'email, soit d'une manière ou d'une autre offrir une copie de cet email pour que vous puissiez le stocker. Étant donné que SparkPost n'a pas de mécanisme de stockage pour les corps d'email mais a un moyen de créer une copie de l'email, nous demanderons à SparkPost de nous envoyer un duplicata de l'email à stocker dans S3.
Ceci est fait en utilisant la fonction Archive de SparkPost. La fonction Archive de SparkPost donne à l'expéditeur la possibilité de dire à SparkPost d'envoyer un duplicata de l'email à une ou plusieurs adresses email et d'utiliser les mêmes liens de suivi et d'ouverture que l'original. La documentation de SparkPost définit leur fonction Archive de la manière suivante :
Les destinataires de la liste d'archives recevront une copie exacte du message envoyé à l'adresse RCPT TO. En particulier, tous les liens encodés destinés au destinataire RCPT TO seront identiques dans les messages d'archive.
Les seules différences avec l'email RCPT TO sont que certains des en-têtes seront différents puisque l'adresse cible pour l'archivage de l'email est différente, mais le corps de l'email sera une réplica exacte !
Si vous souhaitez une explication plus détaillée, voici un lien vers la documentation de SparkPost sur la création de copies d'email dupliquées (ou d'archive).
A titre d'information supplémentaire, SparkPost vous permet effectivement d'envoyer des emails à des adresses cc, bcc et d'archive. Pour cette solution, nous nous concentrons sur les adresses d'archive.
* Remarque * Les emails archivés ne peuvent être créés que lors de l'injection d'emails dans SparkPost via SMTP !
Maintenant que nous savons comment obtenir une copie de l'email original, nous devons examiner les données de journal produites et certaines des subtilités de ces données. SparkPost suit tout ce qui se passe sur ses serveurs et offre cette information sous forme d'événements-messages. Ces événements sont stockés sur SparkPost pendant 10 jours et peuvent être extraits du serveur via une API RESTful appelée événements-messages, ou vous pouvez demander à SparkPost de pousser ces événements vers un nombre quelconque d'applications de collecte de votre choix. Le mécanisme de poussée est réalisé via des webhooks et est fait en temps réel.
Actuellement, il existe 14 événements différents qui peuvent se produire pour un email. Voici une liste des événements actuels :
Rebond
Retard de clic
Distribution
Échec de génération
Rejet de génération
Première Ouverture
InjectionLien Désinscription
Désinscription Liste
Ouverture
Hors bande
Rejet de politiquePlainte de spam
* Suivez ce lien pour un guide de référence à jour pour une description de chaque événement ainsi que les données partagées pour chaque événement.
Chaque événement possède de nombreux champs qui correspondent au type d'événement. Certains champs comme le transmission_id se trouvent dans chaque événement, mais d'autres champs peuvent être plus spécifiques à l'événement ; par exemple, seuls les événements d'ouverture et de clic ont des informations de marquage géographique.
Un élément d'événement message très important pour ce projet est le transmission_id. Toutes les entrées d'événements de message pour l'email original, l'email archivé et toute adresse cc et bcc partageront le même transmission_id.
Il existe également une entrée commune appelée message_id qui aura le même identifiant pour chaque entrée de l'email original et de l'email archivé. Toute adresse cc ou bcc aura son propre identifiant pour l'entrée message_id.
Jusqu'ici tout semble bien et franchement assez facile, mais maintenant la partie difficile commence. Rappelez-vous, afin d'obtenir l'email d'archive, nous avons demandé à SparkPost d'envoyer un duplicata de l'email original à une autre adresse email qui correspond à une boîte de réception à laquelle vous avez accès. Mais pour automatiser cette solution et stocker le corps de l'email, je vais utiliser une autre fonction de SparkPost appelée Relais Email Entrant. Ce que cela fait, c’est prendre tous les emails envoyés à un domaine spécifique et les traiter. En les traitant, il décompose l'email et crée une structure JSON qui est ensuite livrée à une application via un webhook. Voir l'Annexe A pour un échantillon JSON.
Si vous regardez attentivement, vous remarquerez que la structure JSON du relais entrant manque d'un champ très important ; le transmission_id. Alors que tous les emails sortants ont le transmission_id avec la même entrée qui lie toutes les données de l'email original, de l'archive, des adresses cc et bcc ; SparkPost n'a aucun moyen de savoir que l'email capturé par le processus entrant est connecté à l'un des emails sortants. Le processus entrant sait simplement qu'un email a été envoyé à un domaine spécifique et doit analyser cet email. C'est tout. Il traitera tout email envoyé à ce domaine de la même manière, qu'il s'agisse d'une réponse d'un client ou de l'email d'archive envoyé par SparkPost.
Alors l'astuce est ; comment coller les données sortantes au processus entrant qui vient de saisir la version archivée de l'email ? Ce que j'ai décidé de faire est de cacher un identifiant unique dans le corps de l'email. La façon dont cela est fait dépend de vous, mais j'ai simplement créé un champ de saisie avec la balise masquée activée.
J'ai également ajouté ce champ dans le bloc de métadonnées de l'en-tête X-MSYS-API qui est transmis à SparkPost lors de l'injection. Cet UID masqué sera l'élément central de tout le processus et est un composant principal du projet qui sera discuté en profondeur dans les prochains articles de blog.
Maintenant que nous avons l'UID qui réunira ce projet et comprenons pourquoi il est nécessaire, je peux commencer à construire la vision globale du projet et des articles de blog correspondants.
Capturer et stocker l'email d'archive avec une entrée de base de données pour recherche/indexation
Capturer toutes les données des événements-message
Créer une application pour visualiser l'email et toutes les données correspondantes
Voici un diagramme simple du projet :

La première publication de code couvrira le processus d'archivage et le stockage de l'email sur S3, tandis que la deuxième publication couvrira le stockage de toutes les données de journal des événements-message dans MySQL. Vous pouvez vous attendre aux deux premières publications de code et aux entrées de blog au début de 2019. Si vous avez des questions ou des suggestions, n'hésitez pas à les transmettre.
Envoyez bien.
– Jeff
Appendix A:
