Budowanie systemu archiwizacji e-maili: wyzwania i oczywiście rozwiązanie – Część 1

Jeff Goldstein

4 lut 2019

Email

1 min read

Budowanie systemu archiwizacji e-maili: wyzwania i oczywiście rozwiązanie – Część 1

Kluczowe Wnioski

    • Archiwizowanie e-maili jest coraz bardziej konieczne w środowiskach regulacyjnych, zgodności i audytowych.

    • SparkPost nie przechowuje treści e-maili, ale jego funkcja Archiwum pozwala nadawcom otrzymywać duplikaty wiadomości, które odwzorowują linki śledzące i treść.

    • Treści e-maili mogą być przechowywane w Amazon S3, podczas gdy metadane zdarzeń wiadomości można przechowywać w MySQL do zapytań i tworzenia odniesień krzyżowych.

    • Zdarzenia wiadomości w SparkPost dostarczają bogatych dzienników aktywności (odbiory, dostawy, kliknięcia, otwarcia, wypisy, skargi i więcej).

    • Kopie archiwalne są generowane tylko przy wysyłaniu e-maili przez SMTP.

    • Zdarzenia wiadomości dla oryginalnych, archiwalnych, CC i BCC e-maili dzielą wspólny transmission_id.

    • Inbound Email Relay może przetwarzać zarchiwizowane wiadomości, ale nie zawiera transmission_id, co tworzy wyzwanie związane z łączeniem danych.

    • Umieszczenie ukrytego unikalnego identyfikatora (UID) w treści wiadomości wypełnia tę lukę i wiąże zawartość przychodzącą z dziennikami wychodzącymi.

    • Łączenie archiwalnych e-maili + zdarzeń wiadomości umożliwia budowanie przeszukiwalnego, audytowalnego systemu archiwizacji.

    • Długoterminowy projekt obejmuje wydania kodu do przechowywania archiwalnych e-maili w S3 i rejestrowania danych zdarzeń w MySQL.

    • Końcowa aplikacja pozwoli na łatwe wyszukiwanie, przeglądanie i uzgadnianie treści e-maili z całą związaną historią zdarzeń.

    • Idealne dla branż o rygorystycznych wymogach zgodności, które potrzebują pełnej widoczności każdej wysłanej wiadomości.

Q&A Highlights

  • Dlaczego budować własny system archiwizacji email?

    Regulowane branże często wymagają długoterminowego przechowywania zarówno treści e-maila, jak i wszystkich powiązanych dzienników zdarzeń. SparkPost nie przechowuje treści wiadomości, więc stworzenie niestandardowego systemu zapewnia zgodność, audyt i widoczność.

  • Jak uzyskać dokładną kopię oryginalnej wysłanej wiadomości email?

    Funkcja Archive SparkPost wysyła kopię każdego wysłanego e-maila na wyznaczone adresy archiwalne, zachowując wszystkie zakodowane linki i śledzenie zachowań.

  • Dlaczego nie można uchwycić treści e-maila przed wysłaniem?

    Pre-send capture nie obejmuje modyfikacji SparkPost (śledzenie otwarć, śledzenie kliknięć, kodowanie linków). Używanie kopii Archive gwarantuje, że zapisana wersja dokładnie odpowiada temu, co otrzymują odbiorcy.

  • Czy SparkPost archiwizuje e-maile automatycznie?

    Nie. SparkPost nie przechowuje treści wiadomości. Kopie archiwalne muszą być żądane przez określenie adresów archiwizacyjnych podczas wstrzykiwania SMTP.

  • Co jest przechowywane gdzie w tym systemie archiwizacji?

    • Treść e-maila → Amazon S3

    • Logi zdarzeń wiadomości → MySQL
      To rozdzielenie wspiera szybkie wyszukiwanie, zapytania strukturalne i niedrogie przechowywanie obiektów.

  • Jak długo SparkPost przechowuje dane zdarzeń?

    SparkPost przechowuje zdarzenia wiadomości przez 10 dni. Po tym okresie, dane muszą być pobierane za pomocą webhooka lub zapytania i przechowywane w innym miejscu.

  • Jakie zdarzenia wiadomości są dostępne?

    SparkPost obecnie udostępnia 14 zdarzeń, w tym dostawy, odbicia, kliknięcia, otwarcia, odrzucenia, kwestie polityki, skargi dotyczące spamu, wypisania się i więcej.

  • Jakie identyfikatory łączą wszystkie wydarzenia?

    Wszystkie wiadomości wychodzące (oryginał, archiwum, CC, BCC) dzielą ten sam transmission_id. Oryginał i e-mail z archiwum również dzielą ten sam message_id.

  • Dlaczego przetwarzanie inbound jest wyzwaniem?

    SparkPost’s Inbound Email Relay zamienia pocztę przychodzącą na JSON, ale ten JSON nie zawiera transmission_id. Bez dodatkowych danych, kopia przychodząca nie może być powiązana z historią logów wychodzących.

  • Jak połączyć przychodzące zarchiwizowane e-maile z wychodzącymi zdarzeniami wiadomości?

    Osadź ukryty unique identifier (UID) w treści e-maila i przekaż ten sam UID w metadanych. Ten UID staje się wspólnym odniesieniem w przychodzących i wychodzących rekordach.

  • Jak Inbound Email Relay pomaga w automatyzacji archiwizacji?

    Otrzymuje zarchiwizowane e-maile wysłane do twojej domeny archiwalnej, przetwarza je na strukturalne JSON i przesyła do twojej aplikacji za pomocą webhooka—umożliwiając automatyczne wydobywanie i przechowywanie.

  • Jaka jest długoterminowa wizja projektu?

    Kompletna aplikacja, która:

    • Przechowuje archiwalne e-maile w S3

    • Przechowuje wszystkie dzienniki zdarzeń w MySQL

    • Pozwala użytkownikom wyszukiwać e-maile

    • Wyświetla oryginalny e-mail i każde powiązane zdarzenie w jednym, zintegrowanym interfejsie

Około rok temu napisałem blog o tym, jak pobrać kopie e-maili do archiwizacji i przeglądania, ale nie poruszyłem kwestii rzeczywistego przechowywania e-maila ani powiązanych danych, a ostatnio napisałem blog o przechowywaniu wszystkich danych zdarzeń (tj. kiedy wysyłana jest wiadomość e-mail, otwarcia, kliknięcia, odbicia, rezygnacje z subskrypcji itp.) w celu audytu, ale postanowiłem nie tworzyć żadnego wspierającego kodu.

Z rosnącym wykorzystaniem e-maili w środowiskach regulowanych zdecydowałem, że nadszedł czas, aby rozpocząć nowy projekt, który połączy to wszystko z przykładami kodu, jak przechowywać treść wiadomości e-mail oraz wszystkie powiązane dane. W ciągu kolejnego roku będę kontynuował rozwijanie tego projektu, dążąc do stworzenia działającej aplikacji do przechowywania i przeglądania archiwizowanych wiadomości e-mail i wszystkich informacji o logach produkowanych przez SparkPost. SparkPost nie posiada systemu, który by archiwizował treść wiadomości e-mail, ale czyni budowanie platformy archiwizacyjnej dość łatwym.

W tej serii blogów opiszę proces, przez który przeszedłem, aby zapisać treść wiadomości e-mail na S3 (Amazon’s Simple Store Service) oraz wszystkie istotne dane logów w MySQL dla łatwego odniesienia. Dla systemów archiwizacyjnych, które wymagają solidnych strategii tworzenia kopii zapasowych baz danych, rozważ wdrożenie kompleksowego procesu tworzenia kopii zapasowej i odtwarzania PostgreSQL, aby upewnić się, że twoje dane archiwalne są odpowiednio chronione. W końcu jest to punkt początkowy do budowy aplikacji, która umożliwi łatwe przeszukiwanie archiwizowanych wiadomości e-mail, a następnie wyświetlanie tych wiadomości wraz z danymi zdarzeń (logów). Kod dla tego projektu można znaleźć w następującym repozytorium GitHub: PHPArchivePlatform na GitHub

Ten pierwszy wpis serii blogów opisze wyzwanie i zaproponuje architekturę rozwiązania. Reszta blogów szczegółowo opisze części rozwiązania wraz z przykładami kodu.

Pierwszym krokiem w moim procesie było ustalenie, jak uzyskać kopię wiadomości e-mail wysłanej do oryginalnego odbiorcy. Aby uzyskać kopi, musisz:

  1. Przechwytywać treść wiadomości e-mail przed jej wysłaniem

  2. Spowodować, aby serwer e-mail zapisał kopię

  3. Uzyskać, aby serwer e-mail stworzył kopię dla Ciebie do zapisu

Jeśli serwer e-mail dodaje elementy takie jak śledzenie linków czy śledzenie otwarć, nie możesz użyć #1, ponieważ nie odzwierciedli to zmian w śledzeniu otwarć/kliknięć.

To oznacza, że albo serwer musi zapisać wiadomość, albo w jakiś sposób zaoferować jej kopię dla Ciebie do zapisania. Ponieważ SparkPost nie posiada mechanizmu przechowywania treści wiadomości, ale posiada możliwość tworzenia kopii wiadomości, poprosimy SparkPost o wysłanie nam duplikatu wiadomości, abyśmy mogli zapisać go w S3.

To jest realizowane poprzez użycie funkcji Archive SparkPost. Funkcja Archive SparkPost daje nadawcy możliwość poinstruowania SparkPost, aby wysłał duplikat wiadomości na jeden lub więcej adresów e-mail i używa tych samych linków do śledzenia i otwierania co oryginał. Dokumentacja SparkPost definiuje funkcję Archive w następujący sposób:

Odbiorcy na liście archiwalnej otrzymają dokładną replikę wiadomości, która została wysłana na adres RCPT TO. W szczególności wszelkie zakodowane linki przeznaczone dla odbiorcy RCPT TO będą identyczne w wiadomościach archiwalnych

Jedynymi różnicami od wiadomości do RCPT TO są pewne różnice w nagłówkach, ponieważ docelowy adres e-mail dla archiwizacji jest inny, ale treść wiadomości będzie dokładną repliką!

Jeśli chcesz głębszego wyjaśnienia, oto link do dokumentacji SparkPost dotyczącej tworzenia duplikatów (lub kopii archiwalnych) wiadomości e-mail.

Jako uwaga dodatkowa, SparkPost faktycznie pozwala na wysyłanie wiadomości e-mail do adresów cc, bcc i archiwalnych. Dla tego rozwiązania skupiamy się na adresach archiwalnych.

* Uwaga * Archiwalne e-maile mogą być utworzone TYLKO podczas wprowadzania e-maili do SparkPost przez SMTP!

Teraz, gdy wiemy, jak uzyskać kopię oryginalnej wiadomości e-mail, musimy przyjrzeć się danym logów, które są produkowane i niektórym subtelnym niuansom w tych danych. SparkPost śledzi wszystko, co dzieje się na jego serwerach i oferuje te informacje w formie zdarzeń wiadomości. Te zdarzenia są przechowywane w SparkPost przez 10 dni i można je pobrać z serwera za pośrednictwem API RESTful o nazwie zdarzeń wiadomości, lub można poprosić SparkPost o przesyłanie tych zdarzeń do dowolnej liczby aplikacji zbierających, które chcesz. Mechanizm przesyłania jest realizowany za pośrednictwem webhooków i odbywa się w czasie rzeczywistym.

Obecnie istnieje 14 różnych zdarzeń, które mogą dotyczyć wiadomości e-mail.  Oto lista obecnych zdarzeń:

  • Bounce

  • ClickDelay

  • Delivery

  • Generation Failure

  • Generation Rejection

  • Initial Open

  • InjectionLink Unsubscribe

  • List Unsubscribe

  • Open

  • Out of Band

  • Policy RejectionSpam Complaint


* Przejdź do tego linku po aktualny przewodnik referencyjny z opisem każdego zdarzenia wraz z danymi, które są udostępniane dla każdego zdarzenia.

Każde zdarzenie ma liczne pola dopasowane do typu zdarzenia. Niektóre pola, jak transmission_id, znajdują się w każdym zdarzeniu, ale inne pola mogą być bardziej specyficzne dla zdarzenia; na przykład tylko zdarzenia otwarcia i kliknięcia mają informacje geotagowe.

Bardzo ważnym wpisem w zdarzeniu wiadomości dla tego projektu jest transmission_id. Wszystkie wpisy zdarzeń wiadomości dla oryginalnego e-maila, archiwalnego e-maila oraz wszelkich adresów cc i bcc będą miały wspólne transmission_id.

Jest także wspólny wpis o nazwie message_id, który będzie miał to samo id dla każdego wpisu oryginalnego e-maila i e-maila archiwalnego. Wszelkie adresy cc lub bcc będą miały własne id dla wpisu message_id.

Do tej pory wszystko brzmi dobrze, a nawet dość łatwo, ale teraz zaczyna się trudna część. Pamiętaj, aby uzyskać archiwalną wiadomość, prosimy SparkPost o wysłanie duplikatu oryginalnej wiadomości na inny adres e-mail, który odpowiada skrzynce odbiorczej, do której masz dostęp. Ale aby zautomatyzować to rozwiązanie i przechowywać treść wiadomości e-mail, użyję innej funkcji SparkPost o nazwie Inbound Email Relaying. Co to robi, to przechwytuje wszystkie e-maile wysłane na określoną domenę i przetwarza je. Podczas przetwarzania rozdziela wiadomość e-mail i tworzy strukturę JSON, która jest potem dostarczana do aplikacji za pomocą webhooka. Zobacz Dodatek A dla przykładowego JSON.

Jeśli przyjrzysz się uważnie, zauważysz, że struktura JSON z przekazu przychodzącego nie zawiera bardzo ważnego pola; transmission_id. Podczas gdy wszystkie wiadomości wychodzące mają transmission_id z tym samym wpisem, który łączy wszystkie dane z oryginalnej wiadomości e-mail, archiwum, adresów cc i bcc; SparkPost nie ma możliwości wiedzieć, że wiadomość e-mail przechwycona przez proces przychodzący jest powiązana z którąkolwiek z wiadomości wychodzących. Proces przychodzący po prostu wie, że wiadomość e-mail została wysłana na określoną domenę i ma ją przeanalizować. To wszystko. Potraktuje każdą wiadomość e-mail wysłaną na tę domenę jednakowo, niezależnie od tego, czy jest to odpowiedź od klienta, czy archiwalna wiadomość wysłana z SparkPost.

Więc sztuczką jest; jak powiązać dane wychodzące z procesem przychodzącym, który właśnie przechwycił archiwalną wersję wiadomości e-mail? Co postanowiłem zrobić, to ukryć unikalne id w treści wiadomości e-mail. Jak to zrobisz, zależy od Ciebie, ale po prostu stworzyłem pole wejściowe z włączoną tagiem ukrytym.

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

Dodałem ten także ten field do bloku metadanych nagłówka X-MSYS-API, który jest przekazywany do SparkPost podczas wprowadzania. Ten ukryty UID będzie klejem do całego procesu i jest głównym elementem projektu i zostanie omówiony szczegółowo w kolejnych wpisach na blogu.

Teraz, gdy mamy UID, który połączy ten projekt razem i rozumiemy, dlaczego jest to konieczne, mogę zacząć budować wizję całego projektu i odpowiadające wpisy na blogu.

  1. Przechwytywanie i przechowywanie archiwalnej wiadomości e-mail wraz z wpisem do bazy danych do wyszukiwania/indeksowania

  2. Przechwytywanie wszystkich danych zdarzeń wiadomości

  3. Tworzenie aplikacji do przeglądania wiadomości e-mail i wszystkich powiązanych danych

Oto prosty diagram projektu:

build an email archiving system - diagram


Pierwszy zrzut kodu będzie obejmować proces archiwizacji i przechowywanie wiadomości e-mail na S3, podczas gdy drugi zrzut kodu obejmie przechowywanie wszystkich danych logów z message-events do MySQL. Możesz oczekiwać pierwszych dwóch zrzutów kodu i wpisów na blogu na początku 2019 roku.  Jeśli masz jakieś pytania lub sugestie, proszę o przesłanie ich.

Szczęśliwego wysyłania.
– Jeff


Dodatek A:

JSON file example - email archiving system

Inne wiadomości

Czytaj więcej z tej kategorii

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

Kompletna, natywna dla AI platforma, która rośnie wraz z Twoim biznesem.

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

Kompletna, natywna dla AI platforma, która rośnie wraz z Twoim biznesem.