Création d'un système d'archivage des e-mails : Les défis et bien sûr la solution - Partie 1

Création d'un système d'archivage des e-mails : Les défis et bien sûr la solution - Partie 1

Building an Courriel : Archiving System: Le Challenges and of Course the Solution – Part 1

Feb 4, 2019

Publié par

Publié par

Jeff Goldstein

Jeff Goldstein

-

Catégorie :

Catégorie :

Courriel :

Email

Ready to see Bird
in action?

Ready to see Bird
in action?

Création d'un système d'archivage des e-mails : Les défis et bien sûr la solution - Partie 1

À propos de a year ago I wrote a blog on how to retrieve copies of emails for archival and viewing but I did not broach the actual storing of the email or related data, and recently I wrote a blog on storing all of the event data (i.e. when the email was sent, opens, clicks bounces, unsubscribes, etc) on an email for the purpose of auditing, but chose not to create any supporting code.


Avec l'augmentation de l'utilisation du courrier électronique dans les environnements réglementaires, j'ai décidé qu'il était temps de lancer un nouveau projet qui rassemble tout cela avec des exemples de code sur la façon de stocker le corps du courriel et toutes ses données associées. Au cours de l'année prochaine, je continuerai à développer ce projet dans le but de créer une application fonctionnelle de stockage et de visualisation des courriels archivés et de toutes les informations de journal produites par SparkPost. SparkPost ne dispose pas d'un système permettant d'archiver le corps du courriel, mais il permet de construire une plateforme d'archivage assez facilement.


In this blog series, I will describe the process I went through in order to store the email body onto S3 (Amazon’s Simple Store Service) and all relevant log data in MySQL for easy cross-referencing.  Ultimately, this is the starting point for building an application that will allow for easy searching of archived emails, then displaying those emails along with the event (log) data. Le code for this project can be found in the following GitHub repository: https://github.com/jeff-goldstein/PHPArchivePlatform


Le premier article de cette série de blogs décrit le défi à relever et présente l'architecture de la solution. Le reste des blogs détaillera des parties de la solution avec des exemples de code.


La première étape de mon processus consistait à déterminer comment j'allais obtenir une copie de l'e-mail envoyé au destinataire initial. Pour obtenir une copie du corps de l'email, vous devez soit :


  1. Capturez le corps de l'email avant de l'envoyer

  2. Demandez au serveur de messagerie de stocker une copie

  3. Demandez au serveur de messagerie de créer une copie que vous pourrez stocker.


Si le serveur de messagerie ajoute des éléments tels que le suivi des liens ou le suivi des ouvertures, vous ne pouvez pas utiliser le numéro 1, car il ne reflétera pas les modifications apportées au suivi des ouvertures/clics.


Cela signifie que le serveur doit soit stocker le courriel, soit vous proposer une copie de ce courriel pour le stocker. Étant donné que SparkPost ne dispose pas d'un mécanisme de stockage pour les corps d'e-mails mais qu'il a un moyen de créer une copie de l'e-mail, nous demanderons à SparkPost de nous envoyer un double de l'e-mail pour que nous le stockions dans S3.


This is done by using SparkPost’s Archive feature. SparkPost’s Archive feature gives the sender the ability to tell SparkPost to send a duplicate of the email to one or more email addresses and use the same tracking and open links as the original. Documentation de SparkPost defines their Archive feature in the following manner:


Les destinataires de la liste d'archives recevront une réplique exacte du message qui a été envoyé à l'adresse RCPT TO. En particulier, tous les liens codés destinés au destinataire du RCPT TO seront identiques dans les messages d'archive.


Les seules différences par rapport à l'email RCPT TO sont que certains en-têtes seront différents puisque l'adresse cible de l'email d'archivage est différente, mais le corps de l'email sera une réplique exacte !


If you want a deeper explanation here is a link à la SparkPost documentation on creating duplicate (or archive) copies of an email.


À titre d'information, SparkPost vous permet en fait d'envoyer des courriels à des adresses de type cc, bcc et archive. Pour cette solution, nous nous concentrons sur les adresses d'archives.


* Avis * Les emails archivés ne peuvent être créés QUE lors de l'injection d'emails dans SparkPost via SMTP !

Now that we know how to obtain a copy of the original email, we need to look au log data that is produced and some of the subtle nuances within that data. SparkPost tracks everything that happens on its servers and offers that information up to you in the form of message-events. Those events are stored on SparkPost for 10 days and can be pulled from the server via a RESTful API called message-events, or you can have SparkPost push those events to any number of collecting applications that you wish.  The push mechanism is done through webhooks and is done in real time.


Currently, there are 14 different events that may happen to an email.  Here is a list of the current events:


  • Rebondir

  • ClickDelay

  • Livraison

  • Défaut de génération

  • Rejet de la génération

  • Ouverture initiale

  • Désabonnement InjectionLink

  • Désinscription de la liste

  • Ouvrir

  • En dehors de la bande

  • Politique de rejetPlainte pour spam


* Follow ce lien for an up to date reference guide for a description of each event along with the data that is shared for each event.


Each event has numerous fields that match the event type.  Some fields like the transmission_id are found in every event, but other fields may be more event-specific; for example, only open and click events have geotag information.


One very important message event entry to this project is the transmission_id.  All of the message event entries for the original email, archived email, and any cc and bcc addresses will share the same transmission_id.


There is also a common entry called the message_id that will have the same id for each entry of the original email and the archived email. Any cc or bcc addresses will have their own id for the message_id entry.


So far this sounds great and frankly fairly easy, but now is the challenging part. Remember, in order to get the archive email, we have SparkPost send a duplicate of the original email to another email address which corresponds to some inbox that you have access to. But in order to automate this solution and store the email body, I’m going to use another feature of SparkPost’s called Relais d'e-mails entrants. What that does, is take all emails sent to a specific domain and process them. By processing them, it rips the email apart and creates a JSON structure which is then delivered to an application via a webhook. See Appendix A for a sample JSON.


If you look real carefully, you will notice that the JSON structure from the inbound relay is missing a very important field; the transmission_id. While all of the outbound emails have the transmission_id  with the same entry which binds all of the data from the original email, archive, cc, and bcc addresses; SparkPost has no way to know that the email captured by the inbound process is connected to any of the outbound emails. The inbound process simply knows that an email was sent to a specific domain and to parse the email. That’s it. It will treat any email sent to that domain the same way, be it a reply from a customer or the archive email send from SparkPost.


Le problème est donc le suivant : comment coller les données sortantes au processus entrant qui vient de saisir la version archivée de l'e-mail ? Ce que j'ai décidé de faire, c'est de cacher un identifiant unique dans le corps de l'e-mail. La façon de procéder vous appartient, mais j'ai simplement créé un champ de saisie avec la balise cachée activée.


<input name="ArchiveCode" type="hidden" value="<<UID>>">


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 pendant l'injection. Cet UID caché finira par être le ciment de l'ensemble du processus. Il s'agit d'un élément essentiel du projet, qui sera abordé en profondeur dans les prochains articles du blog.


Maintenant que nous disposons de l'UID qui permettra de rassembler ce projet et que nous comprenons pourquoi il est nécessaire, je peux commencer à élaborer la vision du projet global et des articles de blog correspondants.


  1. Capturer et stocker le courriel d'archive avec une entrée dans la base de données pour la recherche/indexation.

  2. Capturez toutes les données relatives aux événements des messages

  3. Créer une application pour visualiser l'email et toutes les données correspondantes


Voici un schéma simple du projet :


build an email archiving system - diagram


The first drop of code will cover the archive process and storing the email onto S3, while the second code drop will cover storing all of the log data from message-events into MySQL. You can expect the first two code drops and blog entries sometime in early 2019.  If you have any questions or suggestions, please feel free to pass them along.

Bon envoi.

- Jeff


Annexe A :


JSON file example - email archiving system

Your new standard in Marketing, Pay & Sales. It's Bird

The right message -> à la right person -> au right time.

By clicking "See Bird" you agree to Bird's Avis de confidentialité.

Your new standard in Marketing, Pay & Sales. It's Bird

The right message -> to the right person -> at the right time.

By clicking "See Bird" you agree to Bird's Avis de confidentialité.