const db = require("../config/db"); const webpush = require('web-push'); const TelegramBot = require("node-telegram-bot-api"); const util = require('util'); const dbRun = util.promisify(db.run).bind(db); 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 ); const TOKEN = process.env.TELEGRAM_TOKEN; const STAND_CHAT_ID = process.env.STAND_CHAT_ID; const bot = new TelegramBot(TOKEN, { polling: false }); 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}`); }); // Формуємо повне повідомлення const fullMessage = `📢 ${title}\n\n${body.replace('«', '«').replace('»', '»')}`; try { const sentMessage = await bot.sendMessage(STAND_CHAT_ID, fullMessage, { parse_mode: 'HTML' }); // Зберігаємо ID нового повідомлення у базі await dbRun( `INSERT INTO sent_messages (last_message_id, created_at) VALUES (?, ?)`, [sentMessage.message_id, Date.now()] ); console.log(`✅ Сповіщення надіслано для стенду: ${stand.title}`); } catch (err) { console.error('❌ Помилка відправки тексту:', err.message); } } }; module.exports = new Notification();