From 3bafa6c0f211a1aa8d223b9ad091016440947f2e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sun, 1 Mar 2026 22:20:59 -0800 Subject: message notifications --- index.ts | 2 ++ lib/dmNotifications.ts | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 lib/dmNotifications.ts diff --git a/index.ts b/index.ts index 362663bd..bbb6aae7 100644 --- a/index.ts +++ b/index.ts @@ -21,6 +21,7 @@ import { getFx } from "$lib/rates"; import { sendHeartbeat, websocket } from "$lib/sockets"; import { initTigerBeetle } from "$lib/tb"; import { startZmq } from "$lib/zmq"; +import { listenForDMs } from "$lib/dmNotifications"; import ecash from "$routes/ecash"; import email from "$routes/email"; @@ -56,6 +57,7 @@ try { } setTimeout(listenForLightning, 2000); +listenForDMs(); setInterval(sendHeartbeat, 2000); app.get("/balances", info.balances); diff --git a/lib/dmNotifications.ts b/lib/dmNotifications.ts new file mode 100644 index 00000000..3f229842 --- /dev/null +++ b/lib/dmNotifications.ts @@ -0,0 +1,52 @@ +import config from "$config"; +import { db, g } from "$lib/db"; +import { l, warn } from "$lib/logging"; +import { getUser } from "$lib/utils"; +import { Relay } from "nostr-tools/relay"; +import webpush from "web-push"; + +export const listenForDMs = async () => { + try { + const relay = await Relay.connect(config.nostr); + const since = Math.floor(Date.now() / 1000); + + relay.subscribe([{ kinds: [1059], since }], { + onevent: async (event) => { + const pTag = event.tags.find((t) => t[0] === "p"); + if (!pTag) return; + + const recipientPubkey = pTag[1]; + + try { + const user = await getUser(recipientPubkey); + if (!user?.id) return; + + const subscriptions = await db.sMembers(`${user.id}:subscriptions`); + if (!subscriptions?.length) return; + + const payload = JSON.stringify({ + title: "New message", + body: "You have a new encrypted message", + url: "/messages", + }); + + for (const s of subscriptions as any) { + webpush + .sendNotification(JSON.parse(s as string), payload) + .catch((e) => { + warn("dm push failed", e.message); + db.sRem(`${user.id}:subscriptions`, s); + }); + } + } catch (e) { + // User not found for this pubkey - not a coinos user + } + }, + }); + + l("listening for DM notifications on relay"); + } catch (e) { + warn("DM notification listener failed", e.message); + setTimeout(listenForDMs, 5000); + } +}; -- cgit v1.2.3