Reach

Grow

Manage

Automate

Reach

Grow

Manage

Automate

Membangun Sistem Pengarsipan Email: Menyimpan Isi Email

Burung

4 Mar 2019

Email

1 min read

Membangun Sistem Pengarsipan Email: Menyimpan Isi Email

Burung

4 Mar 2019

Email

1 min read

Membangun Sistem Pengarsipan Email: Menyimpan Isi Email

Dalam blog ini, saya akan menjelaskan proses yang saya lalui untuk menyimpan isi email ke dalam S3 (Layanan Penyimpanan Sederhana Amazon) dan data tambahan ke dalam tabel MySQL untuk memudahkan referensi silang.

Dalam blog ini, saya akan menjelaskan proses yang saya lalui untuk menyimpan isi email ke S3 (Amazon’s Simple Store Service) dan data tambahan ke dalam tabel MySQL untuk referensi silang yang mudah. Akhirnya, ini adalah titik awal untuk basis kode yang akan mencakup aplikasi yang akan memungkinkan pencarian email yang diarsipkan dengan mudah, dan kemudian menampilkan email tersebut bersama dengan data acara (log). Kode untuk proyek ini dapat ditemukan di repositori GitHub berikut: https://github.com/jeff-goldstein/PHPArchivePlatform.




Meski saya akan memanfaatkan S3 dan MySQL dalam proyek ini, bukan berarti itu adalah satu-satunya teknologi yang dapat digunakan untuk membangun platform pengarsipan, tetapi mengingat ketersebarannya, saya pikir itu adalah pilihan yang baik untuk proyek ini. Dalam sistem skala penuh dengan volume tinggi, saya akan menggunakan basis data dengan kinerja lebih tinggi daripada MySQL, tetapi untuk proyek contoh ini, MySQL sangat cocok.




Saya telah merinci di bawah ini, langkah-langkah yang saya lakukan dalam tahap pertama dari proyek ini:

  1. Membuat duplikat email untuk pengarsipan

  2. Menggunakan fitur Archiving dan Inbound Relay dari SparkPost untuk mengirim salinan email asli kembali ke SparkPost untuk diproses ke dalam struktur JSON, kemudian dikirim ke pengumpul webhook (aplikasi)

  3. Memisahkan struktur JSON untuk mendapatkan komponen yang diperlukan

  4. Mengirim isi email ke S3 untuk penyimpanan

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

Membuat Duplikat dari Email

Dalam SparkPost cara terbaik untuk mengarsipkan email adalah dengan membuat salinan identik dari email yang dirancang khusus untuk tujuan pengarsipan. Ini dilakukan dengan menggunakan fitur Arsip SparkPost. Fitur Arsip SparkPost memberi pengirim kemampuan untuk mengirim duplikat email ke satu atau lebih alamat email.  Duplikat ini menggunakan pelacakan dan tautan terbuka yang sama seperti aslinya. Dokumentasi SparkPost mendefinisikan fitur Arsip dengan cara berikut:

Penerima dalam daftar arsip akan menerima replika pesan yang dikirim ke alamat RCPT TO. Secara khusus, tautan terkode yang ditujukan untuk penerima RCPT TO akan identik dalam pesan arsip.

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

Jika Anda menginginkan penjelasan lebih mendalam, berikut adalah tautan ke dokumentasi SparkPost tentang membuat salinan duplikat (atau arsip) dari email. Contoh header X-MSYS-API untuk proyek ini ditampilkan kemudian dalam blog ini.

Ada satu pengecualian untuk pendekatan ini; sementara semua informasi acara dalam email asli diikat bersama oleh transmission_id dan message_id, tidak ada informasi dalam acara relay masuk (mekanisme untuk memperoleh dan menyebarkan email arsip) untuk email duplikat yang menghubungkan kembali ke salah satu dari dua id tersebut dan dengan demikian informasi untuk email asli. Ini berarti kita perlu menempatkan data dalam badan email dan header email asli sebagai cara untuk menghubungkan semua data SparkPost dari email asli dan arsip.

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

  1. Di suatu tempat dalam badan email, saya menempatkan entri input berikut:<input name="ArchiveCode" type="hidden" value="<<UID>>">

  2. Kemudian saya membuat kode unik dan mengganti bidang <<UID>>:$uid = md5(uniqid(rand(), true)); $emailBody = str_replace(“<<UID>>,$uid,$emailBody);

    Berikut adalah contoh output:

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

  3. Selanjutnya, saya memastikan menambahkan $UID ke blok meta_data pada header X-MSYS-API. Langkah ini memastikan bahwa UID tertanam dalam setiap output acara 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 mengaitkan semua data dari email asli ke badan email dari arsip.

Mendapatkan versi Archive

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

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

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

  3. Buat domain inbound di SparkPost

  4. Buat webhook inbound di SparkPost

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

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

  1. Dokumen teknis SparkPost: Enabling Inbound Email Relaying & Relay Webhooks

  2. Juga, blog yang saya tulis tahun lalu, Archiving Emails: A How-To Guide for Tracking Sent Mail akan membimbing Anda melalui pembuatan inbound relay di dalam SparkPost

* Catatan: mulai Oktober 2018, fitur Arsip hanya berfungsi saat mengirim email menggunakan koneksi SMTP ke SparkPost, API RESTful tidak mendukung fitur ini.  Hal ini mungkin bukan masalah karena sebagian besar email yang memerlukan kontrol audit tingkat ini cenderung merupakan email yang dipersonalisasi dan sepenuhnya dibuat oleh aplikasi backend sebelum pengiriman email diperlukan.

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

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

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

  3. Buat domain inbound di SparkPost

  4. Buat webhook inbound di SparkPost

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

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

  1. Dokumen teknis SparkPost: Enabling Inbound Email Relaying & Relay Webhooks

  2. Juga, blog yang saya tulis tahun lalu, Archiving Emails: A How-To Guide for Tracking Sent Mail akan membimbing Anda melalui pembuatan inbound relay di dalam SparkPost

* Catatan: mulai Oktober 2018, fitur Arsip hanya berfungsi saat mengirim email menggunakan koneksi SMTP ke SparkPost, API RESTful tidak mendukung fitur ini.  Hal ini mungkin bukan masalah karena sebagian besar email yang memerlukan kontrol audit tingkat ini cenderung merupakan email yang dipersonalisasi dan sepenuhnya dibuat oleh aplikasi backend sebelum pengiriman email diperlukan.

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

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

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

  3. Buat domain inbound di SparkPost

  4. Buat webhook inbound di SparkPost

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

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

  1. Dokumen teknis SparkPost: Enabling Inbound Email Relaying & Relay Webhooks

  2. Juga, blog yang saya tulis tahun lalu, Archiving Emails: A How-To Guide for Tracking Sent Mail akan membimbing Anda melalui pembuatan inbound relay di dalam SparkPost

* Catatan: mulai Oktober 2018, fitur Arsip hanya berfungsi saat mengirim email menggunakan koneksi SMTP ke SparkPost, API RESTful tidak mendukung fitur ini.  Hal ini mungkin bukan masalah karena sebagian besar email yang memerlukan kontrol audit tingkat ini cenderung merupakan email yang dipersonalisasi dan sepenuhnya dibuat oleh aplikasi backend sebelum pengiriman email diperlukan.

Mendapatkan email duplikat dalam struktur JSON

Pada fase pertama proyek ini, semua yang saya simpan adalah format email rfc822 di S3 dan beberapa bidang deskripsi tingkat tinggi ke dalam tabel SQL untuk pencarian.  Karena SparkPost akan mengirim data email dalam struktur JSON ke platform pengarsipan saya melalui streaming data webhook, saya membangun aplikasi (yang sering disebut sebagai collector) yang menerima data stream Relay_Webhook.

Setiap paket dari SparkPost Relay_Webhook akan berisi informasi dari satu email duplikat sekaligus, sehingga memecah struktur JSON menjadi komponen yang ditargetkan untuk proyek ini cukup sederhana.  Dalam kode PHP saya, mendapatkan email berformat rfc822 semudah beberapa baris kode berikut:

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'];}

Beberapa informasi yang ingin saya simpan ke dalam tabel SQL saya terdapat dalam array bidang header.  Jadi saya menulis fungsi kecil yang menerima array header dan mengulang melalui array untuk mendapatkan data yang ingin saya simpan:

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 data tersebut, saya siap untuk menyimpan badan ke dalam S3.

Menyimpan email duplikat di S3

Saya minta maaf mengecewakan Anda, tetapi saya tidak akan memberikan tutorial langkah demi langkah tentang cara membuat S3 bucket untuk menyimpan email, dan saya juga tidak akan menjelaskan cara membuat kunci akses yang diperlukan dalam aplikasi Anda untuk mengunggah konten ke bucket Anda; ada tutorial yang lebih baik tentang subjek ini daripada yang pernah saya tulis.  Berikut beberapa artikel yang mungkin bisa membantu:

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

Apa yang akan saya lakukan adalah menunjukkan beberapa pengaturan yang saya pilih yang berkaitan dengan proyek seperti ini.

  1. Kontrol Akses.  Anda tidak hanya perlu mengatur keamanan untuk bucket, tetapi Anda juga harus mengatur izin untuk item-item itu sendiri.  Dalam proyek saya, saya menggunakan kebijakan sangat terbuka berupa public-read karena data sampel tidak bersifat pribadi dan saya menginginkan akses mudah ke data tersebut.  Anda mungkin menginginkan serangkaian kebijakan ACL yang jauh lebih ketat. Berikut adalah artikel bagus tentang pengaturan ACL: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html

  2. Mengarsipkan Arsip. Dalam S3 ada sesuatu yang disebut Lifecycle Management.  Ini memungkinkan Anda memindahkan data dari satu jenis kelas penyimpanan S3 ke yang lain.  Kelas penyimpanan yang berbeda mewakili jumlah akses yang Anda butuhkan ke data yang disimpan dengan biaya lebih rendah terkait dengan penyimpanan yang Anda akses paling sedikit. Penjelasan baik tentang berbagai kelas dan peralihannya dapat ditemukan dalam panduan AWS yang disebut, Transitioning Objects. Dalam kasus saya, saya memilih untuk membuat siklus hidup yang memindahkan setiap objek dari Standard ke Glacier setelah satu tahun. Akses Glacier jauh lebih murah daripada arsip S3 standar dan akan menghemat biaya penyimpanan saya.

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

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

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

* kami berasumsi bahwa $inputField memiliki nilai “ArchiveCode” dan ditemukan dalam file config.php saya.

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

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

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

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

Menyimpan Meta Data di MySQL

Kami telah mengambil semua data yang diperlukan pada langkah sebelumnya, jadi langkah penyimpanannya mudah.  Pada fase pertama ini, saya memilih untuk membuat tabel dengan bidang-bidang berikut:

  • Entri field otomatis untuk tanggal/waktu

  • Alamat email target (RCPT_TO)

  • Stempel waktu dari header email DATE

  • Header SUBJECT

  • 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 menjalani langkah-langkah yang diperlukan untuk membuka tautan ke MySQL, menyuntikkan baris baru, menguji hasil dan menutup tautan. Saya memang menambahkan satu langkah lain untuk memastikan dan itu adalah untuk mencatat data ini ke dalam file teks. Haruskah saya melakukan lebih banyak pencatatan untuk kesalahan? Ya. Namun, saya ingin menjaga kode ini tetap ringan agar dapat berjalan dengan sangat cepat. Terkadang, kode ini akan dipanggil ratusan kali per menit dan perlu seefisien mungkin. Pada pembaruan mendatang, saya akan menambahkan kode tambahan yang akan memproses kegagalan dan mengirim email kegagalan tersebut kepada admin untuk pemantauan.

Menyelesaikannya

Jadi dalam beberapa langkah yang cukup mudah, kami dapat melalui fase pertama membangun sistem pengarsipan email yang kuat yang menyimpan duplikat email di S3 dan data cross-referencing dalam tabel MySQL.  Ini akan memberikan dasar untuk proyek lainnya yang akan ditangani dalam beberapa postingan mendatang.

Dalam revisi proyek di masa depan, saya berharap untuk:

  1. Menyimpan semua log acara dari email asli

  2. Mengirim kesalahan penyimpanan ke admin ketika terjadi kegagalan pengunggahan atau log

  3. Meminimalkan kompleksitas kolektor.

  4. Menambahkan antarmuka pengguna untuk melihat semua data

  5. Mendukung kemampuan untuk mengirim ulang email

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

Mari hubungkan Anda dengan pakar Bird.
Lihat kekuatan penuh dari Bird dalam 30 menit.

Dengan mengirimkan, Anda setuju Bird dapat menghubungi Anda tentang produk dan layanan kami.

Anda dapat berhenti berlangganan kapan saja. Lihat Pernyataan Privasi Bird untuk detail tentang pemrosesan data.

Perusahaan

Newsletter

Tetap terinformasi dengan Bird melalui pembaruan mingguan ke kotak masuk Anda.

Mari hubungkan Anda dengan pakar Bird.
Lihat kekuatan penuh dari Bird dalam 30 menit.

Dengan mengirimkan, Anda setuju Bird dapat menghubungi Anda tentang produk dan layanan kami.

Anda dapat berhenti berlangganan kapan saja. Lihat Pernyataan Privasi Bird untuk detail tentang pemrosesan data.

Perusahaan

Newsletter

Tetap terinformasi dengan Bird melalui pembaruan mingguan ke kotak masuk Anda.

Mari hubungkan Anda dengan pakar Bird.
Lihat kekuatan penuh dari Bird dalam 30 menit.

Dengan mengirimkan, Anda setuju Bird dapat menghubungi Anda tentang produk dan layanan kami.

Anda dapat berhenti berlangganan kapan saja. Lihat Pernyataan Privasi Bird untuk detail tentang pemrosesan data.

R

Reach

G

Grow

M

Manage

A

Automate

Perusahaan

Newsletter

Tetap terinformasi dengan Bird melalui pembaruan mingguan ke kotak masuk Anda.