Bird (sebelumnya MessageBird) Blog | Membangun Sistem Pengarsipan Email: Menyimpan Badan Email

Membangun Sistem Pengarsipan Email: Menyimpan isi email

Membangun Sistem Pengarsipan Email: Menyimpan isi email

Membangun Sistem Pengarsipan Email: Menyimpan isi email

Mar 4, 2019

Diterbitkan oleh

Diterbitkan oleh

Bird

Bird

Kategori:

Kategori:

Email

Email

Ready to see Bird
in action?

Ready to see Bird
in action?

Building an Email Archiving System: Storing the Email Body

In this blog, I will describe the process I went through to store the body of the email onto S3 (Amazon’s Simple Store Service) and ancillary data into a MySQL table for easy cross-referencing. Ultimately, this is the starting point for the code base that will include an application that will allow for easy searching of archived emails, and then displaying those emails along with the event (log) data. The code for this project can be found in the following GitHub repository: https://github.com/jeff-goldstein/PHPArchivePlatform.


Meskipun saya akan memanfaatkan S3 dan MySQL dalam proyek ini, bukan berarti keduanya merupakan satu-satunya teknologi yang dapat digunakan untuk membangun platform pengarsipan, tetapi mengingat keberadaannya yang sudah umum, saya pikir keduanya merupakan pilihan yang tepat untuk proyek ini. Dalam sistem volume tinggi berskala penuh, saya akan menggunakan database berkinerja lebih tinggi daripada MySQL, tetapi untuk proyek contoh ini, MySQL sangat cocok.


I have detailed below, the steps I took in this tahap pertama of the project:

  1. Membuat email duplikat untuk pengarsipan

  2. Gunakan fitur Pengarsipan dan Relai Masuk SparkPost untuk mengirim salinan email asli kembali ke SparkPost untuk diproses ke dalam struktur JSON, kemudian dikirim ke pengumpul webhook (aplikasi)

  3. Bongkar struktur JSON untuk mendapatkan komponen yang diperlukan

  4. Kirim isi email ke S3 untuk disimpan

  5. Mencatat entri ke dalam MySQL untuk setiap email untuk referensi silang


Membuat Duplikat Email

In SparkPost the best way to archive an email is to create an identical copy of the email specifically designed for archival purposes. This is done by using SparkPost’s Archive feature. SparkPost’s Archive feature gives the sender the ability to send a duplicate of the email to one or more email address.  This duplicate uses the same tracking and open links as the original. The SparkPost documentation defines the Archive feature in the following way:

Penerima dalam daftar arsip akan menerima replika yang sama persis dengan pesan yang dikirim ke alamat RCPT TO. Khususnya, setiap tautan yang disandikan yang ditujukan untuk penerima RCPT TO akan identik dalam pesan arsip

Satu-satunya perbedaan antara salinan arsip ini dan email RCPT TO asli adalah bahwa beberapa header akan berbeda karena alamat target untuk email pengarsipan berbeda, tetapi isi email akan menjadi replika yang sama persis!

If you want a deeper explanation, here is a link ke SparkPost documentation on creating duplicate (or archive) copies of an email. Sample X-MSYS-API headers for this project are shown later in this blog.

Ada satu peringatan untuk pendekatan ini; sementara semua informasi peristiwa di email asli diikat bersama oleh transmission_id dan message_id, tidak ada informasi dalam peristiwa relai masuk (mekanisme untuk mendapatkan dan menyebarkan email arsip) untuk email duplikat yang terkait dengan salah satu dari dua id tersebut dan dengan demikian informasi untuk email asli. Ini berarti kita perlu menempatkan data di badan email dan header email asli sebagai cara untuk menyatukan semua data SparkPost dari email asli dan email arsip.

Untuk membuat kode yang ditempatkan ke dalam badan email, saya menggunakan proses berikut dalam aplikasi pembuatan email.

  1. Somewhere in the email body, I placed the following input entry:<input name="ArchiveCode" type="hidden" value="<<UID>>">

  2. Then I created a unique code and replaced the <<UID>> field:$uid = md5(uniqid(rand(), true)); $emailBody = str_replace(“<<UID>>,$uid,$emailBody);

    Berikut ini adalah contoh output:

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

  3. Selanjutnya, saya memastikan bahwa saya menambahkan $UID ke blok meta_data pada header X-MSYS-API. Langkah ini memastikan bahwa UID disematkan ke dalam setiap keluaran peristiwa untuk email asli:

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>" } }

Sekarang kita memiliki cara untuk mengikat semua data dari email asli ke badan email arsip.


Mendapatkan versi Arsip

Untuk mendapatkan salinan email sebagai arsip, Anda perlu melakukan langkah-langkah berikut:

  1. Buat subdomain yang akan digunakan untuk mengirim semua email arsip (duplikat)

  2. Atur catatan DNS yang sesuai agar semua email dikirim ke subdomain tersebut ke SparkPost

  3. Membuat domain masuk di SparkPost

  4. Membuat webhook masuk di SparkPost

  5. Membuat aplikasi (pengumpul) untuk menerima aliran data webhook SparkPost

Dua tautan berikut ini dapat digunakan untuk membantu memandu Anda melalui proses ini:

  1. SparkPost technical doc: Enabling Inbound Email Relaying & Relay Webhooks

  2. Also, the blog I wrote last year, Mengarsipkan Email: Panduan Cara untuk Melacak Email Terkirim will walk you through the creation of the inbound relay within SparkPost

* Note: as of Oct 2018, the Archive feature only works when sending emails using an SMTP connection to SparkPost, the RESTful API does not support this feature.  That probably isn’t an issue because most emails that need this level of audit control tend to be personalized emails that are fully built out by a backend application before email delivery is needed.

Mendapatkan email duplikat dalam struktur JSON

In the first phase of this project, all I’m storing is the rfc822 email format in S3 and some high-level description fields into a SQL table for searching.  Since SparkPost will send the email data in a JSON structure to my archiving platform via webhook data streams, I built an application (often referred to as a kolektor) that accepts the Relay_Webhook data stream.

Each package from the SparkPost Relay_Webhook will contain the information of one duplicate email at a time, so breaking the JSON structure down into the targeted components for this project is rather straightforward.  In my PHP code, getting the rfc822 formatted email was as easy as the following few lines of code:

if ($verb == "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'];}

Some of the information that I want to store into my SQL table resides in an array of header fields.  So I wrote a small function that accepted the header array and looped through the array in order to obtain the data I was interested in storing:

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

Sekarang, setelah saya memiliki datanya, saya siap untuk menyimpan bodi ke dalam S3.


Menyimpan email duplikat di S3

I’m sorry to disappoint you but I’m not going to give a step by step tutorial on creating an S3 bucket for storing the email nor am I going to describe how to create the necessary access key you will need in your application for uploading content to your bucket; there are better tutorials on this subject than I could ever write.  Here a couple of articles that may help:

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

Yang akan saya lakukan adalah menunjukkan sebagian pengaturan yang saya pilih, yang berkaitan dengan proyek seperti ini.

  1. Kontrol Akses.  You not only need to set the security for the bucket, but you need to set the permissions for the items themselves.  In my project, I use a very open policy of public-read because the sample data is not personal and I wanted easy access ke data.  You will probably want a much stricter set of ACL policies. Here is a nice article on ACL settings:

https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html

  2. Mengarsipkan Arsip. In S3 there is something called Lifecycle Management.  This allows you to move data from one type of S3 storage class to another.  The different storage classes represent the amount of access you need to the stored data with lower costs associated with the storage you access the least. A good write up of the different classes and transitioning through them can be found in an AWS guide called, Transisi Objek. In my case, I chose to create a lifecycle that moved each object from Standard to Glacier after one year. Glacier access is much cheaper than the standard S3 archive and will save me money in storage costs.

Setelah bucket S3 dibuat dan pengaturan saya sudah siap, S3 siap untuk saya unggah email yang sesuai dengan rfc822 yang saya peroleh dari aliran data SparkPost Relay Webhook. Tetapi sebelum mengunggah muatan email rfc822 ke S3, saya perlu membuat nama file unik yang akan saya gunakan untuk menyimpan email tersebut.

Untuk nama file yang unik, saya akan mencari id tersembunyi di badan email yang diletakkan oleh aplikasi pengirim di dalam email dan menggunakan id tersebut sebagai nama file. Ada cara yang lebih elegan untuk menarik connectorId dari badan html, tetapi untuk kesederhanaan dan kejelasan saya akan menggunakan kode berikut ini:

       $start = strpos($htmlbody, $inputField);          $start = strpos($htmlbody, "value=", $start) + 7;        $end = strpos($htmlbody, ">", $start) - 1;        $length = $end - $start;        $UID = substr($html, $start, $length);

* kita mengasumsikan bahwa $inputField menyimpan nilai "ArchiveCode" dan ditemukan di file config.php saya.

Dengan UID, kita kemudian dapat membuat nama file yang akan digunakan di S3:

NamaFile = $DirektoriArsip . '/' . $UID . '.eml';

Sekarang saya dapat membuka koneksi saya ke S3 dan mengunggah berkas. Jika Anda melihat berkas s3.php di repositori GitHub, Anda akan melihat bahwa hanya diperlukan sedikit kode untuk mengunggah berkas.

Langkah terakhir saya adalah mencatat entri ini ke dalam tabel MYSQL.


Menyimpan Meta Data di MySQL

We grabbed all of the data necessary in a previous step, so the step of storage is easy.  In this first phase I chose to build a table with the following fields:

  • Entri bidang otomatis untuk tanggal/waktu

  • Alamat email target (RCPT_TO)

  • Cap waktu dari header TANGGAL email

  • Tajuk SUBJEK

  • Header alamat email FROM

  • Direktori yang digunakan dalam bucket S3

  • Nama file S3 untuk email yang diarsipkan

Fungsi bernama, MySQLLog dalam file aplikasi upload.php melakukan langkah-langkah yang diperlukan untuk membuka tautan ke MySQL, menginjeksikan baris baru, menguji hasilnya, dan menutup tautan. Saya menambahkan satu langkah lagi untuk mengukurnya dengan baik, yaitu mencatat data ini ke dalam file teks. Haruskah saya melakukan lebih banyak pencatatan untuk kesalahan? Ya. Tapi saya ingin menjaga kode ini tetap ringan agar dapat berjalan dengan sangat cepat. Terkadang kode ini akan dipanggil ratusan kali per menit dan perlu dibuat seefisien mungkin. Dalam pembaruan di masa mendatang, saya akan menambahkan kode tambahan yang akan memproses kegagalan dan mengirim email kegagalan tersebut ke admin untuk dipantau.

Menyimpulkannya

So in a few fairly easy steps, we were able to walk through the first phase of building a robust email archiving system that holds the email duplicate in S3 and cross-referencing data in a MySQL table.  This will give us a foundation for the rest of the project that will be tackled in several future posts.

Dalam revisi proyek ini di masa mendatang, saya berharap untuk melakukannya:

  1. Menyimpan semua peristiwa log dari email asli

  2. Mengirimkan kesalahan penyimpanan ke admin ketika terjadi kegagalan dalam mengunggah atau mencatat

  3. Meminimalkan kerumitan kolektor.

  4. Menambahkan UI untuk melihat semua data

  5. Mendukung kemampuan untuk mengirim ulang email

Sementara itu, saya harap proyek ini menarik dan bermanfaat bagi Anda; selamat mengirim.

Your new standard in Marketing, Pay & Sales. It's Bird

The right message -> to the right person -> di right time.

By clicking "See Bird" you agree to Bird's Pemberitahuan Privasi.

Your new standard in Marketing, Pay & Sales. It's Bird

The right message -> to the right person -> di right time.

By clicking "See Bird" you agree to Bird's Pemberitahuan Privasi.