const axios = require('axios'); const adminConfig = require('./adminConfig'); const { readNotificationSettings } = require('./userSettingsStore'); function formatDateLabel(dateInput) { try { const date = new Date(dateInput); if (Number.isNaN(date.getTime())) { return 'unbekanntes Datum'; } return date.toLocaleString('de-DE', { weekday: 'short', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } catch (_error) { return 'unbekanntes Datum'; } } async function sendNtfyNotification(adminNtfy, userNtfy, payload) { if (!adminNtfy?.enabled || !userNtfy?.enabled || !userNtfy.topic) { return; } const server = (userNtfy.serverUrl || adminNtfy.serverUrl || 'https://ntfy.sh').replace(/\/+$/, ''); const topicPrefix = adminNtfy.topicPrefix ? `${adminNtfy.topicPrefix.replace(/\/+$/, '')}/` : ''; const topic = `${topicPrefix}${userNtfy.topic.replace(/^\//, '')}`; const url = `${server}/${topic}`; const headers = { Title: payload.title, Priority: payload.priority || 'default' }; if (adminNtfy.username && adminNtfy.password) { const credentials = Buffer.from(`${adminNtfy.username}:${adminNtfy.password}`).toString('base64'); headers.Authorization = `Basic ${credentials}`; } await axios.post(url, payload.message, { headers, timeout: 15000 }); } async function sendTelegramNotification(adminTelegram, userTelegram, payload) { if (!adminTelegram?.enabled || !adminTelegram.botToken || !userTelegram?.enabled || !userTelegram.chatId) { return; } const endpoint = `https://api.telegram.org/bot${adminTelegram.botToken}/sendMessage`; await axios.post( endpoint, { chat_id: userTelegram.chatId, text: `${payload.title}\n${payload.message}`, disable_web_page_preview: true }, { timeout: 15000 } ); } async function notifyChannels(profileId, template) { const adminSettings = adminConfig.readSettings(); const userSettings = readNotificationSettings(profileId); try { await Promise.allSettled([ sendNtfyNotification(adminSettings.notifications?.ntfy, userSettings.notifications?.ntfy, template), sendTelegramNotification(adminSettings.notifications?.telegram, userSettings.notifications?.telegram, template) ]); } catch (error) { console.error('[NOTIFICATIONS] Versand fehlgeschlagen:', error.message); } } async function sendSlotNotification({ profileId, storeName, pickupDate, onlyNotify, booked }) { const dateLabel = formatDateLabel(pickupDate); const title = onlyNotify ? `Slot verfügbar bei ${storeName}` : booked ? `Slot gebucht bei ${storeName}` : `Slot gefunden bei ${storeName}`; const message = onlyNotify ? `Es wurde ein freier Slot am ${dateLabel} entdeckt.` : booked ? `Der Slot am ${dateLabel} wurde erfolgreich gebucht.` : `Es wurde ein Slot am ${dateLabel} gefunden.`; await notifyChannels(profileId, { title, message, priority: booked ? 'high' : 'default' }); } async function sendTestNotification(profileId, channel) { const title = 'Pickup Benachrichtigung (Test)'; const message = 'Das ist eine Testnachricht. Bei Fragen wende dich bitte an den Admin.'; const adminSettings = adminConfig.readSettings(); const userSettings = readNotificationSettings(profileId); const tasks = []; if (!channel || channel === 'ntfy') { tasks.push( sendNtfyNotification(adminSettings.notifications?.ntfy, userSettings.notifications?.ntfy, { title, message, priority: 'default' }) ); } if (!channel || channel === 'telegram') { tasks.push( sendTelegramNotification(adminSettings.notifications?.telegram, userSettings.notifications?.telegram, { title, message, priority: 'default' }) ); } if (tasks.length === 0) { throw new Error('Kein unterstützter Kanal oder Kanal deaktiviert.'); } await Promise.all(tasks); } module.exports = { sendSlotNotification, sendTestNotification };