const webpush = require('web-push'); // VAPID Keys (sollten in Umgebungsvariablen gespeichert werden) const vapidKeys = { publicKey: 'BJmNVx0C3XeVxeKGTP9c-Z4HcuZNmdk6QdiLocZgCmb-miCS0ESFO3W2TvJlRhhNAShV63pWA5p36BTVSetyTds', privateKey: 'HBdRCtmZUAzsWpVjZ2LDaoWliIPHldAb5ExAt8bvDeg' }; // Configure web-push webpush.setVapidDetails( 'mailto:ninjacross@example.com', vapidKeys.publicKey, vapidKeys.privateKey ); class PushService { constructor() { this.subscriptions = new Map(); // In production: use database } // Subscribe user to push notifications subscribe(userId, subscription) { this.subscriptions.set(userId, subscription); console.log(`User ${userId} subscribed to push notifications`); } // Unsubscribe user from push notifications unsubscribe(userId) { this.subscriptions.delete(userId); console.log(`User ${userId} unsubscribed from push notifications`); } // Send push notification to specific user async sendToUser(userId, payload) { const subscription = this.subscriptions.get(userId); if (!subscription) { console.log(`No subscription found for user ${userId}`); return false; } try { await webpush.sendNotification(subscription, JSON.stringify(payload)); console.log(`Push notification sent to user ${userId}`); return true; } catch (error) { console.error(`Error sending push notification to user ${userId}:`, error); // If subscription is invalid, remove it if (error.statusCode === 410) { this.unsubscribe(userId); } return false; } } // Send push notification to all subscribed users async sendToAll(payload) { const results = []; for (const [userId, subscription] of this.subscriptions) { const result = await this.sendToUser(userId, payload); results.push({ userId, success: result }); } return results; } // Send achievement notification async sendAchievementNotification(userId, achievementName) { const payload = { title: '🏆 Neues Achievement!', body: `Du hast "${achievementName}" erreicht!`, icon: '/pictures/icon-192.png', badge: '/pictures/icon-192.png', data: { type: 'achievement', achievement: achievementName, timestamp: Date.now() }, actions: [ { action: 'view', title: 'Dashboard öffnen' } ] }; return await this.sendToUser(userId, payload); } // Send best time notification async sendBestTimeNotification(userId, timeType, locationName) { const payload = { title: `🏁 ${timeType} Bestzeit!`, body: `Du hast die beste Zeit in ${locationName} erreicht!`, icon: '/pictures/icon-192.png', badge: '/pictures/icon-192.png', data: { type: 'best_time', timeType: timeType, location: locationName, timestamp: Date.now() }, actions: [ { action: 'view', title: 'Dashboard öffnen' } ] }; return await this.sendToUser(userId, payload); } // Get subscription count getSubscriptionCount() { return this.subscriptions.size; } // Get all user IDs with subscriptions getSubscribedUsers() { return Array.from(this.subscriptions.keys()); } } module.exports = new PushService();