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. Pada akhirnya, ini adalah titik awal untuk basis kode yang akan menyertakan aplikasi yang memungkinkan pencarian email yang diarsipkan dengan mudah, dan kemudian menampilkan email tersebut bersama dengan data peristiwa (log). Kode untuk proyek ini dapat ditemukan di repositori GitHub berikut: https://github.com/jeff-goldstein/PHPArchivePlatform.

Walaupun saya akan memanfaatkan S3 dan MySQL dalam proyek ini, ini bukan satu-satunya teknologi yang dapat digunakan untuk membangun platform pengarsipan, namun mengingat urgensinya, saya pikir mereka adalah pilihan yang baik untuk proyek ini. Dalam sistem skala penuh dengan volume tinggi, saya akan menggunakan database berkinerja lebih tinggi daripada MySQL, tetapi untuk proyek sampel ini, MySQL sangat cocok. Untuk organisasi yang mempertimbangkan PostgreSQL sebagai pilihan database pengarsipan mereka, menerapkan prosedur pencadangan dan pemulihan yang tepat sangat penting untuk menjaga integritas data dalam sistem produksi.

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

  1. Membuat email duplikat untuk pengarsipan

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

  3. Membongkar struktur JSON untuk mendapatkan komponen yang diperlukan

  4. Mengirim isi email ke S3 untuk penyimpanan

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

Membuat Duplikat dari Email

Di SparkPost, cara terbaik untuk mengarsipkan email adalah dengan membuat salinan identik dari email yang dirancang khusus untuk keperluan pengarsipan. Ini dilakukan dengan menggunakan fitur Arsip SparkPost. Fitur Arsip SparkPost memberikan kemampuan kepada pengirim untuk mengirimkan duplikat email ke satu atau beberapa alamat email.  Duplikat ini menggunakan pelacakan dan tautan buka yang sama seperti aslinya. Dokumentasi SparkPost mendefinisikan fitur Arsip dengan cara berikut:

Penerima dalam daftar arsip akan menerima replika persis dari pesan yang dikirimkan ke alamat RCPT TO. Secara khusus, setiap tautan yang dikodekan 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 persis!

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

Ada satu peringatan untuk pendekatan ini; sementara semua informasi peristiwa dalam email asli dihubungkan bersama oleh transmission_id dan message_id, tidak ada informasi dalam peristiwa relay inbound (mekanisme untuk mendapatkan 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 di badan email dan header dari email asli sebagai cara untuk menghubungkan semua data SparkPost dari email asli dan arsip.

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

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

  2. Lalu saya membuat kode unik dan menggantikan kolom <<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 header X-MSYS-API. Langkah ini memastikan bahwa UID tertanam dalam setiap output 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 menghubungkan semua data dari email asli ke badan email arsip.

Mendapatkan versi Archive

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

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

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

  3. Buat domain masuk di SparkPost

  4. Buat webhook masuk di SparkPost

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

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

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

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

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

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

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

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

  3. Buat domain masuk di SparkPost

  4. Buat webhook masuk di SparkPost

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

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

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

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

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

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

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

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

  3. Buat domain masuk di SparkPost

  4. Buat webhook masuk di SparkPost

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

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

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

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

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

Mendapatkan email duplikat dalam struktur JSON

Dalam fase pertama proyek ini, yang saya simpan hanyalah 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 aliran data webhook, saya membangun sebuah aplikasi (sering disebut sebagai collector) yang menerima aliran data Relay_Webhook.

Setiap paket dari SparkPost Relay_Webhook akan berisi informasi dari satu email duplikat pada satu waktu, jadi memecah struktur JSON menjadi komponen target untuk proyek ini cukup mudah.  Dalam kode PHP saya, mendapatkan email berformat rfc822 semudah beberapa baris kode berikut ini:

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

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

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

Sekarang setelah saya memiliki datanya, saya siap menyimpan badan email ke dalam S3.

Menyimpan email duplikat di S3

Saya minta maaf mengecewakan Anda, tetapi saya tidak akan memberikan tutorial langkah demi langkah tentang membuat bucket S3 untuk menyimpan email, 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 bisa saya tulis.  Berikut beberapa artikel yang mungkin 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 perlu mengatur izin untuk item itu sendiri.  Dalam proyek saya, saya menggunakan kebijakan yang sangat terbuka yakni public-read karena data sampel tidak bersifat pribadi dan saya ingin akses mudah ke data tersebut.  Anda mungkin ingin set 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.  Di 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 paling sedikit Anda akses. Penulisan bagus tentang kelas yang berbeda dan transisi di antaranya dapat ditemukan dalam panduan AWS yang disebut, Transitioning Objects. Dalam kasus saya, saya memilih untuk membuat lifecycle 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 bucket S3 dan pengaturan saya siap, S3 siap untuk mengunggah email yang sesuai dengan rfc822 yang saya peroleh dari aliran data SparkPost Relay Webhook. Namun 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 dalam badan email untuk id tersembunyi yang ditempatkan aplikasi pengirim ke 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:

$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);
        }
    }
}

* kita menganggap bahwa $inputField memegang nilai “ArchiveCode” dan ditemukan di file config.php saya.

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

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

Sekarang saya dapat membuka sambungan saya ke S3 dan mengunggah file tersebut. Jika Anda melihat file s3.php di repositori GitHub, Anda akan melihat bahwa diperlukan sangat sedikit kode untuk mengunggah file tersebut.

Langkah terakhir saya adalah mencatat entri ini ke 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.