@astram/messaging
Email delivery adapters for the Astram framework (G-010). Each one implements the EmailProvider
port from @astram/core.
Apps normally do not import this package. Install it next to @astram/guard and set
ShieldModule.forRoot({ emailSender: 'env' }). Guard reads and checks the EMAIL_* / SMTP_* /
provider env at boot, loads this package and calls createEmailProvider with the result.
Guard also bounds and audits every send.
Providers
EMAIL_PROVIDER | Transport | Probe (sends nothing) |
|---|---|---|
smtp | nodemailer (loaded only when SMTP is configured); TLS starttls, implicit or none (loopback only); certificates always verified | verify(): connect, STARTTLS, AUTH, QUIT |
brevo | POST /v3/smtp/email, plain fetch | GET /v3/account |
sendgrid | POST /v3/mail/send, plain fetch | GET /v3/scopes (must include mail.send) |
mailgun | POST /v3/{domain}/messages, plain fetch, US or EU host | GET /v3/domains/{domain} |
Behaviour
- Every send and probe is bounded by
timeoutMs(default 10 000, max 30 000). At the bound the call is abandoned and its socket or request is aborted. - A
transientfailure (network, HTTP 429/5xx, SMTP 4xx) is retried once, with jittered backoff, only if the bound has room. Apermanentfailure or atimeoutis never retried. - HTTP providers use https only and do not follow redirects.
- Failures are
MessageDeliveryError(transient|permanent|timeout). Their message is built from the provider name, the class and the HTTP status only. It never includes a credential, a recipient, the message, or the provider's response body. - An unusable config (non-https
baseUrl, a timeout out of range, CR/LF in a header value) is refused with a plainErrorthat names the field, never its value.
@astram/core is a peer dependency, so an app installs exactly one copy.