diff options
Diffstat (limited to 'src/dm-inbox.js')
| -rw-r--r-- | src/dm-inbox.js | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/dm-inbox.js b/src/dm-inbox.js index b9eec3a..58fc72d 100644 --- a/src/dm-inbox.js +++ b/src/dm-inbox.js @@ -15,6 +15,8 @@ // notification instead of a filtered one. import { unwrapDM } from './dm.js'; +import { openCall, CALL, RING_S } from './calls.js'; +import * as nip44 from 'nostr-tools/nip44'; const DB = 'coinos-dm-inbox'; const STORE = 'inbox'; @@ -115,3 +117,28 @@ export function shouldNotifyDm(verdict) { if (verdict.followed || verdict.known) return true; return !verdict.hasList; } + +// A call ringing in (NIP-AC), the wrap a push pointed at: opened with the key +// it's for, and worth ringing only as a fresh offer from someone this +// account follows or talks to, and hasn't muted. Returns { offer, name, +// type } to ring with, or null for anything else (a candidate, a stranger, +// a stale one, a wrap we hold no key for); `quiet` for a caller who +// may not ring us (not followed, not written to). +export async function classifyCall(wrap, inboxes, nowS = Math.floor(Date.now() / 1000)) { + for (const rec of inboxes) { + if (!rec || !rec.sk) continue; + let sk; + try { sk = unhex(rec.sk); } catch { continue; } + const ev = await openCall(wrap, async (pk, ct) => nip44.decrypt(ct, nip44.getConversationKey(sk, pk))); + if (!ev) continue; + const from = ev.pubkey; + if (ev.kind !== CALL.OFFER || from === rec.pubkey || nowS - ev.created_at > RING_S) return null; + if ((rec.muted || []).includes(from)) return null; + const type = (ev.tags.find((x) => x[0] === 'call-type') || [])[1] === 'video' ? 'video' : 'voice'; + // someone not followed nor written to doesn't ring — `quiet`: the app + // lists it as a call that didn't ring, next time it opens + const quiet = !(rec.follows || []).includes(from) && !(rec.rings || rec.known || []).includes(from); + return { offer: ev, name: (rec.names || {})[from] || null, type, quiet }; + } + return null; +} |
