Fix push notifications (#1249)

* Fix wrong author in reply push notification

* Fix duplicate mentions push notifications on save

* Fix item mention push notification argument

* Fix zap push notification using stale msats
This commit is contained in:
ekzyis 2024-07-01 22:51:59 +02:00 committed by GitHub
parent 6e1d67b3c0
commit e57c930f0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 27 deletions

View File

@ -218,14 +218,14 @@ export async function onPaid ({ invoice, id }, context) {
FROM ancestors, comment
WHERE ancestors."userId" <> comment."userId"`
notifyItemParents({ item, me: item.userId, models }).catch(console.error)
notifyItemParents({ item, models }).catch(console.error)
}
for (const { userId } of item.mentions) {
notifyMention({ models, item, userId }).catch(console.error)
}
for (const { referee } of item.itemReferrers) {
notifyItemMention({ models, referrerItem: item, refereeItem: referee }).catch(console.error)
for (const { refereeItem } of item.itemReferrers) {
notifyItemMention({ models, referrerItem: item, refereeItem }).catch(console.error)
}
notifyUserSubscribers({ models, item }).catch(console.error)
notifyTerritorySubscribers({ models, item }).catch(console.error)

View File

@ -133,13 +133,13 @@ export async function perform (args, context) {
// TODO: referals for boost
// notify all the mentions if the mention is new
// compare timestamps to only notify if mention or item referral was just created to avoid duplicates on edits
for (const { userId, createdAt } of item.mentions) {
if (item.updatedAt.getTime() === createdAt.getTime()) continue
if (item.updatedAt.getTime() !== createdAt.getTime()) continue
notifyMention({ models, item, userId }).catch(console.error)
}
for (const { refereeItem, createdAt } of item.itemReferrers) {
if (item.updatedAt.getTime() === createdAt.getTime()) continue
if (item.updatedAt.getTime() !== createdAt.getTime()) continue
notifyItemMention({ models, referrerItem: item, refereeItem }).catch(console.error)
}

View File

@ -89,7 +89,7 @@ export async function onPaid ({ invoice, actIds }, { models, tx }) {
// perform denomormalized aggregates: weighted votes, upvotes, msats, lastZapAt
// NOTE: for the rows that might be updated by a concurrent zap, we use UPDATE for implicit locking
await tx.$executeRaw`
const [item] = await tx.$queryRaw`
WITH zapper AS (
SELECT trust FROM users WHERE id = ${itemAct.userId}::INTEGER
), zap AS (
@ -107,7 +107,8 @@ export async function onPaid ({ invoice, actIds }, { models, tx }) {
msats = "Item".msats + ${msats}::BIGINT,
"lastZapAt" = now()
FROM zap, zapper
WHERE "Item".id = ${itemAct.itemId}::INTEGER`
WHERE "Item".id = ${itemAct.itemId}::INTEGER
RETURNING "Item".*`
// record potential bounty payment
// NOTE: we are at least guaranteed that we see the update "ItemUserAgg" from our tx so we can trust
@ -139,7 +140,7 @@ export async function onPaid ({ invoice, actIds }, { models, tx }) {
WHERE "Item".path @> zapped.path AND "Item".id <> zapped.id`
// TODO: referrals
notifyZapped({ models, id: itemAct.itemId }).catch(console.error)
notifyZapped({ models, item }).catch(console.error)
}
export async function onFail ({ invoice }, { tx }) {

View File

@ -1,6 +1,6 @@
import webPush from 'web-push'
import removeMd from 'remove-markdown'
import { USER_ID, COMMENT_DEPTH_LIMIT, FOUND_BLURBS, LOST_BLURBS } from './constants'
import { COMMENT_DEPTH_LIMIT, FOUND_BLURBS, LOST_BLURBS } from './constants'
import { msatsToSats, numWithUnits } from './format'
import models from '@/api/models'
import { isMuted } from '@/lib/user'
@ -178,9 +178,9 @@ export const notifyTerritorySubscribers = async ({ models, item }) => {
}
}
export const notifyItemParents = async ({ models, item, me }) => {
export const notifyItemParents = async ({ models, item }) => {
try {
const user = await models.user.findUnique({ where: { id: me?.id || USER_ID.anon } })
const user = await models.user.findUnique({ where: { id: item.userId } })
const parents = await models.$queryRawUnsafe(
'SELECT DISTINCT p."userId" FROM "Item" i JOIN "Item" p ON p.path @> i.path WHERE i.id = $1 and p."userId" <> $2 ' +
'AND NOT EXISTS (SELECT 1 FROM "Mute" m WHERE m."muterId" = p."userId" AND m."mutedId" = $2)',
@ -198,48 +198,48 @@ export const notifyItemParents = async ({ models, item, me }) => {
}
}
export const notifyZapped = async ({ models, id }) => {
export const notifyZapped = async ({ models, item }) => {
try {
const updatedItem = await models.item.findUnique({ where: { id: Number(id) } })
const forwards = await models.itemForward.findMany({ where: { itemId: Number(id) } })
const forwards = await models.itemForward.findMany({ where: { itemId: item.id } })
const userPromises = forwards.map(fwd => models.user.findUnique({ where: { id: fwd.userId } }))
const userResults = await Promise.allSettled(userPromises)
const mappedForwards = forwards.map((fwd, index) => ({ ...fwd, user: userResults[index].value ?? null }))
let forwardedSats = 0
let forwardedUsers = ''
if (mappedForwards.length) {
forwardedSats = Math.floor(msatsToSats(updatedItem.msats) * mappedForwards.map(fwd => fwd.pct).reduce((sum, cur) => sum + cur) / 100)
forwardedSats = Math.floor(msatsToSats(item.msats) * mappedForwards.map(fwd => fwd.pct).reduce((sum, cur) => sum + cur) / 100)
forwardedUsers = mappedForwards.map(fwd => `@${fwd.user.name}`).join(', ')
}
let notificationTitle
if (updatedItem.title) {
if (item.title) {
if (forwards.length > 0) {
notificationTitle = `your post forwarded ${numWithUnits(forwardedSats)} to ${forwardedUsers}`
} else {
notificationTitle = `your post stacked ${numWithUnits(msatsToSats(updatedItem.msats))}`
notificationTitle = `your post stacked ${numWithUnits(msatsToSats(item.msats))}`
}
} else {
if (forwards.length > 0) {
// I don't think this case is possible
notificationTitle = `your reply forwarded ${numWithUnits(forwardedSats)} to ${forwardedUsers}`
} else {
notificationTitle = `your reply stacked ${numWithUnits(msatsToSats(updatedItem.msats))}`
notificationTitle = `your reply stacked ${numWithUnits(msatsToSats(item.msats))}`
}
}
await sendUserNotification(updatedItem.userId, {
await sendUserNotification(item.userId, {
title: notificationTitle,
body: updatedItem.title ? updatedItem.title : updatedItem.text,
item: updatedItem,
tag: `TIP-${updatedItem.id}`
body: item.title ? item.title : item.text,
item,
tag: `TIP-${item.id}`
})
// send push notifications to forwarded recipients
if (mappedForwards.length) {
await Promise.allSettled(mappedForwards.map(forward => sendUserNotification(forward.user.id, {
title: `you were forwarded ${numWithUnits(Math.round(msatsToSats(updatedItem.msats) * forward.pct / 100))}`,
body: updatedItem.title ?? updatedItem.text,
item: updatedItem,
tag: `FORWARDEDTIP-${updatedItem.id}`
title: `you were forwarded ${numWithUnits(Math.round(msatsToSats(item.msats) * forward.pct / 100))}`,
body: item.title ?? item.text,
item,
tag: `FORWARDEDTIP-${item.id}`
})))
}
} catch (err) {