46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
import { prisma } from '@innungsapp/shared'
|
|
|
|
const EXPO_PUSH_URL = 'https://exp.host/--/api/v2/push/send'
|
|
|
|
/**
|
|
* Send push notifications to all active members in an org who have a push token
|
|
*/
|
|
export async function sendPushNotifications(orgId: string, title: string, body?: string) {
|
|
const members = await prisma.member.findMany({
|
|
where: { orgId, status: 'aktiv', pushToken: { not: null } },
|
|
select: { pushToken: true },
|
|
})
|
|
|
|
const tokens = members
|
|
.map((m) => m.pushToken)
|
|
.filter((t): t is string => t !== null)
|
|
|
|
if (tokens.length === 0) return
|
|
|
|
// Expo Push API supports batches of up to 100
|
|
const batches: string[][] = []
|
|
for (let i = 0; i < tokens.length; i += 100) {
|
|
batches.push(tokens.slice(i, i + 100))
|
|
}
|
|
|
|
for (const batch of batches) {
|
|
const messages = batch.map((token) => ({
|
|
to: token,
|
|
title,
|
|
body: body ?? 'Neue Nachricht von Ihrer Innung',
|
|
sound: 'default',
|
|
data: { type: 'news' },
|
|
}))
|
|
|
|
await fetch(EXPO_PUSH_URL, {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'Accept-encoding': 'gzip, deflate',
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(messages),
|
|
})
|
|
}
|
|
}
|