shellphone.app/app/utils/web-push.server.ts

53 lines
1.5 KiB
TypeScript
Raw Normal View History

import webpush, { type PushSubscription, WebPushError } from "web-push";
2022-06-01 20:45:49 +00:00
import type { NotificationSubscription } from "@prisma/client";
import serverConfig from "~/config/config.server";
import db from "~/utils/db.server";
import logger from "~/utils/logger.server";
export type NotificationPayload = NotificationOptions & {
2022-06-01 20:45:49 +00:00
title: string; // max 50 characters
body: string; // max 150 characters
};
2022-06-01 20:45:49 +00:00
export async function notify(subscriptions: NotificationSubscription[], payload: NotificationPayload) {
webpush.setVapidDetails("mailto:mokht@rmi.al", serverConfig.webPush.publicKey, serverConfig.webPush.privateKey);
2022-06-01 20:45:49 +00:00
const title = truncate(payload.title, 50);
const body = truncate(payload.body, 150);
const _payload = JSON.stringify({
...payload,
title,
body,
});
await Promise.all(
subscriptions.map(async (subscription) => {
const webPushSubscription: PushSubscription = {
endpoint: subscription.endpoint,
keys: {
p256dh: subscription.keys_p256dh,
auth: subscription.keys_auth,
},
};
try {
2022-06-01 20:45:49 +00:00
await webpush.sendNotification(webPushSubscription, _payload);
} catch (error: any) {
logger.error(error);
if (error instanceof WebPushError) {
// subscription most likely expired or has been revoked
await db.notificationSubscription.delete({ where: { id: subscription.id } });
}
}
}),
);
}
2022-06-01 20:45:49 +00:00
function truncate(str: string, maxLength: number) {
if (str.length <= maxLength) {
return str;
}
return str.substring(0, maxLength - 1) + "\u2026";
}