diff options
| author | Fuwn <[email protected]> | 2026-03-28 06:25:30 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-03-28 06:25:30 +0000 |
| commit | b956fafb411fdb4f4ab5d6ed0d417bc3a14c656e (patch) | |
| tree | 2432a44c7ea901e891e36ce4f7fcab5c9f7ec91c /src/trigger/notifications.ts | |
| parent | fix(notifications): prune dead push endpoints (diff) | |
| download | due.moe-b956fafb411fdb4f4ab5d6ed0d417bc3a14c656e.tar.xz due.moe-b956fafb411fdb4f4ab5d6ed0d417bc3a14c656e.zip | |
fix(notifications): stabilize browser subscription identity
Diffstat (limited to 'src/trigger/notifications.ts')
| -rw-r--r-- | src/trigger/notifications.ts | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/trigger/notifications.ts b/src/trigger/notifications.ts index 5b2453c2..30a50a12 100644 --- a/src/trigger/notifications.ts +++ b/src/trigger/notifications.ts @@ -14,6 +14,15 @@ const isExpiredSubscriptionError = (error: unknown) => { return statusCode === 404 || statusCode === 410; }; +const subscriptionEndpoint = (subscription: unknown) => + typeof subscription === "object" && + subscription !== null && + "endpoint" in subscription && + typeof subscription.endpoint === "string" && + subscription.endpoint.length + ? subscription.endpoint + : null; + export const notificationsTask = schedules.task({ id: "notifications", run: async (_payload, { ctx }) => { @@ -56,6 +65,7 @@ export const notificationsTask = schedules.task({ }; const transientErrors: unknown[] = []; + const seenEndpoints = new Set<string>(); webpush.setVapidDetails( ( @@ -81,7 +91,15 @@ export const notificationsTask = schedules.task({ ).value, ); - for (const subscription of await getUserSubscriptions()) + for (const subscription of await getUserSubscriptions()) { + const endpoint = subscriptionEndpoint(subscription.subscription); + + if (endpoint) { + if (seenEndpoints.has(endpoint)) continue; + + seenEndpoints.add(endpoint); + } + try { await webpush.sendNotification(subscription.subscription, "."); } catch (error) { @@ -94,6 +112,7 @@ export const notificationsTask = schedules.task({ console.error(error); } + } if (transientErrors.length > 0) throw new Error("Transient push delivery failures occurred", { |