notify

package
v0.260412.1600-preview Latest Latest
Warning

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

Go to latest
Published: Apr 12, 2026 License: MPL-2.0 Imports: 5 Imported by: 0

README

Notify Package

A unified notification system for Go applications that supports multiple notification providers with a clean, consistent API.

Features

  • Unified Interface: Single API for sending notifications to multiple channels
  • Multiple Providers: Webhook, Slack, Discord, Email, and System notifications
  • Concurrent Delivery: Send to multiple providers simultaneously
  • Provider Filtering: Send to specific providers or all configured providers
  • Notification Levels: Debug, Info, Warning, Error, Critical
  • Rich Content: Support for titles, messages, links, images, metadata, and tags
  • Extensible: Easy to add custom providers

Installation

go get github.com/tingly-dev/tingly-box/pkg/notify

Quick Start

package main

import (
    "context"
    "github.com/tingly-dev/tingly-box/pkg/notify"
    "github.com/tingly-dev/tingly-box/pkg/notify/provider/webhook"
    "github.com/tingly-dev/tingly-box/pkg/notify/provider/slack"
)

func main() {
    ctx := context.Background()

    // Create multiplexer
    notifier := notify.NewMultiplexer()

    // Add providers
    notifier.AddProvider(webhook.New("https://hooks.example.com/notify"))
    notifier.AddProvider(slack.New(slack.Config{
        Token:   "xoxb-your-token",
        Channel: "#alerts",
    }))

    // Send notification
    results, err := notifier.Send(ctx, &notify.Notification{
        Title:   "Deployment Complete",
        Message: "App v1.2.3 deployed successfully",
        Level:   notify.LevelInfo,
        Tags:    []string{"deployment", "production"},
    })

    // Check results
    for _, r := range results {
        if r.Success {
            println(r.Provider, "sent successfully")
        } else {
            println(r.Provider, "failed:", r.Error.Error())
        }
    }
}

Notification Structure

type Notification struct {
    Title        string                 // Notification title/subject
    Message      string                 // Main content (required)
    Level        Level                  // debug, info, warning, error, critical
    Category     string                 // For grouping related notifications
    Tags         []string               // For filtering and routing
    Timestamp    time.Time              // Defaults to now
    Metadata     map[string]interface{} // Additional context
    Links        []Link                 // Clickable links
    ImageURL     string                 // Image to include
    ProviderData map[string]interface{} // Provider-specific overrides
}

type Link struct {
    Text string
    URL  string
}

Providers

Webhook

Send HTTP POST requests with JSON payload.

import "github.com/tingly-dev/tingly-box/pkg/notify/provider/webhook"

provider := webhook.New(
    "https://hooks.example.com/notify",
    webhook.WithName("my-webhook"),
    webhook.WithHeaders(map[string]string{
        "X-Custom-Header": "value",
    }),
    webhook.WithAuth("Bearer token"),
    webhook.WithTimeout(30 * time.Second),
)
Slack

Send messages to Slack channels via the Chat API.

import "github.com/tingly-dev/tingly-box/pkg/notify/provider/slack"

provider := slack.New(slack.Config{
    Token:     "xoxb-your-bot-token",
    Channel:   "#alerts",
    Username:  "Alert Bot",
    IconEmoji: ":robot_face:",
})

Metadata overrides:

  • channel: Override the default channel
Discord

Send messages via Discord webhooks.

import "github.com/tingly-dev/tingly-box/pkg/notify/provider/discord"

provider := discord.New(discord.Config{
    WebhookURL: "https://discord.com/api/webhooks/xxx/yyy",
    Username:   "Alert Bot",
    AvatarURL:  "https://example.com/avatar.png",
})
Email

Send emails via SMTP.

import "github.com/tingly-dev/tingly-box/pkg/notify/provider/email"

provider := email.New(email.Config{
    Host:     "smtp.gmail.com:587",
    Username: "alerts@example.com",
    Password: "app-password",
    From:     "alerts@example.com",
    To:       []string{"team@example.com"},
    UseTLS:   true,
})

Metadata overrides:

  • to: Override recipient list
System

Send desktop notifications (macOS, Linux, Windows).

import "github.com/tingly-dev/tingly-box/pkg/notify/provider/system"

if system.IsSupported() {
    provider := system.New(system.Config{
        AppName: "MyApp",
        Sound:   "default",
    })
}

Multiplexer

The multiplexer sends notifications to multiple providers concurrently.

// Create with options
notifier := notify.NewMultiplexer(
    notify.WithMinLevel(notify.LevelInfo), // Filter out debug messages
)

// Add providers
notifier.AddProvider(webhookProvider)
notifier.AddProvider(slackProvider)

// Send to all providers
results, err := notifier.Send(ctx, notification)

// Send to specific provider
result, err := notifier.SendTo(ctx, "slack", notification)

// Manage providers
notifier.RemoveProvider("webhook")
provider := notifier.GetProvider("slack")
names := notifier.ListProviders()

// Cleanup
notifier.Close()

Notification Levels

notify.LevelDebug    // Debug information, filtered by default
notify.LevelInfo     // General information
notify.LevelWarning  // Warning conditions
notify.LevelError    // Error conditions
notify.LevelCritical // Critical failures

Filter by minimum level:

notifier := notify.NewMultiplexer(
    notify.WithMinLevel(notify.LevelWarning),
)

Error Handling

results, err := notifier.Send(ctx, notification)

// err indicates if ANY provider failed
if err != nil {
    log.Printf("Some providers failed: %v", err)
}

// Check individual results
for _, result := range results {
    if result.Success {
        log.Printf("%s sent successfully (latency: %v)",
            result.Provider, result.Latency)
    } else {
        log.Printf("%s failed: %v", result.Provider, result.Error)
    }
}

Custom Providers

Implement the Provider interface:

type Provider interface {
    Name() string
    Send(ctx context.Context, notification *Notification) (*Result, error)
    Close() error
}

Example custom provider:

type CustomProvider struct {
    name string
    // your fields
}

func (p *CustomProvider) Name() string {
    return p.name
}

func (p *CustomProvider) Send(ctx context.Context, n *notify.Notification) (*notify.Result, error) {
    // your implementation
    return &notify.Result{Provider: p.name, Success: true}, nil
}

func (p *CustomProvider) Close() error {
    return nil
}

Examples

See examples/main.go for complete usage examples including:

  • Basic notifications
  • Warning and error notifications
  • Notifications with links and metadata
  • Provider-specific sending
  • Level filtering
  • Builder pattern for fluent notification creation

License

MIT

Documentation

Overview

Package notify provides a unified notification system for sending messages to various channels like webhooks, Slack, Discord, email, and system notifications.

Basic usage:

// Create a notifier
notifier := notify.NewMultiplexer()

// Add providers
notifier.AddProvider(webhook.New("https://hooks.example.com/notify"))
notifier.AddProvider(slack.New(slack.Config{Token: "xoxb-...", Channel: "#alerts"}))

// Send notification
err := notifier.Send(context.Background(), &notify.Notification{
	Title:   "Deployment Complete",
	Message: "App v1.2.3 deployed successfully",
	Level:   notify.LevelInfo,
})

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrProviderNotFound is returned when a provider is not found
	ErrProviderNotFound = errors.New("provider not found")
	// ErrSendFailed is returned when sending a notification fails
	ErrSendFailed = errors.New("failed to send notification")
)

Error types

Functions

func FormatError

func FormatError(provider string, err error) error

FormatError formats an error with provider context

func IsLevelAtLeast

func IsLevelAtLeast(level, min Level) bool

IsLevelAtLeast checks if a level is at least as severe as another

Types

type Level

type Level string

Level represents the severity level of a notification

const (
	LevelDebug    Level = "debug"
	LevelInfo     Level = "info"
	LevelWarning  Level = "warning"
	LevelError    Level = "error"
	LevelCritical Level = "critical"
)

Notification levels

func (Level) String

func (l Level) String() string

String returns the string representation of the level

type Link struct {
	Text string `json:"text"`
	URL  string `json:"url"`
}

Link represents a clickable link in a notification

type Multiplexer

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

Multiplexer sends notifications to multiple providers

func NewMultiplexer

func NewMultiplexer(opts ...MultiplexerOption) *Multiplexer

NewMultiplexer creates a new notification multiplexer

func (*Multiplexer) AddProvider

func (m *Multiplexer) AddProvider(provider Provider)

AddProvider adds a notification provider

func (*Multiplexer) AddProviderWithConfig

func (m *Multiplexer) AddProviderWithConfig(provider Provider, config *ProviderConfig)

AddProviderWithConfig adds a notification provider with specific configuration

func (*Multiplexer) Close

func (m *Multiplexer) Close() error

Close closes all providers

func (*Multiplexer) GetProvider

func (m *Multiplexer) GetProvider(name string) Provider

GetProvider returns a provider by name

func (*Multiplexer) ListProviders

func (m *Multiplexer) ListProviders() []string

ListProviders returns all registered provider names

func (*Multiplexer) RemoveProvider

func (m *Multiplexer) RemoveProvider(name string) bool

RemoveProvider removes a provider by name

func (*Multiplexer) Send

func (m *Multiplexer) Send(ctx context.Context, notification *Notification) ([]*Result, error)

Send sends a notification to all configured providers concurrently

func (*Multiplexer) SendTo

func (m *Multiplexer) SendTo(ctx context.Context, providerName string, notification *Notification) (*Result, error)

SendTo sends a notification to a specific provider

func (*Multiplexer) SetProviderConfig

func (m *Multiplexer) SetProviderConfig(name string, config ProviderConfig)

SetProviderConfig sets configuration for a provider

type MultiplexerOption

type MultiplexerOption func(*Multiplexer)

MultiplexerOption configures a Multiplexer

func WithDefaultRetry

func WithDefaultRetry(count int) MultiplexerOption

WithDefaultRetry sets the default retry count for all providers

func WithMinLevel

func WithMinLevel(level Level) MultiplexerOption

WithMinLevel sets the minimum notification level to send

type Notification

type Notification struct {
	// Title is the notification title/subject
	Title string `json:"title,omitempty"`
	// Message is the main notification content
	Message string `json:"message"`
	// Level indicates the severity (debug, info, warning, error, critical)
	Level Level `json:"level,omitempty"`
	// Category for grouping related notifications
	Category string `json:"category,omitempty"`
	// Tags for filtering and routing
	Tags []string `json:"tags,omitempty"`
	// Timestamp of the notification (defaults to now if not set)
	Timestamp time.Time `json:"timestamp,omitempty"`
	// Metadata for additional context
	Metadata map[string]interface{} `json:"metadata,omitempty"`
	// Links to include in the notification
	Links []Link `json:"links,omitempty"`
	// Image URL to include (supported by some providers)
	ImageURL string `json:"image_url,omitempty"`
	// Provider-specific overrides
	ProviderData map[string]interface{} `json:"provider_data,omitempty"`
}

Notification represents a notification message to be sent

func (*Notification) Validate

func (n *Notification) Validate() error

Validate checks if the notification is valid

type Notifier

type Notifier interface {
	// Send sends a notification to all configured providers
	Send(ctx context.Context, notification *Notification) ([]*Result, error)
	// SendTo sends a notification to a specific provider by name
	SendTo(ctx context.Context, providerName string, notification *Notification) (*Result, error)
	// AddProvider adds a notification provider
	AddProvider(provider Provider)
	// RemoveProvider removes a provider by name
	RemoveProvider(name string) bool
	// GetProvider returns a provider by name
	GetProvider(name string) Provider
	// ListProviders returns all registered provider names
	ListProviders() []string
}

Notifier defines the interface for sending notifications

type Provider

type Provider interface {
	// Name returns the provider name
	Name() string
	// Send sends a notification
	Send(ctx context.Context, notification *Notification) (*Result, error)
	// Close cleans up provider resources
	Close() error
}

Provider defines the interface for notification providers

type ProviderConfig

type ProviderConfig struct {
	// Name overrides the default provider name
	Name string `json:"name,omitempty"`
	// Enabled controls whether the provider is active
	Enabled bool `json:"enabled"`
	// Timeout for send operations (default: 30 seconds)
	Timeout time.Duration `json:"timeout,omitempty"`
	// RetryCount for failed sends (default: 0, no retry)
	RetryCount int `json:"retry_count,omitempty"`
	// RetryDelay between retries (default: 1 second)
	RetryDelay time.Duration `json:"retry_delay,omitempty"`
}

ProviderConfig holds common provider configuration

type Result

type Result struct {
	// Provider that sent the notification
	Provider string `json:"provider"`
	// Success indicates if the send was successful
	Success bool `json:"success"`
	// MessageID returned by the provider (if applicable)
	MessageID string `json:"message_id,omitempty"`
	// Error if the send failed
	Error error `json:"error,omitempty"`
	// Latency for the send operation
	Latency time.Duration `json:"latency,omitempty"`
	// Raw response from provider (for debugging)
	Raw interface{} `json:"raw,omitempty"`
}

Result represents the result of sending a notification

Directories

Path Synopsis
Example demonstrating the notification system usage
Example demonstrating the notification system usage
provider
discord
Package discord provides a Discord notification provider
Package discord provides a Discord notification provider
email
Package email provides an SMTP email notification provider
Package email provides an SMTP email notification provider
slack
Package slack provides a Slack notification provider
Package slack provides a Slack notification provider
system
Package system provides desktop system notification provider using beeep
Package system provides desktop system notification provider using beeep
webhook
Package webhook provides an HTTP webhook notification provider
Package webhook provides an HTTP webhook notification provider

Jump to

Keyboard shortcuts

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