Traiter automatiquement les pièces jointes d'e-mails

Traiter les fichiers .eml et .msg avec l'API MaraDocs. Extraire, valider et traiter les pièces jointes d'e-mails sous forme d'images ou de PDF. Support récursif pour les e-mails dans les e-mails.

Martin Kurtz
APIE-mailTraitement de documentsDéveloppeurs
Traiter automatiquement les pièces jointes d'e-mails

Les e-mails entrants contiennent fréquemment des documents en pièces jointes – images, PDF, parfois des fichiers .eml ou .msg imbriqués. Dans notre cabinet, un seul e-mail d'un client pouvait contenir une douzaine de photos d'un constat d'accident, une expertise en PDF et un e-mail transféré avec ses propres pièces jointes. Une API de traitement des pièces jointes d'e-mails qui extrait, valide et achemine chaque pièce jointe vers le bon pipeline permettrait d'économiser des heures de travail manuel.

Les images doivent être acheminées vers l'extraction de documents ou l'OCR, les PDF vers la fusion ou la compression – et les e-mails imbriqués doivent être traités de manière récursive.

Pourquoi développer sa propre solution de traitement des pièces jointes d'e-mails prend des semaines

Ceux qui souhaitent construire cela eux-mêmes découvrent rapidement que l'analyse des fichiers .eml et .msg nécessite mail-parser, extract-msg ou similaire. Il faut ensuite décoder le MIME, traiter les messages imbriqués, extraire les données binaires, reconnaître les formats (magika, signatures de fichiers), vérifier les virus et créer des branchements selon la logique image/PDF. Chaque étape comporte ses propres sources d'erreur : en-têtes défectueux, encodages et e-mails imbriqués avec leurs propres pièces jointes. Construire une API de traitement des pièces jointes d'e-mails robuste en interne prend des semaines.

Comment l'API de traitement des pièces jointes d'e-mails MaraDocs résout cela en quelques minutes

L'API MaraDocs valide les fichiers .eml et .msg en un seul appel. Vous obtenez des identifiants de pièces jointes structurés – chacun avec des informations de type. À partir de là, vous pouvez créer des branchements vers des opérations image ou PDF : valider par type, puis appliquer l'extraction de documents, l'OCR, la composition ou la compression. L'API prend en charge le traitement récursif des e-mails joints dans d'autres e-mails.

Workflow de traitement des pièces jointes d'e-mails : télécharger, valider, extraire, acheminer

Téléchargez le fichier e-mail, appelez email.validate. La réponse contient des identifiants de pièces jointes – chacun avec le type de contenu et les métadonnées. Pour chaque pièce jointe, vérifiez le type (image, PDF ou e-mail imbriqué). Validez la pièce jointe avec img.validate ou pdf.validate, puis chaînez dans le pipeline : flow.ocrImg pour les images, pdf.compose pour fusionner les PDF, pdf.optimize pour la compression. Les e-mails imbriqués peuvent être validés à nouveau pour extraire leurs pièces jointes de manière récursive. L'ensemble du pipeline s'exécute côté serveur ; les identifiants sont transmis entre les étapes sans avoir à télécharger et retéléverser.

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 →

Ce qui distingue MaraDocs : espaces de travail, interface web et droit allemand de la protection des données

La plupart des API de documents vous obligent à télécharger chaque pièce jointe, à la retéléverser ailleurs et à suivre les identités à travers plusieurs étapes. Avec MaraDocs, tous les fichiers – l'e-mail et ses pièces jointes – vivent dans le même espace de travail. Validez l'e-mail, itérez sur les identifiants de pièces jointes et transmettez-les aux endpoints img/pdf/flow. Les identifiants circulent ; les données restent côté serveur. Pas de cycles téléchargement-téléversement pour chaque pièce jointe.

Si un e-mail imbriqué a une structure inattendue ou si une pièce jointe doit être vérifiée manuellement, app.maradocs.io peut être ouvert avec le secret de l'espace de travail pour inspecter et réorganiser les fichiers. Vous obtenez un contrôle manuel complet lorsque l'automatisation atteint ses limites.

Le traitement s'effectue en Allemagne (Maramia GmbH), avec chiffrement au repos et pendant le transfert. Les espaces de travail expirent après 7 jours. Aucune donnée ne quitte l'UE. Pour le traitement d'e-mails sensibles en matière de protection des données, c'est pertinent.

Code TypeScript pour extraire les pièces jointes d'e-mails

Référence 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 });

// Téléverser et valider l'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));
  }
}
// Fusionner et télécharger
const composed = await client.pdf.compose({
  pdfs: pdfHandles.map((pdf_handle) => ({ pdf_handle })),
});
const blob = await client.data.downloadPdf({ pdf_handle: composed.pdf_handle });

Code Python pour l'extraction des pièces jointes d'e-mails

Référence 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()

Résumé et prochaines étapes

Une API de traitement des pièces jointes d'e-mails qui extrait, valide et achemine les pièces jointes est disponible. MaraDocs gère l'antivirus, la reconnaissance de format et l'analyse récursive des e-mails. Pour une automatisation complète, combinez avec le scanner de documents, le traitement PDF et la reconnaissance de texte.


Essayez maintenant : API MaraDocs | SDK TypeScript


Abonnez-vous à notre newsletter

Restez au courant et recevez les dernières nouvelles, articles et ressources par e-mail.