Files
Ninjaserver/scripts/iphone_notifications.js
2025-09-23 14:13:24 +02:00

130 lines
3.8 KiB
JavaScript

const { Pool } = require('pg');
const webpush = require('web-push');
// Database connection
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'ninjacross',
password: 'postgres',
port: 5432,
});
// VAPID Keys (generate with: webpush.generateVAPIDKeys())
const vapidKeys = {
publicKey: 'BEl62iUYgUivxIkv69yViEuiBIa40HI6F2B5L4h7Q8Y',
privateKey: 'your-private-key-here'
};
webpush.setVapidDetails(
'mailto:admin@ninjacross.es',
vapidKeys.publicKey,
vapidKeys.privateKey
);
// Store subscription endpoint for each player
async function storePlayerSubscription(playerId, subscription) {
try {
await pool.query(`
INSERT INTO player_subscriptions (player_id, endpoint, p256dh, auth)
VALUES ($1, $2, $3, $4)
`, [
playerId,
subscription.endpoint,
subscription.keys.p256dh,
subscription.keys.auth
]);
console.log(`✅ Subscription stored for player ${playerId}`);
} catch (error) {
console.error('Error storing subscription:', error);
}
}
// Send push notification to player
async function sendPushNotification(playerId, title, message, icon = '🏆') {
try {
const result = await pool.query(`
SELECT endpoint, p256dh, auth
FROM player_subscriptions
WHERE player_id = $1
`, [playerId]);
if (result.rows.length === 0) {
console.log(`No subscription found for player ${playerId}`);
return;
}
const subscription = {
endpoint: result.rows[0].endpoint,
keys: {
p256dh: result.rows[0].p256dh,
auth: result.rows[0].auth
}
};
const payload = JSON.stringify({
title: title,
body: message,
icon: '/pictures/favicon.ico',
badge: '/pictures/favicon.ico',
data: {
url: '/dashboard.html'
}
});
await webpush.sendNotification(subscription, payload);
console.log(`✅ Push notification sent to player ${playerId}`);
} catch (error) {
console.error('Error sending push notification:', error);
}
}
// Send best time notifications
async function sendBestTimeNotifications() {
try {
console.log('🔔 Sending best time notifications...');
// Get daily best
const dailyResult = await pool.query(`
WITH daily_best AS (
SELECT
t.player_id,
MIN(t.recorded_time) as best_time,
CONCAT(p.firstname, ' ', p.lastname) as player_name
FROM times t
JOIN players p ON t.player_id = p.id
WHERE DATE(t.created_at AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE
GROUP BY t.player_id, p.firstname, p.lastname
)
SELECT
player_id,
player_name,
best_time
FROM daily_best
WHERE best_time = (SELECT MIN(best_time) FROM daily_best)
LIMIT 1
`);
if (dailyResult.rows.length > 0) {
const daily = dailyResult.rows[0];
await sendPushNotification(
daily.player_id,
'🏆 Tageskönig!',
`Glückwunsch ${daily.player_name}! Du hast die beste Zeit des Tages mit ${daily.best_time} erreicht!`
);
}
console.log('✅ Best time notifications sent');
} catch (error) {
console.error('❌ Error sending best time notifications:', error);
}
}
module.exports = {
storePlayerSubscription,
sendPushNotification,
sendBestTimeNotifications
};