Wszystkie wpisy
|Dostępne również w:DEENFRESITNO

Automatyczne przetwarzanie załączników e-mail

Przetwarzanie plików .eml i .msg za pomocą API MaraDocs. Wyodrębnianie, walidacja i przetwarzanie załączników e-mail jako obrazów lub plików PDF. Rekurencyjne wsparcie dla e-maili w e-mailach.

Martin Kurtz
APIE-mailPrzetwarzanie dokumentówDeweloperzy
Automatyczne przetwarzanie załączników e-mail

Przychodzące wiadomości e-mail często zawierają dokumenty jako załączniki – obrazy, pliki PDF, czasami zagnieżdżone pliki .eml lub .msg. W naszej kancelarii pojedyncza wiadomość e-mail od klienta mogła zawierać tuzin zdjęć z raportu o wypadku, ekspertyzę w PDF oraz przekazaną wiadomość e-mail z własnymi załącznikami. API przetwarzania załączników e-mail, które wyodrębnia każdy załącznik, waliduje go i kieruje do odpowiedniego procesu, pozwoliłoby zaoszczędzić godziny ręcznej pracy.

Obrazy muszą być przekierowane do ekstrakcji dokumentów lub OCR, pliki PDF do łączenia lub kompresji – a zagnieżdżone e-maile muszą być przetwarzane rekurencyjnie.

Dlaczego własne rozwiązanie do przetwarzania załączników e-mail zajmuje tygodnie

Kto chce to zbudować samodzielnie, szybko odkrywa, że parsowanie .eml i .msg wymaga mail-parser, extract-msg lub podobnych narzędzi. Następnie trzeba zdekodować MIME, przetworzyć zagnieżdżone wiadomości, wyodrębnić dane binarne, rozpoznać formaty (magika, sygnatury plików), sprawdzić pod kątem wirusów i rozgałęzić według logiki obraz/PDF. Każdy krok niesie własne źródła błędów: wadliwe nagłówki, kodowania i zagnieżdżone e-maile z własnymi załącznikami. Zbudowanie solidnego API przetwarzania załączników e-mail wewnętrznie zajmuje tygodnie.

Jak API przetwarzania załączników e-mail MaraDocs rozwiązuje to w minuty

API MaraDocs waliduje pliki .eml i .msg w jednym wywołaniu. Otrzymujesz ustrukturyzowane uchwyty załączników – każdy z informacją o typie. Stamtąd możesz rozgałęzić do operacji na obrazach lub PDF: walidować według typu, a następnie zastosować ekstrakcję dokumentów, OCR, kompozycję lub kompresję. API obsługuje rekurencyjne przetwarzanie e-maili załączonych w e-mailach.

Proces przetwarzania załączników e-mail: przesyłanie, walidacja, wyodrębnianie, przekierowanie

Prześlij plik e-mail, wywołaj email.validate. Odpowiedź zawiera uchwyty załączników – każdy z typem zawartości i metadanymi. Dla każdego załącznika sprawdź typ (obraz, PDF lub zagnieżdżony e-mail). Waliduj załącznik za pomocą img.validate lub pdf.validate, a następnie połącz w łańcuch w procesie: flow.ocrImg dla obrazów, pdf.compose do łączenia plików PDF, pdf.optimize do kompresji. Zagnieżdżone e-maile mogą być ponownie zwalidowane w celu rekurencyjnego wyodrębnienia ich załączników. Cały proces działa po stronie serwera; uchwyty są przekazywane między krokami, bez pobierania i ponownego przesyłania.

Get your API key in under a minute

Register for a free account and get your API key in under a minute. Of course we'll provide you with some developer credits.

Try MaraDocs API now →

Co wyróżnia MaraDocs: obszary robocze, widok webowy i niemieckie prawo ochrony danych

Większość API dokumentów zmusza do pobierania każdego załącznika, ponownego przesyłania go gdzie indziej i śledzenia tożsamości przez wiele kroków. W MaraDocs wszystkie pliki – e-mail i jego załączniki – znajdują się w tym samym obszarze roboczym. Waliduj e-mail, iteruj przez uchwyty załączników i przekazuj je do punktów końcowych img/pdf/flow. Uchwyty przepływają; dane pozostają po stronie serwera. Brak cykli pobierania-przesyłania dla każdego załącznika.

Jeśli zagnieżdżony e-mail ma nieoczekiwaną strukturę lub załącznik wymaga ręcznej kontroli, można otworzyć app.maradocs.io z sekretem obszaru roboczego, aby sprawdzić i uporządkować pliki. Użytkownicy otrzymują pełną ręczną kontrolę, gdy automatyzacja osiąga swoje granice.

Przetwarzanie odbywa się w Niemczech (Maramia GmbH), z szyfrowaniem w spoczynku i podczas transmisji. Obszary robocze wygasają po 7 dniach. Żadne dane nie opuszczają UE. Dla przetwarzania e-maili wrażliwych na ochronę danych jest to istotne.

Kod TypeScript do wyodrębniania załączników e-mail

Dokumentacja API: data/upload, email/validate, img/validate, pdf/validate, flow.ocrImg, data/download/pdf

import { MaraDocsClient } from "@maramia/maradocs-sdk-ts";
import { okEmail } from "@maramia/maradocs-sdk-ts/models/email";
import { okImg } from "@maramia/maradocs-sdk-ts/models/img";
import { okPdf } from "@maramia/maradocs-sdk-ts/models/pdf";

const client = new MaraDocsClient({ workspaceSecret: workspace_secret });

// Prześlij i waliduj e-mail
const uploaded = await client.data.upload(emailFile);
const validated = await client.email.validate({
  unvalidated_file_handle: uploaded.unvalidated_file_handle,
});
const email = okEmail(validated);

const pdfHandles: string[] = [];
for (const att of email.attachments) {
  if (att.content_type?.startsWith("image/")) {
    const imgVal = await client.img.validate({
      unvalidated_file_handle: att.unvalidated_file_handle,
    });
    const imgHandle = okImg(imgVal);
    const pdfHandle = await client.flow.ocrImgHandle(imgHandle);
    pdfHandles.push(pdfHandle);
  } else if (att.content_type === "application/pdf") {
    const pdfVal = await client.pdf.validate({
      unvalidated_file_handle: att.unvalidated_file_handle,
    });
    pdfHandles.push(okPdf(pdfVal));
  }
}
// Połącz i pobierz
const composed = await client.pdf.compose({
  pdfs: pdfHandles.map((pdf_handle) => ({ pdf_handle })),
});
const blob = await client.data.downloadPdf({ pdf_handle: composed.pdf_handle });

Kod Python do wyodrębniania załączników e-mail

Dokumentacja API: data/upload, email/validate, img/validate, pdf/validate, pdf/compose, data/download/pdf

# pip install python-decouple requests
"""Extract PDF attachments from an email using MaraDocs. Set ACCOUNT_SECRET in .env or environment."""

import sys
import time
from pathlib import Path

import requests
from decouple import config

API_URL = "https://api.maradocs.io/v1"


def create_workspace() -> dict:
    """Create a workspace and return auth headers."""
    r = requests.post(
        f"{API_URL}/workspace",
        headers={"Authorization": f"Bearer {config('ACCOUNT_SECRET')}"},
        json={"subaccount": None},
    )
    ws = r.json()
    return {"Authorization": f"Bearer {ws['workspace_secret']}"}


def upload_file(path: Path, auth: dict) -> dict:
    """Upload a file via two-step flow (signed URL + S3 POST). Returns unvalidated_file_handle."""
    data = path.read_bytes()
    resp = requests.post(
        f"{API_URL}/data/upload",
        headers={**auth, "Content-Type": "application/json"},
        json={"name": path.name, "size": len(data)},
    ).json()
    requests.post(
        resp["post_url"],
        data=resp.get("post_header", {}),
        files={"file": (path.name, data, "message/rfc822")},
    )
    return resp["unvalidated_file_handle"]


def run_job(path: str, payload: dict, auth: dict, timeout: int = 60) -> dict:
    """Run a job and poll until complete. Returns the result (unwraps response if present)."""
    url = f"{API_URL}/{path}"
    r = requests.post(url, headers=auth, json=payload).json()
    job_id = r["job_id"]
    start = time.time()
    while time.time() - start < timeout:
        poll_r = requests.get(f"{url}/{job_id}", headers=auth)
        if poll_r.status_code == 200:
            return poll_r.json()
    raise TimeoutError(f"Job {path} timed out")


def pdf_handles_from_email(email_handle: dict) -> list:
    """Recursively extract all pdf_handles from an email_handle (handles nested emails)."""
    handles = []
    for att in email_handle.get("attachments", []):
        media = att.get("media_type") or {}
        mt = media.get("media_type", "") if isinstance(media, dict) else ""
        validated = att.get("validated") or {}

        if mt == "application/pdf":
            resp = validated.get("response", {})
            if pdf_h := resp.get("pdf_handle"):
                handles.append(pdf_h)
        elif mt == "message/rfc822":
            nested = (validated.get("response") or {}).get("email_handle")
            if nested:
                handles.extend(pdf_handles_from_email(nested))
    return handles


def download_pdf(pdf_handle: str, auth: dict) -> bytes:
    """Request signed URL and fetch PDF bytes."""
    r = requests.post(
        f"{API_URL}/data/download/pdf",
        headers=auth,
        json={"pdf_handle": pdf_handle},
    )
    info = r.json()
    dl = requests.get(info["url"], headers=info.get("headers", {}))
    return dl.content


def main() -> None:
    email_path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path("input_email.eml")
    auth = create_workspace()
    handle = upload_file(email_path, auth)
    email_data = run_job("email/validate", {"unvalidated_file_handle": handle}, auth)
    email_handle = email_data["response"]["email_handle"]
    pdf_handles = pdf_handles_from_email(email_handle)

    if not pdf_handles:
        sys.exit("No PDF attachments found")

    composed = run_job(
        "pdf/compose",
        {"pdfs": [{"pdf_handle": h} for h in pdf_handles]},
        auth,
    )
    pdf_handle = composed["pdf_handle"]
    Path("attachments.pdf").write_bytes(download_pdf(pdf_handle, auth))
    print("attachments.pdf created")


if __name__ == "__main__":
    main()

Podsumowanie i kolejne kroki

API przetwarzania załączników e-mail, które wyodrębnia, waliduje i przekierowuje załączniki, jest dostępne. MaraDocs przejmuje skanowanie antywirusowe, rozpoznawanie formatów i rekurencyjne parsowanie e-maili. Dla pełnej automatyzacji połącz ze skanerem dokumentów, przetwarzaniem PDF i rozpoznawaniem tekstu.


Wypróbuj teraz: API MaraDocs | SDK TypeScript


Zasubskrybuj newsletter już teraz

Bądź z nami na bieżąco i otrzymuj najnowsze wiadomości, artykuły i zasoby pocztą e-mail.