KI-AGENT: Mobile Push Registrierung anbinden
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { FastifyInstance } from "fastify"
|
||||
import { eq } from "drizzle-orm"
|
||||
import { authUsers } from "../../db/schema"
|
||||
import { and, eq, isNull } from "drizzle-orm"
|
||||
import { authUsers, notificationMobilePushDevices } from "../../db/schema"
|
||||
import { NotificationService, UserDirectory } from "../modules/notification.service"
|
||||
import { pushServerClient } from "../modules/push-server.client"
|
||||
|
||||
const getUserDirectory: UserDirectory = async (server: FastifyInstance, userId) => {
|
||||
const rows = await server.db
|
||||
@@ -60,6 +61,104 @@ export default async function notificationsRoutes(server: FastifyInstance) {
|
||||
return await svc.disablePushSubscription(requireTenant(req.user.tenant_id), req.user.user_id, body.endpoint)
|
||||
})
|
||||
|
||||
server.post("/notifications/push/mobile/register", async (req) => {
|
||||
const tenantId = requireTenant(req.user.tenant_id)
|
||||
const body = (req.body || {}) as {
|
||||
localDeviceId?: string
|
||||
platform?: "ios" | "android"
|
||||
providerToken?: string
|
||||
deviceLabel?: string
|
||||
meta?: Record<string, unknown>
|
||||
}
|
||||
|
||||
if (!body.localDeviceId) throw new Error("localDeviceId fehlt")
|
||||
if (body.platform !== "ios" && body.platform !== "android") throw new Error("platform ist ungültig")
|
||||
if (!body.providerToken) throw new Error("providerToken fehlt")
|
||||
|
||||
const centralLocalDeviceId = `${tenantId}:${req.user.user_id}:${body.localDeviceId}`
|
||||
const registered = await pushServerClient.registerDevice({
|
||||
localDeviceId: centralLocalDeviceId,
|
||||
platform: body.platform,
|
||||
providerToken: body.providerToken,
|
||||
meta: {
|
||||
...(body.meta || {}),
|
||||
tenantId,
|
||||
userId: req.user.user_id,
|
||||
source: "fedeo-mobile",
|
||||
},
|
||||
})
|
||||
|
||||
const rows = await server.db
|
||||
.insert(notificationMobilePushDevices)
|
||||
.values({
|
||||
tenantId,
|
||||
userId: req.user.user_id,
|
||||
localDeviceId: body.localDeviceId,
|
||||
centralDeviceId: registered.centralDeviceId,
|
||||
platform: body.platform,
|
||||
providerTokenPreview: previewToken(body.providerToken),
|
||||
deviceLabel: body.deviceLabel,
|
||||
meta: body.meta ?? null,
|
||||
lastSeenAt: new Date(),
|
||||
disabledAt: null,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: [
|
||||
notificationMobilePushDevices.tenantId,
|
||||
notificationMobilePushDevices.userId,
|
||||
notificationMobilePushDevices.localDeviceId,
|
||||
],
|
||||
set: {
|
||||
centralDeviceId: registered.centralDeviceId,
|
||||
platform: body.platform,
|
||||
providerTokenPreview: previewToken(body.providerToken),
|
||||
deviceLabel: body.deviceLabel,
|
||||
meta: body.meta ?? null,
|
||||
lastSeenAt: new Date(),
|
||||
disabledAt: null,
|
||||
},
|
||||
})
|
||||
.returning()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
id: rows[0]?.id,
|
||||
centralDeviceId: registered.centralDeviceId,
|
||||
status: registered.status,
|
||||
}
|
||||
})
|
||||
|
||||
server.post("/notifications/test-mobile-push", async (req) => {
|
||||
const tenantId = requireTenant(req.user.tenant_id)
|
||||
const devices = await server.db
|
||||
.select({ centralDeviceId: notificationMobilePushDevices.centralDeviceId })
|
||||
.from(notificationMobilePushDevices)
|
||||
.where(and(
|
||||
eq(notificationMobilePushDevices.tenantId, tenantId),
|
||||
eq(notificationMobilePushDevices.userId, req.user.user_id),
|
||||
isNull(notificationMobilePushDevices.disabledAt)
|
||||
))
|
||||
|
||||
if (!devices.length) {
|
||||
throw new Error("Kein registriertes mobiles Push-Gerät gefunden")
|
||||
}
|
||||
|
||||
return await pushServerClient.sendPush({
|
||||
idempotencyKey: `mobile-test:${tenantId}:${req.user.user_id}:${Date.now()}`,
|
||||
devices: devices.map((device) => device.centralDeviceId),
|
||||
priority: "high",
|
||||
ttlSeconds: 600,
|
||||
notification: {
|
||||
title: "FEDEO Mobile Push ist aktiv",
|
||||
body: "Diese Testnachricht wurde über den zentralen Push-Server zugestellt.",
|
||||
},
|
||||
data: {
|
||||
type: "system.test_mobile_push",
|
||||
link: "/",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
server.post("/notifications/test-push", async (req) => {
|
||||
return await svc.trigger({
|
||||
tenantId: requireTenant(req.user.tenant_id),
|
||||
@@ -90,3 +189,8 @@ export default async function notificationsRoutes(server: FastifyInstance) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function previewToken(token: string) {
|
||||
if (token.length <= 14) return token
|
||||
return `${token.slice(0, 6)}...${token.slice(-6)}`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user