push notificaitons

This commit is contained in:
toni
2026-03-16 00:46:30 +01:00
parent 2620538a2c
commit e3184be911
20 changed files with 237 additions and 253 deletions
@@ -22,7 +22,7 @@ export class FoundEventsService {
maxRequestsPerMinute: 100,
maxConcurrency: 2,
requestHandler: async ({ request, page, log }) => {
if (request.retryCount > 0) return;
// if (request.retryCount > 0) return;
const label = request.label;
@@ -67,8 +67,8 @@ export async function parseTUSDetail(
const aboluteUrl =
url != null
? isAbsolute
? new URL(url)
: new URL(url, pageUrl)
? new URL(url).toString()
: new URL(url, pageUrl).toString()
: "";
return {
url: aboluteUrl,
+58 -137
View File
@@ -134,164 +134,85 @@ export class PushService {
lang: "de-DE",
// TODO renotify: true, re-enable when tag
requireInteraction: true,
timestamp: date?.valueOf(),
// timestamp: date?.valueOf(),
vibrate: [100],
// TODO tag: Topic.EVENTS, implement grouping in Angular SW
},
};
for (const subscription of subscriptions) {
if (
subscription.lastNotified &&
subscription.lastNotified >= event.foundDate
) {
for (const s of subscriptions) {
if (s.lastNotified && s.lastNotified >= event.foundDate) {
// this subscription has already seen this event
continue;
}
if (
!this.eventMatchesFilter(
event,
subscription.topicConfiguration,
)
) {
if (!this.eventMatchesFilter(event, s.topicConfiguration)) {
// this subscription does not care for this event
continue;
}
console.log(`sending ${subscriptions.length} test messages`);
for (const s of subscriptions) {
try {
let backoff = 500;
let retry: boolean;
do {
console.log("SENDING");
console.dir("payload");
retry = await this.sendNotification(
s,
payload,
backoff,
);
backoff *= 2;
} while (retry);
} catch (error) {
console.error("Cannot send notification: ", error);
throw error;
}
try {
let backoff = 500;
let retry: boolean;
let maxRetry = 5;
do {
retry = await this.sendNotification(
s,
payload,
backoff,
);
if (maxRetry <= 0) {
throw new Error("Exceeded max retry");
}
backoff *= 2;
maxRetry--;
} while (retry);
await this.db.doRequest(
async prisma =>
prisma.pushSubscription.update({
where: {
id: s.id,
},
data: {
lastNotified: new Date(Date.now()),
},
}),
null,
);
} catch (error) {
console.error("Cannot send notification: ", error);
// throw error;
}
}
}
await this.db.doRequest(
async prisma =>
prisma.pushSubscription.updateMany({
where: {
id: {
in: subscriptions.map(s => s.id),
},
},
data: {
lastNotified: new Date(Date.now()),
},
}),
null,
);
}
public async sendtestNotification(request: Request) {
const subscriptions = await this.db.doRequest(
async prisma =>
prisma.pushSubscription.findMany({ where: { topic: "TEST" } }),
request,
);
const payload: AngularPushPayload = {
notification: {
title: "ATitle",
actions: [
{
action: "explode",
title: "Make Boom",
},
],
body: "DatBod",
data: {
onActionClick: {
default: {
operation: NotificationActionOperation.OPEN_WINDOW,
},
explode: {
operation: NotificationActionOperation.OPEN_WINDOW,
url: "explode.html",
},
},
},
icon: "https://taekwondo-chemnitz.toni714.de/favicon.ico",
lang: "de-DE",
renotify: true,
requireInteraction: true,
tag: "group-tag",
timestamp: Date.now(),
vibrate: [100, 50, 100],
},
};
console.log(`sending ${subscriptions.length} test messages`);
for (const s of subscriptions) {
const subscription: webpush.PushSubscription = {
endpoint: s.endpoint,
keys: {
auth: s.auth,
p256dh: s.p256dh,
},
expirationTime: s.expirationTime,
};
try {
const result = await webpush.sendNotification(
subscription,
JSON.stringify(payload),
{
topic: Topic.TEST,
},
);
console.log("success");
console.dir(result);
} catch (error) {
console.error("Cannot send notification: ", error);
throw error;
}
}
}
public async reset(request: Request): Promise<void> {
const userId = await this.userService.getUid(request, request.res);
const subscriptions = await this.db.doRequest(
async prisma =>
await prisma.pushSubscription.deleteMany({
where: { userId: userId },
}),
request,
);
console.log(`deleted ${subscriptions.count} subs for ${userId}`);
}
public async clearSubscription(
clientId: string,
clientId: string | null,
request: Request,
): Promise<number> {
const userId = await this.userService.getUid(request, request.res);
const batchResult = await this.db.doRequest(
async prisma =>
await prisma.pushSubscription.deleteMany({
where: {
userId: userId,
AND: {
clientId: clientId,
},
},
}),
request,
);
const batchResult = clientId
? await this.db.doRequest(
async prisma =>
await prisma.pushSubscription.deleteMany({
where: {
userId: userId,
AND: {
clientId: clientId,
},
},
}),
request,
)
: await this.db.doRequest(
async prisma =>
await prisma.pushSubscription.deleteMany({
where: {
userId: userId,
},
}),
request,
);
return batchResult.count;
}