Documentation
¶
Overview ¶
Package tracking mints and verifies the per-message tokens used by the email open/click/unsubscribe endpoints, and rewrites an email's HTML to route links through the click tracker and embed the open pixel + unsubscribe footer. An open or click token names the Outbound message (ADR 0053), whatever surface sent it.
Tokens are signed JWTs (HS256) — we reuse the existing JWT secret rather than hand-rolling a MAC. Link rewriting uses the official x/net/html tokenizer, not regexes, so arbitrary author markup round-trips safely.
Index ¶
- func IsExpired(err error) bool
- type ConfirmTarget
- type Tracker
- func (t *Tracker) ClickURL(messageID int64, dest string) (string, error)
- func (t *Tracker) ConfirmURL(target ConfirmTarget) (string, error)
- func (t *Tracker) Decode(token string) (int64, error)
- func (t *Tracker) DecodeClick(token string) (messageID int64, destination string, err error)
- func (t *Tracker) DecodeConfirm(token string) (ConfirmTarget, error)
- func (t *Tracker) DecodeUnsub(token string) (UnsubTarget, error)
- func (t *Tracker) Instrument(body string, messageID int64) (string, error)
- func (t *Tracker) OnHost(host string) *Tracker
- func (t *Tracker) OpenURL(token string) string
- func (t *Tracker) Origin() string
- func (t *Tracker) Rewrite(body string, messageID int64, unsub UnsubTarget, postalAddress string) (string, error)
- func (t *Tracker) Token(messageID int64) (string, error)
- func (t *Tracker) UnsubscribeFooter(target UnsubTarget, postalAddress string) (string, error)
- func (t *Tracker) UnsubscribeURL(target UnsubTarget) (string, error)
- type UnsubTarget
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type ConfirmTarget ¶
ConfirmTarget is the payload a double-opt-in confirmation link carries (ADR 0013). Like the opt-out, the confirmation is destination-keyed and not source-scoped: confirming an address makes it mailable across sources, so the link records against the destination directly (no contact-row lookup) and survives the contact being deleted between send and click.
type Tracker ¶
type Tracker struct {
// contains filtered or unexported fields
}
Tracker mints recipient tokens and builds tracking URLs against baseURL.
func New ¶
New builds a Tracker. baseURL is the public origin (e.g. https://sphericon.localhost); a trailing slash is trimmed.
func (*Tracker) ClickURL ¶
ClickURL wraps a destination link so a click is recorded before redirecting. The destination travels inside the signed token, never as a bare parameter.
func (*Tracker) ConfirmURL ¶
func (t *Tracker) ConfirmURL(target ConfirmTarget) (string, error)
ConfirmURL is the public double-opt-in link (ADR 0013). Like UnsubscribeURL the GET is safe: it renders the SPA confirmation page, and the confirmation is recorded only when the recipient POSTs back (scanner-safe, deliberate consent).
func (*Tracker) Decode ¶
Decode validates an open token and returns the Outbound message id it carries. A click token carries a destination and is refused: each link kind has its own token.
func (*Tracker) DecodeClick ¶
DecodeClick validates a click token and returns the Outbound message id and the destination it carries. An open token (pixel) has no destination and is refused, as is any destination that is not an absolute http(s) URL.
func (*Tracker) DecodeConfirm ¶
func (t *Tracker) DecodeConfirm(token string) (ConfirmTarget, error)
DecodeConfirm validates a confirmation token and returns its target. It rejects a token whose exp has passed (and requires exp to be present), so an expired link cannot confirm — the endpoint surfaces that as "request a new one".
func (*Tracker) DecodeUnsub ¶
func (t *Tracker) DecodeUnsub(token string) (UnsubTarget, error)
DecodeUnsub validates a scoped-unsubscribe token and returns its target.
func (*Tracker) Instrument ¶
Instrument routes a body's http(s) links through the click tracker (mid token) and appends the open pixel, nothing else: a Transactional send that asks for tracking uses it as is. On a tokenizer error it falls back to the original body plus the pixel, so a send is never blocked by odd markup.
func (*Tracker) OnHost ¶
OnHost returns a Tracker that signs with the same secret but builds every link on https://<host>, the Tracking domain of one message's Sending domain (ADR 0038).
func (*Tracker) Origin ¶
Origin is the public origin the Tracker builds its links on, without a trailing slash.
func (*Tracker) Rewrite ¶
func (t *Tracker) Rewrite(body string, messageID int64, unsub UnsubTarget, postalAddress string) (string, error)
Rewrite prepares a marketing body for one Outbound message: Instrument, plus the unsubscribe footer (scoped to unsub, carrying the workspace's CAN-SPAM postal address).
func (*Tracker) UnsubscribeFooter ¶
func (t *Tracker) UnsubscribeFooter(target UnsubTarget, postalAddress string) (string, error)
UnsubscribeFooter is the email's unsubscribe footer, scoped to target. Shared by the broadcast Rewrite and the automation send step (which appends it directly). postalAddress is the sending workspace's physical address (CAN-SPAM); when non-empty it is escaped and appended below the unsubscribe line (its own newlines become <br>). An empty address renders the footer unchanged — the address is a non-gating nudge, not a send-blocker.
func (*Tracker) UnsubscribeURL ¶
func (t *Tracker) UnsubscribeURL(target UnsubTarget) (string, error)
UnsubscribeURL is the public link that records the scoped opt-out in target.
type UnsubTarget ¶
type UnsubTarget struct {
Source string
Destination string
WorkspaceID int64
ContactID int64
BroadcastID int64
}
UnsubTarget is the self-describing payload an unsubscribe link carries. The opt-out is destination-keyed (ADR 0001), so the link records against the destination directly — no contact-row lookup, and it survives the contact being deleted between send and click. BroadcastID is set only for broadcast sends (for per-broadcast attribution); Source is the sending-source string the opt-out is scoped to ("broadcasts" / "automation:<id>" / "everything").