Documentation
¶
Overview ¶
Package email provides a provider-agnostic email transport layer.
The package exposes a small Transport interface that can be implemented by any backend. Out of the box it ships with:
- SMTP transport (works with Gmail, AWS SES, SendGrid, Mailgun, Postmark, and any other provider that exposes SMTP).
- Chain transport that tries multiple transports in order, providing primary/secondary/tertiary failover.
- LogOnly transport for local development when no SMTP is configured; it emits a structured WARN log with the recipient and subject so the developer can manually deliver the message.
A small templates sub-package embeds plain text+HTML templates for common transactional emails (password reset, email verification, invitations).
Index ¶
Constants ¶
const ( TemplatePasswordReset = "password_reset" TemplateEmailVerification = "email_verification" TemplateInvitation = "invitation" // TemplateEmailChangeVerify is sent to the *new* address with the // verification link to confirm the email change. TemplateEmailChangeVerify = "email_change_verify" // TemplateEmailChangeNotice is sent to the *old* address as a // security notice that an email change has been requested. TemplateEmailChangeNotice = "email_change_notice" )
Known template names. Keep this list in sync with templates/.
Variables ¶
var ( // ErrInvalidMessage is returned (wrapped) when a Message fails validation. ErrInvalidMessage = errors.New("email: invalid message") // ErrTransport is returned (wrapped) when an underlying transport fails. ErrTransport = errors.New("email: transport failure") )
Sentinel errors returned by the email package. Underlying errors are wrapped with %w so callers can use errors.Is to test against these sentinels.
Functions ¶
Types ¶
type Chain ¶
type Chain struct {
// OnAttempt, if non-nil, is invoked synchronously after each inner Send
// with the index of the transport and the error it returned (nil on
// success). Hook is intended for metrics; keep it cheap and non-blocking.
OnAttempt func(idx int, err error)
// contains filtered or unexported fields
}
Chain is a Transport that delegates to an ordered list of inner transports, trying each in turn until one succeeds. Use it for primary/secondary/tertiary failover across providers.
type Message ¶
type Message struct {
// To is the recipient address (RFC 5322). Exactly one recipient is
// supported; for multi-recipient sends, call Send once per recipient so
// each delivery can be tracked and retried independently.
To string
// From is the sender address (RFC 5322). May be left empty when using a
// transport that injects a default From (e.g. SMTPConfig.From).
From string
// Subject is the email subject line.
Subject string
// HTML is the HTML body. Optional if Text is set.
HTML string
// Text is the plain-text body. Optional if HTML is set.
Text string
}
Message is a single outgoing email. Validate must be called (or NewMessage used) before passing to a Transport. Either HTML or Text (or both) must be non-empty.
func NewMessage ¶
NewMessage constructs a Message and runs Validate. Returns a wrapped ErrInvalidMessage on failure.
type SMTPConfig ¶
type SMTPConfig struct {
// Host is the SMTP server hostname (e.g. "smtp.gmail.com").
Host string
// Port is the SMTP server port. Common values:
// 25 - plain (dev / on-prem only).
// 587 - submission with STARTTLS upgrade.
// 465 - implicit TLS (a.k.a. SMTPS).
Port int
// User and Pass are credentials for PLAIN auth. If User is empty, no auth
// is attempted.
User string
Pass string
// From is the default From address used when Message.From is empty.
From string
// TLS enables implicit TLS on dial (use with port 465).
TLS bool
// StartTLS issues a STARTTLS upgrade after EHLO (use with port 587).
StartTLS bool
// InsecureSkipVerify disables TLS certificate verification. ONLY use this
// in tests against self-signed servers; never enable it in production.
InsecureSkipVerify bool
// DialTimeout caps how long Dial may block. Defaults to 10s.
DialTimeout time.Duration
}
SMTPConfig configures an SMTP transport. The zero value is not valid; use NewSMTP.
type Transport ¶
type Transport interface {
// Send delivers m. It must validate m and return a wrapped ErrInvalidMessage
// for malformed inputs, or a wrapped ErrTransport (or other error) for
// backend failures.
Send(ctx context.Context, m Message) error
}
Transport is the abstraction over an email backend. Implementations must be safe for concurrent use and should honor ctx cancellation as best they can.
func NewLogOnly ¶
NewLogOnly returns a Transport that logs each Send at WARN and returns nil. Intended for local development when no SMTP server is configured.
func NewSMTP ¶
func NewSMTP(cfg SMTPConfig) (Transport, error)
NewSMTP builds an SMTP transport from cfg.