Documentation
¶
Overview ¶
Package push holds what backd knows about push notification messages that doesn't depend on the realm's settings or its store: the templates they are written from, the portable message and its validation, and the payloads each provider receives (design: design/push-notifications.md §6).
Index ¶
- Constants
- Variables
- func CheckSize(targets []Target, m Message) error
- func Prepare(tpl *Templates, realm string, locales []string, targets []Target, kind string, ...) (map[string]Message, error)
- func Shape(t Target, m Message) ([]byte, error)
- type Data
- type Delivery
- type DeviceResult
- type Message
- type Rendered
- type Request
- type Sender
- type Target
- type Templates
- type TooLargeError
- type ValidationError
Constants ¶
const ( // MaxDataBytes is the serialized size of Message.Data. MaxDataBytes = 2048 // MaxTTL is the longest time providers keep a push (FCM's four weeks). MaxTTL = 28 * 24 * time.Hour // DefaultTTL is how long a push is kept when the message doesn't say. DefaultTTL = 24 * time.Hour )
Limits of the portable fields.
const ( PriorityNormal = "normal" PriorityHigh = "high" )
The priorities.
const ( ProviderFCM = "fcm" ProviderAPNs = "apns" ProviderWebPush = "webpush" ProviderCapture = "capture" )
The providers a platform's pushes can go through.
const ( // FCMLimit and APNsLimit are the 4 KiB of the providers' messages. FCMLimit = 4096 APNsLimit = 4096 // WebPushLimit is what RFC 8291 leaves of a 4096-byte record for the plaintext. WebPushLimit = 3993 )
Payload limits, in bytes.
const ( // StatusSent: the provider accepted the push. StatusSent = "sent" // StatusInvalid: the token is dead; the device is removed. StatusInvalid = "invalid" // StatusRetry: throttled or transient; only these devices are sent again. StatusRetry = "retry" // StatusFailed: permanent for this push; the device is kept. StatusFailed = "failed" )
The result of one device of a delivery unit.
const DirName = "push"
DirName is the folder of a realm that holds its push templates: <realm>/push/<kind>/<locale>.yaml.
const RawKind = "raw"
RawKind is the kind of a message whose text the function wrote itself.
Variables ¶
var ErrUnknownKind = errors.New("unknown push kind")
ErrUnknownKind is a kind the realm has no template for.
Functions ¶
func CheckSize ¶
CheckSize shapes the message for every target and refuses it when one is over its limit.
func Prepare ¶
func Prepare(tpl *Templates, realm string, locales []string, targets []Target, kind string, in Message) (map[string]Message, error)
Prepare writes the message of a send in every language the realm lists and checks each one, so a send that can't be delivered is refused before anything is queued. kind is a template kind, or "" / RawKind for a message whose title and body the function wrote; in is the message as the function gave it (its Data is also what templates see as .Data). The result has one message per locale; raw messages are the same text in all of them.
Types ¶
type Data ¶
Data is what a template can use: the realm, the recipient's language and the call's data. Templates get no address or profile field: lock screens are seen by others.
type DeviceResult ¶
DeviceResult is how one device went. Detail is for logs and never contains the token.
type Message ¶
type Message struct {
// Kind is the template the text came from, or RawKind.
Kind string
Title, Body string
Link string
// Data is delivered to the app as it is: strings only, at most MaxDataBytes serialized.
Data map[string]string
Badge *int
Sound string
// Group replaces an earlier push with the same key (collapse key, collapse id, topic).
Group string
// TTL is how long providers keep trying; nil is DefaultTTL, zero is now or never.
TTL *time.Duration
Priority string
// Silent is data only: no visible notification.
Silent bool
// Platform holds keys android, ios and web, merged into that platform's payload.
Platform map[string]map[string]any
}
Message is what is sent to a user's devices, in their language.
func (Message) TTLOrDefault ¶
TTLOrDefault is the message's time to live.
type Request ¶
type Request struct {
Realm string
SendID string
Attempt int // 1 for the first try of the unit
Platform string
Provider string
// Config is the platform's block of realm.yaml with the secrets it names read: credentials
// (FCM's service-account JSON), key (APNs' .p8 key), private_key and subject (Web Push),
// and key_id, team_id, topic, sandbox ("true"), public_key and allowed_hosts (comma
// separated: where a web subscription may point).
Config map[string]string
// Parallelism is how many provider requests may be in flight at once.
Parallelism int
Deliveries []Delivery
}
Request is what a sender is asked to do: deliver to the devices of one platform with the realm's configuration for the provider.
type Sender ¶
type Sender interface {
Send(ctx context.Context, req Request) ([]DeviceResult, error)
}
Sender delivers to one provider. It answers a result per device; an error means the call as a whole failed (the network is down, the credentials were refused) and the unit is tried again. A device with no result counts as failed.
type Target ¶
type Target struct{ Platform, Provider string }
Target is one enabled platform and the provider that delivers to it.
type Templates ¶
type Templates struct {
// contains filtered or unexported fields
}
Templates are the parsed push templates of a realm, by kind and locale.
func Load ¶
Load reads <dir>/<kind>/<locale>.yaml for every kind in the folder and checks that each kind has a file for every locale and that every file parses. A missing folder is no templates.
type TooLargeError ¶
TooLargeError says a message doesn't fit a provider.
func (*TooLargeError) Error ¶
func (e *TooLargeError) Error() string
type ValidationError ¶
type ValidationError struct{ Field, Reason string }
ValidationError is a message field that can't be sent.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string