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
| Function | Signature | Description |
|---|---|---|
NewNotifier | func NewNotifier() Notifier | Creates a new notifier instance |
NewEmailChannel | func NewEmailChannel(m mailer.Mailer, templatePath string) Channel | Creates an email delivery channel |
NewPushChannel | func NewPushChannel(cfg PushConfig) Channel | Creates a push notification channel (FCM/APNs) |
NewWebhookChannel | func NewWebhookChannel(cfg WebhookConfig) Channel | Creates 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},
})
}Related Pages
Last updated on