Documentation
¶
Overview ¶
Package tracking mints and verifies the per-recipient tokens used by the email open/click/unsubscribe endpoints, and rewrites a broadcast's HTML to route links through the click tracker and embed the open pixel + unsubscribe footer.
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(recipientID 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) (int64, string, error)
- func (t *Tracker) DecodeConfirm(token string) (ConfirmTarget, error)
- func (t *Tracker) DecodeUnsub(token string) (UnsubTarget, 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, recipientID int64, unsub UnsubTarget, postalAddress string) (string, error)
- func (t *Tracker) Token(recipientID 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 recipient 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 recipient id and the destination it carries. A recipient token (open 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) 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, recipientID int64, unsub UnsubTarget, postalAddress string) (string, error)
Rewrite prepares a broadcast body for a recipient: it routes http(s) links through the click tracker (rid token), appends the open pixel, and adds the unsubscribe footer (scoped to unsub, carrying the workspace's CAN-SPAM postal address). On a tokenizer error it falls back to the original body plus pixel and footer so a send is never blocked by odd markup.
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").