Created
April 12, 2023 11:45
-
-
Save KTibow/77a4a69591b3b38327ca37f39a95aac5 to your computer and use it in GitHub Desktop.
My system for web notifications
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
import { PUBLIC_NOTIF_KEY } from "$env/static/public"; | |
let setupState = false; | |
async function setup() { | |
setupState = "loading-0"; | |
await Notification.requestPermission(); | |
const registration = await navigator.serviceWorker.ready; | |
setupState = "loading-1"; | |
let sub; | |
try { | |
sub = await registration.pushManager.subscribe({ | |
userVisibleOnly: true, | |
applicationServerKey: Uint8Array.from( | |
atob(PUBLIC_NOTIF_KEY.replace(/-/g, "+").replace(/_/g, "/")) | |
.split("") | |
.map((x) => x.charCodeAt()) | |
), | |
}); | |
} catch (e) { | |
console.error(e); | |
setupState = "errored"; | |
const sub = await registration.pushManager.getSubscription(); | |
await sub.unsubscribe(); | |
return; | |
} | |
setupState = "loading-2"; | |
await fetch("/savePush", { method: "POST", body: JSON.stringify(sub) }); | |
setupState = false; | |
} | |
</script> | |
<button class="w-full bg-stone-800 py-2 px-4" on:click={setup}>Get the notification</button> | |
{#if setupState == "loading-0"} | |
<p class="mt-2 text-stone-300">Setting up for notifications</p> | |
{:else if setupState == "loading-1"} | |
<p class="mt-2 text-stone-300">Getting the notification bridge</p> | |
{:else if setupState == "loading-2"} | |
<p class="mt-2 text-stone-300">Communicating with the server</p> | |
{:else if setupState == "errored"} | |
<p class="mt-2 text-red-300">Configuring notification failed, try again</p> | |
{/if} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ApplicationServerKeys, generatePushHTTPRequest, setWebCrypto } from "webpush-webcrypto"; | |
import { PUBLIC_NOTIF_KEY } from "$env/static/public"; | |
import { PRIVATE_NOTIF_KEY } from "$env/static/private"; | |
setWebCrypto(crypto); | |
let keys; | |
export function unflattenTarget(target) { | |
return { endpoint: target.endpoint, keys: { p256dh: target.p256dh, auth: target.auth } }; | |
} | |
export async function sendNotification(target, payload) { | |
if (!keys) | |
keys = await ApplicationServerKeys.fromJSON({ | |
publicKey: PUBLIC_NOTIF_KEY, | |
privateKey: PRIVATE_NOTIF_KEY, | |
}); | |
const { headers, body, endpoint } = await generatePushHTTPRequest({ | |
applicationServerKeys: keys, | |
payload: JSON.stringify(payload), | |
target, | |
ttl: 60 * 60 * 24, | |
}); | |
return await fetch(endpoint, { | |
method: "POST", | |
headers, | |
body, | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <reference no-default-lib="true"/> | |
/// <reference lib="esnext" /> | |
/// <reference lib="webworker" /> | |
/** @type {ServiceWorkerGlobalScope} sw */ | |
const sw = self; | |
sw.addEventListener("install", () => sw.skipWaiting()); | |
sw.addEventListener("push", async (event) => { | |
const data = await event.data.json(); | |
// logic here, must always send notification | |
}); | |
sw.addEventListener("notificationclick", (event) => { | |
// logic here | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment