Een e-mailarchiveringssysteem bouwen: het opslaan van de e-mailinhoud

Bird

4 mrt 2019

E-mail

1 min read

Een e-mailarchiveringssysteem bouwen: het opslaan van de e-mailinhoud

Belangrijkste punten

    • Doel: Dit bericht schetst de eerste fase van het bouwen van een e-mailarchiveringssysteem met behulp van SparkPost, Amazon S3, en MySQL. Het legt uit hoe e-mails gedupliceerd, vastgelegd en opgeslagen kunnen worden voor langdurige toegang en compliance.

    • Kernidee: Het systeem slaat automatisch de ruwe e-mailinhoud (rfc822-formaat) op in S3 en logt metadata (onderwerp, afzender, tijdstempel, enz.) in MySQL voor snelle zoekopdrachten en terughaling.

    • Essentiële zaken behandeld:

      1. Dupliceer maken voor archivering: Gebruik de Archive feature van SparkPost om identieke kopieën van uitgaande e-mails naar een aangewezen archiefadres te sturen, waarbij de inhoud en volgkoppelingslinks identiek blijven.

      2. Data binding via UID: Voeg een unieke identificatiecode (UID) in zowel de e-mailinhoud als de X-MSYS-API-metadata om de originele en gearchiveerde berichten te koppelen.

      3. Inbound verwerking: Configureer een inbound domein en webhook in SparkPost om de gearchiveerde e-mail JSON-payloads via een applicatiecollector te ontvangen.

      4. E-mails opslaan in S3: Upload het geparseerde rfc822 lichaam naar een S3 bucket, gebruikmakend van levenscyclusregels (bijv. overgang naar Glacier na een jaar) om opslagkosten te verlagen.

      5. Metadata loggen in MySQL: Sla belangrijke velden op zoals RCPT_TO, FROM, SUBJECT, en S3-bestandsnaam voor zoekindexering en toekomstige terughaling.

      6. Overwegingen voor prestaties: Code-efficiëntie en minimale logging zorgen ervoor dat de collector honderden verzoeken per minuut kan verwerken met minimale latentie.

    • Groot geheel: Deze basis ondersteunt toekomstige verbeteringen zoals opslag van loggebeurtenissen, foutwaarschuwingen, en UI-visualisatie, en legt de basis voor een schaalbare, controleerbare e-mailarchiefoplossing.

Q&A Hoogtepunten

  • Wat is het doel van dit project?

    Om een geautomatiseerd e-mailsysteem te maken dat berichtlichamen opslaat in Amazon S3 terwijl het doorzoekbare metadata behoudt in een MySQL-database.

  • Waarom de Archive functie van SparkPost gebruiken?

    Het stelt je in staat om exacte duplicaten van uitgaande e-mails te genereren, waarbij hun structuur en volggegevens voor naleving en beoordeling behouden blijven.

  • Hoe is elke gearchiveerde e-mail gekoppeld aan zijn oorspronkelijke bericht?

    Een unieke UID is ingebed in zowel de e-mailbody als de metadata, waardoor nauwkeurige kruisverwijzing tussen de originele en gearchiveerde kopieën mogelijk is.

  • Waarom S3 gebruiken voor opslag?

    S3 biedt schaalbare opslag- en levenscyclusbeheeropties (zoals Glacier), waardoor het kosteneffectief is voor langdurige e-mailopslag.

  • Wat slaat de MySQL database op?

    Het slaat doorzoekbare metadata velden op—zoals onderwerpregel, afzender, tijdstempels, en de S3-bestandsnaam—waardoor efficiënte query en retrieval mogelijk is.

  • Wat zijn de volgende ontwikkelingsstappen?

    Het toevoegen van logboekgebeurtenistracering, geautomatiseerde foutrapportage, een vereenvoudigde collector en een UI voor het bekijken of opnieuw verzenden van gearchiveerde e-mails.

In deze blog zal ik het proces beschrijven dat ik heb doorlopen om de inhoud van de e-mail op te slaan in S3 (Amazons Simple Store Service) en aanvullende gegevens in een MySQL-tabel voor eenvoudige kruisverwijzing. Uiteindelijk is dit het beginpunt voor de codebasis die een applicatie zal bevatten waarmee eenvoudig kan worden gezocht naar gearchiveerde e-mails, en vervolgens die e-mails samen met de gebeurtenis (log) gegevens kan worden weergegeven. De code voor dit project is te vinden in de volgende GitHub-repository: https://github.com/jeff-goldstein/PHPArchivePlatform.

Hoewel ik S3 en MySQL in dit project zal gebruiken, zijn dit zeker niet de enige technologieën die kunnen worden gebruikt om een archiveringsplatform te bouwen, maar gezien hun alomtegenwoordigheid dacht ik dat ze een goede keuze waren voor dit project. In een grootschalig hoogvolume systeem zou ik een database met hogere prestaties dan MySQL gebruiken, maar voor dit voorbeeldproject is MySQL perfect. Voor organisaties die PostgreSQL overwegen als hun archiveringsdatabaseselectie, is het implementeren van de juiste back-up- en herstelprocedures essentieel voor het behouden van de gegevensintegriteit in productiesystemen.

Ik heb hieronder de stappen beschreven die ik heb genomen in deze eerste fase van het project:

  1. Het creëren van de dubbele e-mail voor archivering

  2. Gebruik de Archivering en Inbound Relay-functies van SparkPost om een kopie van de oorspronkelijke e-mail terug te sturen naar SparkPost voor verwerking in een JSON-structuur, die vervolgens wordt verzonden naar een webhook-verzamelaar (applicatie)

  3. Demonteer de JSON-structuur om de nodige componenten te verkrijgen

  4. Verstuur de inhoud van de e-mail naar S3 voor opslag

  5. Log een vermelding in MySQL voor elke e-mail voor kruisverwijzing

In deze blog zal ik het proces beschrijven dat ik heb doorlopen om de inhoud van de e-mail op te slaan in S3 (Amazons Simple Store Service) en aanvullende gegevens in een MySQL-tabel voor eenvoudige kruisverwijzing. Uiteindelijk is dit het beginpunt voor de codebasis die een applicatie zal bevatten waarmee eenvoudig kan worden gezocht naar gearchiveerde e-mails, en vervolgens die e-mails samen met de gebeurtenis (log) gegevens kan worden weergegeven. De code voor dit project is te vinden in de volgende GitHub-repository: https://github.com/jeff-goldstein/PHPArchivePlatform.

Hoewel ik S3 en MySQL in dit project zal gebruiken, zijn dit zeker niet de enige technologieën die kunnen worden gebruikt om een archiveringsplatform te bouwen, maar gezien hun alomtegenwoordigheid dacht ik dat ze een goede keuze waren voor dit project. In een grootschalig hoogvolume systeem zou ik een database met hogere prestaties dan MySQL gebruiken, maar voor dit voorbeeldproject is MySQL perfect. Voor organisaties die PostgreSQL overwegen als hun archiveringsdatabaseselectie, is het implementeren van de juiste back-up- en herstelprocedures essentieel voor het behouden van de gegevensintegriteit in productiesystemen.

Ik heb hieronder de stappen beschreven die ik heb genomen in deze eerste fase van het project:

  1. Het creëren van de dubbele e-mail voor archivering

  2. Gebruik de Archivering en Inbound Relay-functies van SparkPost om een kopie van de oorspronkelijke e-mail terug te sturen naar SparkPost voor verwerking in een JSON-structuur, die vervolgens wordt verzonden naar een webhook-verzamelaar (applicatie)

  3. Demonteer de JSON-structuur om de nodige componenten te verkrijgen

  4. Verstuur de inhoud van de e-mail naar S3 voor opslag

  5. Log een vermelding in MySQL voor elke e-mail voor kruisverwijzing

In deze blog zal ik het proces beschrijven dat ik heb doorlopen om de inhoud van de e-mail op te slaan in S3 (Amazons Simple Store Service) en aanvullende gegevens in een MySQL-tabel voor eenvoudige kruisverwijzing. Uiteindelijk is dit het beginpunt voor de codebasis die een applicatie zal bevatten waarmee eenvoudig kan worden gezocht naar gearchiveerde e-mails, en vervolgens die e-mails samen met de gebeurtenis (log) gegevens kan worden weergegeven. De code voor dit project is te vinden in de volgende GitHub-repository: https://github.com/jeff-goldstein/PHPArchivePlatform.

Hoewel ik S3 en MySQL in dit project zal gebruiken, zijn dit zeker niet de enige technologieën die kunnen worden gebruikt om een archiveringsplatform te bouwen, maar gezien hun alomtegenwoordigheid dacht ik dat ze een goede keuze waren voor dit project. In een grootschalig hoogvolume systeem zou ik een database met hogere prestaties dan MySQL gebruiken, maar voor dit voorbeeldproject is MySQL perfect. Voor organisaties die PostgreSQL overwegen als hun archiveringsdatabaseselectie, is het implementeren van de juiste back-up- en herstelprocedures essentieel voor het behouden van de gegevensintegriteit in productiesystemen.

Ik heb hieronder de stappen beschreven die ik heb genomen in deze eerste fase van het project:

  1. Het creëren van de dubbele e-mail voor archivering

  2. Gebruik de Archivering en Inbound Relay-functies van SparkPost om een kopie van de oorspronkelijke e-mail terug te sturen naar SparkPost voor verwerking in een JSON-structuur, die vervolgens wordt verzonden naar een webhook-verzamelaar (applicatie)

  3. Demonteer de JSON-structuur om de nodige componenten te verkrijgen

  4. Verstuur de inhoud van de e-mail naar S3 voor opslag

  5. Log een vermelding in MySQL voor elke e-mail voor kruisverwijzing

Een duplicaat van de Email maken

In SparkPost is de beste manier om een e-mail te archiveren het maken van een identieke kopie van de e-mail die specifiek is ontworpen voor archiveringsdoeleinden. Dit wordt gedaan door gebruik te maken van de Archive functie van SparkPost. De Archive functie van SparkPost geeft de verzender de mogelijkheid om een duplicaat van de e-mail te verzenden naar één of meer e-mailadressen.  Dit duplicaat gebruikt dezelfde tracking en open links als het origineel. De documentatie van SparkPost definieert de Archive functie op de volgende manier:

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

Het enige verschil tussen deze archiefkopie en de originele RCPT TO-e-mail is dat sommige van de headers anders zullen zijn, aangezien het doeladres voor de archiveringsmail anders is, maar de inhoud van de e-mail zal een exacte replica zijn!

Als je een diepere uitleg wilt, hier is een link naar de documentatie van SparkPost over het maken van dubbele (of archief) kopieën van een e-mail. Voorbeeldheaders van X-MSYS-API voor dit project worden later in deze blog getoond.

Er is één kanttekening bij deze benadering; terwijl alle gebeurtenisinformatie in de originele e-mail samenhangt door zowel een transmission_id als een message_id, is er geen informatie in het inkomende relay-gebeurtenis (het mechanisme voor het verkrijgen en verspreiden van de archiefmail) voor de dubbele e-mail die terugleidt naar een van die twee id’s en dus de informatie voor de originele e-mail. Dit betekent dat we gegevens in de e-mailinhoud en de header van de originele e-mail moeten plaatsen als een manier om alle SparkPost-gegevens van de originele en archiefmail te verbinden.

Om de code te maken die in de e-mailinhoud wordt geplaatst, gebruikte ik het volgende proces in de e-mailcreatie applicatie.

  1. Ergens in de e-mailinhoud plaatste ik de volgende invoer:<input name="ArchiveCode" type="hidden" value="<<UID>>">

  2. Vervolgens creëerde ik een unieke code en verving het <<UID>> veld:$uid = md5(uniqid(rand(), true)); $emailBody = str_replace(“<<UID>>,$uid,$emailBody);

    Hier is een voorbeeldoutput:

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

  3. Daarna zorgde ik ervoor dat ik de $UID aan het meta_data blok van de X-MSYS-API header toevoegde. Deze stap zorgt ervoor dat de UID is ingesloten in elke gebeurtenisoutput voor de originele e-mail:

X-MSYS-API: {
  "campaign_id": "<my_campaign>",
  "metadata": {
    "UID": "<UID>"
  },
  "archive": [
    {
      "email": "archive@geekwithapersonality.com"
    }
  ],
  "options": {
    "open_tracking": false,
    "click_tracking": false,
    "transactional": false,
    "ip_pool": "<my_ip_pool>"
  }
}

Nu hebben we een manier om alle gegevens van de originele e-mail te koppelen aan de e-mailinhoud van de archiefkopie.

In SparkPost is de beste manier om een e-mail te archiveren het maken van een identieke kopie van de e-mail die specifiek is ontworpen voor archiveringsdoeleinden. Dit wordt gedaan door gebruik te maken van de Archive functie van SparkPost. De Archive functie van SparkPost geeft de verzender de mogelijkheid om een duplicaat van de e-mail te verzenden naar één of meer e-mailadressen.  Dit duplicaat gebruikt dezelfde tracking en open links als het origineel. De documentatie van SparkPost definieert de Archive functie op de volgende manier:

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

Het enige verschil tussen deze archiefkopie en de originele RCPT TO-e-mail is dat sommige van de headers anders zullen zijn, aangezien het doeladres voor de archiveringsmail anders is, maar de inhoud van de e-mail zal een exacte replica zijn!

Als je een diepere uitleg wilt, hier is een link naar de documentatie van SparkPost over het maken van dubbele (of archief) kopieën van een e-mail. Voorbeeldheaders van X-MSYS-API voor dit project worden later in deze blog getoond.

Er is één kanttekening bij deze benadering; terwijl alle gebeurtenisinformatie in de originele e-mail samenhangt door zowel een transmission_id als een message_id, is er geen informatie in het inkomende relay-gebeurtenis (het mechanisme voor het verkrijgen en verspreiden van de archiefmail) voor de dubbele e-mail die terugleidt naar een van die twee id’s en dus de informatie voor de originele e-mail. Dit betekent dat we gegevens in de e-mailinhoud en de header van de originele e-mail moeten plaatsen als een manier om alle SparkPost-gegevens van de originele en archiefmail te verbinden.

Om de code te maken die in de e-mailinhoud wordt geplaatst, gebruikte ik het volgende proces in de e-mailcreatie applicatie.

  1. Ergens in de e-mailinhoud plaatste ik de volgende invoer:<input name="ArchiveCode" type="hidden" value="<<UID>>">

  2. Vervolgens creëerde ik een unieke code en verving het <<UID>> veld:$uid = md5(uniqid(rand(), true)); $emailBody = str_replace(“<<UID>>,$uid,$emailBody);

    Hier is een voorbeeldoutput:

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

  3. Daarna zorgde ik ervoor dat ik de $UID aan het meta_data blok van de X-MSYS-API header toevoegde. Deze stap zorgt ervoor dat de UID is ingesloten in elke gebeurtenisoutput voor de originele e-mail:

X-MSYS-API: {
  "campaign_id": "<my_campaign>",
  "metadata": {
    "UID": "<UID>"
  },
  "archive": [
    {
      "email": "archive@geekwithapersonality.com"
    }
  ],
  "options": {
    "open_tracking": false,
    "click_tracking": false,
    "transactional": false,
    "ip_pool": "<my_ip_pool>"
  }
}

Nu hebben we een manier om alle gegevens van de originele e-mail te koppelen aan de e-mailinhoud van de archiefkopie.

In SparkPost is de beste manier om een e-mail te archiveren het maken van een identieke kopie van de e-mail die specifiek is ontworpen voor archiveringsdoeleinden. Dit wordt gedaan door gebruik te maken van de Archive functie van SparkPost. De Archive functie van SparkPost geeft de verzender de mogelijkheid om een duplicaat van de e-mail te verzenden naar één of meer e-mailadressen.  Dit duplicaat gebruikt dezelfde tracking en open links als het origineel. De documentatie van SparkPost definieert de Archive functie op de volgende manier:

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

Het enige verschil tussen deze archiefkopie en de originele RCPT TO-e-mail is dat sommige van de headers anders zullen zijn, aangezien het doeladres voor de archiveringsmail anders is, maar de inhoud van de e-mail zal een exacte replica zijn!

Als je een diepere uitleg wilt, hier is een link naar de documentatie van SparkPost over het maken van dubbele (of archief) kopieën van een e-mail. Voorbeeldheaders van X-MSYS-API voor dit project worden later in deze blog getoond.

Er is één kanttekening bij deze benadering; terwijl alle gebeurtenisinformatie in de originele e-mail samenhangt door zowel een transmission_id als een message_id, is er geen informatie in het inkomende relay-gebeurtenis (het mechanisme voor het verkrijgen en verspreiden van de archiefmail) voor de dubbele e-mail die terugleidt naar een van die twee id’s en dus de informatie voor de originele e-mail. Dit betekent dat we gegevens in de e-mailinhoud en de header van de originele e-mail moeten plaatsen als een manier om alle SparkPost-gegevens van de originele en archiefmail te verbinden.

Om de code te maken die in de e-mailinhoud wordt geplaatst, gebruikte ik het volgende proces in de e-mailcreatie applicatie.

  1. Ergens in de e-mailinhoud plaatste ik de volgende invoer:<input name="ArchiveCode" type="hidden" value="<<UID>>">

  2. Vervolgens creëerde ik een unieke code en verving het <<UID>> veld:$uid = md5(uniqid(rand(), true)); $emailBody = str_replace(“<<UID>>,$uid,$emailBody);

    Hier is een voorbeeldoutput:

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

  3. Daarna zorgde ik ervoor dat ik de $UID aan het meta_data blok van de X-MSYS-API header toevoegde. Deze stap zorgt ervoor dat de UID is ingesloten in elke gebeurtenisoutput voor de originele e-mail:

X-MSYS-API: {
  "campaign_id": "<my_campaign>",
  "metadata": {
    "UID": "<UID>"
  },
  "archive": [
    {
      "email": "archive@geekwithapersonality.com"
    }
  ],
  "options": {
    "open_tracking": false,
    "click_tracking": false,
    "transactional": false,
    "ip_pool": "<my_ip_pool>"
  }
}

Nu hebben we een manier om alle gegevens van de originele e-mail te koppelen aan de e-mailinhoud van de archiefkopie.

De Archief versie verkrijgen

Om een kopie van een e-mail voor archivering te verkrijgen, moet u de volgende stappen ondernemen:

  1. Maak een subdomein waarop u alle archive (dubbele) e-mail(s) naartoe stuurt

  2. Stel de juiste DNS-records in zodat alle e-mails naar dat subdomein naar SparkPost worden verzonden

  3. Maak een inbound domein in SparkPost

  4. Maak een inbound webhook in SparkPost

  5. Maak een applicatie (collector) om de SparkPost webhook datastroom te ontvangen

De volgende twee links kunnen u helpen bij het begeleiden door dit proces:

  1. SparkPost technische documentatie: Enabling Inbound Email Relaying & Relay Webhooks

  2. Ook, de blog die ik vorig jaar schreef, Archiving Emails: A How-To Guide for Tracking Sent Mail zal u begeleiden bij de creatie van de inbound relay binnen SparkPost

* Opmerking: vanaf oktober 2018 werkt de Archive functie alleen bij het verzenden van e-mails met behulp van een SMTP-verbinding naar SparkPost, de RESTful API ondersteunt deze functie niet.  Dat is waarschijnlijk niet een probleem omdat de meeste e-mails die dit niveau van auditcontrole nodig hebben, gepersonaliseerde e-mails zijn die volledig door een backend applicatie worden opgebouwd voordat e-maillevering nodig is.

Om een kopie van een e-mail voor archivering te verkrijgen, moet u de volgende stappen ondernemen:

  1. Maak een subdomein waarop u alle archive (dubbele) e-mail(s) naartoe stuurt

  2. Stel de juiste DNS-records in zodat alle e-mails naar dat subdomein naar SparkPost worden verzonden

  3. Maak een inbound domein in SparkPost

  4. Maak een inbound webhook in SparkPost

  5. Maak een applicatie (collector) om de SparkPost webhook datastroom te ontvangen

De volgende twee links kunnen u helpen bij het begeleiden door dit proces:

  1. SparkPost technische documentatie: Enabling Inbound Email Relaying & Relay Webhooks

  2. Ook, de blog die ik vorig jaar schreef, Archiving Emails: A How-To Guide for Tracking Sent Mail zal u begeleiden bij de creatie van de inbound relay binnen SparkPost

* Opmerking: vanaf oktober 2018 werkt de Archive functie alleen bij het verzenden van e-mails met behulp van een SMTP-verbinding naar SparkPost, de RESTful API ondersteunt deze functie niet.  Dat is waarschijnlijk niet een probleem omdat de meeste e-mails die dit niveau van auditcontrole nodig hebben, gepersonaliseerde e-mails zijn die volledig door een backend applicatie worden opgebouwd voordat e-maillevering nodig is.

Om een kopie van een e-mail voor archivering te verkrijgen, moet u de volgende stappen ondernemen:

  1. Maak een subdomein waarop u alle archive (dubbele) e-mail(s) naartoe stuurt

  2. Stel de juiste DNS-records in zodat alle e-mails naar dat subdomein naar SparkPost worden verzonden

  3. Maak een inbound domein in SparkPost

  4. Maak een inbound webhook in SparkPost

  5. Maak een applicatie (collector) om de SparkPost webhook datastroom te ontvangen

De volgende twee links kunnen u helpen bij het begeleiden door dit proces:

  1. SparkPost technische documentatie: Enabling Inbound Email Relaying & Relay Webhooks

  2. Ook, de blog die ik vorig jaar schreef, Archiving Emails: A How-To Guide for Tracking Sent Mail zal u begeleiden bij de creatie van de inbound relay binnen SparkPost

* Opmerking: vanaf oktober 2018 werkt de Archive functie alleen bij het verzenden van e-mails met behulp van een SMTP-verbinding naar SparkPost, de RESTful API ondersteunt deze functie niet.  Dat is waarschijnlijk niet een probleem omdat de meeste e-mails die dit niveau van auditcontrole nodig hebben, gepersonaliseerde e-mails zijn die volledig door een backend applicatie worden opgebouwd voordat e-maillevering nodig is.

Het verkrijgen van de dubbele e-mail in een JSON-structuur

In de eerste fase van dit project sla ik alleen de rfc822-e-mailindeling op in S3 en enkele hoog-niveau beschrijvingsvelden in een SQL-tabel voor zoeken.  Aangezien SparkPost de e-mailgegevens in een JSON-structuur naar mijn archiveringsplatform stuurt via webhook-datastromen, heb ik een applicatie gebouwd (vaak een collector genoemd) die de Relay_Webhook-datastroom accepteert.

Elk pakket van de SparkPost Relay_Webhook bevat de informatie van één dubbele e-mail tegelijk, dus het uiteenzetten van de JSON-structuur in de doelcomponenten voor dit project is vrij eenvoudig.  In mijn PHP-code was het verkrijgen van de rfc822-geformatteerde e-mail net zo eenvoudig als de volgende paar regels code:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $body = file_get_contents("php://input");
    $fields = json_decode($body, true);
    $rfc822body = $fields[0]['msys']['relay_message']['content']['email_rfc822'];
    $htmlbody = $fields[0]['msys']['relay_message']['content']['html'];
    $headers  = $fields[0]['msys']['relay_message']['content']['headers'];
}

Een deel van de informatie die ik in mijn SQL-tabel wil opslaan bevindt zich in een array van header-velden.  Daarom heb ik een kleine functie geschreven die de header-array accepteert en door de array heen loopt om de gegevens te verkrijgen waarin ik geïnteresseerd ben om op te slaan:

function get_important_headers($headers, &$original_to, &$headerDate, &$subject, &$from) {
    foreach ($headers as $headerGroup) {
        foreach ($headerGroup as $key => $value) {
            if ($key === 'To') {
                $original_to = $value;
            } elseif ($key === 'Date') {
                $headerDate = $value;
            } elseif ($key === 'Subject') {
                $subject = $value;
            } elseif ($key === 'From') {
                $from = $value;
            }
        }
    }
}

Nu ik de gegevens heb, ben ik klaar om de body op te slaan in S3.

In de eerste fase van dit project sla ik alleen de rfc822-e-mailindeling op in S3 en enkele hoog-niveau beschrijvingsvelden in een SQL-tabel voor zoeken.  Aangezien SparkPost de e-mailgegevens in een JSON-structuur naar mijn archiveringsplatform stuurt via webhook-datastromen, heb ik een applicatie gebouwd (vaak een collector genoemd) die de Relay_Webhook-datastroom accepteert.

Elk pakket van de SparkPost Relay_Webhook bevat de informatie van één dubbele e-mail tegelijk, dus het uiteenzetten van de JSON-structuur in de doelcomponenten voor dit project is vrij eenvoudig.  In mijn PHP-code was het verkrijgen van de rfc822-geformatteerde e-mail net zo eenvoudig als de volgende paar regels code:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $body = file_get_contents("php://input");
    $fields = json_decode($body, true);
    $rfc822body = $fields[0]['msys']['relay_message']['content']['email_rfc822'];
    $htmlbody = $fields[0]['msys']['relay_message']['content']['html'];
    $headers  = $fields[0]['msys']['relay_message']['content']['headers'];
}

Een deel van de informatie die ik in mijn SQL-tabel wil opslaan bevindt zich in een array van header-velden.  Daarom heb ik een kleine functie geschreven die de header-array accepteert en door de array heen loopt om de gegevens te verkrijgen waarin ik geïnteresseerd ben om op te slaan:

function get_important_headers($headers, &$original_to, &$headerDate, &$subject, &$from) {
    foreach ($headers as $headerGroup) {
        foreach ($headerGroup as $key => $value) {
            if ($key === 'To') {
                $original_to = $value;
            } elseif ($key === 'Date') {
                $headerDate = $value;
            } elseif ($key === 'Subject') {
                $subject = $value;
            } elseif ($key === 'From') {
                $from = $value;
            }
        }
    }
}

Nu ik de gegevens heb, ben ik klaar om de body op te slaan in S3.

In de eerste fase van dit project sla ik alleen de rfc822-e-mailindeling op in S3 en enkele hoog-niveau beschrijvingsvelden in een SQL-tabel voor zoeken.  Aangezien SparkPost de e-mailgegevens in een JSON-structuur naar mijn archiveringsplatform stuurt via webhook-datastromen, heb ik een applicatie gebouwd (vaak een collector genoemd) die de Relay_Webhook-datastroom accepteert.

Elk pakket van de SparkPost Relay_Webhook bevat de informatie van één dubbele e-mail tegelijk, dus het uiteenzetten van de JSON-structuur in de doelcomponenten voor dit project is vrij eenvoudig.  In mijn PHP-code was het verkrijgen van de rfc822-geformatteerde e-mail net zo eenvoudig als de volgende paar regels code:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $body = file_get_contents("php://input");
    $fields = json_decode($body, true);
    $rfc822body = $fields[0]['msys']['relay_message']['content']['email_rfc822'];
    $htmlbody = $fields[0]['msys']['relay_message']['content']['html'];
    $headers  = $fields[0]['msys']['relay_message']['content']['headers'];
}

Een deel van de informatie die ik in mijn SQL-tabel wil opslaan bevindt zich in een array van header-velden.  Daarom heb ik een kleine functie geschreven die de header-array accepteert en door de array heen loopt om de gegevens te verkrijgen waarin ik geïnteresseerd ben om op te slaan:

function get_important_headers($headers, &$original_to, &$headerDate, &$subject, &$from) {
    foreach ($headers as $headerGroup) {
        foreach ($headerGroup as $key => $value) {
            if ($key === 'To') {
                $original_to = $value;
            } elseif ($key === 'Date') {
                $headerDate = $value;
            } elseif ($key === 'Subject') {
                $subject = $value;
            } elseif ($key === 'From') {
                $from = $value;
            }
        }
    }
}

Nu ik de gegevens heb, ben ik klaar om de body op te slaan in S3.

Het opslaan van de dubbele email in S3

Het spijt me om u teleur te stellen, maar ik ga geen stapsgewijze handleiding geven over het maken van een S3-bucket voor het opslaan van de e-mail, noch ga ik beschrijven hoe u de noodzakelijke toegangssleutel kunt maken die u in uw applicatie nodig zult hebben voor het uploaden van inhoud naar uw bucket; er zijn betere tutorials over dit onderwerp dan ik ooit zou kunnen schrijven.  Hier zijn een paar artikelen die mogelijk helpen:

https://docs.aws.amazon.com/quickstarts/latest/s3backup/step-1-create-bucket.html
https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/

Wat ik wel zal doen, is enkele van de instellingen aanwijzen die ik heb gekozen voor een project als dit.

  1. Toegangscontrole.  U moet niet alleen de beveiliging voor de bucket instellen, maar u moet ook de machtigingen voor de items zelf instellen.  In mijn project gebruik ik een zeer open beleid van public-read omdat de voorbeeldgegevens niet persoonlijk zijn en ik gemakkelijk toegang tot de gegevens wilde.  U zult waarschijnlijk een veel strikter set van ACL-beleid willen. Hier is een goed artikel over ACL-instellingen: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html

  2. Archivering van het archief. In S3 is er iets dat Lifecycle Management wordt genoemd.  Dit stelt u in staat om gegevens van het ene type S3-opslagklasse naar een andere te verplaatsen.  De verschillende opslagklassen vertegenwoordigen de hoeveelheid toegang die u nodig hebt tot de opgeslagen gegevens met lagere kosten gekoppeld aan de opslag die u het minst aanspreekt. Een goed verslag van de verschillende klassen en het doorlopen ervan kan worden gevonden in een AWS-gids genaamd, Transitioning Objects. In mijn geval koos ik ervoor om een lifecycle te maken die elk object na een jaar van Standard naar Glacier verplaatst. Glacier-toegang is veel goedkoper dan het standaard S3-archief en zal me geld besparen in opslagkosten.

Zodra ik de S3-bucket heb aangemaakt en mijn instellingen zijn geplaatst, is S3 klaar voor mij om de rfc822-conforme e-mail te uploaden die ik verkreeg van de SparkPost Relay Webhook-datastroom. Maar voordat ik de rfc822-e-mail upload naar S3, moet ik een unieke bestandsnaam creëren die ik ga gebruiken om die e-mail op te slaan.

Voor de unieke bestandsnaam ga ik het e-mailbody doorzoeken voor het verborgen id dat de verzendende applicatie in de e-mail heeft geplaatst en dat id gebruiken als de naam van het bestand. Er zijn meer elegante manieren om de connectorId uit de html-body te halen, maar voor eenvoud en duidelijkheid ga ik de volgende code gebruiken:

$start = strpos($htmlbody, $inputField);
if ($start !== false) {
    $start = strpos($htmlbody, 'value="', $start);
    if ($start !== false) {
        $start += 7; // Move past 'value="'
        $end = strpos($htmlbody, '"', $start);
        if ($end !== false) {
            $length = $end - $start;
            $UID = substr($htmlbody, $start, $length);
        }
    }
}

* we gaan ervan uit dat $inputField de waarde “ArchiveCode” bevat en werd gevonden in mijn config.php-bestand.

Met de UID kunnen we dan de bestandsnaam maken die zal worden gebruikt in S3:

$fileName = $ArchiveDirectory . '/' . $UID . '.eml';

Nu kan ik mijn verbinding met S3 openen en het bestand uploaden. Als u naar de s3.php-bestand in de GitHub-repository kijkt, zult u zien dat er maar heel weinig code nodig is om het bestand te uploaden.

Mijn laatste stap is om deze invoer in de MYSQL-tabel te loggen.

Het spijt me om u teleur te stellen, maar ik ga geen stapsgewijze handleiding geven over het maken van een S3-bucket voor het opslaan van de e-mail, noch ga ik beschrijven hoe u de noodzakelijke toegangssleutel kunt maken die u in uw applicatie nodig zult hebben voor het uploaden van inhoud naar uw bucket; er zijn betere tutorials over dit onderwerp dan ik ooit zou kunnen schrijven.  Hier zijn een paar artikelen die mogelijk helpen:

https://docs.aws.amazon.com/quickstarts/latest/s3backup/step-1-create-bucket.html
https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/

Wat ik wel zal doen, is enkele van de instellingen aanwijzen die ik heb gekozen voor een project als dit.

  1. Toegangscontrole.  U moet niet alleen de beveiliging voor de bucket instellen, maar u moet ook de machtigingen voor de items zelf instellen.  In mijn project gebruik ik een zeer open beleid van public-read omdat de voorbeeldgegevens niet persoonlijk zijn en ik gemakkelijk toegang tot de gegevens wilde.  U zult waarschijnlijk een veel strikter set van ACL-beleid willen. Hier is een goed artikel over ACL-instellingen: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html

  2. Archivering van het archief. In S3 is er iets dat Lifecycle Management wordt genoemd.  Dit stelt u in staat om gegevens van het ene type S3-opslagklasse naar een andere te verplaatsen.  De verschillende opslagklassen vertegenwoordigen de hoeveelheid toegang die u nodig hebt tot de opgeslagen gegevens met lagere kosten gekoppeld aan de opslag die u het minst aanspreekt. Een goed verslag van de verschillende klassen en het doorlopen ervan kan worden gevonden in een AWS-gids genaamd, Transitioning Objects. In mijn geval koos ik ervoor om een lifecycle te maken die elk object na een jaar van Standard naar Glacier verplaatst. Glacier-toegang is veel goedkoper dan het standaard S3-archief en zal me geld besparen in opslagkosten.

Zodra ik de S3-bucket heb aangemaakt en mijn instellingen zijn geplaatst, is S3 klaar voor mij om de rfc822-conforme e-mail te uploaden die ik verkreeg van de SparkPost Relay Webhook-datastroom. Maar voordat ik de rfc822-e-mail upload naar S3, moet ik een unieke bestandsnaam creëren die ik ga gebruiken om die e-mail op te slaan.

Voor de unieke bestandsnaam ga ik het e-mailbody doorzoeken voor het verborgen id dat de verzendende applicatie in de e-mail heeft geplaatst en dat id gebruiken als de naam van het bestand. Er zijn meer elegante manieren om de connectorId uit de html-body te halen, maar voor eenvoud en duidelijkheid ga ik de volgende code gebruiken:

$start = strpos($htmlbody, $inputField);
if ($start !== false) {
    $start = strpos($htmlbody, 'value="', $start);
    if ($start !== false) {
        $start += 7; // Move past 'value="'
        $end = strpos($htmlbody, '"', $start);
        if ($end !== false) {
            $length = $end - $start;
            $UID = substr($htmlbody, $start, $length);
        }
    }
}

* we gaan ervan uit dat $inputField de waarde “ArchiveCode” bevat en werd gevonden in mijn config.php-bestand.

Met de UID kunnen we dan de bestandsnaam maken die zal worden gebruikt in S3:

$fileName = $ArchiveDirectory . '/' . $UID . '.eml';

Nu kan ik mijn verbinding met S3 openen en het bestand uploaden. Als u naar de s3.php-bestand in de GitHub-repository kijkt, zult u zien dat er maar heel weinig code nodig is om het bestand te uploaden.

Mijn laatste stap is om deze invoer in de MYSQL-tabel te loggen.

Het spijt me om u teleur te stellen, maar ik ga geen stapsgewijze handleiding geven over het maken van een S3-bucket voor het opslaan van de e-mail, noch ga ik beschrijven hoe u de noodzakelijke toegangssleutel kunt maken die u in uw applicatie nodig zult hebben voor het uploaden van inhoud naar uw bucket; er zijn betere tutorials over dit onderwerp dan ik ooit zou kunnen schrijven.  Hier zijn een paar artikelen die mogelijk helpen:

https://docs.aws.amazon.com/quickstarts/latest/s3backup/step-1-create-bucket.html
https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/

Wat ik wel zal doen, is enkele van de instellingen aanwijzen die ik heb gekozen voor een project als dit.

  1. Toegangscontrole.  U moet niet alleen de beveiliging voor de bucket instellen, maar u moet ook de machtigingen voor de items zelf instellen.  In mijn project gebruik ik een zeer open beleid van public-read omdat de voorbeeldgegevens niet persoonlijk zijn en ik gemakkelijk toegang tot de gegevens wilde.  U zult waarschijnlijk een veel strikter set van ACL-beleid willen. Hier is een goed artikel over ACL-instellingen: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html

  2. Archivering van het archief. In S3 is er iets dat Lifecycle Management wordt genoemd.  Dit stelt u in staat om gegevens van het ene type S3-opslagklasse naar een andere te verplaatsen.  De verschillende opslagklassen vertegenwoordigen de hoeveelheid toegang die u nodig hebt tot de opgeslagen gegevens met lagere kosten gekoppeld aan de opslag die u het minst aanspreekt. Een goed verslag van de verschillende klassen en het doorlopen ervan kan worden gevonden in een AWS-gids genaamd, Transitioning Objects. In mijn geval koos ik ervoor om een lifecycle te maken die elk object na een jaar van Standard naar Glacier verplaatst. Glacier-toegang is veel goedkoper dan het standaard S3-archief en zal me geld besparen in opslagkosten.

Zodra ik de S3-bucket heb aangemaakt en mijn instellingen zijn geplaatst, is S3 klaar voor mij om de rfc822-conforme e-mail te uploaden die ik verkreeg van de SparkPost Relay Webhook-datastroom. Maar voordat ik de rfc822-e-mail upload naar S3, moet ik een unieke bestandsnaam creëren die ik ga gebruiken om die e-mail op te slaan.

Voor de unieke bestandsnaam ga ik het e-mailbody doorzoeken voor het verborgen id dat de verzendende applicatie in de e-mail heeft geplaatst en dat id gebruiken als de naam van het bestand. Er zijn meer elegante manieren om de connectorId uit de html-body te halen, maar voor eenvoud en duidelijkheid ga ik de volgende code gebruiken:

$start = strpos($htmlbody, $inputField);
if ($start !== false) {
    $start = strpos($htmlbody, 'value="', $start);
    if ($start !== false) {
        $start += 7; // Move past 'value="'
        $end = strpos($htmlbody, '"', $start);
        if ($end !== false) {
            $length = $end - $start;
            $UID = substr($htmlbody, $start, $length);
        }
    }
}

* we gaan ervan uit dat $inputField de waarde “ArchiveCode” bevat en werd gevonden in mijn config.php-bestand.

Met de UID kunnen we dan de bestandsnaam maken die zal worden gebruikt in S3:

$fileName = $ArchiveDirectory . '/' . $UID . '.eml';

Nu kan ik mijn verbinding met S3 openen en het bestand uploaden. Als u naar de s3.php-bestand in de GitHub-repository kijkt, zult u zien dat er maar heel weinig code nodig is om het bestand te uploaden.

Mijn laatste stap is om deze invoer in de MYSQL-tabel te loggen.

Het opslaan van de Meta Data in MySQL

We hebben alle benodigde gegevens in een eerdere stap verzameld, dus de opslagstap is eenvoudig.  In deze eerste fase koos ik ervoor om een tabel te maken met de volgende velden:

MySQL Metadata Velden

Veld

Doel

Datum/tijd (automatisch)

Tijdstempel wanneer de invoer werd geregistreerd

RCPT_TO-adres

Doel-e-mailadres voor het gearchiveerde bericht

DATE-header tijdstempel

Verzendtijd van de oorspronkelijke e-mail

SUBJECT-header

Onderwerpregel voor indexering en zoeken

FROM-header

Zendidentificatie voor opzoeking

S3-map

Map pad binnen S3-bucket

S3-bestandsnaam

Uniek .eml-bestand opgeslagen in S3

De functie genaamd, MySQLLog binnen het upload.php toepassingsbestand doorloopt de nodige stappen om de link naar MySQL te openen, de nieuwe rij in te voegen, de resultaten te testen en de link te sluiten. Ik voeg één andere stap toe voor de zekerheid, namelijk om deze gegevens in een tekstbestand te loggen. Moet ik veel meer loggen voor fouten? Ja. Maar ik wil deze code licht houden om ervoor te zorgen dat het extreem snel kan draaien. Soms wordt deze code honderden keren per minuut aangeroepen en moet het zo efficiënt mogelijk zijn. In toekomstige updates zal ik aanvullende code toevoegen die fouten verwerkt en die fouten naar een beheerder e-mailt voor monitoring.

We hebben alle benodigde gegevens in een eerdere stap verzameld, dus de opslagstap is eenvoudig.  In deze eerste fase koos ik ervoor om een tabel te maken met de volgende velden:

MySQL Metadata Velden

Veld

Doel

Datum/tijd (automatisch)

Tijdstempel wanneer de invoer werd geregistreerd

RCPT_TO-adres

Doel-e-mailadres voor het gearchiveerde bericht

DATE-header tijdstempel

Verzendtijd van de oorspronkelijke e-mail

SUBJECT-header

Onderwerpregel voor indexering en zoeken

FROM-header

Zendidentificatie voor opzoeking

S3-map

Map pad binnen S3-bucket

S3-bestandsnaam

Uniek .eml-bestand opgeslagen in S3

De functie genaamd, MySQLLog binnen het upload.php toepassingsbestand doorloopt de nodige stappen om de link naar MySQL te openen, de nieuwe rij in te voegen, de resultaten te testen en de link te sluiten. Ik voeg één andere stap toe voor de zekerheid, namelijk om deze gegevens in een tekstbestand te loggen. Moet ik veel meer loggen voor fouten? Ja. Maar ik wil deze code licht houden om ervoor te zorgen dat het extreem snel kan draaien. Soms wordt deze code honderden keren per minuut aangeroepen en moet het zo efficiënt mogelijk zijn. In toekomstige updates zal ik aanvullende code toevoegen die fouten verwerkt en die fouten naar een beheerder e-mailt voor monitoring.

We hebben alle benodigde gegevens in een eerdere stap verzameld, dus de opslagstap is eenvoudig.  In deze eerste fase koos ik ervoor om een tabel te maken met de volgende velden:

MySQL Metadata Velden

Veld

Doel

Datum/tijd (automatisch)

Tijdstempel wanneer de invoer werd geregistreerd

RCPT_TO-adres

Doel-e-mailadres voor het gearchiveerde bericht

DATE-header tijdstempel

Verzendtijd van de oorspronkelijke e-mail

SUBJECT-header

Onderwerpregel voor indexering en zoeken

FROM-header

Zendidentificatie voor opzoeking

S3-map

Map pad binnen S3-bucket

S3-bestandsnaam

Uniek .eml-bestand opgeslagen in S3

De functie genaamd, MySQLLog binnen het upload.php toepassingsbestand doorloopt de nodige stappen om de link naar MySQL te openen, de nieuwe rij in te voegen, de resultaten te testen en de link te sluiten. Ik voeg één andere stap toe voor de zekerheid, namelijk om deze gegevens in een tekstbestand te loggen. Moet ik veel meer loggen voor fouten? Ja. Maar ik wil deze code licht houden om ervoor te zorgen dat het extreem snel kan draaien. Soms wordt deze code honderden keren per minuut aangeroepen en moet het zo efficiënt mogelijk zijn. In toekomstige updates zal ik aanvullende code toevoegen die fouten verwerkt en die fouten naar een beheerder e-mailt voor monitoring.

Het afsluiten

Dus in een paar redelijk eenvoudige stappen konden we door de eerste fase van het bouwen van een robuust e-mailarchiveringssysteem lopen dat de e-mailduplicaat in S3 bewaart en gegevens kruislings controleert in een MySQL-tabel.  Dit geeft ons een basis voor de rest van het project dat in verschillende toekomstige posts zal worden aangepakt.

In toekomstige revisies van dit project zou ik verwachten:

  1. Alle loggebeurtenissen van de originele e-mail opslaan

  2. Opslagfouten naar een beheerder sturen wanneer een upload- of logfout optreedt

  3. De verzamelcomplexiteit minimaliseren.

  4. Een UI toevoegen voor het bekijken van alle gegevens

  5. De mogelijkheid ondersteunen om de e-mail opnieuw te verzenden

In de tussentijd hoop ik dat dit project interessant en nuttig voor je is geweest; veel plezier met versturen.

Dus in een paar redelijk eenvoudige stappen konden we door de eerste fase van het bouwen van een robuust e-mailarchiveringssysteem lopen dat de e-mailduplicaat in S3 bewaart en gegevens kruislings controleert in een MySQL-tabel.  Dit geeft ons een basis voor de rest van het project dat in verschillende toekomstige posts zal worden aangepakt.

In toekomstige revisies van dit project zou ik verwachten:

  1. Alle loggebeurtenissen van de originele e-mail opslaan

  2. Opslagfouten naar een beheerder sturen wanneer een upload- of logfout optreedt

  3. De verzamelcomplexiteit minimaliseren.

  4. Een UI toevoegen voor het bekijken van alle gegevens

  5. De mogelijkheid ondersteunen om de e-mail opnieuw te verzenden

In de tussentijd hoop ik dat dit project interessant en nuttig voor je is geweest; veel plezier met versturen.

Dus in een paar redelijk eenvoudige stappen konden we door de eerste fase van het bouwen van een robuust e-mailarchiveringssysteem lopen dat de e-mailduplicaat in S3 bewaart en gegevens kruislings controleert in een MySQL-tabel.  Dit geeft ons een basis voor de rest van het project dat in verschillende toekomstige posts zal worden aangepakt.

In toekomstige revisies van dit project zou ik verwachten:

  1. Alle loggebeurtenissen van de originele e-mail opslaan

  2. Opslagfouten naar een beheerder sturen wanneer een upload- of logfout optreedt

  3. De verzamelcomplexiteit minimaliseren.

  4. Een UI toevoegen voor het bekijken van alle gegevens

  5. De mogelijkheid ondersteunen om de e-mail opnieuw te verzenden

In de tussentijd hoop ik dat dit project interessant en nuttig voor je is geweest; veel plezier met versturen.

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.