Add the Web Push sender for the push channel (Feature 19)
push.Sender implements notify.Sender for the "push" channel with
webpush-go and the VAPID key pair: it sends {title, body, url, tag} to
every stored subscription with a TTL of 12 hours, one request each.
Per subscription, an accepted notification records last_success_at, any
failure increments failure_count, and a 404 or 410 deletes the
subscription. Send succeeds when one device accepted it or when there
are no subscriptions (logged as nothing to send); otherwise it returns
an error so the outbox retries. Errors and logs name subscriptions by
id; a transport *url.Error is unwrapped so the endpoint is never quoted.
A mailto: VAPID subject is passed to webpush-go as its bare address,
since webpush-go prefixes mailto: itself.
The server registers the sender with the notify service.
Maestro task 32a1a4ad-9221-46de-8468-3ffce19b108c.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,8 @@ type Querier interface {
|
||||
DeleteAIRunsBefore(ctx context.Context, cutoff string) (int64, error)
|
||||
DeleteIntegrationsGoogle(ctx context.Context) error
|
||||
DeletePushSubscription(ctx context.Context, endpoint string) (int64, error)
|
||||
// Removes a subscription the push service reports gone (404 or 410).
|
||||
DeletePushSubscriptionByID(ctx context.Context, id string) error
|
||||
DeleteRecipeIngredients(ctx context.Context, recipeID string) error
|
||||
DeleteRecipeSteps(ctx context.Context, recipeID string) error
|
||||
DeleteShoppingGroup(ctx context.Context, id string) error
|
||||
@@ -188,6 +190,9 @@ type Querier interface {
|
||||
// The planned dinners dated from from_date up to but not including
|
||||
// to_date, oldest first. Days with no dinner are left out.
|
||||
ListPlannedDinners(ctx context.Context, arg ListPlannedDinnersParams) ([]ListPlannedDinnersRow, error)
|
||||
// Every stored subscription with its keys, for the push sender, oldest
|
||||
// first.
|
||||
ListPushSubscriptions(ctx context.Context) ([]ListPushSubscriptionsRow, error)
|
||||
// Reads for the AI household context block (internal/ai/harness).
|
||||
// The most recent names the household turned down, newest first, as
|
||||
// ListPassedNames has them.
|
||||
@@ -255,6 +260,10 @@ type Querier interface {
|
||||
// event id while its dinner stays the same; a new dinner clears it, since
|
||||
// Calendar no longer shows the day as planned.
|
||||
PutPlanDay(ctx context.Context, arg PutPlanDayParams) error
|
||||
// Counts a delivery to a subscription that the push service did not accept.
|
||||
RecordPushFailure(ctx context.Context, id string) error
|
||||
// Records that the push service accepted a notification for a subscription.
|
||||
RecordPushSuccess(ctx context.Context, arg RecordPushSuccessParams) error
|
||||
// Records a new draft over plan id: its status and note, raising its
|
||||
// revision.
|
||||
RedraftWeekPlan(ctx context.Context, arg RedraftWeekPlanParams) error
|
||||
|
||||
Reference in New Issue
Block a user