Core Concepts

Webhook delivery

When MailLaser receives and parses a valid email, it sends the extracted content to your configured webhook URL as an HTTP POST request with a JSON body.


HTTP request details

Every webhook delivery uses these HTTP settings:

PropertyValue
MethodPOST
Content-Typeapplication/json
User-AgentMailLaser/2.0.0
URLValue of MAIL_LASER_WEBHOOK_URL

The User-Agent header reflects the application name and version from the Cargo package metadata.

In release builds, MailLaser enforces HTTPS-only connections to the webhook URL. In debug builds, HTTP is also permitted for local development.


JSON payload format

The payload contains the parsed email content:

{
  "sender": "user@example.com",
  "sender_name": "John Doe",
  "recipient": "alerts@myapp.com",
  "subject": "Monthly Report",
  "body": "Please find the report attached.\n\nBest regards,\nJohn",
  "html_body": "<html><body><p>Please find the report attached.</p><p>Best regards,<br>John</p></body></html>",
  "headers": {
    "X-Custom-Id": "12345",
    "X-Priority": "high"
  }
}

Required fields

These fields are always present in every payload:

FieldTypeDescription
senderstringThe email address from the MAIL FROM command.
recipientstringThe accepted email address from the RCPT TO command.
subjectstringThe Subject: header value. Empty string if no subject header exists.
bodystringPlain text body content. If the email is HTML-only, this contains a text conversion generated by html2text.

Optional fields

These fields are omitted entirely from the JSON when they have no value. They are not set to null; they are absent from the payload.

FieldTypeDescription
sender_namestringDisplay name from the From: header (e.g., "John Doe" from John Doe <john@example.com>). Omitted when the From: header contains only an email address or is absent.
html_bodystringRaw HTML content from the text/html MIME part. Omitted when the email has no HTML content.
headersobjectKey-value map of headers matching the configured MAIL_LASER_HEADER_PREFIX. Omitted when no prefixes are configured or no headers match. See Header passthrough.

Body processing

MailLaser determines the body and html_body fields through this logic:

  1. If the email has a text/plain MIME part and a text/html MIME part (typical for multipart/alternative), the body is generated from the HTML using html2text, and html_body contains the raw HTML.
  2. If the email has only a text/html part, the body is generated from the HTML using html2text, and html_body contains the raw HTML.
  3. If the email has only a text/plain part, the body contains the plain text directly, and html_body is omitted.
  4. If neither part is found, body is an empty string and html_body is omitted.

Text conversion

The html2text library converts HTML to readable plain text. It preserves paragraph structure, converts links to reference-style notation, and handles bold/italic formatting. The output width is set to 80 characters.


Delivery behavior

Webhook delivery is handled by the WebhookActor, which runs as a persistent actor in the acton-reactive framework. The actor processes emails sequentially, applying resilience patterns to each delivery attempt.

For each email:

  1. The circuit breaker is checked. If the circuit is open, the email is dropped (see Resilience).
  2. The initial delivery attempt is made with a configurable timeout (MAIL_LASER_WEBHOOK_TIMEOUT, default 30 seconds).
  3. If the attempt fails or times out, retries occur with exponential backoff up to MAIL_LASER_WEBHOOK_MAX_RETRIES (default 3).
  4. The circuit breaker state is updated based on the outcome.

Webhook delivery is fire-and-forget from the SMTP session's perspective. The SMTP session responds with 250 OK: Message accepted for delivery as soon as the email data is parsed and passed to the webhook actor. A webhook failure does not cause the SMTP transaction to fail.


Response handling

MailLaser checks the HTTP status code of the webhook response:

  • 2xx: Logged as successful. The circuit breaker's failure counter resets.
  • 4xx or 5xx: Logged as an error. Counts as a failure for retry and circuit breaker purposes.
  • Timeout: Logged as a timeout. Counts as a failure.

The response body from the webhook endpoint is not read or logged. MailLaser only examines the status code.

Previous
SMTP server