Email parsing daripada fail EML yang dibekalkan: pengepala dan bahagian MIME

Email parsing menukar bait EML yang dibekalkan kepada pengepala mesej, bahagian MIME dan metadata yang boleh disemak. Gunakan penghurai yang memahami MIME untuk mengekalkan pengepala berulang dan menyahkod teks mengikut pengekodan yang dinyatakan; jangan pisahkan mesej menggunakan ungkapan biasa. Menghuraikan medan From atau Reply-To menerangkan mesej yang dibekalkan, tanpa mengesahkan siapa yang menghantarnya.

Aliran kerja ini bermula dengan fail EML yang dibenarkan dan dibekalkan untuk pemeriksaan. Ia tidak memerlukan sambungan peti mel. Panduan pengekstrakan dokumen membincangkan medan perniagaan dalam dokumen yang boleh dibaca; tugas di sini ialah memahami struktur pengepala dan berbilang bahagian mesej terlebih dahulu.

contoh konfigurasi, bukan ujian yang direkodkan. Antara muka aliran kerja didokumenkan dalam katalog; Ai Flowi belum mengujinya dalam persekitaran pengeluaran untuk proses EML ini. Fungsi bantuan dan data ujian sintetik di bawah menetapkan kontrak penerimaan yang dicadangkan untuk bait mesej yang dibekalkan.

Berkaitan: Transkripsi audio ke Google Docs.

1. Takrifkan sempadan bait dan output

Anda memerlukan AI Flowi Workflow, sampel EML sintetik yang dibekalkan atau sampel lain yang dibenarkan, serta penyemak. Tiada akaun emel atau kunci API model diperlukan untuk penghuraian setempat yang deterministik. Jika anda kemudian menambahkan model atau perkhidmatan luar, gunakan akaun/kunci API penyedia anda sendiri dan bayar penggunaannya secara berasingan.

Kekalkan bait asal. Mengekod semula fail EML melalui pembaca teks sembarangan sebelum penghuraian boleh mengubah maklumat tentang pengekodannya. Contoh ini hanya menerima bait, mengehadkan mesej kepada 1 MiB, membenarkan paling banyak 64 nod MIME dilawati dan mengehadkan setiap bahagian teks biasa yang dinyahkod kepada 256 KiB. Ini ialah had demonstrasi yang dipilih, bukan had produk atau dakwaan perlindungan menyeluruh terhadap input berniat jahat.

Output yang dimaksudkan mengandungi pengepala mentah berulang, nilai pengepala yang dinyahkod, bahagian teks biasa, metadata bahagian lain dan amaran. Asingkan unsur tersebut. Amaran bermaksud penyemak mesti memeriksa sumber; objek JSON yang berjaya dikembalikan bukan kelulusan kandungan mesej.

2. Periksa mesej sintetik dengan pengepala berulang

From: sender@example.invalid
Reply-To: replies@example.invalid
Subject: =?utf-8?b?Q2Fmw6k=?=
Message-ID: <synthetic@example.invalid>
X-Trace: first
X-Trace: second
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Caf=C3=A9

Subjek pengepala dan isi mesej masing-masing mengekod “Café” dengan cara berbeza. Kekalkan kedua-dua kemunculan X-Trace mengikut urutannya. Alamat dan pengecam mesej ialah pemegang tempat yang direka. Reply-To ialah arahan alamat balasan dalam mesej, bukan bukti bahawa pengirim mengawal alamat tersebut.

Mesej MIME yang mengandungi bahagian alternatif boleh mempunyai versi teks biasa dan HTML bagi kandungan yang sama. Jangan gabungkan kedua-duanya seolah-olah masing-masing mengandungi fakta yang berasingan. HTML tidak dirender dalam contoh ini, dan lampiran teks tidak dijadikan sebahagian daripada isi teks biasa utama. Mesej terbenam kekal sebagai entri metadata berasingan, bukannya menyumbangkan pengepala atau isinya kepada mesej luar.

3. Gunakan pustaka standard Python dengan dasar yang jelas

Fungsi bantuan yang dicadangkan menggunakan BytesParser(policy=policy.default), mengekalkan raw_items() dan merekodkan kecacatan penghurai. Set aksara yang dinyatakan dinyahkod secara ketat terlebih dahulu; jika set aksara tidak diketahui atau urutan teks tidak sah, fungsi bantuan merekodkan amaran dan menghasilkan paparan gantian UTF-8 yang ditandakan dengan jelas sebagai tidak mengekalkan semua maklumat asal.

Fungsi bantuan pemeriksaan EML dengan had
from email import policy
from email.parser import BytesParser


def parse_eml(raw):
    if not isinstance(raw, bytes):
        raise TypeError("Supply EML bytes")
    if len(raw) > 1024 * 1024:
        raise ValueError("EML exceeds example byte limit")
    # ponytail: materializes the capped message before the part check; use a streaming parser for stricter hostile-input resource limits.
    msg = BytesParser(policy=policy.default).parsebytes(raw)
    out = {"headers": list(msg.raw_items()), "decoded_headers": [],
           "plain_text_parts": [], "other_parts": [], "warnings": []}
    out["decoded_headers"] = [(name, str(value)) for name, value in msg.items()]
    for name in ("From", "Subject", "Message-ID"):
        if not msg.get_all(name):
            out["warnings"].append("missing " + name)
    pending, seen = [msg], 0
    while pending:
        part = pending.pop()
        seen += 1
        if seen > 64:
            raise ValueError("EML exceeds example part limit")
        kind, filename = part.get_content_type(), part.get_filename()
        for header in part.values():
            out["warnings"].extend(type(d).__name__ for d in getattr(header, "defects", ()))
        if part.get_content_disposition() == "attachment" or filename is not None or kind == "message/rfc822":
            out["other_parts"].append({"type": kind, "filename": filename})
            if filename and (filename in (".", "..") or any(c in filename for c in "/\\") or any(ord(c) < 32 or ord(c) == 127 for c in filename)):
                out["warnings"].append("unsafe attachment name")
        elif part.is_multipart():
            pending.extend(reversed(list(part.iter_parts())))
        elif kind == "text/plain":
            payload = part.get_payload(decode=True) or b""
            if len(payload) > 256 * 1024:
                raise ValueError("Text part exceeds example byte limit")
            charset = part.get_content_charset() or "ascii"
            try:
                text = payload.decode(charset, errors="strict")
            except (LookupError, UnicodeError):
                out["warnings"].append("charset failure: " + charset)
                text = payload.decode("utf-8", errors="replace")
            out["plain_text_parts"].append(text)
        else:
            out["other_parts"].append({"type": kind, "filename": filename})
        out["warnings"].extend(type(d).__name__ for d in part.defects)
    return out

Panggil parse_eml(raw) dengan bait yang sudah dibekalkan. Contoh ini tidak membuka laluan fail sembarangan atau memuat turun kandungan. Nama lampiran kekal sebagai metadata: walaupun nama cuba keluar daripada folder (dua titik diikuti garis miring, berulang), ia tidak pernah digunakan sebagai laluan destinasi. Fungsi bantuan melaporkan pemisah atau aksara kawalan yang mencurigakan; semakan itu bukan pembersih nama fail atau pengesan perisian hasad.

4. Konfigurasikan serahan aliran kerja secara berasingan

Katalog menerangkan Python Interpreter sebagai Jalankan kod Python dengan import pilihan. Gunakan print() untuk melihat output. Medan wajib global_imports dan python_code menyediakan antara muka pelaksanaan. Eksport tidak menyatakan akses fail, import yang tersedia atau cara JSON yang dicetak dibungkus dalam results.

Jadual data ujian dan aliran kerja kekal dalam kawasan yang boleh ditatal pada peranti mudah alih. Fokus papan kekunci membolehkan anda memeriksa lajur di luar pandangan awal.

Tetapan katalog yang masih memerlukan pemeriksaan semasa pelaksanaan
PeringkatInput yang dicadangkanSempadan pengesahan
Python InterpreterTetapkan global_imports untuk modul pustaka standard yang dibenarkan oleh persekitaran pelaksanaan; letakkan fungsi bantuan yang disemak dalam python_code.Sahkan import dan mekanisme pembekalan bait yang diberi kuasa. Periksa results, yang dinyatakan sebagai JSON, selepas panggilan sintetik.
JSON Operationsdata: JSON penghurai yang diperiksa; pilih "Select Keys" atau "JQ Expression" yang disemak melalui operations.Asingkan pengepala, bahagian dan amaran. Jangan anggap stdout terus menjadi objek hasil penghuraian tanpa pembungkus.
JSON Object Builder, pilihanfield_names: satu kunci rekod yang disemak, seperti parsed_message.Periksa input yang dijana dan boleh disambungkan, serta json_object. Sintaks berbilang kunci dan jenis input yang dijana tidak dieksport.

Gunakan semakan sintetik yang dicadangkan untuk menetapkan output yang dijangkakan, kemudian periksa import dan hasil pada sampel yang tidak berbahaya dalam ruang kerja anda. Python Interpreter tiada input muat naik EML yang dieksport. Jangan mereka sambungan daripada Read File kepada Python Interpreter atau mengandaikan pemegang fail wujud dalam pentafsir. Sahkan penghantaran bait dan pemetaan hasil cetakan sebelum mencuba serahan aliran kerja.

5. Kekalkan set semakan kegagalan yang kecil

Semakan penerimaan sintetik yang dicadangkan
Data ujianHasil pemeriksaan yang dijangkakan
X-Trace berulang serta subjek/isi yang dikodkanKedua-dua nilai mentah kekal; subjek dan isi yang dinyahkod mengekalkan aksara beraksen.
From, Subject atau Message-ID yang tiadaLaporkan amaran pengepala yang tiada, bukannya mereka nilai.
Alternatif teks biasa/HTML berbilang bahagianKekalkan teks biasa sebagai teks dan HTML sebagai metadata bahagian yang tidak dirender.
Set aksara tidak diketahui, UTF-8 tidak sah atau base64 rosakCatatkan amaran penyahkodan atau kecacatan penghurai; teks gantian bukan bukti tepat.
Nama lampiran berbentuk perentasan laluan dan mesej terbenamKekalkan metadata tanpa menulis fail atau menjadikan teks terbenam sebagai isi utama.
Sempadan berbilang bahagian yang tiadaPaparkan kecacatan penghurai, bukannya menganggap struktur rosak sebagai teks biasa yang lengkap.
Jenis input salah atau had mesej, teks atau bahagian dilampauiCetuskan ralat yang dinyatakan sebelum menerima rekod pemeriksaan.

Terapkan kriteria ini pada contoh yang dibenarkan daripada format mesej anda sebelum menerima pakai kontrak. Kekalkan amaran yang dijangkakan di sebelah setiap data ujian supaya amaran yang tiada dapat dikesan semasa semakan. Penghurai boleh menerima input rosak dan memaparkan kecacatan; ketiadaan pengecualian tidak membuktikan emel berstruktur betul atau tulen.

Apakah batas kepercayaan penghuraian e-mel dan bilakah perlu berhenti?

From, Reply-To dan Message-ID ialah pengepala yang dibekalkan. Pengesahan identiti pada peringkat penghantaran emel memerlukan bukti daripada sistem penerima yang dipercayai; pengepala berkaitan pengesahan yang ditampal masih merupakan teks yang dibekalkan. Halaman ini tidak memberikan jaminan pengesanan penyamaran atau pengesahan peti mel, dan tidak menyediakan arahan menghantar atau menerima.

Gunakan penghurai setempat yang terkawal apabila mesej sensitif dan tiada pemprosesan luar diperlukan. Jangan jalankan lampiran, elakkan merender HTML dan jangan ambil imej yang dipautkan. Tolak input yang melebihi had sebelum menambahkan tindakan hiliran, dan wajibkan semakan sumber apabila penyahkodan kehilangan maklumat.

Pelan: Go dari USD8/bulan dengan bil tahunan (USD10 bulanan), Plus dari USD16 (USD20 bulanan), Pro 100 dari USD80 (USD100 bulanan), Pro 200 dari USD160 (USD200 bulanan) dan Pro 500 dari USD400 (USD500 bulanan), dengan 5,000 hingga 250,000 Flowi Tokens sebulan dan pilihan tambah nilai; 1 token bagi setiap pelaksanaan nod; penggunaan API dan model pihak ketiga tidak termasuk.

Kira pelaksanaan pentafsir dan pemprosesan hanya selepas mengkonfigurasikan serahan aliran kerja. Mesej yang ditolak patut mengekalkan sebab dan rujukan sumbernya tanpa menjadi rekod hiliran yang diterima. Tiada penggunaan aliran kerja yang diukur dibekalkan untuk reka bentuk pemeriksaan EML yang dicadangkan ini.

Oleh Ai Flowi · Diterbitkan .