package storage import ( "context" "errors" ) // ErrNoSuchPusher is a pusher that does not exist. var ErrNoSuchPusher = errors.New("no such pusher") // Pusher is one place a user's notifications are pushed to: an app on a // device, reached through its push gateway. type Pusher struct { Localpart string // DeviceID is the session that registered the pusher, so that logging // the device out removes it. Empty for a pusher whose session is not // known. DeviceID string Kind string AppID string PushKey string AppDisplayName string DeviceDisplayName string ProfileTag string Lang string // Data is the pusher's data object as the client sent it: the gateway // URL, the payload format, and anything else the app wants passed to // its gateway. Data []byte // PushKeyTSMS is when the push key was last set, which a gateway uses // to tell an old registration of a key from a newer one. PushKeyTSMS int64 } // NewNotification is one event that notifies one user. type NewNotification struct { UserID string RoomID string EventID string // EventPos is the event's position in the room event stream, which is // what a read receipt is compared against. EventPos int64 TimestampMS int64 Highlight bool // Actions are the matched rule's actions, as JSON, which GET // /notifications reports. Actions []byte } // Notification is a stored notification. type Notification struct { NewNotification // ID orders a user's notifications, newest highest, and is what GET // /notifications pages by. ID int64 Read bool } // NotificationCounts is a room's unread notifications for one user. type NotificationCounts struct { Notifications int Highlights int } // PushStore persists pushers and the notifications push rules produce. // // Notification counts are a stream of their own: every write that changes // a user's counts in a room stamps the room with a new position, inside // the transaction that changes them, so that an incremental sync can ask // which rooms' counts moved since its token. A count moves without an // event — a read receipt sent from another device sets it back to zero — // and a sync that only looked at events would go on showing the old one. type PushStore interface { // Pushers lists a user's pushers. Pushers(ctx context.Context, localpart string) ([]Pusher, error) // SetPusher creates or replaces the user's pusher with the same app ID // and push key. Unless appendOthers is set, any other user's pusher // with the same app ID and push key is removed: a push key names a // device, and the device is now this user's. SetPusher(ctx context.Context, p Pusher, appendOthers bool) error // DeletePusher removes one of a user's pushers. Removing one that is // not there is not an error. DeletePusher(ctx context.Context, localpart, appID, pushKey string) error // DeletePushersForDevices removes the pushers registered by the given // sessions, or by every session of the user when deviceIDs is empty. DeletePushersForDevices(ctx context.Context, localpart string, deviceIDs []string) error // AddNotifications records notifications and moves the counts of // each (user, room) they are for, returning the position the last // count moved to. AddNotifications(ctx context.Context, ns []NewNotification) (int64, error) // MarkNotificationsRead marks a user's notifications in a room up to // and including an event position as read, and reports whether the // counts moved. MarkNotificationsRead(ctx context.Context, userID, roomID string, upTo int64) (pos int64, moved bool, err error) // NotificationCounts reads a user's unread counts in the given rooms. // A room with nothing unread is in the result with zero counts. NotificationCounts(ctx context.Context, userID string, roomIDs []string) (map[string]NotificationCounts, error) // NotificationCountChanges lists the rooms whose counts for a user // moved after from and at or before to. NotificationCountChanges(ctx context.Context, userID string, from, to int64) ([]string, error) // UnreadNotifications is a user's unread notifications across every // room, which a push tells the device to show as its badge. UnreadNotifications(ctx context.Context, userID string) (int, error) // Notifications pages through a user's notifications, newest first, // starting below the ID before (0 for the newest). Notifications(ctx context.Context, userID string, before int64, limit int, onlyHighlight bool) ([]Notification, error) // PruneNotifications removes read notifications older than a time, // returning how many went. PruneNotifications(ctx context.Context, beforeMS int64) (int64, error) }