Diverse änderungen am Push system
This commit is contained in:
125
routes/api.js
125
routes/api.js
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user