Mobile notifications for iOS (#210)
* 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
This commit was merged in pull request #210.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
package pushnotify
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// Service stores per-device Expo push tokens and exposes the operations
|
||||
// needed by both the HTTP handlers and the worker-side notifier.
|
||||
type Service interface {
|
||||
// Register returns ErrInvalidToken / ErrInvalidPlatform on bad input.
|
||||
Register(ctx context.Context, humanID string, in RegisterInput) error
|
||||
// Unregister is scoped to humanID so a user can't delete another user's
|
||||
// token. Returns ErrNotFound if the token isn't owned by humanID.
|
||||
Unregister(ctx context.Context, humanID, token string) error
|
||||
// ListForHumans returns an empty slice when nothing matches.
|
||||
ListForHumans(ctx context.Context, humanIDs []string) ([]*PushToken, error)
|
||||
// DeleteByToken removes a token regardless of owner — used to prune after
|
||||
// Expo reports DeviceNotRegistered.
|
||||
DeleteByToken(ctx context.Context, token string) error
|
||||
}
|
||||
|
||||
type RegisterInput struct {
|
||||
Token string
|
||||
Platform Platform
|
||||
AppVersion string
|
||||
}
|
||||
|
||||
type serviceImpl struct {
|
||||
repo repository
|
||||
}
|
||||
|
||||
func NewService(pool *pgxpool.Pool) Service {
|
||||
return &serviceImpl{repo: newRepository(pool)}
|
||||
}
|
||||
|
||||
func (s *serviceImpl) Register(ctx context.Context, humanID string, in RegisterInput) error {
|
||||
if !in.Platform.Valid() {
|
||||
return ErrInvalidPlatform
|
||||
}
|
||||
if !IsValidExpoToken(in.Token) {
|
||||
return ErrInvalidToken
|
||||
}
|
||||
return s.repo.upsert(ctx, &PushToken{
|
||||
Token: in.Token,
|
||||
HumanID: humanID,
|
||||
Platform: in.Platform,
|
||||
AppVersion: in.AppVersion,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *serviceImpl) Unregister(ctx context.Context, humanID, token string) error {
|
||||
if token == "" {
|
||||
return ErrInvalidToken
|
||||
}
|
||||
return s.repo.deleteForHuman(ctx, humanID, token)
|
||||
}
|
||||
|
||||
func (s *serviceImpl) ListForHumans(ctx context.Context, humanIDs []string) ([]*PushToken, error) {
|
||||
return s.repo.listForHumans(ctx, humanIDs)
|
||||
}
|
||||
|
||||
func (s *serviceImpl) DeleteByToken(ctx context.Context, token string) error {
|
||||
return s.repo.deleteByToken(ctx, token)
|
||||
}
|
||||
Reference in New Issue
Block a user