webhook

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2026 License: GPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

Package webhook provides webhook event dispatching and delivery.

Index

Constants

View Source
const (
	MaxAttempts    = 5                // Maximum number of delivery attempts
	InitialBackoff = 1 * time.Minute  // Initial backoff delay
	MaxBackoff     = 24 * time.Hour   // Maximum backoff delay
	RequestTimeout = 30 * time.Second // HTTP request timeout
	MaxResponseLen = 10 * 1024        // Maximum response body to store (10KB)
	UserAgent      = "oCMS/1.0"       // User-Agent header value
)

Delivery configuration constants

View Source
const (
	RetryInterval     = 30 * time.Second    // How often to check for pending deliveries
	RetryBatchSize    = 50                  // Max number of pending deliveries to process per batch
	CleanupInterval   = 24 * time.Hour      // How often to clean up old deliveries
	DeliveryRetention = 30 * 24 * time.Hour // How long to keep delivered/dead entries (30 days)
)

Retry worker configuration

Variables

This section is empty.

Functions

func ConfigureAllowedHosts added in v0.10.0

func ConfigureAllowedHosts(raw string) error

ConfigureAllowedHosts parses and stores webhook destination host allowlist.

func DestinationHost added in v0.10.0

func DestinationHost(rawURL string) (string, error)

DestinationHost returns normalized destination hostname for a webhook URL.

func GenerateSignature

func GenerateSignature(payload []byte, secret string) string

GenerateSignature generates an HMAC-SHA256 signature for the payload.

func ParseAllowedHosts added in v0.10.0

func ParseAllowedHosts(raw string) (map[string]struct{}, error)

ParseAllowedHosts parses comma-separated exact webhook destination hosts.

func SetRequireAllowedHosts added in v0.10.0

func SetRequireAllowedHosts(required bool)

SetRequireAllowedHosts configures whether webhook destination host allowlist must be configured and enforced.

func ValidateDestinationHostPolicy added in v0.10.0

func ValidateDestinationHostPolicy(rawURL string, allowedHosts map[string]struct{}, requireAllowedHosts bool) error

ValidateDestinationHostPolicy validates webhook destination hostname against the configured allowlist policy.

func ValidateDestinationURL added in v0.10.0

func ValidateDestinationURL(rawURL string) error

ValidateDestinationURL validates webhook destination URL against SSRF and destination host policies currently configured for the process.

func ValidateDestinationURLWithPolicy added in v0.10.0

func ValidateDestinationURLWithPolicy(rawURL string, allowedHosts map[string]struct{}, requireAllowedHosts bool) error

ValidateDestinationURLWithPolicy validates webhook destination URL using explicit host allowlist policy values.

func VerifySignature

func VerifySignature(payload []byte, signature, secret string) bool

VerifySignature verifies an HMAC-SHA256 signature.

Types

type Config

type Config struct {
	Workers        int            // Number of concurrent delivery workers
	EnableDebounce bool           // Enable event debouncing
	Debounce       DebounceConfig // Debounce configuration
}

Config holds dispatcher configuration.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns default dispatcher configuration.

type DebounceConfig

type DebounceConfig struct {
	// Interval is the debounce window duration.
	// Events within this window will be coalesced into a single event.
	Interval time.Duration
	// MaxWait is the maximum time to wait before dispatching.
	// Even if events keep coming, dispatch after this time.
	MaxWait time.Duration
}

DebounceConfig holds debouncer configuration.

func DefaultDebounceConfig

func DefaultDebounceConfig() DebounceConfig

DefaultDebounceConfig returns default debounce configuration.

type Debouncer

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

Debouncer coalesces rapid-fire events into single deliveries. This is useful when the same entity (e.g., page) is updated multiple times in quick succession - we only want to send one webhook notification.

func NewDebouncer

func NewDebouncer(dispatcher *Dispatcher, config DebounceConfig) *Debouncer

NewDebouncer creates a new event debouncer.

func (*Debouncer) Dispatch

func (d *Debouncer) Dispatch(_ context.Context, event *Event) error

Dispatch queues an event for debounced delivery. If an event for the same entity is already pending, it will be updated with the latest data and the timer will be reset.

func (*Debouncer) DispatchEvent

func (d *Debouncer) DispatchEvent(ctx context.Context, eventType string, data any) error

DispatchEvent is a convenience method to dispatch an event with debouncing.

func (*Debouncer) Flush

func (d *Debouncer) Flush()

Flush immediately dispatches all pending events. This is useful during shutdown to ensure no events are lost.

func (*Debouncer) PendingCount

func (d *Debouncer) PendingCount() int

PendingCount returns the number of pending events.

func (*Debouncer) Stop

func (d *Debouncer) Stop()

Stop stops the debouncer and flushes all pending events.

type DeliveryResult

type DeliveryResult struct {
	Success      bool
	StatusCode   int
	ResponseBody string
	Error        error
	ShouldRetry  bool
}

DeliveryResult represents the result of a delivery attempt.

type Dispatcher

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

Dispatcher handles webhook event dispatching and queuing.

func NewDispatcher

func NewDispatcher(db *sql.DB, logger *slog.Logger, cfg Config) *Dispatcher

NewDispatcher creates a new webhook dispatcher.

func (*Dispatcher) DebounceStats

func (d *Dispatcher) DebounceStats() (pending int, enabled bool)

DebounceStats returns debounce statistics if debouncing is enabled.

func (*Dispatcher) Dispatch

func (d *Dispatcher) Dispatch(ctx context.Context, event *Event) error

Dispatch dispatches an event to all subscribed webhooks.

func (*Dispatcher) DispatchEvent

func (d *Dispatcher) DispatchEvent(ctx context.Context, eventType string, data any) error

DispatchEvent is a convenience method to dispatch an event with the given type and data. If debouncing is enabled, events will be debounced; otherwise, they are dispatched immediately.

func (*Dispatcher) DispatchImmediate

func (d *Dispatcher) DispatchImmediate(ctx context.Context, eventType string, data any) error

DispatchImmediate dispatches an event immediately, bypassing debouncing. Use this for events that should never be debounced (e.g., delete events).

func (*Dispatcher) Start

func (d *Dispatcher) Start(ctx context.Context)

Start starts the dispatcher workers.

func (*Dispatcher) Stop

func (d *Dispatcher) Stop()

Stop stops the dispatcher and waits for workers to finish.

type Event

type Event struct {
	Type      string    `json:"type"`
	Timestamp time.Time `json:"timestamp"`
	Data      any       `json:"data"`
}

Event represents a webhook event to be dispatched.

func NewEvent

func NewEvent(eventType string, data any) *Event

NewEvent creates a new webhook event.

type FormEventData

type FormEventData struct {
	FormID       int64             `json:"form_id"`
	FormName     string            `json:"form_name"`
	FormSlug     string            `json:"form_slug"`
	SubmissionID int64             `json:"submission_id"`
	Data         map[string]string `json:"data,omitempty"`
	DataMode     string            `json:"data_mode,omitempty"`
	SubmittedAt  time.Time         `json:"submitted_at"`
}

FormEventData contains data for form submission events.

type MediaEventData

type MediaEventData struct {
	ID         int64  `json:"id"`
	UUID       string `json:"uuid"`
	Filename   string `json:"filename"`
	MimeType   string `json:"mime_type"`
	Size       int64  `json:"size"`
	UploaderID int64  `json:"uploader_id"`
}

MediaEventData contains data for media-related events.

type PageEventData

type PageEventData struct {
	ID           int64   `json:"id"`
	Title        string  `json:"title"`
	Slug         string  `json:"slug"`
	Status       string  `json:"status"`
	AuthorID     int64   `json:"author_id"`
	AuthorEmail  string  `json:"author_email,omitempty"`
	LanguageCode *string `json:"language_code,omitempty"`
	PublishedAt  *string `json:"published_at,omitempty"`
}

PageEventData contains data for page-related events.

type QueuedDelivery

type QueuedDelivery struct {
	DeliveryID int64
	WebhookID  int64
	Event      string
	Payload    []byte
	URL        string
	Secret     string
	Headers    map[string]string
}

QueuedDelivery represents a delivery queued for processing.

type TestEventData

type TestEventData struct {
	Message   string    `json:"message"`
	Timestamp time.Time `json:"timestamp"`
}

TestEventData contains data for test webhook events.

type UserEventData

type UserEventData struct {
	ID    int64  `json:"id"`
	Email string `json:"email"`
	Name  string `json:"name"`
	Role  string `json:"role"`
}

UserEventData contains data for user-related events.

Jump to

Keyboard shortcuts

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