Canonical normalized inbound message passed to routing and mailbox code.
MailglassInbound.InboundMessage is the stable adopter-facing contract for
the first inbound package slice. It models the normalized fields Mailglass
can promise across first-party ingress providers while keeping raw payloads,
signature evidence, replay metadata, and mailbox execution state out of the
public struct.
Stable Fields
:tenant_id- explicit tenant scope for routing and execution.:provider- first-party ingress provider name.:provider_message_id- provider-specific message reference when present.:message_id- RFCMessage-IDheader value when present.:envelope_recipient- SMTP/envelope recipient used for routing.:from,:to,:cc,:bcc,:reply_to- normalized address data.:subject- normalized message subject.:headers- normalized header map for routing and mailbox reads.:sent_at,:received_at- normalized timestamps.:text_body,:html_body- normalized body fields.:attachments- normalized attachment manifest without attachment bytes.:signals- framework-derived, read-only signals about the message; a typedMailglassInbound.InboundMessage.Signalsstruct (framework writes, adopter reads). SeeMailglassInbound.InboundMessage.Signals.
Reading framework signals (IOPS-05, D-49-21)
The :signals field exposes framework-derived facts, today the
suppression_flagged boolean. Read it via safe dot-access or pattern-match it
in a mailbox process/1 head:
def process(%MailglassInbound.InboundMessage{
signals: %MailglassInbound.InboundMessage.Signals{suppression_flagged: true}
}), do: {:reject, :sender_suppressed}
def process(%MailglassInbound.InboundMessage{} = message) do
if MailglassInbound.InboundMessage.suppression_flagged?(message),
do: ...,
else: :accept
endDeviation D-49-21: IOPS-05's literal wording exposes the flag at
%InboundMessage{}.metadata.suppression_flagged. Mailglass instead ships%InboundMessage{}.signals.suppression_flaggedas a deliberate, documented improvement (the SESI-04-erratum precedent)::metadatais reserved framework-wide for adopter-owned data, so framework-derived facts live on the distinct, framework-owned:signalstyped struct.
Summary
Functions
Returns the message's suppression_flagged signal (IOPS-05).
Types
@type provider() :: :postmark | :sendgrid | String.t()
@type t() :: %MailglassInbound.InboundMessage{ attachments: [attachment()], bcc: [address()], cc: [address()], envelope_recipient: String.t() | nil, from: [address()], headers: %{optional(String.t()) => [String.t()]}, html_body: String.t() | nil, message_id: String.t() | nil, provider: provider() | nil, provider_message_id: String.t() | nil, received_at: DateTime.t() | nil, reply_to: [address()], sent_at: DateTime.t() | nil, signals: MailglassInbound.InboundMessage.Signals.t(), subject: String.t() | nil, tenant_id: String.t() | nil, text_body: String.t() | nil, to: [address()] }
Functions
Returns the message's suppression_flagged signal (IOPS-05).
true when the message's first from address was on the tenant's suppression
list at receipt time. This is the one convenience predicate over the :signals
struct; read other signals via dot-access or pattern-matching. Safe on any
%InboundMessage{} — the :signals default guarantees no KeyError.