mail

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package mail sends e-mail for modules: confirmations, notifications and newsletters. A site picks the Sender in webthings.Config.Mail; SMTP is built in, other providers implement Sender. Without one, messages are logged instead of sent, which suits development.

Index

Constants

View Source
const DefaultSMTPTimeout = 30 * time.Second

DefaultSMTPTimeout bounds one SMTP.Send when SMTP.Timeout is zero.

View Source
const Rule = "mail"

Rule is the name of the go-form validation of addresses mail can be sent to, validate:"mail" on a field, which the site's visitor forms and the admin's forms register (see FormRule):

Email string `form:"input,email" name:"email" required:"true" validate:"mail"`

Variables

This section is empty.

Functions

func Compose

func Compose(from string, message Message) ([]byte, error)

Compose renders a message as RFC 5322 bytes, multipart when HTML is set.

func FormRule

func FormRule(value any, field reflect.StructField, _ form.Localizer) form.FieldErrors

FormRule is the go-form validation Rule (a form.LocalizedValidationFunc): an address that is not Valid gets go-form's message of an invalid e-mail address (form.TranslationKeyInvalidEmail), translated like go-form's own messages, at its field. An empty value passes; required checks that. An address go-form already refuses itself, the value of an email input (form:"input,email" or email:"true") that is no address at all, gets no second message.

func Valid

func Valid(address string) bool

Valid reports whether address is a single plain e-mail address, as go-form checks email inputs (form.ValidEmail), with a dot in it: mail is sent to addresses on the internet, not to local hosts.

Types

type Describer

type Describer interface {
	Describe() string
}

Describer is a Sender that can say how it sends, for people who check the site's set-up, such as the admin's setup guide: "SMTP mail.example.com:587, from Site <noreply@example.com>". The description never holds a secret, such as a password or an API key. SMTP, Log and Memory implement it.

type Log

type Log struct {
	Logger *slog.Logger
}

Log writes messages to the log instead of sending them.

func (Log) Describe

func (l Log) Describe() string

Describe implements Describer.

func (Log) Send

func (l Log) Send(_ context.Context, message Message) error

Send implements Sender: it logs the recipients, subject and text at info level and never fails, so development needs no mail server.

type Memory

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

Memory keeps sent messages, for tests.

func (*Memory) Describe

func (m *Memory) Describe() string

Describe implements Describer.

func (*Memory) Send

func (m *Memory) Send(_ context.Context, message Message) error

Send implements Sender: it keeps the message for Sent and never fails.

func (*Memory) Sent

func (m *Memory) Sent() []Message

Sent returns the messages sent so far.

type Message

type Message struct {
	// To are the recipients' addresses; every recipient sees them all.
	To []string
	// ReplyTo is where replies go instead of the sender, such as the
	// visitor who filled in a contact form.
	ReplyTo string
	Subject string
	// Text is the plain text body, which every mail program can show.
	Text string
	// HTML is the optional rich body, sent next to Text.
	HTML string
	// Headers are extra header fields, for example List-Unsubscribe and
	// List-Unsubscribe-Post (RFC 8058) on newsletters. Compose refuses names
	// it writes itself, such as From or Content-Type, and line breaks.
	Headers map[string]string
}

Message is one e-mail. Text is required; HTML is optional.

type SMTP

type SMTP struct {
	// Host is the mail server's name, also checked against its
	// certificate.
	Host string
	// Port is the server's port; 587 when zero.
	Port int
	// Username and Password sign in to the server; an empty Username
	// sends without signing in.
	Username string
	Password string
	// From is the sender's address, such as "Site <noreply@example.com>".
	From string
	// Timeout bounds the whole conversation with the server, from dialling
	// to QUIT. Zero uses DefaultSMTPTimeout.
	Timeout time.Duration
}

SMTP sends through a mail server, with PLAIN authentication when Username is set. STARTTLS is used when the server offers it (ports 587 and 25); implicit TLS on port 465 is not supported.

Send stops when its context ends or after Timeout, whichever comes first, so a slow or hanging mail server cannot hold the caller indefinitely.

func (SMTP) Describe

func (s SMTP) Describe() string

Describe implements Describer: the server, its port and the From address, without the username and password.

func (SMTP) Send

func (s SMTP) Send(ctx context.Context, message Message) error

Send implements Sender: it delivers message to every recipient in one conversation with the server, from the From address.

type Sender

type Sender interface {
	Send(ctx context.Context, message Message) error
}

Sender delivers messages.

Jump to

Keyboard shortcuts

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