Skip to content

Commit

Permalink
add options to delay broadcast notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
ice-cronus committed Jan 17, 2024
1 parent 2c60a49 commit b7e95b8
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 7 deletions.
11 changes: 11 additions & 0 deletions notifications/push/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ type (
Title string `json:"title,omitempty"`
Body string `json:"body,omitempty"`
ImageURL string `json:"imageUrl,omitempty"`
MinDelay uint `json:"minDelay"`
MaxDelay uint `json:"maxDelay"`
}
Client interface {
io.Closer
Expand All @@ -47,6 +49,15 @@ const (
requestDeadline = 25 * stdlibtime.Second
fcmSendAllBufferingDeadline = 1 * stdlibtime.Second
fcmSendAllSlowProcessingMonitoringTickerDeadline = 3 * fcmSendAllBufferingDeadline

dataOnlyTitle = "title"
dataOnlyBody = "body"
dataOnlyImageURL = "imageURL"
dataOnlyMinDelay = "minDelaySec"
dataOnlyMaxDelay = "maxDelaySec"
dataOnlyType = "type"

typeDelayedNotification = "delayed"
)

type (
Expand Down
47 changes: 40 additions & 7 deletions notifications/push/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"os"
"runtime"
"strconv"
"strings"
"sync"
stdlibtime "time"
Expand Down Expand Up @@ -124,19 +125,51 @@ func (p *push) Send(ctx context.Context, notif *Notification[DeviceToken], respo
func (p *push) Broadcast(ctx context.Context, notification *Notification[SubscriptionTopic]) error {
return errors.Wrapf(retry(ctx, func() error {
_, err := p.client.Send(ctx, &fcm.Message{
Data: notification.Data,
Notification: &fcm.Notification{
Title: notification.Title,
Body: notification.Body,
ImageURL: notification.ImageURL,
},
Topic: string(notification.Target),
Data: notification.Data,
Android: buildAndroidDataOnlyNotification(notification),
APNS: buildAppleNotification(notification),
Topic: string(notification.Target),
})

return err //nolint:wrapcheck // No need to do that, it's wrapped outside.
}), "[%v] permanently failed to broadcast %#v", p.applicationYAMLKey, notification)
}

func buildAndroidDataOnlyNotification(notification *Notification[SubscriptionTopic]) *fcm.AndroidConfig {
dataOnlyNotification := make(map[string]string, len(notification.Data)+3)
for k, v := range notification.Data {
dataOnlyNotification[k] = v
}
dataOnlyNotification[dataOnlyTitle] = notification.Title
dataOnlyNotification[dataOnlyBody] = notification.Body
dataOnlyNotification[dataOnlyImageURL] = notification.ImageURL
dataOnlyNotification[dataOnlyType] = typeDelayedNotification
dataOnlyNotification[dataOnlyMinDelay] = strconv.FormatUint(uint64(notification.MinDelay), 10)
dataOnlyNotification[dataOnlyMaxDelay] = strconv.FormatUint(uint64(notification.MaxDelay), 10)

return &fcm.AndroidConfig{
Data: dataOnlyNotification,
Priority: "high",
}
}

func buildAppleNotification(notification *Notification[SubscriptionTopic]) *fcm.APNSConfig {
return &fcm.APNSConfig{
Payload: &fcm.APNSPayload{
Aps: &fcm.Aps{
AlertString: "",
Alert: &fcm.ApsAlert{
Title: notification.Title,
Body: notification.Body,
},
},
},
FCMOptions: &fcm.APNSFCMOptions{
ImageURL: notification.ImageURL,
},
}
}

func retry(ctx context.Context, op func() error) error {
//nolint:wrapcheck // No need, its just a proxy.
return backoff.RetryNotify(
Expand Down

0 comments on commit b7e95b8

Please sign in to comment.