File size: 1,624 Bytes
e14bacb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | const webpush = require('web-push');
const User = require('../models/User');
// Configure Keys (Ensure these are in your .env)
webpush.setVapidDetails(
process.env.VAPID_EMAIL,
process.env.VAPID_PUBLIC_KEY,
process.env.VAPID_PRIVATE_KEY
);
// SEND TO ONE USER
const sendToUser = async (userId, title, message, url = '/') => {
try {
const user = await User.findById(userId);
if (user && user.pushSubscription) {
await webpush.sendNotification(
user.pushSubscription,
JSON.stringify({ title, body: message, url })
);
}
} catch (err) {
// 410 = Gone (User unsubscribed/cleared cache)
if (err.statusCode === 410) {
await User.findByIdAndUpdate(userId, { $unset: { pushSubscription: "" } });
}
console.error("Push Error (Single):", err.statusCode);
}
};
// SEND TO EVERYONE (Batching for performance)
const sendGlobal = async (title, message, url = '/') => {
try {
// Fetch users who have a subscription
const users = await User.find({ pushSubscription: { $exists: true } });
const payload = JSON.stringify({ title, body: message, url });
console.log(`📢 Sending Global Push to ${users.length} devices...`);
const promises = users.map(user =>
webpush.sendNotification(user.pushSubscription, payload).catch(err => {
if (err.statusCode === 410) {
User.findByIdAndUpdate(user._id, { $unset: { pushSubscription: "" } });
}
})
);
await Promise.all(promises);
} catch (err) {
console.error("Push Error (Global):", err);
}
};
module.exports = { sendToUser, sendGlobal };
|