Diverse änderungen am Push system

This commit is contained in:
2025-09-16 21:00:12 +02:00
parent 69e3985af3
commit b2fc63e2d0
7 changed files with 992 additions and 164 deletions

View File

@@ -2848,12 +2848,33 @@ router.get('/v1/public/best-times', async (req, res) => {
// Subscribe to push notifications
router.post('/v1/public/subscribe', async (req, res) => {
try {
const { endpoint, keys } = req.body;
console.log('📱 Push subscription request received:', JSON.stringify(req.body, null, 2));
const { endpoint, keys, playerId: requestPlayerId } = req.body;
const userId = req.session.userId || 'anonymous';
// Generate a UUID for anonymous users or use existing UUID
// Validate required fields
if (!endpoint) {
console.error('❌ Missing endpoint in request');
return res.status(400).json({
success: false,
message: 'Endpoint ist erforderlich'
});
}
if (!keys || !keys.p256dh || !keys.auth) {
console.error('❌ Missing keys in request:', keys);
return res.status(400).json({
success: false,
message: 'Push-Keys sind erforderlich'
});
}
// Use playerId from request if provided, otherwise generate one
let playerId;
if (userId === 'anonymous') {
if (requestPlayerId) {
playerId = requestPlayerId;
} else if (userId === 'anonymous') {
// Generate a random UUID for anonymous users
const { v4: uuidv4 } = require('uuid');
playerId = uuidv4();
@@ -2861,6 +2882,8 @@ router.post('/v1/public/subscribe', async (req, res) => {
playerId = userId;
}
console.log(`📱 Processing subscription for player: ${playerId}`);
// Store subscription in database
await pool.query(`
INSERT INTO player_subscriptions (player_id, endpoint, p256dh, auth, created_at)
@@ -2890,7 +2913,8 @@ router.post('/v1/public/subscribe', async (req, res) => {
res.json({
success: true,
message: 'Push subscription erfolgreich gespeichert'
message: 'Push subscription erfolgreich gespeichert',
playerId: playerId
});
} catch (error) {
console.error('Error storing push subscription:', error);
@@ -2902,6 +2926,42 @@ router.post('/v1/public/subscribe', async (req, res) => {
}
});
// Unsubscribe from push notifications
router.post('/v1/public/unsubscribe', async (req, res) => {
try {
const { playerId } = req.body;
if (!playerId) {
return res.status(400).json({
success: false,
message: 'Player ID erforderlich'
});
}
// Remove from push service
pushService.unsubscribe(playerId);
// Remove from database
await pool.query(`
DELETE FROM player_subscriptions
WHERE player_id = $1
`, [playerId]);
console.log(`User ${playerId} unsubscribed from push notifications`);
res.json({
success: true,
message: 'Push subscription erfolgreich entfernt'
});
} catch (error) {
console.error('Error removing push subscription:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Entfernen der Push Subscription'
});
}
});
// Test push notification endpoint
router.post('/v1/public/test-push', async (req, res) => {
try {
@@ -2960,6 +3020,63 @@ router.get('/v1/public/push-status', async (req, res) => {
}
});
// Check if notification was already sent today
router.get('/v1/public/notification-sent/:playerId/:type', async (req, res) => {
try {
const { playerId, type } = req.params;
const { achievementId, locationId } = req.query;
const today = new Date().toISOString().split('T')[0];
const result = await pool.query(`
SELECT COUNT(*) as count
FROM sent_notifications
WHERE player_id = $1
AND notification_type = $2
AND (achievement_id = $3 OR ($3 IS NULL AND achievement_id IS NULL))
AND (location_id = $4 OR ($4 IS NULL AND location_id IS NULL))
AND DATE(sent_at) = $5
`, [playerId, type, achievementId || null, locationId || null, today]);
const wasSent = parseInt(result.rows[0].count) > 0;
res.json({
success: true,
wasSent: wasSent
});
} catch (error) {
console.error('Error checking notification status:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Prüfen des Notification-Status'
});
}
});
// Mark notification as sent
router.post('/v1/public/notification-sent', async (req, res) => {
try {
const { playerId, notificationType, achievementId, locationId } = req.body;
await pool.query(`
INSERT INTO sent_notifications (player_id, notification_type, achievement_id, location_id)
VALUES ($1, $2, $3, $4)
ON CONFLICT DO NOTHING
`, [playerId, notificationType, achievementId || null, locationId || null]);
res.json({
success: true,
message: 'Notification als gesendet markiert'
});
} catch (error) {
console.error('Error marking notification as sent:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Markieren der Notification'
});
}
});
// ==================== ANALYTICS HELPER FUNCTIONS ====================
async function getPerformanceTrends(playerId) {