Help us shape the future of Go! Take the 2026 Go Developer Survey

email

package
v0.36.21 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package email sends transactional mail via the Resend HTTP API.

Rivolt previously had no direct email path — Kratos was the only component that talked to Resend, and it did so via SMTP. The signup-request approval flow needs Rivolt itself to send a one-off "you're in, here's your invite code" mail, so this package wraps Resend's REST endpoint with a tiny client.

HTTP rather than SMTP keeps the dependency surface flat (no STARTTLS dance, no net/smtp) and reuses the same Resend account/sender domain that Kratos already authenticates against.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotConfigured = errors.New("email: client not configured")

ErrNotConfigured is returned by Send when called on a nil Client so admin handlers can branch cleanly ("email not configured — copy the code manually") without a separate has-email check at every site.

Functions

This section is empty.

Types

type Client

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

Client posts to https://api.resend.com/emails.

func New

func New(cfg Config) *Client

New returns a Client, or nil when APIKey/From are empty so the caller can wire the dependency optionally without a separate "disabled" type.

func (*Client) FromAddress added in v0.18.25

func (c *Client) FromAddress() string

FromAddress returns the bare email parsed out of the configured `Name <addr>` From string (e.g. "Rivolt <anton@rivolt.dev>" → "anton@rivolt.dev"). Empty when the client is nil or when the From has no angle-bracketed address. Used by admin notifications so the same env var that gates the verified sender also targets the admin's inbox — no second env var to keep in sync.

func (*Client) Send

func (c *Client) Send(ctx context.Context, m Message) error

Send posts a single message. Returns nil on 2xx; the Resend body is surfaced verbatim in the error otherwise so admin logs can show why.

type Config

type Config struct {
	APIKey  string
	From    string
	Counter Counter // optional; nil is fine
}

Config carries the construction parameters. From must be a verified sender on the Resend account (e.g. "Rivolt <hello@rivolt.dev>").

type Counter added in v0.18.71

type Counter interface {
	IncEmailSend(provider, status string)
}

Counter is the metric-recording surface the Resend client uses without taking a hard dependency on internal/metrics (avoids a package-level import cycle: metrics imports nothing application, application imports metrics from main, email is a leaf). Implementations must be safe for concurrent use.

type Message

type Message struct {
	To      string
	Subject string
	Text    string // plain-text body; rendered as-is
	HTML    string // optional HTML alternative; nil-coalesced to "" if absent
	// Headers are extra message headers passed through Resend's
	// `headers` object (List-Unsubscribe, List-Unsubscribe-Post). Names
	// and values containing CR or LF are dropped so a value can never
	// inject another header.
	Headers map[string]string
	// IdempotencyKey, when set, is sent as Resend's Idempotency-Key
	// header so a retried send of the same message is not delivered
	// twice.
	IdempotencyKey string
}

Message is the shape Resend's /emails endpoint accepts. Only the fields the signup-approval template needs are exposed.

Jump to

Keyboard shortcuts

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