* mobile: wire notification registration and listener
* implement backend components for push notifications
* refactor: agentic comment cleanup
* docs: use proper module name for particle processor
* set required env variables for push notifications
* bump version
* fix: always upsert push token on mobile start
* Revert "fix: always upsert push token on mobile start"
This reverts commit 90ff18a788.
* send push notifications regardless of online status
44 lines
1.1 KiB
Go
44 lines
1.1 KiB
Go
// Package pushnotify owns mobile push notification delivery: storage of per-device
|
|
// Expo push tokens, and the worker-side orchestration of sending notifications
|
|
// to offline recipients via the Expo Push API.
|
|
package pushnotify
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Platform string
|
|
|
|
const (
|
|
PlatformIOS Platform = "ios"
|
|
PlatformAndroid Platform = "android"
|
|
)
|
|
|
|
func (p Platform) Valid() bool {
|
|
return p == PlatformIOS || p == PlatformAndroid
|
|
}
|
|
|
|
type PushToken struct {
|
|
Token string
|
|
HumanID string
|
|
Platform Platform
|
|
AppVersion string
|
|
CreatedAt time.Time
|
|
LastSeenAt time.Time
|
|
}
|
|
|
|
var (
|
|
ErrInvalidPlatform = errors.New("invalid platform")
|
|
ErrInvalidToken = errors.New("invalid expo push token")
|
|
ErrNotFound = errors.New("push token not found")
|
|
)
|
|
|
|
// IsValidExpoToken matches the two prefix formats Expo currently uses.
|
|
// We don't validate the inner contents — Expo's server will reject malformed
|
|
// tokens with a per-message error and we'll clean those up via DeviceNotRegistered.
|
|
func IsValidExpoToken(token string) bool {
|
|
return strings.HasPrefix(token, "ExponentPushToken[") || strings.HasPrefix(token, "ExpoPushToken[")
|
|
}
|