ntfy

package
v1.1.4 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 10 Imported by: 0

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

View Source
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

func New(opts Options) *Client

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

func (c *Client) IsNoop() bool

IsNoop reports whether this client is a configured-out noop (empty server or topic). Useful for `budgetclaw alerts status` output.

func (*Client) Send

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

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

func (c *Client) SendKill(ctx context.Context, title, body string) error

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.

func (*Client) SendWarn

func (c *Client) SendWarn(ctx context.Context, title, body string) error

SendWarn is a convenience wrapper that sets priority=high and adds a "warning" tag. Use for Action=warn verdicts.

func (*Client) Test

func (c *Client) Test(ctx context.Context) error

Test sends a diagnostic message with default priority so the user can verify end-to-end delivery. Wired to `budgetclaw alerts test`.

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.

Jump to

Keyboard shortcuts

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