Het bouwen van een e-mailarchiveringssysteem: De uitdagingen en natuurlijk de oplossing – Deel 1
Jeff Goldstein
4 feb 2019
1 min read

Belangrijkste punten
Email archivering wordt steeds essentiëler voor regelgevende, compliance en auditomgevingen.
SparkPost slaat geen e-mailinhoud op, maar de Archive feature stelt verzenders in staat om dubbele berichten te ontvangen die spiegeltracking links en inhoud weerspiegelen.
E-mailinhoud kan worden opgeslagen in Amazon S3, terwijl berichteventmetadata kan worden opgeslagen in MySQL voor query's en kruisverwijzingen.
SparkPost berichtgebeurtenissen bieden rijke activiteitslogboeken (bounces, leveringen, klikken, opens, afmeldingen, klachten, en meer).
Archiefkopieën worden alleen gegenereerd bij het e-mailen via SMTP.
Berichtgebeurtenissen voor originele, archief-, CC- en BCC-mails delen een gemeenschappelijke transmission_id.
Inbound Email Relay kan gearchiveerde berichten opnemen, maar bevat niet de transmission_id, waardoor een datalink-uitdaging ontstaat.
Het inbedden van een verborgen unieke identificator (UID) in de berichtinhoud sluit die kloof en koppelt inkomende inhoud aan uitgaande logboeken.
Het combineren van archiefmails + berichtgebeurtenissen maakt het mogelijk om een doorzoekbaar, verifieerbaar archiefsysteem te bouwen.
Het langetermijnproject omvat code-uitgaven voor het opslaan van archiefmails in S3 en het loggen van gebeurtenisgegevens in MySQL.
De uiteindelijke applicatie maakt eenvoudig zoeken, bekijken en afstemmen van e-mailinhoud met alle gerelateerde gebeurtenisgeschiedenis mogelijk.
Ideaal voor industries die zwaar afhankelijk zijn van naleving en volledige zichtbaarheid in elke verzonden boodschap nodig hebben.
Q&A Hoogtepunten
Waarom uw eigen e-mailarchiveringssysteem bouwen?
Gereguleerde industrieën vereisen vaak langdurige opslag van zowel de e-mailbody als alle bijbehorende gebeurtenislogboeken. SparkPost slaat geen berichtinhoud op, dus het bouwen van een aangepast systeem zorgt voor naleving, auditing en zichtbaarheid.
Hoe verkrijg je een exacte kopie van de originele verzonden e-mail?
De Archive feature van SparkPost stuurt een duplicaat van elke uitgaande e-mail naar aangewezen archiefadressen, waarbij alle gecodeerde links en volgactiviteiten behouden blijven.
Waarom kun je de e-mail body niet vastleggen voordat je deze verstuurt?
De pre-send capture omvat niet de aanpassingen van SparkPost (open tracking, click tracking, link encoding). Het gebruik van Archiefkopieën zorgt ervoor dat uw opgeslagen versie exact overeenkomt met wat ontvangers ontvangen.
Archiveert SparkPost e-mails automatisch?
Nee. SparkPost bewaart niet de inhoud van berichten. Archiefkopieën moeten worden aangevraagd door archiefadressen op te geven tijdens SMTP-injectie.
Wat wordt waar opgeslagen in dit archiveringssysteem?
Email body → Amazon S3
Berichtevenement logs → MySQL
Deze scheiding ondersteunt snelle zoekopdrachten, gestructureerde queries en goedkope objectopslag.
Hoe lang bewaart SparkPost eventgegevens?
SparkPost slaat berichtgebeurtenissen op gedurende 10 dagen. Daarna moet de data via webhook worden ingenomen of elders worden opgevraagd en opgeslagen.
Welke berichten gebeurtenissen zijn beschikbaar?
SparkPost maakt momenteel 14 evenementen openbaar, waaronder leveringen, bounces, klikken, opens, afwijzingen, beleidskwesties, spamklachten, uitschrijvingen en meer.
Welke identificatoren verbinden alle evenementen met elkaar?
Alle uitgaande berichten (origineel, archief, CC, BCC) delen dezelfde transmission_id. Het originele en archief e-mail delen ook dezelfde message_id.
Waarom is inbound processing een uitdaging?
SparkPost's Inbound Email Relay zet binnenkomende e-mail om in JSON, maar deze JSON bevat geen transmission_id. Zonder aanvullende gegevens kan de binnenkomende kopie niet worden gekoppeld aan zijn uitgaande logboekgeschiedenis.
Hoe koppel je inkomende gearchiveerde e-mails aan uitgaande berichtgebeurtenissen?
Voeg een verborgen unique identifier (UID) toe in de e-mailtekst en geef dezelfde UID door in de metadata. Deze UID wordt de gedeelde referentie voor inkomende en uitgaande records.
Hoe helpt Inbound Email Relay bij het automatiseren van archivering?
Het ontvangt archief-e-mails die naar uw archiefdomein zijn verzonden, verwerkt ze tot gestructureerde JSON en plaatst ze via webhook in uw applicatie—waardoor geautomatiseerde extractie en opslag mogelijk is.
Wat is de langetermijnvisie van het project?
Een complete applicatie die:
Archiveert e-mails in S3
Alle gebeurtenislogboeken opslaat in MySQL
Gebruikers laat zoeken naar e-mails
De originele e-mail en elke bijbehorende gebeurtenis in één uniforme interface weergeeft
Ongeveer een jaar geleden schreef ik een blog over hoe je kopieën van e-mails kunt ophalen voor archivering en weergave, maar ik ging niet in op het daadwerkelijke opslaan van de e-mail of bijbehorende gegevens. Onlangs schreef ik een blog over het opslaan van alle gebeurtenisgegevens (dwz wanneer de e-mail werd verzonden, geopend, geklikt, bounces, afmeldingen, enz.) voor de audit, maar koos ervoor om geen ondersteunende code te maken.
Met de toename van e-mailgebruik in gereguleerde omgevingen, heb ik besloten dat het tijd is om een nieuw project te starten dat dit allemaal samenbrengt met codevoorbeelden over hoe de e-mailinhoud en alle bijbehorende gegevens kunnen worden opgeslagen. In het komende jaar zal ik dit project verder ontwikkelen met als doel een werkende opslag- en weergavetoepassing voor gearchiveerde e-mails en alle loginformatie die is geproduceerd door SparkPost te creëren. SparkPost heeft geen systeem dat de e-mailinhoud archiveert, maar het maakt het bouwen van een archiveringsplatform vrij eenvoudig.
In deze blogserie zal ik het proces beschrijven dat ik heb doorlopen om de e-mailinhoud op S3 (Amazon’s Simple Store Service) op te slaan en alle relevante loggegevens in MySQL voor eenvoudige kruisintegratie. Voor productarchiveringssystemen die robuuste strategieën voor databaseback-ups vereisen, overweeg een uitgebreide PostgreSQL-back-up- en herstelproces te implementeren om ervoor te zorgen dat je archiveringsgegevens goed worden beschermd. Uiteindelijk is dit het startpunt voor het bouwen van een toepassing die het zoeken naar gearchiveerde e-mails eenvoudig maakt en deze e-mails samen met de gebeurtenis (log)gegevens weergeeft. De code voor dit project is te vinden in de volgende GitHub-repository: PHPArchivePlatform op GitHub
In deze eerste post van de blogserie ga ik de uitdaging beschrijven en een architectuur voor de oplossing uitwerken. De rest van de blogs zal delen van de oplossing met codevoorbeelden beschrijven.
De eerste stap in mijn proces was om uit te zoeken hoe ik een kopie van de verzonden e-mail naar de oorspronkelijke ontvanger zou verkrijgen. Om een kopie van de e-mailinhoud te verkrijgen, moet je ofwel:
E-mailinhoud Vangopties
Methode | Wie maakt de kopie | Geeft wijzigingen in tracking weer | Automatiseringsvriendelijk | Gebruikt in deze oplossing |
|---|---|---|---|---|
Vang voor verzending | Toepassing | ❌ Nee | ✅ Ja | ❌ |
E-mailserver slaat kopie op | Mailserver | ✅ Ja | ❌ Beperkt | ❌ |
SparkPost Archive-functie | SparkPost | ✅ Ja | ✅ Ja | ✅ |
De inhoud van de e-mail vangen voordat je de e-mail verzendt
De e-mailserver vragen een kopie op te slaan
De e-mailserver vragen een kopie voor je te maken om op te slaan
Als de e-mailserver items toevoegt zoals linktracking of opentracking, kun je nummer 1 niet gebruiken omdat het de wijzigingen in open/kliktracking niet weergeeft.
Dat betekent dat de server de e-mail moet opslaan of dat je op een of andere manier een kopie van die e-mail ter opslag aangeboden moet krijgen. Aangezien SparkPost geen opslagmechanisme voor e-maillichamen heeft, maar wel een manier heeft om een kopie van de e-mail te maken, laten we SparkPost ons een duplicaat van de e-mail sturen zodat we het in S3 kunnen opslaan.
Dit wordt gedaan door de Archive-functie van SparkPost te gebruiken. De Archive-functie van SparkPost geeft de afzender de mogelijkheid om SparkPost te vertellen een duplicaat van de e-mail naar een of meer e-mailadressen te sturen en dezelfde tracking- en openlinks te gebruiken als het origineel. SparkPost-documentatie definieert hun Archief-functie op de volgende manier:
Ontvangers in de archieflijst ontvangen een exacte replica van het bericht dat is verzonden naar het RCPT TO-adres. In het bijzonder zijn alle gecodeerde links bedoeld voor de RCPT TO-ontvanger identiek in de archiefberichten
De enige verschillen met de RCPT TO-e-mail zijn dat sommige headers anders zullen zijn omdat het doeladres voor de archiveringse-mail anders is, maar de inhoud van de e-mail blijft een exacte replica!
Als je een diepere toelichting wilt, hier is een link naar de documentatie van SparkPost over het maken van duplicaten (of archiefkopieën) van een e-mail.
Als een kanttekening stelt SparkPost je daadwerkelijk in staat om e-mails naar cc, bcc en archieve-mailadressen te sturen. Voor deze oplossing richten we ons op de archiefadressen.
* Let op * Gearchiveerde e-mails kunnen ALLEEN worden gemaakt bij het injecteren van e-mails in SparkPost via SMTP!
Nu we weten hoe we een kopie van de originele e-mail kunnen verkrijgen, moeten we kijken naar de loggegevens die worden gegenereerd en sommige van de subtiele nuances binnen die gegevens. SparkPost volgt alles wat er op zijn servers gebeurt en biedt die informatie aan jou aan in de vorm van gebeurtenis-gebeurtenissen. Die gebeurtenissen worden 10 dagen lang op SparkPost opgeslagen en kunnen vanaf de server worden opgehaald via een RESTful API genaamd message-events, of je kunt SparkPost die gebeurtenissen naar een willekeurig aantal verzameltoepassingen laten pushen. Het pushmechanisme gebeurt via webhooks en gebeurt in real time.
Momenteel zijn er 14 verschillende gebeurtenissen die bij een e-mail kunnen plaatsvinden. Hier is een lijst van de huidige gebeurtenissen:
Bounce
ClickDelay
Bezorging
Generatiefout
Generatieafwijzing
Initiële Open
InjectionLink Afmelden
Lijst Afmelden
Open
Out of Band
BeleidsafwijzingSpam Klacht
* Volg deze link voor een actuele referentiegids voor een beschrijving van elke gebeurtenis samen met de gegevens die voor elke gebeurtenis worden gedeeld.
Elke gebeurtenis heeft talrijke velden die overeenkomen met het gebeurtenistype. Sommige velden zoals de transmission_id zijn te vinden in elke gebeurtenis, maar andere velden kunnen meer gebeurtenisspecifiek zijn; bijvoorbeeld alleen open- en klikgebeurtenissen hebben geotag-informatie.
Identificatoren Gebruikt in het Archiefsysteem
Id | Waar het vandaan komt | Gedeeld over | Doel | Beperking |
|---|---|---|---|---|
transmission_id | SparkPost uitgaand | Origineel, archief, cc, bcc | Correspondeert met alle gebeurtenis-gebeurtenissen | Niet beschikbaar in inkomende relay |
message_id | SparkPost uitgaand | Origineel + archief | Identificeert individuele berichten | Anders voor cc/bcc |
Verborgen UID | Geïnjecteerd door afzender | Uitgaand + inkomend | Linkt gearchiveerde e-mailinhoud aan gebeurtenissen | Moet op maat worden geïmplementeerd |
Een zeer belangrijk berichtgebeurtenis-item voor dit project is de transmission_id. Alle berichtgebeurtenis-items voor de originele e-mail, gearchiveerde e-mail en alle cc en bcc adressen delen dezelfde transmission_id.
Er is ook een gemeenschappelijk item genaamd message_id dat dezelfde id heeft voor elk item van de oorspronkelijke e-mail en de gearchiveerde e-mail. Alle cc- of bcc-adressen hebben hun eigen id voor het message_id-item.
Tot nu toe klinkt dit geweldig en eerlijk gezegd vrij eenvoudig, maar nu is het uitdagende deel. Onthoud dat om de gearchiveerde e-mail te verkrijgen, we SparkPost een duplicaat van de oorspronkelijke e-mail laten sturen naar een ander e-mailadres dat overeenkomt met een inbox waartoe je toegang hebt. Maar om deze oplossing te automatiseren en de e-mailinhoud op te slaan, ga ik een andere functie van SparkPost gebruiken, genaamd Inkomende E-mail Routing. Wat dat doet, is alle e-mails die naar een specifiek domein worden gestuurd, nemen en verwerken. Door ze te verwerken, worden de e-mails opgesplitst en wordt er een JSON-structuur van gemaakt, die vervolgens naar een toepassing wordt gestuurd via een webhook. Zie Appendix A voor een JSON-voorbeeld.
Als je goed kijkt, zul je opmerken dat de JSON-structuur van de inkomende relay een zeer belangrijk veld mist; de transmission_id. Terwijl alle uitgaande e-mails de transmission_id met hetzelfde item hebben dat alle gegevens van de originele e-mail, het archief, cc en bcc-adressen bindt; heeft SparkPost geen manier om te weten dat de e-mail die door het inkomende proces is vastgelegd, is gekoppeld aan een van de uitgaande e-mails. Het inkomende proces weet eenvoudigweg dat een e-mail naar een specifiek domein is gestuurd en moet deze analyseren. Dat is het. Het zal elke e-mail die naar dat domein wordt verzonden op dezelfde manier behandelen, of het nu een antwoord van een klant is of de archievingestuurde e-mail van SparkPost.
Dus de truc is; hoe plak je de uitgaande gegevens aan het inkomende proces dat zojuist de gearchiveerde versie van de e-mail heeft opgepikt? Wat ik besloot te doen, is een unieke id te verbergen in de inhoud van de e-mail. Hoe dit wordt gedaan, is aan jou, maar ik creëerde simpelweg een invoerveld met de verborgen tag ingeschakeld.
<input name="ArchiveCode" type="hidden" value="<<UID>>">
Ik voegde dat veld ook toe aan het metadatablok van de X-MSYS-API-header die tijdens injectie naar SparkPost wordt gestuurd. Deze verborgen UID zal de lijm worden voor het hele proces, en is een belangrijk onderdeel van het project en zal uitgebreid worden besproken in de volgende blogposts.
Nu we de UID hebben die dit project samen zal lijmen en begrijpen waarom het nodig is, kan ik beginnen met het opbouwen van de visie van het gehele project en bijbehorende blogposts.
Vastleggen en opslaan van de archief-e-mail samen met een database-item voor zoeken/indexeren
Alle berichtgebeurtenisgegevens vastleggen
Een toepassing maken om de e-mail en alle bijbehorende gegevens te bekijken
Hier is een eenvoudig diagram van het project:

De eerste code publicatie zal het archiveringsproces en het opslaan van de e-mail op S3 behandelen, terwijl de tweede code publicatie het opslaan van alle loggegevens van berichtgebeurtenissen in MySQL zal behandelen. Je kunt de eerste twee codepublicaties en blogposts verwachten begin 2019. Als je vragen of suggesties hebt, aarzel dan niet om ze door te geven.
Succes met verzenden.
– Jeff
Appendix A:

Ongeveer een jaar geleden schreef ik een blog over hoe je kopieën van e-mails kunt ophalen voor archivering en weergave, maar ik ging niet in op het daadwerkelijke opslaan van de e-mail of bijbehorende gegevens. Onlangs schreef ik een blog over het opslaan van alle gebeurtenisgegevens (dwz wanneer de e-mail werd verzonden, geopend, geklikt, bounces, afmeldingen, enz.) voor de audit, maar koos ervoor om geen ondersteunende code te maken.
Met de toename van e-mailgebruik in gereguleerde omgevingen, heb ik besloten dat het tijd is om een nieuw project te starten dat dit allemaal samenbrengt met codevoorbeelden over hoe de e-mailinhoud en alle bijbehorende gegevens kunnen worden opgeslagen. In het komende jaar zal ik dit project verder ontwikkelen met als doel een werkende opslag- en weergavetoepassing voor gearchiveerde e-mails en alle loginformatie die is geproduceerd door SparkPost te creëren. SparkPost heeft geen systeem dat de e-mailinhoud archiveert, maar het maakt het bouwen van een archiveringsplatform vrij eenvoudig.
In deze blogserie zal ik het proces beschrijven dat ik heb doorlopen om de e-mailinhoud op S3 (Amazon’s Simple Store Service) op te slaan en alle relevante loggegevens in MySQL voor eenvoudige kruisintegratie. Voor productarchiveringssystemen die robuuste strategieën voor databaseback-ups vereisen, overweeg een uitgebreide PostgreSQL-back-up- en herstelproces te implementeren om ervoor te zorgen dat je archiveringsgegevens goed worden beschermd. Uiteindelijk is dit het startpunt voor het bouwen van een toepassing die het zoeken naar gearchiveerde e-mails eenvoudig maakt en deze e-mails samen met de gebeurtenis (log)gegevens weergeeft. De code voor dit project is te vinden in de volgende GitHub-repository: PHPArchivePlatform op GitHub
In deze eerste post van de blogserie ga ik de uitdaging beschrijven en een architectuur voor de oplossing uitwerken. De rest van de blogs zal delen van de oplossing met codevoorbeelden beschrijven.
De eerste stap in mijn proces was om uit te zoeken hoe ik een kopie van de verzonden e-mail naar de oorspronkelijke ontvanger zou verkrijgen. Om een kopie van de e-mailinhoud te verkrijgen, moet je ofwel:
E-mailinhoud Vangopties
Methode | Wie maakt de kopie | Geeft wijzigingen in tracking weer | Automatiseringsvriendelijk | Gebruikt in deze oplossing |
|---|---|---|---|---|
Vang voor verzending | Toepassing | ❌ Nee | ✅ Ja | ❌ |
E-mailserver slaat kopie op | Mailserver | ✅ Ja | ❌ Beperkt | ❌ |
SparkPost Archive-functie | SparkPost | ✅ Ja | ✅ Ja | ✅ |
De inhoud van de e-mail vangen voordat je de e-mail verzendt
De e-mailserver vragen een kopie op te slaan
De e-mailserver vragen een kopie voor je te maken om op te slaan
Als de e-mailserver items toevoegt zoals linktracking of opentracking, kun je nummer 1 niet gebruiken omdat het de wijzigingen in open/kliktracking niet weergeeft.
Dat betekent dat de server de e-mail moet opslaan of dat je op een of andere manier een kopie van die e-mail ter opslag aangeboden moet krijgen. Aangezien SparkPost geen opslagmechanisme voor e-maillichamen heeft, maar wel een manier heeft om een kopie van de e-mail te maken, laten we SparkPost ons een duplicaat van de e-mail sturen zodat we het in S3 kunnen opslaan.
Dit wordt gedaan door de Archive-functie van SparkPost te gebruiken. De Archive-functie van SparkPost geeft de afzender de mogelijkheid om SparkPost te vertellen een duplicaat van de e-mail naar een of meer e-mailadressen te sturen en dezelfde tracking- en openlinks te gebruiken als het origineel. SparkPost-documentatie definieert hun Archief-functie op de volgende manier:
Ontvangers in de archieflijst ontvangen een exacte replica van het bericht dat is verzonden naar het RCPT TO-adres. In het bijzonder zijn alle gecodeerde links bedoeld voor de RCPT TO-ontvanger identiek in de archiefberichten
De enige verschillen met de RCPT TO-e-mail zijn dat sommige headers anders zullen zijn omdat het doeladres voor de archiveringse-mail anders is, maar de inhoud van de e-mail blijft een exacte replica!
Als je een diepere toelichting wilt, hier is een link naar de documentatie van SparkPost over het maken van duplicaten (of archiefkopieën) van een e-mail.
Als een kanttekening stelt SparkPost je daadwerkelijk in staat om e-mails naar cc, bcc en archieve-mailadressen te sturen. Voor deze oplossing richten we ons op de archiefadressen.
* Let op * Gearchiveerde e-mails kunnen ALLEEN worden gemaakt bij het injecteren van e-mails in SparkPost via SMTP!
Nu we weten hoe we een kopie van de originele e-mail kunnen verkrijgen, moeten we kijken naar de loggegevens die worden gegenereerd en sommige van de subtiele nuances binnen die gegevens. SparkPost volgt alles wat er op zijn servers gebeurt en biedt die informatie aan jou aan in de vorm van gebeurtenis-gebeurtenissen. Die gebeurtenissen worden 10 dagen lang op SparkPost opgeslagen en kunnen vanaf de server worden opgehaald via een RESTful API genaamd message-events, of je kunt SparkPost die gebeurtenissen naar een willekeurig aantal verzameltoepassingen laten pushen. Het pushmechanisme gebeurt via webhooks en gebeurt in real time.
Momenteel zijn er 14 verschillende gebeurtenissen die bij een e-mail kunnen plaatsvinden. Hier is een lijst van de huidige gebeurtenissen:
Bounce
ClickDelay
Bezorging
Generatiefout
Generatieafwijzing
Initiële Open
InjectionLink Afmelden
Lijst Afmelden
Open
Out of Band
BeleidsafwijzingSpam Klacht
* Volg deze link voor een actuele referentiegids voor een beschrijving van elke gebeurtenis samen met de gegevens die voor elke gebeurtenis worden gedeeld.
Elke gebeurtenis heeft talrijke velden die overeenkomen met het gebeurtenistype. Sommige velden zoals de transmission_id zijn te vinden in elke gebeurtenis, maar andere velden kunnen meer gebeurtenisspecifiek zijn; bijvoorbeeld alleen open- en klikgebeurtenissen hebben geotag-informatie.
Identificatoren Gebruikt in het Archiefsysteem
Id | Waar het vandaan komt | Gedeeld over | Doel | Beperking |
|---|---|---|---|---|
transmission_id | SparkPost uitgaand | Origineel, archief, cc, bcc | Correspondeert met alle gebeurtenis-gebeurtenissen | Niet beschikbaar in inkomende relay |
message_id | SparkPost uitgaand | Origineel + archief | Identificeert individuele berichten | Anders voor cc/bcc |
Verborgen UID | Geïnjecteerd door afzender | Uitgaand + inkomend | Linkt gearchiveerde e-mailinhoud aan gebeurtenissen | Moet op maat worden geïmplementeerd |
Een zeer belangrijk berichtgebeurtenis-item voor dit project is de transmission_id. Alle berichtgebeurtenis-items voor de originele e-mail, gearchiveerde e-mail en alle cc en bcc adressen delen dezelfde transmission_id.
Er is ook een gemeenschappelijk item genaamd message_id dat dezelfde id heeft voor elk item van de oorspronkelijke e-mail en de gearchiveerde e-mail. Alle cc- of bcc-adressen hebben hun eigen id voor het message_id-item.
Tot nu toe klinkt dit geweldig en eerlijk gezegd vrij eenvoudig, maar nu is het uitdagende deel. Onthoud dat om de gearchiveerde e-mail te verkrijgen, we SparkPost een duplicaat van de oorspronkelijke e-mail laten sturen naar een ander e-mailadres dat overeenkomt met een inbox waartoe je toegang hebt. Maar om deze oplossing te automatiseren en de e-mailinhoud op te slaan, ga ik een andere functie van SparkPost gebruiken, genaamd Inkomende E-mail Routing. Wat dat doet, is alle e-mails die naar een specifiek domein worden gestuurd, nemen en verwerken. Door ze te verwerken, worden de e-mails opgesplitst en wordt er een JSON-structuur van gemaakt, die vervolgens naar een toepassing wordt gestuurd via een webhook. Zie Appendix A voor een JSON-voorbeeld.
Als je goed kijkt, zul je opmerken dat de JSON-structuur van de inkomende relay een zeer belangrijk veld mist; de transmission_id. Terwijl alle uitgaande e-mails de transmission_id met hetzelfde item hebben dat alle gegevens van de originele e-mail, het archief, cc en bcc-adressen bindt; heeft SparkPost geen manier om te weten dat de e-mail die door het inkomende proces is vastgelegd, is gekoppeld aan een van de uitgaande e-mails. Het inkomende proces weet eenvoudigweg dat een e-mail naar een specifiek domein is gestuurd en moet deze analyseren. Dat is het. Het zal elke e-mail die naar dat domein wordt verzonden op dezelfde manier behandelen, of het nu een antwoord van een klant is of de archievingestuurde e-mail van SparkPost.
Dus de truc is; hoe plak je de uitgaande gegevens aan het inkomende proces dat zojuist de gearchiveerde versie van de e-mail heeft opgepikt? Wat ik besloot te doen, is een unieke id te verbergen in de inhoud van de e-mail. Hoe dit wordt gedaan, is aan jou, maar ik creëerde simpelweg een invoerveld met de verborgen tag ingeschakeld.
<input name="ArchiveCode" type="hidden" value="<<UID>>">
Ik voegde dat veld ook toe aan het metadatablok van de X-MSYS-API-header die tijdens injectie naar SparkPost wordt gestuurd. Deze verborgen UID zal de lijm worden voor het hele proces, en is een belangrijk onderdeel van het project en zal uitgebreid worden besproken in de volgende blogposts.
Nu we de UID hebben die dit project samen zal lijmen en begrijpen waarom het nodig is, kan ik beginnen met het opbouwen van de visie van het gehele project en bijbehorende blogposts.
Vastleggen en opslaan van de archief-e-mail samen met een database-item voor zoeken/indexeren
Alle berichtgebeurtenisgegevens vastleggen
Een toepassing maken om de e-mail en alle bijbehorende gegevens te bekijken
Hier is een eenvoudig diagram van het project:

De eerste code publicatie zal het archiveringsproces en het opslaan van de e-mail op S3 behandelen, terwijl de tweede code publicatie het opslaan van alle loggegevens van berichtgebeurtenissen in MySQL zal behandelen. Je kunt de eerste twee codepublicaties en blogposts verwachten begin 2019. Als je vragen of suggesties hebt, aarzel dan niet om ze door te geven.
Succes met verzenden.
– Jeff
Appendix A:

Ongeveer een jaar geleden schreef ik een blog over hoe je kopieën van e-mails kunt ophalen voor archivering en weergave, maar ik ging niet in op het daadwerkelijke opslaan van de e-mail of bijbehorende gegevens. Onlangs schreef ik een blog over het opslaan van alle gebeurtenisgegevens (dwz wanneer de e-mail werd verzonden, geopend, geklikt, bounces, afmeldingen, enz.) voor de audit, maar koos ervoor om geen ondersteunende code te maken.
Met de toename van e-mailgebruik in gereguleerde omgevingen, heb ik besloten dat het tijd is om een nieuw project te starten dat dit allemaal samenbrengt met codevoorbeelden over hoe de e-mailinhoud en alle bijbehorende gegevens kunnen worden opgeslagen. In het komende jaar zal ik dit project verder ontwikkelen met als doel een werkende opslag- en weergavetoepassing voor gearchiveerde e-mails en alle loginformatie die is geproduceerd door SparkPost te creëren. SparkPost heeft geen systeem dat de e-mailinhoud archiveert, maar het maakt het bouwen van een archiveringsplatform vrij eenvoudig.
In deze blogserie zal ik het proces beschrijven dat ik heb doorlopen om de e-mailinhoud op S3 (Amazon’s Simple Store Service) op te slaan en alle relevante loggegevens in MySQL voor eenvoudige kruisintegratie. Voor productarchiveringssystemen die robuuste strategieën voor databaseback-ups vereisen, overweeg een uitgebreide PostgreSQL-back-up- en herstelproces te implementeren om ervoor te zorgen dat je archiveringsgegevens goed worden beschermd. Uiteindelijk is dit het startpunt voor het bouwen van een toepassing die het zoeken naar gearchiveerde e-mails eenvoudig maakt en deze e-mails samen met de gebeurtenis (log)gegevens weergeeft. De code voor dit project is te vinden in de volgende GitHub-repository: PHPArchivePlatform op GitHub
In deze eerste post van de blogserie ga ik de uitdaging beschrijven en een architectuur voor de oplossing uitwerken. De rest van de blogs zal delen van de oplossing met codevoorbeelden beschrijven.
De eerste stap in mijn proces was om uit te zoeken hoe ik een kopie van de verzonden e-mail naar de oorspronkelijke ontvanger zou verkrijgen. Om een kopie van de e-mailinhoud te verkrijgen, moet je ofwel:
E-mailinhoud Vangopties
Methode | Wie maakt de kopie | Geeft wijzigingen in tracking weer | Automatiseringsvriendelijk | Gebruikt in deze oplossing |
|---|---|---|---|---|
Vang voor verzending | Toepassing | ❌ Nee | ✅ Ja | ❌ |
E-mailserver slaat kopie op | Mailserver | ✅ Ja | ❌ Beperkt | ❌ |
SparkPost Archive-functie | SparkPost | ✅ Ja | ✅ Ja | ✅ |
De inhoud van de e-mail vangen voordat je de e-mail verzendt
De e-mailserver vragen een kopie op te slaan
De e-mailserver vragen een kopie voor je te maken om op te slaan
Als de e-mailserver items toevoegt zoals linktracking of opentracking, kun je nummer 1 niet gebruiken omdat het de wijzigingen in open/kliktracking niet weergeeft.
Dat betekent dat de server de e-mail moet opslaan of dat je op een of andere manier een kopie van die e-mail ter opslag aangeboden moet krijgen. Aangezien SparkPost geen opslagmechanisme voor e-maillichamen heeft, maar wel een manier heeft om een kopie van de e-mail te maken, laten we SparkPost ons een duplicaat van de e-mail sturen zodat we het in S3 kunnen opslaan.
Dit wordt gedaan door de Archive-functie van SparkPost te gebruiken. De Archive-functie van SparkPost geeft de afzender de mogelijkheid om SparkPost te vertellen een duplicaat van de e-mail naar een of meer e-mailadressen te sturen en dezelfde tracking- en openlinks te gebruiken als het origineel. SparkPost-documentatie definieert hun Archief-functie op de volgende manier:
Ontvangers in de archieflijst ontvangen een exacte replica van het bericht dat is verzonden naar het RCPT TO-adres. In het bijzonder zijn alle gecodeerde links bedoeld voor de RCPT TO-ontvanger identiek in de archiefberichten
De enige verschillen met de RCPT TO-e-mail zijn dat sommige headers anders zullen zijn omdat het doeladres voor de archiveringse-mail anders is, maar de inhoud van de e-mail blijft een exacte replica!
Als je een diepere toelichting wilt, hier is een link naar de documentatie van SparkPost over het maken van duplicaten (of archiefkopieën) van een e-mail.
Als een kanttekening stelt SparkPost je daadwerkelijk in staat om e-mails naar cc, bcc en archieve-mailadressen te sturen. Voor deze oplossing richten we ons op de archiefadressen.
* Let op * Gearchiveerde e-mails kunnen ALLEEN worden gemaakt bij het injecteren van e-mails in SparkPost via SMTP!
Nu we weten hoe we een kopie van de originele e-mail kunnen verkrijgen, moeten we kijken naar de loggegevens die worden gegenereerd en sommige van de subtiele nuances binnen die gegevens. SparkPost volgt alles wat er op zijn servers gebeurt en biedt die informatie aan jou aan in de vorm van gebeurtenis-gebeurtenissen. Die gebeurtenissen worden 10 dagen lang op SparkPost opgeslagen en kunnen vanaf de server worden opgehaald via een RESTful API genaamd message-events, of je kunt SparkPost die gebeurtenissen naar een willekeurig aantal verzameltoepassingen laten pushen. Het pushmechanisme gebeurt via webhooks en gebeurt in real time.
Momenteel zijn er 14 verschillende gebeurtenissen die bij een e-mail kunnen plaatsvinden. Hier is een lijst van de huidige gebeurtenissen:
Bounce
ClickDelay
Bezorging
Generatiefout
Generatieafwijzing
Initiële Open
InjectionLink Afmelden
Lijst Afmelden
Open
Out of Band
BeleidsafwijzingSpam Klacht
* Volg deze link voor een actuele referentiegids voor een beschrijving van elke gebeurtenis samen met de gegevens die voor elke gebeurtenis worden gedeeld.
Elke gebeurtenis heeft talrijke velden die overeenkomen met het gebeurtenistype. Sommige velden zoals de transmission_id zijn te vinden in elke gebeurtenis, maar andere velden kunnen meer gebeurtenisspecifiek zijn; bijvoorbeeld alleen open- en klikgebeurtenissen hebben geotag-informatie.
Identificatoren Gebruikt in het Archiefsysteem
Id | Waar het vandaan komt | Gedeeld over | Doel | Beperking |
|---|---|---|---|---|
transmission_id | SparkPost uitgaand | Origineel, archief, cc, bcc | Correspondeert met alle gebeurtenis-gebeurtenissen | Niet beschikbaar in inkomende relay |
message_id | SparkPost uitgaand | Origineel + archief | Identificeert individuele berichten | Anders voor cc/bcc |
Verborgen UID | Geïnjecteerd door afzender | Uitgaand + inkomend | Linkt gearchiveerde e-mailinhoud aan gebeurtenissen | Moet op maat worden geïmplementeerd |
Een zeer belangrijk berichtgebeurtenis-item voor dit project is de transmission_id. Alle berichtgebeurtenis-items voor de originele e-mail, gearchiveerde e-mail en alle cc en bcc adressen delen dezelfde transmission_id.
Er is ook een gemeenschappelijk item genaamd message_id dat dezelfde id heeft voor elk item van de oorspronkelijke e-mail en de gearchiveerde e-mail. Alle cc- of bcc-adressen hebben hun eigen id voor het message_id-item.
Tot nu toe klinkt dit geweldig en eerlijk gezegd vrij eenvoudig, maar nu is het uitdagende deel. Onthoud dat om de gearchiveerde e-mail te verkrijgen, we SparkPost een duplicaat van de oorspronkelijke e-mail laten sturen naar een ander e-mailadres dat overeenkomt met een inbox waartoe je toegang hebt. Maar om deze oplossing te automatiseren en de e-mailinhoud op te slaan, ga ik een andere functie van SparkPost gebruiken, genaamd Inkomende E-mail Routing. Wat dat doet, is alle e-mails die naar een specifiek domein worden gestuurd, nemen en verwerken. Door ze te verwerken, worden de e-mails opgesplitst en wordt er een JSON-structuur van gemaakt, die vervolgens naar een toepassing wordt gestuurd via een webhook. Zie Appendix A voor een JSON-voorbeeld.
Als je goed kijkt, zul je opmerken dat de JSON-structuur van de inkomende relay een zeer belangrijk veld mist; de transmission_id. Terwijl alle uitgaande e-mails de transmission_id met hetzelfde item hebben dat alle gegevens van de originele e-mail, het archief, cc en bcc-adressen bindt; heeft SparkPost geen manier om te weten dat de e-mail die door het inkomende proces is vastgelegd, is gekoppeld aan een van de uitgaande e-mails. Het inkomende proces weet eenvoudigweg dat een e-mail naar een specifiek domein is gestuurd en moet deze analyseren. Dat is het. Het zal elke e-mail die naar dat domein wordt verzonden op dezelfde manier behandelen, of het nu een antwoord van een klant is of de archievingestuurde e-mail van SparkPost.
Dus de truc is; hoe plak je de uitgaande gegevens aan het inkomende proces dat zojuist de gearchiveerde versie van de e-mail heeft opgepikt? Wat ik besloot te doen, is een unieke id te verbergen in de inhoud van de e-mail. Hoe dit wordt gedaan, is aan jou, maar ik creëerde simpelweg een invoerveld met de verborgen tag ingeschakeld.
<input name="ArchiveCode" type="hidden" value="<<UID>>">
Ik voegde dat veld ook toe aan het metadatablok van de X-MSYS-API-header die tijdens injectie naar SparkPost wordt gestuurd. Deze verborgen UID zal de lijm worden voor het hele proces, en is een belangrijk onderdeel van het project en zal uitgebreid worden besproken in de volgende blogposts.
Nu we de UID hebben die dit project samen zal lijmen en begrijpen waarom het nodig is, kan ik beginnen met het opbouwen van de visie van het gehele project en bijbehorende blogposts.
Vastleggen en opslaan van de archief-e-mail samen met een database-item voor zoeken/indexeren
Alle berichtgebeurtenisgegevens vastleggen
Een toepassing maken om de e-mail en alle bijbehorende gegevens te bekijken
Hier is een eenvoudig diagram van het project:

De eerste code publicatie zal het archiveringsproces en het opslaan van de e-mail op S3 behandelen, terwijl de tweede code publicatie het opslaan van alle loggegevens van berichtgebeurtenissen in MySQL zal behandelen. Je kunt de eerste twee codepublicaties en blogposts verwachten begin 2019. Als je vragen of suggesties hebt, aarzel dan niet om ze door te geven.
Succes met verzenden.
– Jeff
Appendix A:




