Documentation
¶
Overview ¶
Package notify stores in-app notifications per user and fans them out to mail and real-time broadcast.
A notification is any value with a Kind; its JSON encoding is stored as the row's data. Send writes it through the channels you pass:
nf := notify.New(db, nil)
_, err := nf.Send(ctx, user.ID, CommentReplied{PostID: 7},
notify.Database,
notify.Mail(mailer, replyMail),
notify.Broadcast(hub, func(id string) string { return "private-user." + id }))
SendTx does the same inside a transaction: the row is written with it, the mail is queued only if it commits and the broadcast is published after the commit. Unread, List, MarkRead and MarkAllRead serve the bell icon and the notification page; every query is scoped to the user id it receives.
Index ¶
- Constants
- Variables
- func Database(ctx context.Context, ex database.Executor, s Stored, _ Notification) error
- func Migration(id string) schema.Migration
- type Channel
- type Notification
- type Notifier
- func (nf *Notifier) List(ctx context.Context, userID, cursor string, limit int) ([]Stored, string, error)
- func (nf *Notifier) MarkAllRead(ctx context.Context, userID string) (int64, error)
- func (nf *Notifier) MarkRead(ctx context.Context, userID string, ids ...string) (int64, error)
- func (nf *Notifier) Prune(ctx context.Context, cutoff time.Time) (int64, error)
- func (nf *Notifier) Send(ctx context.Context, userID string, n Notification, channels ...Channel) (Stored, error)
- func (nf *Notifier) SendTx(ctx context.Context, ex database.Executor, userID string, n Notification, ...) (Stored, error)
- func (nf *Notifier) Unread(ctx context.Context, userID string) (int64, error)
- type Publisher
- type Stored
Constants ¶
const MaxKind = 100
MaxKind is the longest Kind a notification may have.
const Table = "notifications"
Table is the table holding notifications.
Variables ¶
var ErrNoChannels = errors.New("notify: no channel")
ErrNoChannels is returned by Send and SendTx without a channel.
Functions ¶
Types ¶
type Channel ¶
Channel delivers one notification. ex is the Executor Send or SendTx ran with (the transaction for SendTx); s is the stored form, n the original.
func Broadcast ¶
Broadcast returns a channel that publishes the Stored notification as event Kind on the channel named by channelFor (a private per-user channel). Inside SendTx it publishes after the commit, and a publish error then cannot fail the committed work: it is dropped, since the Database row stays the source of truth the client reloads.
func Mail ¶
func Mail( m *mail.Mailer, build func(ctx context.Context, userID string, n Notification) (mail.Mailable, error), ) Channel
Mail returns a channel that queues the mailable build returns with Mailer.SendLaterTx, so it is sent only if the transaction commits. build returning a nil mailable skips the mail (a user without an address, or one who turned these mails off). The Mailer needs a queue (mail.ErrNoQueue otherwise).
type Notification ¶
type Notification interface {
Kind() string
}
Notification is something a user is told about. Kind names it ("comment.replied") so the front end can pick an icon and a text; the JSON encoding of the value is stored as Stored.Data.
type Notifier ¶
type Notifier struct {
// contains filtered or unexported fields
}
Notifier sends and reads notifications in Table.
func (*Notifier) List ¶
func (nf *Notifier) List(ctx context.Context, userID, cursor string, limit int) ([]Stored, string, error)
List returns up to limit of userID's notifications, newest first, after the cursor (empty for the first page), and the cursor of the next page ("" on the last one). limit is clamped to 1..100; 0 means 20. The cursor is the last id of the page: ids sort by creation time.
func (*Notifier) MarkAllRead ¶
MarkAllRead marks every unread notification of userID as read and returns how many changed.
func (*Notifier) MarkRead ¶
MarkRead marks userID's notifications with the given ids as read and returns how many changed. Ids of other users' notifications are ignored.
func (*Notifier) Prune ¶
Prune deletes the notifications, read or not, created before cutoff and returns how many it deleted. Schedule it to bound the table.
func (*Notifier) Send ¶
func (nf *Notifier) Send(ctx context.Context, userID string, n Notification, channels ...Channel) (Stored, error)
Send delivers n to userID through each channel in order and returns the stored form. It stops at the first channel error.
func (*Notifier) SendTx ¶
func (nf *Notifier) SendTx( ctx context.Context, ex database.Executor, userID string, n Notification, channels ...Channel, ) (Stored, error)
SendTx is Send inside the transaction of ex (a *database.Tx from DB.Tx): a rollback discards the row, the queued mail and the broadcast.
type Stored ¶
type Stored struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Kind string `json:"kind"`
Data json.RawMessage `json:"data"`
ReadAt *time.Time `json:"read_at"`
CreatedAt time.Time `json:"created_at"`
}
Stored is a notification as written to Table and returned by List. It is also the data a Broadcast channel publishes.