Skip to Content

Notifications

The notifications package provides a unified notification dispatch system that supports multiple channels including email, push notifications, and custom channels. It decouples notification logic from delivery mechanisms.

Import

import "github.com/gofastadev/gofasta/pkg/notifications"

Key Types

Notifier

type Notifier interface { Send(ctx context.Context, notification Notification) error SendTo(ctx context.Context, notification Notification, channels ...string) error RegisterChannel(name string, channel Channel) }

Channel

type Channel interface { Deliver(ctx context.Context, recipient Recipient, notification Notification) error Name() string }

Notification

type Notification struct { Type string `json:"type"` Title string `json:"title"` Body string `json:"body"` Data map[string]interface{} `json:"data,omitempty"` }

Recipient

type Recipient struct { ID string `json:"id"` Email string `json:"email,omitempty"` DeviceID string `json:"device_id,omitempty"` Meta map[string]string `json:"meta,omitempty"` Channels []string `json:"channels"` }

Key Functions

FunctionSignatureDescription
NewNotifierfunc NewNotifier() NotifierCreates a new notifier instance
NewEmailChannelfunc NewEmailChannel(m mailer.Mailer, templatePath string) ChannelCreates an email delivery channel
NewPushChannelfunc NewPushChannel(cfg PushConfig) ChannelCreates a push notification channel (FCM/APNs)
NewWebhookChannelfunc NewWebhookChannel(cfg WebhookConfig) ChannelCreates a webhook delivery channel

Usage

Setting Up Notifications

notifier := notifications.NewNotifier() // Register email channel emailCh := notifications.NewEmailChannel(mailClient, "templates/notifications/") notifier.RegisterChannel("email", emailCh) // Register push notification channel pushCh := notifications.NewPushChannel(notifications.PushConfig{ FCMServerKey: "your-fcm-key", }) notifier.RegisterChannel("push", pushCh)

Sending a Notification

notification := notifications.Notification{ Type: "order_confirmed", Title: "Order Confirmed", Body: "Your order #12345 has been confirmed.", Data: map[string]interface{}{ "order_id": "12345", "amount": 99.99, }, } recipient := notifications.Recipient{ ID: "user-123", Email: "user@example.com", DeviceID: "fcm-device-token", Channels: []string{"email", "push"}, } err := notifier.Send(ctx, notification)

Sending to Specific Channels

// Send only via push, skipping email err := notifier.SendTo(ctx, notification, "push")

Creating a Custom Channel

Implement the Channel interface to add custom delivery mechanisms.

type SlackChannel struct { webhookURL string } func (s *SlackChannel) Name() string { return "slack" } func (s *SlackChannel) Deliver(ctx context.Context, recipient Recipient, n Notification) error { payload := map[string]string{ "text": fmt.Sprintf("*%s*\n%s", n.Title, n.Body), } body, _ := json.Marshal(payload) _, err := http.Post(s.webhookURL, "application/json", bytes.NewReader(body)) return err } // Register it notifier.RegisterChannel("slack", &SlackChannel{webhookURL: "https://hooks.slack.com/..."})

Notification in Service Layer

func (s *OrderService) ConfirmOrder(ctx context.Context, orderID string) error { order, err := s.repo.FindByID(ctx, orderID) if err != nil { return err } order.Status = "confirmed" if err := s.repo.Update(ctx, order); err != nil { return err } return s.notifier.Send(ctx, notifications.Notification{ Type: "order_confirmed", Title: "Order Confirmed", Body: fmt.Sprintf("Your order #%s has been confirmed.", order.ID), Data: map[string]interface{}{"order_id": order.ID}, }) }
  • Mailer — Email channel uses the mailer package
  • Queue — Queue notifications for async delivery
  • WebSocket — Real-time notifications via WebSocket
Last updated on