notify

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package notify delivers panel events to the outside world.

The panel already recorded everything worth knowing in its event log, but a log only helps someone who is already looking. A node going offline at 3am, a subscriber hitting their quota, a server payment coming due — those are worth pushing rather than waiting to be read.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TelegramText

func TelegramText(e domain.Event) string

TelegramText renders an event as the message a human reads on their phone.

func ValidateWebhookURL

func ValidateWebhookURL(raw string) error

ValidateWebhookURL rejects destinations a panel should never be talked into calling. The URL is operator-supplied, but an operator is not the only person who can end up owning an admin session, and a panel that will POST to any address is a request forgery primitive pointed at its own private network.

Types

type Dispatcher

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

Dispatcher fans events out to every channel subscribed to them.

Delivery is deliberately decoupled from whatever produced the event: an admin clicking "disable user" must not wait on someone's webhook endpoint, and a dead endpoint must not turn into a failed API request. Events go onto a buffered queue and a worker drains it.

func New

func New(store Store, log *slog.Logger) *Dispatcher

New starts a dispatcher. Call Close to drain and stop it.

func (*Dispatcher) Close

func (d *Dispatcher) Close()

func (*Dispatcher) Publish

func (d *Dispatcher) Publish(e domain.Event)

Publish queues an event. It never blocks: a panel that stalls because a notification queue is full is a worse outcome than a dropped notification, so a full queue drops and says so.

func (*Dispatcher) Test

Test delivers one event to one channel and reports the outcome, bypassing both the queue and the channel's event subscription. An operator setting a webhook up needs the answer now, not the next time something happens to break — and they explicitly asked for this delivery, so the subscription filter would only get in the way.

It records the attempt like any other, so a failed test is visible in the delivery log alongside real traffic.

type Store

type Store interface {
	EnabledChannels(ctx context.Context) ([]domain.NotificationChannel, error)
	RecordDelivery(ctx context.Context, d domain.NotificationDelivery) error
}

Store is the slice of persistence the dispatcher needs.

type WebhookPayload

type WebhookPayload struct {
	Event     domain.EventKind `json:"event"`
	Actor     string           `json:"actor,omitempty"`
	Subject   string           `json:"subject,omitempty"`
	Message   string           `json:"message,omitempty"`
	Meta      json.RawMessage  `json:"meta,omitempty"`
	Timestamp time.Time        `json:"timestamp"`
	Panel     string           `json:"panel"`
}

WebhookPayload is the JSON body posted to a webhook endpoint. It is a stable shape on purpose: receivers switch on `event` and read `subject`, and adding fields must not move the ones they already read.

Jump to

Keyboard shortcuts

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