Het bouwen van een e-mailarchiveringssysteem: De uitdagingen en natuurlijk de oplossing – Deel 1

Jeff Goldstein

4 feb 2019

E-mail

1 min read

Het bouwen van een e-mailarchiveringssysteem: De uitdagingen en natuurlijk de oplossing – Deel 1

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 daadwerkelijk opslaan van de e-mail of gerelateerde gegevens. Recentelijk heb ik een blog geschreven over het opslaan van alle gebeurtenisdata (d.w.z. wanneer de e-mail is verzonden, geopend, klikken, bounces, uitschrijvingen, enz.) op een e-mail met als doel controle, 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 alles samenbrengt met codevoorbeelden over hoe de e-mail en alle bijbehorende gegevens kunnen worden opgeslagen. In het komende jaar zal ik doorgaan met het bouwen aan dit project met als doel een werkende opslag- en weergaveapplicatie te creëren voor gearchiveerde e-mails en alle loginformatie geproduceerd door SparkPost. SparkPost heeft geen systeem dat het e-maillichaam archiveert, maar het maakt het bouwen van een archiveringsplatform redelijk eenvoudig.

In deze blogserie zal ik het proces beschrijven dat ik doorliep om het e-maillichaam op te slaan op S3 (Amazon's Simple Store Service) en alle relevante loggegevens in MySQL voor eenvoudige kruisverwijzing. Voor productiesystemen voor archivering die robuuste database-backupstrategieën vereisen, overweeg een uitgebreide PostgreSQL-backup- en herstelproces te implementeren om ervoor te zorgen dat uw archiveringsgegevens goed beschermd zijn. Uiteindelijk is dit het startpunt voor het bouwen van een applicatie die eenvoudig zoeken in gearchiveerde e-mails mogelijk maakt en deze e-mails weergeeft samen met de evenement (log)gegevens. De code voor dit project is te vinden in de volgende GitHub-repository: PHPArchivePlatform op GitHub

Deze eerste aflevering van de blogserie gaat de uitdaging beschrijven en een architectuur voor de oplossing uitwerken. De rest van de blogs zal delen van de oplossing in detail bespreken, samen met codevoorbeelden.

De eerste stap in mijn proces was om uit te vogelen hoe ik een kopie van de verzonden e-mail naar de oorspronkelijke ontvanger kon verkrijgen. Om een kopie van het e-maillichaam te verkrijgen, moet je ofwel:

  1. Het e-maillichaam vastleggen voordat je de e-mail verstuurt

  2. De e-mailserver een kopie laten opslaan

  3. De e-mailserver een kopie voor je laten maken om op te slaan

Als de e-mailserver items zoals linktracking of open tracking toevoegt, kun je #1 niet gebruiken omdat het de open-/kliktrackingwijzigingen niet zal weerspiegelen.

Dat betekent dat de server ofwel de e-mail moet opslaan of op de een of andere manier een kopie van die e-mail voor je moet aanbieden om op te slaan. Aangezien SparkPost geen opslagmechanisme voor e-maillichamen heeft, maar wel een manier om een kopie van de e-mail te maken, laten we SparkPost ons een duplicaat van de e-mail sturen om in S3 op te slaan.

Dit wordt gedaan door het gebruik van SparkPost's Archive-functie. De Archive-functie van SparkPost geeft de verzender 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 de oorspronkelijke. De documentatie van SparkPost definieert hun Archive-functie als volgt:

Ontvangers in de archieflijst ontvangen een exacte replica van het bericht dat naar het RCPT TO-adres is verzonden. In het bijzonder, alle gecodeerde links bedoeld voor de RCPT TO-ontvanger zullen identiek zijn in de archiefberichten.

De enige verschillen van de RCPT TO-e-mail zijn dat sommige headers anders zullen zijn, aangezien het doeladres voor de archive-e-mail anders is, maar het lichaam van de e-mail zal een exacte replica zijn!

Als je een diepere uitleg wilt, hier is een link naar de SparkPost-documentatie over het maken van duplicaat (of archief) kopieën van een e-mail.

Terzijde, SparkPost staat je eigenlijk toe om e-mails te sturen naar cc, bcc, en archive-e-mailadressen. Voor deze oplossing focussen we ons op de archive-adressen.

* Opmerking * Gearchiveerde e-mails kunnen ALLEEN worden gemaakt wanneer e-mails worden geïnjecteerd in SparkPost via SMTP!

Nu we weten hoe we een kopie van de oorspronkelijke e-mail kunnen verkrijgen, moeten we kijken naar de loggegevens die worden geproduceerd en enkele subtiele nuances binnen die gegevens. SparkPost houdt alles bij wat er op zijn servers gebeurt en biedt die informatie aan jou aan in de vorm van message-events. Die gebeurtenissen worden 10 dagen lang op SparkPost opgeslagen en kunnen van de server worden gehaald via een RESTful API genaamd message-events, of je kunt SparkPost die gebeurtenissen naar een aantal verzamelapplicaties laten pushen die je wilt. Het pushmechanisme wordt uitgevoerd via webhooks en gebeurt real-time.

Momenteel zijn er 14 verschillende gebeurtenissen die bij een e-mail kunnen optreden.  Hier is een lijst van de huidige gebeurtenissen:

  • Bounce

  • ClickDelay

  • Bezorging

  • Generatiefout

  • Genereertijdafwijzing

  • Initiële open

  • InjectieLink Uitschrijving

  • Lijstuitschrijving

  • Open

  • Buiten Band

  • BeleidafwijzingSpam 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 type gebeurtenis. Sommige velden, zoals de transmission_id, komen voor in elke gebeurtenis, maar andere velden kunnen meer specifieke gebeurtenissen zijn; bijvoorbeeld alleen open- en klikgebeurtenissen hebben geotag-informatie.

Een zeer belangrijke boodschap-gebeurtenisinvoer voor dit project is de transmission_id. Alle boodschap-gebeurtenisvermeldingen voor de oorspronkelijke e-mail, gearchiveerde e-mail, en eventuele cc en bcc-adressen delen dezelfde transmission_id.

Er is ook een gemeenschappelijke invoer genaamd de message_id, die dezelfde id zal hebben voor elke invoer van de oorspronkelijke e-mail en de gearchiveerde e-mail. Eventuele cc- of bcc-adressen zullen hun eigen id hebben voor de message_id-invoer.

Tot nu toe klinkt dit geweldig en eerlijk gezegd vrij eenvoudig, maar nu komt het uitdagende deel. Vergeet niet, om de gearchiveerde e-mail te krijgen, laten we SparkPost een duplicaat van de oorspronkelijke e-mail sturen naar een ander e-mailadres dat overeenkomt met een inbox waartoe je toegang hebt. Maar om deze oplossing te automatiseren en het e-maillichaam op te slaan, ga ik een andere functie van SparkPost gebruiken, genaamd Inbound Email Relaying. Wat dat doet, is alle e-mails naar een specifiek domein nemen en verwerken. Door ze te verwerken, wordt de e-mail uit elkaar gehaald en een JSON-structuur gemaakt die vervolgens via een webhook naar een applicatie wordt gestuurd. Zie Appendix A voor een voorbeeld van JSON.

Als je goed kijkt, zul je merken dat de JSON-structuur van de inkomende relay een heel belangrijk veld mist; de transmission_id. Terwijl alle uitgaande e-mails de transmission_id met dezelfde invoer hebben, die alle gegevens van de oorspronkelijke e-mail, 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 verbonden met een van de uitgaande e-mails. Het inkomende proces weet gewoon dat een e-mail naar een specifiek domein is verzonden en de e-mail moet worden geparsed. Dat is het gewicht. Het zal elke e-mail verzonden naar dat domein hetzelfde behandelen, of het nu een reactie van een klant is of de archief-e-mail verzonden door SparkPost.

Dus de truc is; hoe verbind je de uitgaande gegevens met het inkomende proces dat net de gearchiveerde versie van de e-mail heeft opgehaald? Wat ik besloot te doen, is een unieke id in het lichaam van de e-mail te verbergen. Hoe dit moet worden gedaan, is aan jou, maar ik heb gewoon een invoerveld gemaakt met de verborgen tag ingeschakeld.

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

Ik heb dat veld ook toegevoegd aan het metadata-blok van de X-MSYS-API-header die wordt doorgestuurd naar SparkPost tijdens injectie. Deze verborgen UID zal de lijm zijn voor het hele proces en is een hoofdbestanddeel van het project en zal uitgebreid worden besproken in de volgende blogposts.

Nu we de UID hebben die dit project samen zal brengen en begrijpen waarom het noodzakelijk is, kan ik beginnen met het bouwen van de visie van het algehele project en de bijbehorende blogposts.

  1. Het vastleggen en opslaan van de gearchiveerde e-mail samen met een databasevermelding voor zoeken/indexeren

  2. Alle boodschap-gebeurtenisdata vastleggen

  3. Een applicatie creëren om de e-mail en alle bijbehorende gegevens te bekijken

Hier is een eenvoudig diagram van het project:

build an email archiving system - diagram


De eerste oplevering van code zal het archiveringsproces en het opslaan van de e-mail op S3 behandelen, terwijl de tweede oplevering van de code het opslaan van alle loggegevens van boodschap-gebeurtenissen in MySQL zal behandelen. Je kunt de eerste twee codeopleveringen en blogberichten verwachten ergens begin 2019.  Als je vragen of suggesties hebt, aarzel dan niet om ze door te geven.

Veel plezier met versturen.
– Jeff


Bijlage A:

JSON file example - email archiving system

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 daadwerkelijk opslaan van de e-mail of gerelateerde gegevens. Recentelijk heb ik een blog geschreven over het opslaan van alle gebeurtenisdata (d.w.z. wanneer de e-mail is verzonden, geopend, klikken, bounces, uitschrijvingen, enz.) op een e-mail met als doel controle, 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 alles samenbrengt met codevoorbeelden over hoe de e-mail en alle bijbehorende gegevens kunnen worden opgeslagen. In het komende jaar zal ik doorgaan met het bouwen aan dit project met als doel een werkende opslag- en weergaveapplicatie te creëren voor gearchiveerde e-mails en alle loginformatie geproduceerd door SparkPost. SparkPost heeft geen systeem dat het e-maillichaam archiveert, maar het maakt het bouwen van een archiveringsplatform redelijk eenvoudig.

In deze blogserie zal ik het proces beschrijven dat ik doorliep om het e-maillichaam op te slaan op S3 (Amazon's Simple Store Service) en alle relevante loggegevens in MySQL voor eenvoudige kruisverwijzing. Voor productiesystemen voor archivering die robuuste database-backupstrategieën vereisen, overweeg een uitgebreide PostgreSQL-backup- en herstelproces te implementeren om ervoor te zorgen dat uw archiveringsgegevens goed beschermd zijn. Uiteindelijk is dit het startpunt voor het bouwen van een applicatie die eenvoudig zoeken in gearchiveerde e-mails mogelijk maakt en deze e-mails weergeeft samen met de evenement (log)gegevens. De code voor dit project is te vinden in de volgende GitHub-repository: PHPArchivePlatform op GitHub

Deze eerste aflevering van de blogserie gaat de uitdaging beschrijven en een architectuur voor de oplossing uitwerken. De rest van de blogs zal delen van de oplossing in detail bespreken, samen met codevoorbeelden.

De eerste stap in mijn proces was om uit te vogelen hoe ik een kopie van de verzonden e-mail naar de oorspronkelijke ontvanger kon verkrijgen. Om een kopie van het e-maillichaam te verkrijgen, moet je ofwel:

  1. Het e-maillichaam vastleggen voordat je de e-mail verstuurt

  2. De e-mailserver een kopie laten opslaan

  3. De e-mailserver een kopie voor je laten maken om op te slaan

Als de e-mailserver items zoals linktracking of open tracking toevoegt, kun je #1 niet gebruiken omdat het de open-/kliktrackingwijzigingen niet zal weerspiegelen.

Dat betekent dat de server ofwel de e-mail moet opslaan of op de een of andere manier een kopie van die e-mail voor je moet aanbieden om op te slaan. Aangezien SparkPost geen opslagmechanisme voor e-maillichamen heeft, maar wel een manier om een kopie van de e-mail te maken, laten we SparkPost ons een duplicaat van de e-mail sturen om in S3 op te slaan.

Dit wordt gedaan door het gebruik van SparkPost's Archive-functie. De Archive-functie van SparkPost geeft de verzender 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 de oorspronkelijke. De documentatie van SparkPost definieert hun Archive-functie als volgt:

Ontvangers in de archieflijst ontvangen een exacte replica van het bericht dat naar het RCPT TO-adres is verzonden. In het bijzonder, alle gecodeerde links bedoeld voor de RCPT TO-ontvanger zullen identiek zijn in de archiefberichten.

De enige verschillen van de RCPT TO-e-mail zijn dat sommige headers anders zullen zijn, aangezien het doeladres voor de archive-e-mail anders is, maar het lichaam van de e-mail zal een exacte replica zijn!

Als je een diepere uitleg wilt, hier is een link naar de SparkPost-documentatie over het maken van duplicaat (of archief) kopieën van een e-mail.

Terzijde, SparkPost staat je eigenlijk toe om e-mails te sturen naar cc, bcc, en archive-e-mailadressen. Voor deze oplossing focussen we ons op de archive-adressen.

* Opmerking * Gearchiveerde e-mails kunnen ALLEEN worden gemaakt wanneer e-mails worden geïnjecteerd in SparkPost via SMTP!

Nu we weten hoe we een kopie van de oorspronkelijke e-mail kunnen verkrijgen, moeten we kijken naar de loggegevens die worden geproduceerd en enkele subtiele nuances binnen die gegevens. SparkPost houdt alles bij wat er op zijn servers gebeurt en biedt die informatie aan jou aan in de vorm van message-events. Die gebeurtenissen worden 10 dagen lang op SparkPost opgeslagen en kunnen van de server worden gehaald via een RESTful API genaamd message-events, of je kunt SparkPost die gebeurtenissen naar een aantal verzamelapplicaties laten pushen die je wilt. Het pushmechanisme wordt uitgevoerd via webhooks en gebeurt real-time.

Momenteel zijn er 14 verschillende gebeurtenissen die bij een e-mail kunnen optreden.  Hier is een lijst van de huidige gebeurtenissen:

  • Bounce

  • ClickDelay

  • Bezorging

  • Generatiefout

  • Genereertijdafwijzing

  • Initiële open

  • InjectieLink Uitschrijving

  • Lijstuitschrijving

  • Open

  • Buiten Band

  • BeleidafwijzingSpam 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 type gebeurtenis. Sommige velden, zoals de transmission_id, komen voor in elke gebeurtenis, maar andere velden kunnen meer specifieke gebeurtenissen zijn; bijvoorbeeld alleen open- en klikgebeurtenissen hebben geotag-informatie.

Een zeer belangrijke boodschap-gebeurtenisinvoer voor dit project is de transmission_id. Alle boodschap-gebeurtenisvermeldingen voor de oorspronkelijke e-mail, gearchiveerde e-mail, en eventuele cc en bcc-adressen delen dezelfde transmission_id.

Er is ook een gemeenschappelijke invoer genaamd de message_id, die dezelfde id zal hebben voor elke invoer van de oorspronkelijke e-mail en de gearchiveerde e-mail. Eventuele cc- of bcc-adressen zullen hun eigen id hebben voor de message_id-invoer.

Tot nu toe klinkt dit geweldig en eerlijk gezegd vrij eenvoudig, maar nu komt het uitdagende deel. Vergeet niet, om de gearchiveerde e-mail te krijgen, laten we SparkPost een duplicaat van de oorspronkelijke e-mail sturen naar een ander e-mailadres dat overeenkomt met een inbox waartoe je toegang hebt. Maar om deze oplossing te automatiseren en het e-maillichaam op te slaan, ga ik een andere functie van SparkPost gebruiken, genaamd Inbound Email Relaying. Wat dat doet, is alle e-mails naar een specifiek domein nemen en verwerken. Door ze te verwerken, wordt de e-mail uit elkaar gehaald en een JSON-structuur gemaakt die vervolgens via een webhook naar een applicatie wordt gestuurd. Zie Appendix A voor een voorbeeld van JSON.

Als je goed kijkt, zul je merken dat de JSON-structuur van de inkomende relay een heel belangrijk veld mist; de transmission_id. Terwijl alle uitgaande e-mails de transmission_id met dezelfde invoer hebben, die alle gegevens van de oorspronkelijke e-mail, 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 verbonden met een van de uitgaande e-mails. Het inkomende proces weet gewoon dat een e-mail naar een specifiek domein is verzonden en de e-mail moet worden geparsed. Dat is het gewicht. Het zal elke e-mail verzonden naar dat domein hetzelfde behandelen, of het nu een reactie van een klant is of de archief-e-mail verzonden door SparkPost.

Dus de truc is; hoe verbind je de uitgaande gegevens met het inkomende proces dat net de gearchiveerde versie van de e-mail heeft opgehaald? Wat ik besloot te doen, is een unieke id in het lichaam van de e-mail te verbergen. Hoe dit moet worden gedaan, is aan jou, maar ik heb gewoon een invoerveld gemaakt met de verborgen tag ingeschakeld.

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

Ik heb dat veld ook toegevoegd aan het metadata-blok van de X-MSYS-API-header die wordt doorgestuurd naar SparkPost tijdens injectie. Deze verborgen UID zal de lijm zijn voor het hele proces en is een hoofdbestanddeel van het project en zal uitgebreid worden besproken in de volgende blogposts.

Nu we de UID hebben die dit project samen zal brengen en begrijpen waarom het noodzakelijk is, kan ik beginnen met het bouwen van de visie van het algehele project en de bijbehorende blogposts.

  1. Het vastleggen en opslaan van de gearchiveerde e-mail samen met een databasevermelding voor zoeken/indexeren

  2. Alle boodschap-gebeurtenisdata vastleggen

  3. Een applicatie creëren om de e-mail en alle bijbehorende gegevens te bekijken

Hier is een eenvoudig diagram van het project:

build an email archiving system - diagram


De eerste oplevering van code zal het archiveringsproces en het opslaan van de e-mail op S3 behandelen, terwijl de tweede oplevering van de code het opslaan van alle loggegevens van boodschap-gebeurtenissen in MySQL zal behandelen. Je kunt de eerste twee codeopleveringen en blogberichten verwachten ergens begin 2019.  Als je vragen of suggesties hebt, aarzel dan niet om ze door te geven.

Veel plezier met versturen.
– Jeff


Bijlage A:

JSON file example - email archiving system

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 daadwerkelijk opslaan van de e-mail of gerelateerde gegevens. Recentelijk heb ik een blog geschreven over het opslaan van alle gebeurtenisdata (d.w.z. wanneer de e-mail is verzonden, geopend, klikken, bounces, uitschrijvingen, enz.) op een e-mail met als doel controle, 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 alles samenbrengt met codevoorbeelden over hoe de e-mail en alle bijbehorende gegevens kunnen worden opgeslagen. In het komende jaar zal ik doorgaan met het bouwen aan dit project met als doel een werkende opslag- en weergaveapplicatie te creëren voor gearchiveerde e-mails en alle loginformatie geproduceerd door SparkPost. SparkPost heeft geen systeem dat het e-maillichaam archiveert, maar het maakt het bouwen van een archiveringsplatform redelijk eenvoudig.

In deze blogserie zal ik het proces beschrijven dat ik doorliep om het e-maillichaam op te slaan op S3 (Amazon's Simple Store Service) en alle relevante loggegevens in MySQL voor eenvoudige kruisverwijzing. Voor productiesystemen voor archivering die robuuste database-backupstrategieën vereisen, overweeg een uitgebreide PostgreSQL-backup- en herstelproces te implementeren om ervoor te zorgen dat uw archiveringsgegevens goed beschermd zijn. Uiteindelijk is dit het startpunt voor het bouwen van een applicatie die eenvoudig zoeken in gearchiveerde e-mails mogelijk maakt en deze e-mails weergeeft samen met de evenement (log)gegevens. De code voor dit project is te vinden in de volgende GitHub-repository: PHPArchivePlatform op GitHub

Deze eerste aflevering van de blogserie gaat de uitdaging beschrijven en een architectuur voor de oplossing uitwerken. De rest van de blogs zal delen van de oplossing in detail bespreken, samen met codevoorbeelden.

De eerste stap in mijn proces was om uit te vogelen hoe ik een kopie van de verzonden e-mail naar de oorspronkelijke ontvanger kon verkrijgen. Om een kopie van het e-maillichaam te verkrijgen, moet je ofwel:

  1. Het e-maillichaam vastleggen voordat je de e-mail verstuurt

  2. De e-mailserver een kopie laten opslaan

  3. De e-mailserver een kopie voor je laten maken om op te slaan

Als de e-mailserver items zoals linktracking of open tracking toevoegt, kun je #1 niet gebruiken omdat het de open-/kliktrackingwijzigingen niet zal weerspiegelen.

Dat betekent dat de server ofwel de e-mail moet opslaan of op de een of andere manier een kopie van die e-mail voor je moet aanbieden om op te slaan. Aangezien SparkPost geen opslagmechanisme voor e-maillichamen heeft, maar wel een manier om een kopie van de e-mail te maken, laten we SparkPost ons een duplicaat van de e-mail sturen om in S3 op te slaan.

Dit wordt gedaan door het gebruik van SparkPost's Archive-functie. De Archive-functie van SparkPost geeft de verzender 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 de oorspronkelijke. De documentatie van SparkPost definieert hun Archive-functie als volgt:

Ontvangers in de archieflijst ontvangen een exacte replica van het bericht dat naar het RCPT TO-adres is verzonden. In het bijzonder, alle gecodeerde links bedoeld voor de RCPT TO-ontvanger zullen identiek zijn in de archiefberichten.

De enige verschillen van de RCPT TO-e-mail zijn dat sommige headers anders zullen zijn, aangezien het doeladres voor de archive-e-mail anders is, maar het lichaam van de e-mail zal een exacte replica zijn!

Als je een diepere uitleg wilt, hier is een link naar de SparkPost-documentatie over het maken van duplicaat (of archief) kopieën van een e-mail.

Terzijde, SparkPost staat je eigenlijk toe om e-mails te sturen naar cc, bcc, en archive-e-mailadressen. Voor deze oplossing focussen we ons op de archive-adressen.

* Opmerking * Gearchiveerde e-mails kunnen ALLEEN worden gemaakt wanneer e-mails worden geïnjecteerd in SparkPost via SMTP!

Nu we weten hoe we een kopie van de oorspronkelijke e-mail kunnen verkrijgen, moeten we kijken naar de loggegevens die worden geproduceerd en enkele subtiele nuances binnen die gegevens. SparkPost houdt alles bij wat er op zijn servers gebeurt en biedt die informatie aan jou aan in de vorm van message-events. Die gebeurtenissen worden 10 dagen lang op SparkPost opgeslagen en kunnen van de server worden gehaald via een RESTful API genaamd message-events, of je kunt SparkPost die gebeurtenissen naar een aantal verzamelapplicaties laten pushen die je wilt. Het pushmechanisme wordt uitgevoerd via webhooks en gebeurt real-time.

Momenteel zijn er 14 verschillende gebeurtenissen die bij een e-mail kunnen optreden.  Hier is een lijst van de huidige gebeurtenissen:

  • Bounce

  • ClickDelay

  • Bezorging

  • Generatiefout

  • Genereertijdafwijzing

  • Initiële open

  • InjectieLink Uitschrijving

  • Lijstuitschrijving

  • Open

  • Buiten Band

  • BeleidafwijzingSpam 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 type gebeurtenis. Sommige velden, zoals de transmission_id, komen voor in elke gebeurtenis, maar andere velden kunnen meer specifieke gebeurtenissen zijn; bijvoorbeeld alleen open- en klikgebeurtenissen hebben geotag-informatie.

Een zeer belangrijke boodschap-gebeurtenisinvoer voor dit project is de transmission_id. Alle boodschap-gebeurtenisvermeldingen voor de oorspronkelijke e-mail, gearchiveerde e-mail, en eventuele cc en bcc-adressen delen dezelfde transmission_id.

Er is ook een gemeenschappelijke invoer genaamd de message_id, die dezelfde id zal hebben voor elke invoer van de oorspronkelijke e-mail en de gearchiveerde e-mail. Eventuele cc- of bcc-adressen zullen hun eigen id hebben voor de message_id-invoer.

Tot nu toe klinkt dit geweldig en eerlijk gezegd vrij eenvoudig, maar nu komt het uitdagende deel. Vergeet niet, om de gearchiveerde e-mail te krijgen, laten we SparkPost een duplicaat van de oorspronkelijke e-mail sturen naar een ander e-mailadres dat overeenkomt met een inbox waartoe je toegang hebt. Maar om deze oplossing te automatiseren en het e-maillichaam op te slaan, ga ik een andere functie van SparkPost gebruiken, genaamd Inbound Email Relaying. Wat dat doet, is alle e-mails naar een specifiek domein nemen en verwerken. Door ze te verwerken, wordt de e-mail uit elkaar gehaald en een JSON-structuur gemaakt die vervolgens via een webhook naar een applicatie wordt gestuurd. Zie Appendix A voor een voorbeeld van JSON.

Als je goed kijkt, zul je merken dat de JSON-structuur van de inkomende relay een heel belangrijk veld mist; de transmission_id. Terwijl alle uitgaande e-mails de transmission_id met dezelfde invoer hebben, die alle gegevens van de oorspronkelijke e-mail, 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 verbonden met een van de uitgaande e-mails. Het inkomende proces weet gewoon dat een e-mail naar een specifiek domein is verzonden en de e-mail moet worden geparsed. Dat is het gewicht. Het zal elke e-mail verzonden naar dat domein hetzelfde behandelen, of het nu een reactie van een klant is of de archief-e-mail verzonden door SparkPost.

Dus de truc is; hoe verbind je de uitgaande gegevens met het inkomende proces dat net de gearchiveerde versie van de e-mail heeft opgehaald? Wat ik besloot te doen, is een unieke id in het lichaam van de e-mail te verbergen. Hoe dit moet worden gedaan, is aan jou, maar ik heb gewoon een invoerveld gemaakt met de verborgen tag ingeschakeld.

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

Ik heb dat veld ook toegevoegd aan het metadata-blok van de X-MSYS-API-header die wordt doorgestuurd naar SparkPost tijdens injectie. Deze verborgen UID zal de lijm zijn voor het hele proces en is een hoofdbestanddeel van het project en zal uitgebreid worden besproken in de volgende blogposts.

Nu we de UID hebben die dit project samen zal brengen en begrijpen waarom het noodzakelijk is, kan ik beginnen met het bouwen van de visie van het algehele project en de bijbehorende blogposts.

  1. Het vastleggen en opslaan van de gearchiveerde e-mail samen met een databasevermelding voor zoeken/indexeren

  2. Alle boodschap-gebeurtenisdata vastleggen

  3. Een applicatie creëren om de e-mail en alle bijbehorende gegevens te bekijken

Hier is een eenvoudig diagram van het project:

build an email archiving system - diagram


De eerste oplevering van code zal het archiveringsproces en het opslaan van de e-mail op S3 behandelen, terwijl de tweede oplevering van de code het opslaan van alle loggegevens van boodschap-gebeurtenissen in MySQL zal behandelen. Je kunt de eerste twee codeopleveringen en blogberichten verwachten ergens begin 2019.  Als je vragen of suggesties hebt, aarzel dan niet om ze door te geven.

Veel plezier met versturen.
– Jeff


Bijlage A:

JSON file example - email archiving system

Andere nieuws

Lees meer uit deze categorie

A person is standing at a desk while typing on a laptop.

Het complete AI-native platform dat met uw bedrijf meegroeit.

A person is standing at a desk while typing on a laptop.

Het complete AI-native platform dat met uw bedrijf meegroeit.