Додані повідомлення та перепрацьована структура застосунку та api

This commit is contained in:
2026-03-15 00:25:10 +02:00
parent 85483b85bb
commit 4bc9c11512
101 changed files with 5763 additions and 2546 deletions

152
ws/utils/notification.js Normal file
View File

@@ -0,0 +1,152 @@
const db = require("../config/db");
const webpush = require('web-push');
const VAPID_PUBLIC_KEY = process.env.VAPID_PUBLIC_KEY;
const VAPID_PRIVATE_KEY = process.env.VAPID_PRIVATE_KEY;
webpush.setVapidDetails(
'mailto:rozenrod320@gmail.com',
VAPID_PUBLIC_KEY,
VAPID_PRIVATE_KEY
);
class Notification {
async sendSheep({ sheep_id, title, body, page }) {
const sql = `
SELECT * FROM subscription
WHERE sheep_id = ?
ORDER BY id
`;
db.all(sql, [sheep_id], async (err, rows) => {
if (err) {
console.error('DB error:', err.message);
return;
}
if (!rows.length) {
console.log(`🐑 No subscriptions found for sheep_id: ${sheep_id}`);
return;
}
console.log(`📨 Sending notification to ${rows.length} subscriptions...`);
const payload = JSON.stringify({
title: title ?? "Тестове повідомлення",
body: body ?? "Ви успішно підписалися на отримання push повідомлень!",
url: `https://${process.env.DOMAIN}${page ?? ""}`
});
const results = await Promise.allSettled(rows.map(row => {
const subscription = {
endpoint: row.endpoint,
keys: JSON.parse(row.keys),
};
return webpush.sendNotification(subscription, payload);
}));
const failed = results.filter(r => r.status === 'rejected').length;
console.log(`✅ Sent: ${rows.length - failed}, ❌ Failed: ${failed}`);
});
}
async sendGroup({ group_id, title, body, page }) {
const sql = `
SELECT
subscription.*
FROM
subscription
JOIN
sheeps
ON
sheeps.id = subscription.sheep_id
WHERE
sheeps.group_id = ?
ORDER BY
subscription.id;
`;
db.all(sql, [group_id], async (err, rows) => {
if (err) {
console.error('DB error:', err.message);
return;
}
if (!rows.length) {
console.log(`🐑 No subscriptions found for sheep_id: ${sheep_id}`);
return;
}
console.log(`📨 Sending notification to ${rows.length} subscriptions...`);
const payload = JSON.stringify({
title: title ?? "Тестове повідомлення",
body: body ?? "Ви успішно підписалися на отримання push повідомлень!",
url: `https://${process.env.DOMAIN}${page ?? ""}`
});
const results = await Promise.allSettled(rows.map(row => {
const subscription = {
endpoint: row.endpoint,
keys: JSON.parse(row.keys),
};
return webpush.sendNotification(subscription, payload);
}));
const failed = results.filter(r => r.status === 'rejected').length;
console.log(`✅ Sent: ${rows.length - failed}, ❌ Failed: ${failed}`);
});
}
async sendStand({ title, body, page }) {
const sql = `
SELECT
subscription.*
FROM
subscription
JOIN
sheeps
ON sheeps.id = subscription.sheep_id
JOIN
possibilities
ON possibilities.sheep_id = sheeps.id
WHERE
possibilities.can_view_stand = '1'
ORDER BY
subscription.id;
`;
db.all(sql, async (err, rows) => {
if (err) {
console.error('DB error:', err.message);
return;
}
if (!rows.length) {
console.log(`🐑 No subscriptions`);
return;
}
console.log(`📨 Sending notification to ${rows.length} subscriptions...`);
const payload = JSON.stringify({
title: title ?? "Тестове повідомлення",
body: body ?? "Ви успішно підписалися на отримання push повідомлень!",
url: `https://${process.env.DOMAIN}${page ?? ""}`
});
const results = await Promise.allSettled(rows.map(row => {
const subscription = {
endpoint: row.endpoint,
keys: JSON.parse(row.keys),
};
return webpush.sendNotification(subscription, payload);
}));
const failed = results.filter(r => r.status === 'rejected').length;
console.log(`✅ Sent: ${rows.length - failed}, ❌ Failed: ${failed}`);
});
}
};
module.exports = new Notification();