Documentation
¶
Overview ¶
Package mail sends email. A Mailable describes one email (envelope and content); a Mailer renders it and hands the Message to a Transport: SMTP, Resend, log (development) or Array (tests).
type Welcome struct{ User models.User }
func (m Welcome) Envelope() mail.Envelope {
return mail.Envelope{To: []string{m.User.Email}, Subject: "Welcome!"}
}
func (m Welcome) Content() mail.Content { return mail.View("mail/welcome", m) }
err := app.Mailer().Send(ctx, Welcome{User: u})
The app builds its Mailer from MAIL_* variables; Preview renders mailables in the browser during development.
See https://github.com/AlexGalhardo/vukem/blob/main/docs/subsystems.md#mail.
Example ¶
package main
import (
"context"
"fmt"
"github.com/AlexGalhardo/vukem/mail"
)
type Welcome struct{ Email string }
func (m Welcome) Envelope() mail.Envelope {
return mail.Envelope{To: []string{m.Email}, Subject: "Welcome!"}
}
func (m Welcome) Content() mail.Content { return mail.Text("Thanks for signing up.") }
func main() {
// Array keeps messages in memory (tests); apps configure SMTP or
// Resend through MAIL_* variables.
sent := mail.NewArray()
m := mail.New(sent, "Shop <hello@shop.test>", nil)
if err := m.Send(context.Background(), Welcome{Email: "ada@example.com"}); err != nil {
fmt.Println(err)
return
}
msgs := sent.SentTo("ada@example.com")
for i := range msgs {
fmt.Println(msgs[i].From, "|", msgs[i].Subject, "|", msgs[i].Text)
}
}
Output: "Shop" <hello@shop.test> | Welcome! | Thanks for signing up.
Index ¶
- Variables
- func Build(msg *Message) ([]byte, error)
- func Preview(m *Mailer, mailables map[string]Mailable) http.Handler
- type Array
- type Attachable
- type Attachment
- type Content
- type Envelope
- type Log
- type Mailable
- type Mailer
- type Message
- type Resend
- type ResendConfig
- type ResendError
- type SMTP
- type SMTPConfig
- type Transport
- type WithAttachmentsdeprecated
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNoRecipients = errors.New("mail: no recipients")
ErrNoRecipients is returned for messages without To, Cc or Bcc.
Functions ¶
func Build ¶
Build renders msg as RFC 5322 bytes: multipart/mixed (attachments) over multipart/related (inline parts) over multipart/alternative (text, HTML). Bcc is never written as a header.
func Preview ¶
Preview serves rendered mailables for development: the index lists names, "<name>" shows the HTML part and "<name>?text=1" the text part. Mount it only outside production:
if !app.Config.IsProduction() {
r.Handle("/_mail/", http.StripPrefix("/_mail/", mail.Preview(mailer, map[string]mail.Mailable{...})))
}
Types ¶
type Array ¶
type Array struct {
// contains filtered or unexported fields
}
Array keeps sent messages in memory (tests; vukemtest uses it).
type Attachable ¶ added in v0.21.0
type Attachable interface {
Attachments() []Attachment
}
Attachable is implemented by mailables that attach files.
type Attachment ¶
type Attachment struct {
Filename string
ContentType string
Data []byte
Inline bool
ContentID string
}
Attachment is a file sent with the message; Inline parts are referenced from HTML as cid:<ContentID>.
type Content ¶
type Content struct {
// contains filtered or unexported fields
}
Content is the body: a view (rendered by the Mailer) or literal parts.
type Envelope ¶
type Envelope struct {
From string
To []string
Cc []string
Bcc []string
ReplyTo []string
Subject string
// Tags are provider metadata (Resend tags; X-Tag headers over SMTP).
Tags map[string]string
}
Envelope holds addresses and headers. Addresses accept "Name <a@b.c>".
type Log ¶
Log writes messages to a logger instead of sending them (development). Bodies are logged at debug level only.
type Mailer ¶
type Mailer struct {
// contains filtered or unexported fields
}
Mailer renders mailables and sends them.
func New ¶
New returns a Mailer sending from the default from address through t. views renders View contents (the app's view engine); it may be nil when only literal contents are used.
type Message ¶
type Message struct {
// ID identifies the message (Message-ID, Resend idempotency key).
ID string
From string
To []string
Cc []string
Bcc []string
ReplyTo []string
Subject string
HTML string
Text string
Attachments []Attachment
Tags map[string]string
}
Message is a rendered email ready for a Transport.
type Resend ¶
type Resend struct {
// contains filtered or unexported fields
}
Resend sends through the Resend HTTP API. The message ID is the Idempotency-Key, so retries never send twice.
type ResendConfig ¶
type ResendConfig struct {
APIKey config.Secret
// BaseURL defaults to https://api.resend.com (tests use a fake).
BaseURL string
// HTTP is the client (10s timeout by default).
HTTP *http.Client
// MaxRetries for 429 and 5xx responses (default 2).
MaxRetries int
// MaxBackoff caps waits between retries, including Retry-After (default 5s).
MaxBackoff time.Duration
}
ResendConfig configures the Resend transport (https://resend.com).
type ResendError ¶
ResendError is an error answered by the Resend API. It never contains the API key.
func (*ResendError) Error ¶
func (e *ResendError) Error() string
func (*ResendError) Retryable ¶
func (e *ResendError) Retryable() bool
Retryable reports whether the request may succeed later.
type SMTP ¶
type SMTP struct {
// contains filtered or unexported fields
}
SMTP sends through an SMTP server with STARTTLS (or implicit TLS on 465).
type SMTPConfig ¶
type SMTPConfig struct {
Host string
Port int // 587 (STARTTLS, default) or 465 (implicit TLS)
Username string
Password config.Secret
// InsecureSkipTLS sends without TLS (local catchers such as Mailpit
// only); by default STARTTLS is required.
InsecureSkipTLS bool
// Timeout bounds dialing and the whole exchange (default 30s).
Timeout time.Duration
// TLSConfig overrides the TLS settings (tests).
TLSConfig *tls.Config
}
SMTPConfig configures the SMTP transport.
type WithAttachments
deprecated
type WithAttachments = Attachable
WithAttachments is the pre-1.0 name of Attachable; With* names are reserved for options.
Deprecated: use Attachable.