]> littlesong.place Git - littlesongplace.git/commitdiff
Periodically renew push subscriptions
authorChris Fulljames <christianfulljames@gmail.com>
Fri, 1 Aug 2025 21:21:50 +0000 (17:21 -0400)
committerChris Fulljames <christianfulljames@gmail.com>
Sat, 23 Aug 2025 11:30:17 +0000 (07:30 -0400)
src/littlesongplace/push_notifications.py
src/littlesongplace/static/nav.js
src/littlesongplace/templates/activity.html

index 2a17dead33232bf809af08d51c68213bc0a6cff6..a5c535e9a340b62cb3c38950ff6325dfcd1fc304 100644 (file)
@@ -24,13 +24,30 @@ def subscribe():
         # Request must contain valid subscription JSON
         abort(400)
 
-    row = db.query(
-            """
-            INSERT INTO users_push_subscriptions (userid, subscription, settings)
-            VALUES (?, ?, ?)
-            RETURNING subid
-            """,
-            [g.userid, json.dumps(request.json), 0], expect_one=True)
+    subid = request.args.get("subid", None)
+    existing_sub = None
+    if subid:
+        existing_sub = db.query(
+                "SELECT * FROM users_push_subscriptions WHERE subid = ? AND userid = ?",
+                [subid, g.userid])
+
+    if existing_sub:
+        row = db.query(
+                """
+                UPDATE users_push_subscriptions
+                SET userid = ?, subscription = ?
+                WHERE subid = ? AND userid = ?
+                RETURNING subid
+                """,
+                [g.userid, json.dumps(request.json), subid, g.userid], expect_one=True)
+    else:
+        row = db.query(
+                """
+                INSERT INTO users_push_subscriptions (userid, subscription, settings)
+                VALUES (?, ?, ?)
+                RETURNING subid
+                """,
+                [g.userid, json.dumps(request.json), 0], expect_one=True)
     db.commit()
 
     current_app.logger.info(f"{g.username} registered push subscription")
@@ -58,6 +75,15 @@ def update_subscription(subid):
 
     return {"status": "success", "subid": row["subid"]}
 
+@bp.get("/vapid-public-key")
+def vapid_public_key():
+    try:
+        with open(datadir.get_vapid_public_key_path(), "r") as keyfile:
+            key = keyfile.read().strip()
+        return {"status": "ok", "public_key": key}
+    except OSError:
+        return {"status": "error"}
+
 @bp.get("/settings")
 @auth.requires_login
 def get_settings():
index efb7e9bee3821a977d9ddb2b2f31a3ea84f5b5c1..5a16cbda4f08dd35d8d9e389118440689b430049 100644 (file)
@@ -258,3 +258,47 @@ function updateImageColors() {
     });
 }
 
+async function periodicPushSync() {
+    console.log("sync");
+    if (!("serviceWorker" in navigator)) {
+        return;  // No service woker available
+    }
+    const subid = window.localStorage.getItem("subid");
+    console.log(subid);
+    if (subid) {
+        await syncPushSubscription();
+    }
+}
+
+async function syncPushSubscription() {
+    const registration = await navigator.serviceWorker.getRegistration();
+    let subscription = await registration.pushManager.getSubscription();
+    if (!subscription)
+    {
+        // Subscribe via browser's push service
+        const data = await fetch("/push-notifications/vapid-public-key").then((r) => { return r.json() });
+        const vapid_public_key = data.public_key;
+        const options = {userVisibleOnly: true, applicationServerKey: vapid_public_key};
+        subscription = await registration.pushManager.subscribe(options);
+        console.log(JSON.stringify(subscription));
+    }
+
+    // Register (or update) subscription with LSP server
+    const subid = window.localStorage.getItem("subid");
+    const params = subid ? `?subid=${subid}` : "";
+    const response = await fetch(
+        `/push-notifications/subscribe${params}`, {
+            method: "post",
+            headers: {"Content-Type": "application/json"},
+            body: JSON.stringify(subscription)
+        }
+    );
+
+    const rspJson = await response.json();
+    console.log("Subscription ID:", rspJson.subid);
+    window.localStorage.setItem("subid", rspJson.subid);
+}
+
+periodicPushSync();
+setInterval(periodicPushSync, 10000);
+
index f28531a0a63e655922f1f26a3da7a5a00d134ac6..ed82c76f5df3facbd94f89503532cce944f1a727 100644 (file)
@@ -80,29 +80,7 @@ async function enablePushNotifications() {
     if (permission === "granted") {
         // Subscribe to push notifications (if we don't already have an active subscription)
         try {
-            const registration = await navigator.serviceWorker.getRegistration();
-            const existingSubscription = await registration.pushManager.getSubscription();
-            if (!existingSubscription || !window.localStorage.getItem("subid"))
-            {
-                // Subscribe via browser's push service
-                const vapid_public_key = "{{ vapid_public_key }}";
-                const options = {userVisibleOnly: true, applicationServerKey: vapid_public_key};
-                const subscription = await registration.pushManager.subscribe(options);
-                console.log(JSON.stringify(subscription));
-
-                // Register subscription with LSP server
-                const response = await fetch(
-                    "/push-notifications/subscribe", {
-                        method: "post",
-                        headers: {"Content-Type": "application/json"},
-                        body: JSON.stringify(subscription)
-                    }
-                );
-
-                const rspJson = await response.json();
-                console.log("Subscription ID:", rspJson.subid);
-                window.localStorage.setItem("subid", rspJson.subid);
-            }
+            await syncPushSubscription();
         }
         catch (err) {
             console.log("Error subscribing to push notifications:", err);