Documentation
¶
Overview ¶
Package ntfy is a minimal client for ntfy.sh-compatible push notification servers. It is used by the budgetclaw watcher to deliver phone alerts when a budget cap is warned or killed.
The client talks to ntfy's header-style HTTP API:
POST https://<server>/<topic> Title: Budget breach Priority: 4 Tags: warning,money Click: https://roninforge.org/budgetclaw Body: myapp/main hit $5.10 daily cap
On 2xx the call succeeds. On 4xx it fails immediately (client error: bad topic, bad server, bad headers — no point retrying). On 5xx or network errors it retries with exponential backoff up to MaxRetries times. Context cancellation aborts mid-retry.
A Client with an empty Server or Topic becomes a "noop" client whose Send method silently returns nil. That lets the watcher always call ntfy.Send regardless of whether the user has configured alerts — no nil checks required at call sites.
Index ¶
Constants ¶
const ( PriorityMin = 1 PriorityLow = 2 PriorityDefault = 3 PriorityHigh = 4 PriorityMax = 5 )
Priority levels match ntfy's scale: 1=min, 3=default, 5=max.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client sends push notifications to a ntfy server.
func New ¶
New constructs a Client from Options. If Server or Topic is empty, New returns a noop client whose Send is a silent no-op. This makes the "ntfy not configured" path a first-class zero value rather than a nil-check at every call site.
func (*Client) IsNoop ¶
IsNoop reports whether this client is a configured-out noop (empty server or topic). Useful for `budgetclaw alerts status` output.
func (*Client) Send ¶
Send delivers a single notification. Returns nil on success, a non-nil error on irrecoverable failure, or ctx.Err() if the context is canceled mid-retry.
A nil *Client is treated as a noop so callers who keep an optional client in a struct field don't need to nil-check.
func (*Client) SendKill ¶
SendKill is a convenience wrapper that sets priority=max and tags the message as destructive. Use for Action=kill verdicts. The higher priority means iOS and Android will bypass Do Not Disturb for urgent breach notifications.
type Message ¶
type Message struct {
// Title is the notification headline (H1 on the phone).
Title string
// Message is the body text. Required.
Message string
// Priority is the ntfy priority level (1-5). Zero means "use
// the server default" — no header sent.
Priority int
// Tags are shown as emoji on the notification. See
// https://docs.ntfy.sh/emojis/ for the full list.
Tags []string
// Click is a URL the phone opens when the notification is
// tapped. Empty string means no action.
Click string
}
Message is one push notification. Title, Priority, Tags, and Click are optional; Message is the only required field.
type Options ¶
type Options struct {
// Server is the base URL of the ntfy server, e.g.
// "https://ntfy.sh" or "https://push.roninforge.org".
Server string
// Topic is the ntfy topic name. Treated as a shared secret:
// anyone who knows the topic can subscribe and publish.
Topic string
// HTTPClient lets tests inject a custom transport. Defaults
// to &http.Client{Timeout: 15*time.Second}.
HTTPClient *http.Client
// MaxRetries is the number of retry attempts on 5xx or
// network errors. 0 means "no retry" (still one initial
// attempt). Defaults to 3 (so up to 4 total attempts).
MaxRetries int
// BackoffFunc computes the sleep duration between retries.
// Defaults to exponential: 500ms, 1s, 2s, ... capped at 10s.
// Tests can pass a zero-duration function to skip the waits.
BackoffFunc func(attempt int) time.Duration
}
Options configures a Client. Server and Topic are the only required fields. The rest have sensible defaults.