notify

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2025 License: MIT Imports: 9 Imported by: 0

README

notify

A flexible and extensible Go library for sending notifications across multiple platforms including Telegram, Slack, and more.

Go Reference Go Report Card

Features

  • 🚀 Multi-Platform Support: Send notifications to Telegram, Slack, and easily extend to other platforms
  • 🎯 Simple Interface: Clean and intuitive API for sending notifications
  • 📦 Manager Pattern: Centralized management of multiple notification providers
  • Async Broadcasting: Send notifications to multiple platforms concurrently
  • 🔧 Extensible: Implement your own custom notification providers
  • 🎨 Rich Messages: Support for titles, attachments, fields, and formatting
  • Type Safe: Full type safety with Go interfaces
  • 🧪 Well Tested: Comprehensive test coverage

Installation

go get github.com/milano15662/notify

Quick Start

Telegram
package main

import (
    "context"
    "log"
    
    "github.com/milano15662/notify"
)

func main() {
    ctx := context.Background()
    
    // Create a Telegram notifier
    telegram, err := notify.NewTelegramNotifier(notify.TelegramConfig{
        BotToken: "YOUR_BOT_TOKEN",
        ChatID:   "YOUR_CHAT_ID",
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // Send a simple message
    err = telegram.Send(ctx, "Hello from notify! 🚀")
    if err != nil {
        log.Fatal(err)
    }
}
Slack
package main

import (
    "context"
    "log"
    
    "github.com/milano15662/notify"
)

func main() {
    ctx := context.Background()
    
    // Create a Slack notifier
    slack, err := notify.NewSlackNotifier(notify.SlackConfig{
        Token:          "YOUR_SLACK_TOKEN",
        DefaultChannel: "#general",
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // Send a simple message
    err = slack.Send(ctx, "Hello from notify! 🚀")
    if err != nil {
        log.Fatal(err)
    }
}

Usage

Rich Messages

Send messages with titles, priorities, and attachments:

msg := &notify.Message{
    Title:    "System Alert",
    Text:     "Server CPU usage is at 85%",
    Priority: notify.PriorityHigh,
    Attachments: []notify.Attachment{
        {
            Title: "Details",
            Color: "warning",
            Fields: []notify.Field{
                {Title: "Server", Value: "prod-01", Short: true},
                {Title: "Region", Value: "us-east-1", Short: true},
            },
        },
    },
}

err := notifier.SendWithOptions(ctx, msg)
Manager - Multiple Providers

Use the Manager to handle multiple notification providers:

// Create a manager
manager := notify.NewManager()

// Register providers
telegram, _ := notify.NewTelegramNotifier(telegramConfig)
slack, _ := notify.NewSlackNotifier(slackConfig)

manager.Register(telegram)
manager.Register(slack)

// Send to specific provider
manager.Send(ctx, "telegram", "Hello Telegram!")

// Broadcast to all providers (synchronous)
errors := manager.Broadcast(ctx, "Hello everyone!")

// Broadcast asynchronously
resultChan := manager.BroadcastAsync(ctx, "Async broadcast!")
for result := range resultChan {
    if result.Success {
        fmt.Printf("✓ %s: Success\n", result.Provider)
    } else {
        fmt.Printf("✗ %s: %v\n", result.Provider, result.Error)
    }
}
Custom Notifier

Implement your own notification provider:

type EmailNotifier struct {
    smtpServer string
    from       string
    to         string
}

func (e *EmailNotifier) Name() string {
    return "email"
}

func (e *EmailNotifier) Send(ctx context.Context, message string) error {
    // Implement your email sending logic
    return nil
}

func (e *EmailNotifier) SendWithOptions(ctx context.Context, msg *notify.Message) error {
    // Implement rich email sending logic
    return nil
}

// Use it
emailNotifier := &EmailNotifier{
    smtpServer: "smtp.gmail.com:587",
    from:       "bot@example.com",
    to:         "admin@example.com",
}

manager.Register(emailNotifier)

Supported Platforms

Telegram

Features:

  • Simple text messages
  • Markdown/HTML formatting
  • Photo messages
  • Silent notifications (low priority)
  • Custom parse modes

Configuration:

config := notify.TelegramConfig{
    BotToken:   "YOUR_BOT_TOKEN",      // Required
    ChatID:     "YOUR_CHAT_ID",        // Required
    ParseMode:  "Markdown",            // Optional: Markdown, HTML, or empty
    HTTPClient: &http.Client{},        // Optional: Custom HTTP client
}

To get a bot token:

  1. Talk to @BotFather on Telegram
  2. Create a new bot with /newbot
  3. Copy the token

To get your chat ID:

  1. Send a message to your bot
  2. Visit https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
  3. Look for the chat.id field
Slack

Features:

  • Simple text messages
  • Rich messages with blocks
  • Attachments with fields
  • File uploads
  • Custom username and icon

Configuration:

config := notify.SlackConfig{
    Token:          "xoxb-your-token",  // Required (Bot or User token)
    DefaultChannel: "#general",          // Required
    Username:       "NotifyBot",         // Optional
    IconEmoji:      ":robot_face:",      // Optional
}

To get a Slack token:

  1. Go to Slack API
  2. Create a new app or use an existing one
  3. Add the Bot Token Scope: chat:write
  4. Install the app to your workspace
  5. Copy the Bot User OAuth Token

API Reference

Notifier Interface

All notification providers implement this interface:

type Notifier interface {
    Send(ctx context.Context, message string) error
    SendWithOptions(ctx context.Context, msg *Message) error
    Name() string
}
Message Structure
type Message struct {
    Text        string        // Main message content
    Title       string        // Optional title
    Priority    string        // high, normal, low
    Channel     string        // Target channel (provider-specific)
    Attachments []Attachment  // Rich message attachments
    Metadata    map[string]interface{} // Provider-specific data
}
Manager Methods
// Register/Unregister
Register(notifier Notifier) error
Unregister(name string)
Get(name string) (Notifier, bool)
List() []string

// Send to specific provider
Send(ctx context.Context, provider, message string) error
SendWithOptions(ctx context.Context, provider string, msg *Message) error

// Broadcast to all providers
Broadcast(ctx context.Context, message string) []error
BroadcastWithOptions(ctx context.Context, msg *Message) []error
BroadcastAsync(ctx context.Context, message string) <-chan NotificationResult
BroadcastAsyncWithOptions(ctx context.Context, msg *Message) <-chan NotificationResult

Examples

Check out the examples directory for complete working examples:

  • simple - Basic usage of Telegram and Slack
  • manager - Using the Manager for multiple providers
  • custom - Implementing custom notification providers

To run examples:

# Set environment variables
export TELEGRAM_BOT_TOKEN="your_token"
export TELEGRAM_CHAT_ID="your_chat_id"
export SLACK_BOT_TOKEN="your_token"
export SLACK_CHANNEL="#general"

# Run example
cd examples/simple
go run main.go

Error Handling

All errors are wrapped in NotificationError which includes:

  • Provider name
  • Error message
  • Underlying error (if any)
err := notifier.Send(ctx, "Hello")
if err != nil {
    if notifErr, ok := err.(*notify.NotificationError); ok {
        fmt.Printf("Provider: %s\n", notifErr.Provider)
        fmt.Printf("Message: %s\n", notifErr.Message)
        fmt.Printf("Error: %v\n", notifErr.Unwrap())
    }
}

Best Practices

  1. Use Context: Always pass a context with timeout for production use:

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
  2. Environment Variables: Store tokens in environment variables, never in code:

    token := os.Getenv("TELEGRAM_BOT_TOKEN")
    
  3. Error Handling: Always check errors and handle them appropriately:

    if err := notifier.Send(ctx, msg); err != nil {
        log.Printf("Failed to send notification: %v", err)
        // Implement retry logic or fallback
    }
    
  4. Async for Multiple Providers: Use async broadcasting when sending to multiple providers:

    resultChan := manager.BroadcastAsync(ctx, message)
    

Testing

Run tests:

go test -v ./...

Run with coverage:

go test -v -cover ./...

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Adding a New Provider
  1. Implement the Notifier interface
  2. Add configuration struct
  3. Add tests
  4. Update documentation
  5. Add example

License

MIT License - see LICENSE file for details

Roadmap

  • Email provider (SMTP)
  • Discord provider
  • Microsoft Teams provider
  • WhatsApp Business API provider
  • SMS providers (Twilio, AWS SNS)
  • Push notifications (FCM, APNS)
  • Webhook provider
  • Rate limiting
  • Retry logic with exponential backoff
  • Message templates
  • Metrics and monitoring

Support

If you have any questions or need help, please:

  • Open an issue on GitHub
  • Check existing issues for solutions
  • Review the examples directory

Acknowledgments


Made with ❤️ by milano15662

Documentation

Index

Constants

View Source
const (
	PriorityHigh   = "high"
	PriorityNormal = "normal"
	PriorityLow    = "low"
)

Priority constants

Variables

This section is empty.

Functions

This section is empty.

Types

type Attachment

type Attachment struct {
	Title      string
	Text       string
	ImageURL   string
	Color      string
	Fields     []Field
	Footer     string
	FooterIcon string
}

Attachment represents a message attachment

type Field

type Field struct {
	Title string
	Value string
	Short bool
}

Field represents a key-value field in an attachment

type Manager

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

Manager manages multiple notification providers

func NewManager

func NewManager() *Manager

NewManager creates a new notification manager

func (*Manager) Broadcast

func (m *Manager) Broadcast(ctx context.Context, message string) []error

Broadcast sends a message to all registered notifiers

func (*Manager) BroadcastAsync

func (m *Manager) BroadcastAsync(ctx context.Context, message string) <-chan NotificationResult

BroadcastAsync sends a message to all registered notifiers asynchronously

func (*Manager) BroadcastAsyncWithOptions

func (m *Manager) BroadcastAsyncWithOptions(ctx context.Context, msg *Message) <-chan NotificationResult

BroadcastAsyncWithOptions sends a message with options to all registered notifiers asynchronously

func (*Manager) BroadcastWithOptions

func (m *Manager) BroadcastWithOptions(ctx context.Context, msg *Message) []error

BroadcastWithOptions sends a message with options to all registered notifiers

func (*Manager) Get

func (m *Manager) Get(name string) (Notifier, bool)

Get retrieves a notifier by name

func (*Manager) List

func (m *Manager) List() []string

List returns all registered notifier names

func (*Manager) Register

func (m *Manager) Register(notifier Notifier) error

Register adds a notifier to the manager

func (*Manager) Send

func (m *Manager) Send(ctx context.Context, provider, message string) error

Send sends a message to a specific notifier

func (*Manager) SendWithOptions

func (m *Manager) SendWithOptions(ctx context.Context, provider string, msg *Message) error

SendWithOptions sends a message with options to a specific notifier

func (*Manager) Unregister

func (m *Manager) Unregister(name string)

Unregister removes a notifier from the manager

type Message

type Message struct {
	// Text is the main message content
	Text string

	// Title is an optional title for the message
	Title string

	// Priority defines the message priority (high, normal, low)
	Priority string

	// Channel defines the target channel/chat (provider-specific)
	Channel string

	// Attachments for rich messages (provider-specific)
	Attachments []Attachment

	// Metadata for additional provider-specific data
	Metadata map[string]interface{}
}

Message represents a notification message with options

type NotificationError

type NotificationError struct {
	Provider string
	Message  string
	Err      error
}

NotificationError represents an error that occurred during notification

func (*NotificationError) Error

func (e *NotificationError) Error() string

func (*NotificationError) Unwrap

func (e *NotificationError) Unwrap() error

type NotificationResult

type NotificationResult struct {
	Provider string
	Success  bool
	Error    error
}

NotificationResult represents the result of a notification attempt

type Notifier

type Notifier interface {
	// Send sends a simple text message
	Send(ctx context.Context, message string) error

	// SendWithOptions sends a message with additional options
	SendWithOptions(ctx context.Context, msg *Message) error

	// Name returns the name of the notification provider
	Name() string
}

Notifier defines the interface that all notification providers must implement

type SlackConfig

type SlackConfig struct {
	// Token is the Slack Bot or User OAuth token
	Token string

	// DefaultChannel is the default channel to send messages to (e.g., #general or @username)
	DefaultChannel string

	// Username is the bot username (optional)
	Username string

	// IconEmoji is the bot icon emoji (optional, e.g., :robot_face:)
	IconEmoji string

	// WebhookURL for incoming webhooks (alternative to Token)
	WebhookURL string
}

SlackConfig holds configuration for Slack notifications

type SlackNotifier

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

SlackNotifier sends notifications via Slack API

func NewSlackNotifier

func NewSlackNotifier(config SlackConfig) (*SlackNotifier, error)

NewSlackNotifier creates a new Slack notifier

func (*SlackNotifier) GetClient

func (s *SlackNotifier) GetClient() *slack.Client

GetClient returns the underlying Slack client for advanced usage

func (*SlackNotifier) Name

func (s *SlackNotifier) Name() string

Name returns the name of the provider

func (*SlackNotifier) Send

func (s *SlackNotifier) Send(ctx context.Context, message string) error

Send sends a simple text message

func (*SlackNotifier) SendFile

func (s *SlackNotifier) SendFile(ctx context.Context, channel, filePath, title, comment string) error

SendFile uploads a file to Slack

func (*SlackNotifier) SendRichMessage

func (s *SlackNotifier) SendRichMessage(ctx context.Context, channel string, blocks []slack.Block) error

SendRichMessage sends a message with blocks for rich formatting

func (*SlackNotifier) SendWithOptions

func (s *SlackNotifier) SendWithOptions(ctx context.Context, msg *Message) error

SendWithOptions sends a message with additional options

type TelegramConfig

type TelegramConfig struct {
	// BotToken is the Telegram Bot API token
	BotToken string

	// ChatID is the default chat ID to send messages to
	ChatID string

	// ParseMode defines how to parse the message (Markdown, HTML, or empty for plain text)
	ParseMode string

	// HTTPClient allows custom HTTP client (optional)
	HTTPClient *http.Client
}

TelegramConfig holds configuration for Telegram notifications

type TelegramNotifier

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

TelegramNotifier sends notifications via Telegram Bot API

func NewTelegramNotifier

func NewTelegramNotifier(config TelegramConfig) (*TelegramNotifier, error)

NewTelegramNotifier creates a new Telegram notifier

func (*TelegramNotifier) Name

func (t *TelegramNotifier) Name() string

Name returns the name of the provider

func (*TelegramNotifier) Send

func (t *TelegramNotifier) Send(ctx context.Context, message string) error

Send sends a simple text message

func (*TelegramNotifier) SendPhoto

func (t *TelegramNotifier) SendPhoto(ctx context.Context, chatID, photoURL, caption string) error

SendPhoto sends a photo with caption

func (*TelegramNotifier) SendWithOptions

func (t *TelegramNotifier) SendWithOptions(ctx context.Context, msg *Message) error

SendWithOptions sends a message with additional options

Directories

Path Synopsis
examples
custom command
manager command
simple command

Jump to

Keyboard shortcuts

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