Mailglass.Compliance (Mailglass v1.0.0)

Copy Markdown View Source

Injects RFC-required and mailglass-specific headers into outbound messages.

Phase 1 ships functional stubs for the v0.1 RFC floor:

  • Date — RFC 2822 format; injected if absent.
  • Message-ID — RFC 5322 unique identifier; injected if absent.
  • MIME-Version — always "1.0"; injected if absent.
  • Mailglass-Mailable"Module.function/arity"; injected if absent.

Full RFC 8058 List-Unsubscribe + List-Unsubscribe-Post lands in v0.5 (DELIV-01). Feedback-ID gets its full shape once tenant-scoped streams land in Phase 2.

Invariant

add_rfc_required_headers/1 NEVER overwrites a header that already exists. Adopters who set their own Date or Message-ID keep their values intact.

Summary

Functions

Adds the Mailglass-Mailable header identifying the source mailable.

Injects RFC-required headers (Date, Message-ID, MIME-Version) and the Mailglass-Mailable header if absent.

Applies message-aware outbound compliance headers after render while stream context is still available.

Writes the RFC 8058 unsubscribe header pair atomically on the inner %Swoosh.Email{}.

Injects the Feedback-ID header into the inner %Swoosh.Email{} if configured and absent.

Functions

add_mailable_header(email, module, function, arity)

(since 0.1.0)
@spec add_mailable_header(Swoosh.Email.t(), module(), atom(), non_neg_integer()) ::
  Swoosh.Email.t()

Adds the Mailglass-Mailable header identifying the source mailable.

Format: "ModuleName.function/arity" — e.g., "MyApp.UserMailer.welcome/1".

Does NOT overwrite an existing Mailglass-Mailable header.

Examples

iex> email = %Swoosh.Email{}
iex> result = Mailglass.Compliance.add_mailable_header(email, MyApp.UserMailer, :welcome, 1)
iex> result.headers["Mailglass-Mailable"]
"MyApp.UserMailer.welcome/1"

add_rfc_required_headers(email)

(since 0.1.0)
@spec add_rfc_required_headers(Swoosh.Email.t()) :: Swoosh.Email.t()

Injects RFC-required headers (Date, Message-ID, MIME-Version) and the Mailglass-Mailable header if absent.

Does NOT overwrite existing header values.

Examples

iex> email = %Swoosh.Email{}
iex> updated = Mailglass.Compliance.add_rfc_required_headers(email)
iex> Map.has_key?(updated.headers, "Date")
true
iex> updated.headers["MIME-Version"]
"1.0"

apply_outbound_headers(message)

(since 0.2.0)
@spec apply_outbound_headers(Mailglass.Message.t()) :: Mailglass.Message.t()

Applies message-aware outbound compliance headers after render while stream context is still available.

Generic RFC headers stay on the %Swoosh.Email{} primitive. Stream-aware headers such as Feedback-ID and RFC 8058 unsubscribe headers flow through this wrapper.

inject_unsubscribe_headers(message, url)

(since 0.2.0)
@spec inject_unsubscribe_headers(Mailglass.Message.t(), String.t()) ::
  Mailglass.Message.t()

Writes the RFC 8058 unsubscribe header pair atomically on the inner %Swoosh.Email{}.

This is the only allowed mutation path for List-Unsubscribe and List-Unsubscribe-Post.

maybe_add_feedback_id(message)

(since 0.2.0)
@spec maybe_add_feedback_id(Mailglass.Message.t()) :: Mailglass.Message.t()

Injects the Feedback-ID header into the inner %Swoosh.Email{} if configured and absent.

Requires a %Mailglass.Message{} because it interpolates the stream, tenant, and mailable.