email

package
v1.3.7 Latest Latest
Warning

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

Go to latest
Published: Sep 14, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TypeVerifyEmail          = "verify_email"
	TypeVerificationReminder = "verification_reminder"
	TypePasswordReset        = "password_reset"
	TypePasswordChanged      = "password_changed"
	TypeTwoFactorReset       = "two_factor_reset"
	TypeNotification         = "notification"
	TypeSignatureRequest     = "signature_request"
	TypeSignatureCompleted   = "signature_completed"
	TypeAdminTest            = "admin_test"
)

Message type identifiers used across the codebase.

Variables

View Source
var (
	// EmailSendTotal counts email send attempts by result.
	// Results: success, failure, dry_run, invalid_address.
	EmailSendTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "email_send_total",
			Help: "Total number of email send attempts.",
		},
		[]string{"result"},
	)

	// EmailDeliveryTotal counts send attempts by message type and delivery
	// outcome. Statuses: delivered, hard_bounce, soft_bounce, rejected,
	// invalid_address, suppressed, server_error, dry_run.
	EmailDeliveryTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "email_delivery_total",
			Help: "Email send attempts by message type and delivery outcome.",
		},
		[]string{"type", "status"},
	)

	// EmailSuppressedAddresses is the number of addresses currently suppressed
	// after a hard bounce.
	EmailSuppressedAddresses = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "email_suppressed_addresses",
			Help: "Number of email addresses suppressed after a permanent delivery failure.",
		},
	)

	// EmailSendDurationSeconds tracks SMTP send latency for delivered emails.
	EmailSendDurationSeconds = prometheus.NewHistogram(
		prometheus.HistogramOpts{
			Name:    "email_send_duration_seconds",
			Help:    "Latency of the SMTP send call in seconds (both successful and failed attempts).",
			Buckets: prometheus.DefBuckets,
		},
	)
)

Functions

func Templates

func Templates(locale string) templateSet

Templates returns the email template functions for the given locale. Falls back to English if locale is not supported.

Types

type Attempt added in v1.3.2

type Attempt struct {
	Recipient string
	Type      string
	Status    DeliveryStatus
	// Code is the SMTP reply code, 0 when there was no conversation.
	Code int
	// Detail is the server's reply text or a local classification note; never
	// shown to the recipient.
	Detail string
}

Attempt is one row of the delivery log.

type CredentialExpiryParams

type CredentialExpiryParams struct {
	UserName       string
	CredentialType string
	ExpiryDate     string
	DaysRemaining  int
}

type CurrencyMessageParams added in v1.3.7

type CurrencyMessageParams struct {
	Days   *int
	Needed *int
	Date   *string
}

CurrencyMessageParams carries the params a currency message key interpolates. Mirrors currency.MessageParams; see ninerlog-api docs/CURRENCY_MESSAGES.md.

type CustomCurrencyParams added in v1.3.1

type CustomCurrencyParams struct {
	UserName string
	RuleName string
	// Expiring is true for a "will lapse soon" warning (ExpiresOn set), false
	// for a "no longer current" notice.
	Expiring  bool
	ExpiresOn string
}

type DeliveryRecorder added in v1.3.2

type DeliveryRecorder interface {
	RecordAttempt(ctx context.Context, a Attempt)
	// IsSuppressed reports whether the address has hard-bounced before.
	// Implementations fail open (return false) when they cannot answer.
	IsSuppressed(ctx context.Context, recipient string) bool
}

DeliveryRecorder persists what happened to each send and answers whether an address has been given up on. The implementation lives in internal/service.

RecordAttempt returns nothing; implementations log their own storage errors.

type DeliveryStatus added in v1.3.2

type DeliveryStatus string

DeliveryStatus classifies the outcome of one send attempt.

const (
	// StatusDelivered means the receiving server accepted the message;
	// asynchronous bounces are not visible here.
	StatusDelivered DeliveryStatus = "delivered"

	// StatusHardBounce means the recipient was refused permanently: a 5xx reply
	// to RCPT TO or to the message data.
	StatusHardBounce DeliveryStatus = "hard_bounce"

	// StatusSoftBounce is a temporary refusal of the recipient (4xx): greylisting,
	// a full mailbox, a server over quota.
	StatusSoftBounce DeliveryStatus = "soft_bounce"

	// StatusInvalidAddress means the address failed to parse; nothing was
	// dialled.
	StatusInvalidAddress DeliveryStatus = "invalid_address"

	// StatusSuppressed means the send was skipped: the address is on the
	// suppression list from an earlier hard bounce.
	StatusSuppressed DeliveryStatus = "suppressed"

	// StatusRejected means the server took the recipient but refused the
	// message itself (size limit, content or reputation policy); it never
	// suppresses the address.
	StatusRejected DeliveryStatus = "rejected"

	// StatusServerError covers failures of our side or the connection rather
	// than the recipient: DNS, refused connections, TLS failures, bad SMTP
	// credentials.
	StatusServerError DeliveryStatus = "server_error"

	// StatusDryRun records a send skipped while SMTP is not configured.
	StatusDryRun DeliveryStatus = "dry_run"
)

func (DeliveryStatus) IsRecipientFailure added in v1.3.2

func (s DeliveryStatus) IsRecipientFailure() bool

IsRecipientFailure reports whether the status blames the address rather than the sending infrastructure.

type FlightReviewExpiryParams

type FlightReviewExpiryParams struct {
	UserName      string
	ExpiryDate    string
	DaysRemaining int
}

type FlightReviewRequiredParams

type FlightReviewRequiredParams struct {
	UserName      string
	MessageKey    string
	MessageParams CurrencyMessageParams
}

type Message added in v1.3.2

type Message struct {
	To       string
	Subject  string
	HTMLBody string
	Type     string
}

Message is one outbound email. Type is a short stable identifier for the message's purpose ("verify_email", "verification_reminder", …).

type PassengerCurrencyParams

type PassengerCurrencyParams struct {
	UserName  string
	ClassType string
	Landings  int
	Required  int
	Remaining int
	Period    string // "day" or "night"
}

type PasswordChangedParams added in v1.3.2

type PasswordChangedParams struct {
	UserName string
	// TwoFactorEnabled reports whether 2FA is still active on the account.
	TwoFactorEnabled bool
}

PasswordChangedParams drives the security notice sent after a password reset completes.

type PasswordResetParams added in v1.3.2

type PasswordResetParams struct {
	UserName string
	Link     string
	// TwoFactorEnabled warns the user up front that finishing the reset also
	// requires their authenticator code or a recovery code.
	TwoFactorEnabled bool
}

type RatingExpiryParams

type RatingExpiryParams struct {
	UserName      string
	LicenseType   string
	ClassType     string
	ExpiryDate    string
	DaysRemaining int
}

type RevalidationParams

type RevalidationParams struct {
	UserName      string
	LicenseType   string
	ClassType     string
	MessageKey    string
	MessageParams CurrencyMessageParams
}

type SMTPConfig

type SMTPConfig struct {
	Host     string
	Port     string
	Username string
	Password string
	From     string
}

SMTPConfig holds SMTP server configuration

func LoadSMTPConfig

func LoadSMTPConfig() *SMTPConfig

LoadSMTPConfig loads SMTP configuration from environment variables

func (*SMTPConfig) IsConfigured

func (c *SMTPConfig) IsConfigured() bool

IsConfigured returns true if SMTP is properly configured

type SendError added in v1.3.2

type SendError struct {
	Status DeliveryStatus
	// Code is the SMTP reply code when the server gave one, 0 otherwise.
	Code int
	Err  error
}

SendError carries the delivery classification alongside the underlying failure.

func (*SendError) Error added in v1.3.2

func (e *SendError) Error() string

func (*SendError) Permanent added in v1.3.2

func (e *SendError) Permanent() bool

Permanent reports whether the failure blames the address itself.

func (*SendError) Unwrap added in v1.3.2

func (e *SendError) Unwrap() error

type Sender

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

Sender sends emails via SMTP

func NewSender

func NewSender(config *SMTPConfig) *Sender

NewSender creates a new SMTP email sender

func (*Sender) IsConfigured added in v1.2.6

func (s *Sender) IsConfigured() bool

IsConfigured returns true when the sender has a usable SMTP configuration.

func (*Sender) Send

func (s *Sender) Send(to, subject, htmlBody string) error

Send sends an email with a background context and no message type.

func (*Sender) SendMessage added in v1.3.2

func (s *Sender) SendMessage(ctx context.Context, msg Message) error

SendMessage sends an email and records what the SMTP conversation said about it. The recipient is validated with net/mail.ParseAddress and conveyed only through the SMTP envelope; the subject is MIME Q-encoded. A returned error is always a *SendError.

func (*Sender) SetDeliveryRecorder added in v1.3.2

func (s *Sender) SetDeliveryRecorder(r DeliveryRecorder)

SetDeliveryRecorder attaches the delivery log. A sender without a recorder still sends and keeps no history.

type SignatureCompletedParams added in v1.2.9

type SignatureCompletedParams struct {
	OwnerName     string
	FlightSummary string
	SignerName    string
}

type SignatureRequestParams added in v1.2.9

type SignatureRequestParams struct {
	OwnerName string
	// OwnerEmail is the requester's verified account address, shown alongside
	// the free-form OwnerName.
	OwnerEmail    string
	FlightSummary string // e.g. "12 Jul 2026 — D-EFGH (C172), 1h24m"
	Link          string
	ExpiresAt     string
}

type TwoFactorResetParams added in v1.3.2

type TwoFactorResetParams struct {
	UserName string
}

TwoFactorResetParams drives the notice sent when an administrator clears a user's 2FA enrolment.

type VerificationReminderParams added in v1.3.2

type VerificationReminderParams struct {
	UserName string
	Link     string
	// DeletionDays is how long the account survives from this reminder.
	DeletionDays int
	// LinkValidDays is how long the enclosed link works, which is shorter.
	LinkValidDays int
}

VerificationReminderParams drives the follow-up sent when an account is still unverified a day after signup.

type VerifyEmailParams added in v1.2.5

type VerifyEmailParams struct {
	UserName string
	Link     string
}

Jump to

Keyboard shortcuts

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