Files
wtr/lib/notification-api.ts

68 lines
2.4 KiB
TypeScript

import type { Language } from "@/lib/i18n";
import type { Province } from "@/types/province";
interface VapidKeyResponse {
configured: boolean;
publicKey: string | null;
}
export async function fetchVapidPublicKey(signal?: AbortSignal) {
const response = await fetch("/api/notifications/vapid-key", { signal });
if (!response.ok) throw new Error("Unable to load Web Push configuration.");
return response.json() as Promise<VapidKeyResponse>;
}
interface SavePushSubscriptionOptions {
morningBriefEnabled?: boolean;
tomorrowBriefEnabled?: boolean;
latitude?: number | null;
longitude?: number | null;
locationName?: string | null;
countyTeryt?: string | null;
}
export async function savePushSubscription(subscription: PushSubscription, province: Province, language: Language, options: SavePushSubscriptionOptions = {}) {
const response = await fetch("/api/notifications/subscriptions", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
subscription: subscription.toJSON(),
province,
language,
enabled: true,
morningBriefEnabled: options.morningBriefEnabled === true,
tomorrowBriefEnabled: options.tomorrowBriefEnabled === true,
latitude: options.latitude ?? null,
longitude: options.longitude ?? null,
locationName: options.locationName ?? null,
countyTeryt: options.countyTeryt ?? null,
}),
});
if (!response.ok) throw new Error("Unable to save push subscription.");
}
export async function deletePushSubscription(endpoint: string) {
const response = await fetch("/api/notifications/subscriptions", {
method: "DELETE",
headers: { "content-type": "application/json" },
body: JSON.stringify({ endpoint }),
});
if (!response.ok) throw new Error("Unable to delete push subscription.");
}
export async function sendTestPushNotification(endpoint: string) {
const response = await fetch("/api/notifications/test", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ endpoint }),
});
if (!response.ok) throw new Error("Unable to send test notification.");
}
export function decodeBase64UrlKey(value: string) {
const padding = "=".repeat((4 - (value.length % 4)) % 4);
const base64 = `${value}${padding}`.replace(/-/g, "+").replace(/_/g, "/");
const raw = window.atob(base64);
return Uint8Array.from(raw, (character) => character.charCodeAt(0));
}