
In deze blog zal ik het proces beschrijven dat ik heb doorlopen om de inhoud van de e-mail op te slaan op S3 (Amazon's Simple Storage Service) en bijkomende gegevens in een MySQL-tabel voor eenvoudige 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:
Het creëren van de dubbele e-mail voor archivering
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)
Demonteer de JSON-structuur om de nodige componenten te verkrijgen
Verstuur de inhoud van de e-mail naar S3 voor opslag
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, een identieke kopie van de e-mail te maken die specifiek ontworpen is voor archiveringsdoeleinden. Dit wordt gedaan door gebruik te maken van SparkPost’s Archive functie. SparkPost’s Archive functie geeft de afzender de mogelijkheid een duplicaat van de e-mail naar één of meer e-mailadressen te sturen. Dit duplicaat gebruikt dezelfde tracking- en open-links als het origineel. De SparkPost documentatie 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 die bedoeld zijn voor de RCPT TO ontvanger identiek zijn in de archiefberichten
Het enige verschil tussen deze archiefkopie en de oorspronkelijke RCPT TO e-mail is dat sommige headers anders zullen zijn, aangezien het doeladres voor de archivering e-mail verschillend is, maar de body 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. Voorbeeld X-MSYS-API headers voor dit project worden later in deze blog getoond.
Er is één kanttekening bij deze benadering; terwijl alle informatie over het evenement in de oorspronkelijke e-mail aan elkaar wordt gekoppeld door zowel een transmission_id als een message_id, is er geen informatie in het inbound relay evenement (het mechanisme voor het verkrijgen en verspreiden van de archiefe-mail) voor de duplicaat e-mail die terugverwijst naar een van die twee id’s en dus de informatie van de oorspronkelijke e-mail. Dit betekent dat we gegevens in de e-mail body en de header van de oorspronkelijke e-mail moeten plaatsen als een manier om alle SparkPost gegevens van de oorspronkelijke en archiefe-mail samen te brengen.
Om de code te maken die in de e-mail body wordt geplaatst, gebruikte ik het volgende proces in de e-mail creatie applicatie.
Ergens in de e-mail body plaatste ik de volgende invoer:<input name="ArchiveCode" type="hidden" value="<<UID>>">
Vervolgens maakte 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">
Vervolgens zorgde ik ervoor dat ik de $UID toevoegde aan het meta_data blok van de X-MSYS-API header. Deze stap zorgt ervoor dat de UID is ingebed in elke evenementoutput voor de oorspronkelijke e-mail:
Nu hebben we een manier om alle gegevens van de oorspronkelijke e-mail aan de e-mail body van het archief te koppelen.
Verkrijgen van de Archive-versie
Het verkrijgen van het dubbele e-mailadres in een JSON-structuur
In de eerste fase van dit project sla ik alleen het rfc822 e-mailformaat op in S3 en enkele beschrijvingsvelden op hoog niveau in een SQL-tabel voor zoekdoeleinden. Aangezien SparkPost de e-mailgegevens in een JSON-structuur naar mijn archiveringsplatform zal sturen via webhook-datastromen, heb ik een applicatie gebouwd (vaak aangeduid als een collector) die de Relay_Webhook datastroom accepteert.
Elk pakket van de SparkPost Relay_Webhook bevat de informatie van één dubbele e-mail tegelijk, dus het opsplitsen van de JSON-structuur in de gerichte componenten 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:
Enkele van de informatie die ik in mijn SQL-tabel wil opslaan bevindt zich in een reeks van headervelden. Dus schreef ik een kleine functie die de header-array accepteerde en door de array heen liep om de gegevens te verkrijgen die ik wilde opslaan:
Nu ik de gegevens heb, ben ik klaar om het lichaam in S3 op te slaan.
De duplicaat e-mail opslaan in S3
Het spijt me u teleur te stellen, maar ik ga geen stapsgewijze handleiding geven voor het maken van een S3-bucket voor het opslaan van de e-mail, noch ga ik beschrijven hoe u de benodigde toegangssleutel kunt aanmaken die u nodig hebt in uw toepassing 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 wellicht nuttig zijn:
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 aangeven die ik heb gekozen die betrekking hebben op een project zoals dit.
Toegangscontrole. U moet niet alleen de beveiliging voor de bucket instellen, maar ook de machtigingen voor de items zelf instellen. In mijn project gebruik ik een heel open beleid van public-read omdat de voorbeeldgegevens niet persoonlijk zijn en ik gemakkelijke toegang tot de gegevens wilde. U zult waarschijnlijk een veel strikter pakket ACL-beleid willen. Hier is een goed artikel over ACL-instellingen: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html
Archivering van het archief. In S3 is er iets dat Lifecycle Management wordt genoemd. Dit stelt u in staat gegevens van het ene type S3-opslagklasse naar het andere te verplaatsen. De verschillende opslagklassen vertegenwoordigen de mate van toegang die u nodig heeft tot de opgeslagen gegevens, waarbij lagere kosten zijn verbonden aan de opslag die u het minst benadert. Een goed overzicht van de verschillende klassen en het doorlopen ervan is te vinden in een AWS-gids genaamd, Transitioning Objects. In mijn geval koos ik ervoor om een levenscyclus te creëren die elk object na een jaar van Standard naar Glacier verplaatst. Glacier-toegang is veel goedkoper dan de standaard S3-archief en bespaart mij geld op opslagkosten.
Wanneer ik de S3-bucket heb aangemaakt en mijn instellingen op hun plaats zijn, is S3 klaar voor mij om de rfc822-compliant e-mail te uploaden die ik heb verkregen vanuit de SparkPost Relay Webhook datastroom. Maar voordat ik de rfc822-email payload naar S3 upload, moet ik een unieke bestandsnaam creëren die ik zal gebruiken om die e-mail op te slaan.
Voor de unieke bestandsnaam ga ik in de e-mailbody zoeken naar de verborgen id die de verzendende applicatie in de e-mail heeft geplaatst en die id gebruiken als 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:
* we gaan ervan uit dat $inputField de waarde “ArchiveCode” bevat en in mijn config.php-bestand is gevonden.
Met de UID kunnen we dan de bestandsnaam maken die in S3 zal worden gebruikt:
$fileName = $ArchiveDirectory . '/' . $UID . '.eml';
Nu kan ik mijn verbinding met S3 openen en het bestand uploaden. Als u kijkt naar het s3.php-bestand in de GitHub repository, zult u zien dat er heel weinig code nodig is om het bestand te uploaden.
Mijn laatste stap is om deze invoer in de MYSQL-tabel te loggen.
Opslaan van de Meta Data in MySQL
We hebben alle noodzakelijke gegevens in een eerdere stap verzameld, dus de stap van opslag is eenvoudig. In deze eerste fase koos ik ervoor om een tabel te bouwen met de volgende velden:
Een automatisch invulveld voor datum/tijd
Het doel e-mailadres (RCPT_TO)
Het tijdstempel uit de e-mail DATE-header
De SUBJECT-header
De FROM e-mailadresheader
De directory die wordt gebruikt in de S3-bucket
De S3-bestandsnaam voor de gearchiveerde e-mail
De functie genaamd MySQLLog binnen het bestand upload.php van de toepassing 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 nog een andere stap toe voor de zekerheid en dat is om deze gegevens in een tekstbestand te loggen. Moet ik veel meer loggen voor fouten? Ja. Maar ik wil deze code licht houden om toe te staan 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 extra code toevoegen die mislukkingen verwerkt en die mislukkingen per e-mail naar een beheerder stuurt voor monitoring.
Afronding
Dus in een paar redelijk eenvoudige stappen konden we de eerste fase doorlopen van het bouwen van een robuust e-mailarchiveringssysteem dat het e-mailduplicaat opslaat in S3 en gegevens kruislings verwijst 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 herzieningen van dit project verwacht ik:
Alle logboekgebeurtenissen van de originele e-mail op te slaan
Opslagfouten naar een beheerder te sturen wanneer een upload- of logboekfout optreedt
De complexiteit van de verzamelaar te minimaliseren.
Een gebruikersinterface toe te voegen voor het bekijken van alle gegevens
De mogelijkheid te ondersteunen om de e-mail opnieuw te verzenden
In de tussentijd hoop ik dat dit project interessant en nuttig voor u is geweest; veel plezier met verzenden.