mailer

package
v0.19.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: AGPL-3.0 Imports: 29 Imported by: 0

Documentation

Overview

Package mailer sends transactional email over SMTP or Resend using mail.* settings. When mail.host is unset it logs the message instead: in development (WithEnv("dev")) including the text body, so magic links still work; otherwise only the recipient and subject, with a warning.

Index

Constants

View Source
const (
	TLSStartTLS = "starttls"
	TLSImplicit = "tls"
	TLSNone     = "none"
)

TLS modes for mail.tls.

View Source
const ServiceName = "mailer"

ServiceName is the kernel service name the admin module registers the *Mailer under (kernel.Get[*mailer.Mailer](d, mailer.ServiceName)).

Variables

This section is empty.

Functions

func DecryptSecret

func DecryptSecret(key []byte, enc string) (string, error)

DecryptSecret reverses EncryptSecret.

func EncryptSecret

func EncryptSecret(key []byte, plain string) (string, error)

EncryptSecret encrypts plain with key (32 bytes, cfg.SecretKey). TODO(consolidate): migrate to db.Encrypt with fallback read (db.Encrypt is AAD-bound std base64 without the enc:v1: prefix; DecryptSecret must keep reading existing enc:v1: values until they are re-saved).

func ParseRecipients added in v0.18.2

func ParseRecipients(s string) ([]string, error)

ParseRecipients normalizes the native form-recipient list: comma, semicolon or newline separated plain addresses, with duplicates dropped and at most ten recipients.

func ValidPlainAddress added in v0.18.2

func ValidPlainAddress(address string) bool

ValidPlainAddress reports a plain address without a display name, up to 254 bytes.

Types

type Attachment

type Attachment struct {
	Name, ContentType string
	Data              []byte
}

Attachment is a file sent with a Message. ContentType defaults to application/octet-stream; Name is encoded per RFC 2231 when needed.

type Config

type Config struct {
	Host, Username, Password, From, FromName, TLS string
	Port                                          int
	Provider, ResendAPIKey                        string
	// ReplyTo is the default Reply-To address (mail.reply_to); a message's
	// own ReplyTo takes precedence.
	ReplyTo string
}

Config is the selected provider configuration; only its secret is decrypted.

type Mailer

type Mailer struct {
	// contains filtered or unexported fields
}

Mailer sends email. It is safe for concurrent use.

func New

func New(s *settings.Store, log *slog.Logger) *Mailer

New returns a mailer reading SMTP settings from s. Call WithKey to enable decrypting mail.password.

func (*Mailer) Config

func (m *Mailer) Config(ctx context.Context) (Config, error)

Config reads mail.* settings and decrypts only the selected provider secret.

func (*Mailer) Configured

func (m *Mailer) Configured(ctx context.Context) bool

Configured reports local settings presence, not provider reachability or delivery.

func (*Mailer) Key

func (m *Mailer) Key() []byte

Key returns the secret key used for mail.password (for callers that store an encrypted password).

func (*Mailer) Render

func (m *Mailer) Render(locale, name string, data any) (subject, html, text string, err error)

Render executes templates/<name>.<locale>.html (html/template) and templates/<name>.<locale>.txt (text/template; it must define "subject"), falling back to the English templates when the locale has none.

func (*Mailer) Send

func (m *Mailer) Send(ctx context.Context, to, subject, html, text string) error

Send delivers one message to a single recipient. Without mail.host it returns nil after logging the message: in dev the text body too (e.g. a magic link) at INFO; in any other env only recipient and subject, at WARN, because a body can carry a sign-in link.

func (*Mailer) SendMessage

func (m *Mailer) SendMessage(ctx context.Context, msg Message) error

SendMessage is Send with the optional headers of msg (Reply-To).

func (*Mailer) SendRequired

func (m *Mailer) SendRequired(ctx context.Context, to, subject, html, text string) error

SendRequired uses one configuration snapshot and never logs a message as a delivery fallback.

func (*Mailer) WithEnv

func (m *Mailer) WithEnv(env string) *Mailer

WithEnv returns a copy of m for the runtime environment env (cfg.Env). Only "dev" logs message bodies when SMTP is not configured.

func (*Mailer) WithKey

func (m *Mailer) WithKey(key []byte) *Mailer

WithKey returns a copy of m that decrypts mail.password with key (cfg.SecretKey).

type Message

type Message struct {
	To, ReplyTo, Subject, HTML, Text string
	Attachments                      []Attachment // optional; makes the message multipart/mixed
}

Message is one email for SendMessage. ReplyTo is optional (an address, optionally with a display name).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL