From 43699a210fdc7b75a5d88a531067b7dc4cb4ee45 Mon Sep 17 00:00:00 2001 From: M_Viper Date: Sat, 6 Dec 2025 15:13:40 +0000 Subject: [PATCH] background.js aktualisiert --- background.js | 366 ++++++++++++++++++++++++++++---------------------- 1 file changed, 202 insertions(+), 164 deletions(-) diff --git a/background.js b/background.js index ecd5c45..95a1b1e 100644 --- a/background.js +++ b/background.js @@ -1,165 +1,203 @@ -// In Minuten (1 Minute) -const CHECK_INTERVAL_MINUTES = 1; -const HISTORY_RETENTION_DAYS = 7; - -// Funktion, um einen einzelnen Dienst zu prüfen und die Antwortzeit zu messen -async function checkService(service) { - const startTime = performance.now(); - try { - const response = await fetch(service.adresse, { method: 'HEAD', mode: 'no-cors', cache: 'no-cache' }); - const endTime = performance.now(); - const responseTime = Math.round(endTime - startTime); - return { status: 'online', responseTime }; - } catch (error) { - return { status: 'offline', responseTime: null }; - } -} - -// Funktion, um Verlaufsdaten zu aktualisieren -async function updateHistory(serviceName, status) { - const data = await chrome.storage.local.get({ history: {} }); - const history = data.history; - const now = new Date(); - const hourKey = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}`; - - if (!history[serviceName]) history[serviceName] = {}; - if (!history[serviceName][hourKey]) history[serviceName][hourKey] = { checks: 0, up_checks: 0 }; - - history[serviceName][hourKey].checks++; - if (status === 'online') history[serviceName][hourKey].up_checks++; - - await chrome.storage.local.set({ history }); -} - -// Funktion, um alte Verlaufsdaten zu löschen -async function cleanupHistory() { - const data = await chrome.storage.local.get({ history: {} }); - const history = data.history; - const cutoffDate = new Date(); - cutoffDate.setDate(cutoffDate.getDate() - HISTORY_RETENTION_DAYS); - const cutoffHourKey = `${cutoffDate.getFullYear()}-${String(cutoffDate.getMonth() + 1).padStart(2, '0')}-${String(cutoffDate.getDate()).padStart(2, '0')}-${String(cutoffDate.getHours()).padStart(2, '0')}`; - - for (const serviceName in history) { - for (const hourKey in history[serviceName]) { - if (hourKey < cutoffHourKey) delete history[serviceName][hourKey]; - } - if (Object.keys(history[serviceName]).length === 0) delete history[serviceName]; - } - await chrome.storage.local.set({ history }); -} - -// NEU: Funktion zum Senden einer Discord-Benachrichtigung -async function sendDiscordNotification(service, status, responseTime = null) { - const settings = await chrome.storage.sync.get({ discordWebhookUrl: '' }); - if (!settings.discordWebhookUrl) return; // Kein Webhook konfiguriert - - const isOnline = status === 'online'; - const embed = { - title: `Status-Update: ${service.name}`, - url: service.adresse, - description: isOnline ? '✅ Der Server ist wieder online.' : '❌ Der Server ist nicht erreichbar.', - color: isOnline ? 0x31A24C : 0xE4606D, // Grün / Rot - timestamp: new Date().toISOString(), - fields: [ - { name: 'Status', value: status.toUpperCase(), inline: true }, - { name: 'Adresse', value: service.adresse, inline: true } - ] - }; - - if (isOnline && responseTime !== null) { - embed.fields.push({ name: 'Antwortzeit', value: `${responseTime} ms`, inline: true }); - } - - const payload = { - username: 'Uptime Monitor', - embeds: [embed] - }; - - try { - const response = await fetch(settings.discordWebhookUrl, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload) - }); - if (!response.ok) { - console.error('Discord-Webhook fehlgeschlagen:', response.statusText, await response.text()); - } - } catch (error) { - console.error('Fehler beim Senden der Discord-Benachrichtigung:', error); - } -} - -// MODIFIZIERT: Funktion, um alle Dienste zu prüfen und Benachrichtigungen zu senden -async function checkAllServices() { - const data = await chrome.storage.sync.get({ services: [], notifyOnline: false }); - const services = data.services; - const notifyOnline = data.notifyOnline; - - if (services.length === 0) return; - - const lastStatusData = await chrome.storage.local.get({ serviceStatus: {} }); - const lastStatus = lastStatusData.serviceStatus; - - for (const service of services) { - const currentResult = await checkService(service); - const previousResult = lastStatus[service.name]; - lastStatus[service.name] = currentResult; - - // Benachrichtigung für Offline-Wechsel - if (previousResult?.status === 'online' && currentResult.status === 'offline') { - chrome.notifications.create({ - type: 'basic', iconUrl: 'icons/notification_warning.png', - title: `Server "${service.name}" ist offline`, - message: 'Der Dienst antwortet nicht mehr.', contextMessage: `Adresse: ${service.adresse}`, - priority: 1, isClickable: true, - buttons: [{ title: 'Anzeigen' }, { title: 'Ignorieren' }] - }); - await sendDiscordNotification(service, 'offline'); // NEU - } - - // Benachrichtigung für Online-Wechsel (wenn aktiviert) - if (notifyOnline && previousResult?.status === 'offline' && currentResult.status === 'online') { - chrome.notifications.create({ - type: 'basic', iconUrl: 'icons/notification_warning.png', - title: `Server "${service.name}" ist wieder online!`, - message: 'Der Dienst ist wieder erreichbar.', contextMessage: `Adresse: ${service.adresse}`, - priority: 0, isClickable: true, - buttons: [{ title: 'Anzeigen' }] - }); - await sendDiscordNotification(service, 'online', currentResult.responseTime); // NEU - } - - // Verlaufsdaten aktualisieren - await updateHistory(service.name, currentResult.status); - } - - await chrome.storage.local.set({ serviceStatus: lastStatus }); -} - -// Alarm und Setup-Logik -async function setupAlarm() { - const data = await chrome.storage.sync.get({ checkInterval: 1 }); - const intervalMinutes = data.checkInterval; - await chrome.alarms.clear('uptimeCheck'); - chrome.alarms.create('uptimeCheck', { periodInMinutes: intervalMinutes }); -} - -chrome.runtime.onInstalled.addListener(() => { setupAlarm(); }); -chrome.runtime.onStartup.addListener(() => { setupAlarm(); }); -chrome.alarms.onAlarm.addListener((alarm) => { if (alarm.name === 'uptimeCheck') checkAllServices(); }); - -// Nachrichtensystem für Einstellungen -chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { - if (message.type === 'updateInterval') { setupAlarm().then(() => sendResponse({ status: 'ok' })); return true; } - if (message.type === 'cleanupHistory') { cleanupHistory().then(() => sendResponse({ status: 'ok' })); return true; } -}); - -// Benachrichtigungs-Listener -chrome.notifications.onButtonClicked.addListener((notificationId, buttonIndex) => { - if (buttonIndex === 0) chrome.action.openPopup(); - chrome.notifications.clear(notificationId); -}); -chrome.notifications.onClicked.addListener((notificationId) => { - chrome.action.openPopup(); - chrome.notifications.clear(notificationId); +// In Minuten (1 Minute) +const CHECK_INTERVAL_MINUTES = 1; +const HISTORY_RETENTION_DAYS = 7; + +// Funktion, um einen einzelnen Dienst zu prüfen und die Antwortzeit zu messen +async function checkService(service) { + const startTime = performance.now(); + try { + const response = await fetch(service.adresse, { method: 'HEAD', mode: 'no-cors', cache: 'no-cache' }); + const endTime = performance.now(); + const responseTime = Math.round(endTime - startTime); + return { status: 'online', responseTime }; + } catch (error) { + return { status: 'offline', responseTime: null }; + } +} + +// Funktion, um Verlaufsdaten zu aktualisieren +async function updateHistory(serviceName, status) { + const data = await chrome.storage.local.get({ history: {} }); + const history = data.history; + const now = new Date(); + const hourKey = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}`; + + if (!history[serviceName]) history[serviceName] = {}; + if (!history[serviceName][hourKey]) history[serviceName][hourKey] = { checks: 0, up_checks: 0 }; + + history[serviceName][hourKey].checks++; + if (status === 'online') history[serviceName][hourKey].up_checks++; + + await chrome.storage.local.set({ history }); +} + +// Funktion, um alte Verlaufsdaten zu löschen +async function cleanupHistory() { + const data = await chrome.storage.local.get({ history: {} }); + const history = data.history; + const cutoffDate = new Date(); + cutoffDate.setDate(cutoffDate.getDate() - HISTORY_RETENTION_DAYS); + const cutoffHourKey = `${cutoffDate.getFullYear()}-${String(cutoffDate.getMonth() + 1).padStart(2, '0')}-${String(cutoffDate.getDate()).padStart(2, '0')}-${String(cutoffDate.getHours()).padStart(2, '0')}`; + + for (const serviceName in history) { + for (const hourKey in history[serviceName]) { + if (hourKey < cutoffHourKey) delete history[serviceName][hourKey]; + } + if (Object.keys(history[serviceName]).length === 0) delete history[serviceName]; + } + await chrome.storage.local.set({ history }); +} + +// Funktion zum Senden einer Discord-Benachrichtigung +async function sendDiscordNotification(service, status, responseTime = null) { + const settings = await chrome.storage.sync.get({ discordWebhookUrl: '' }); + if (!settings.discordWebhookUrl) return; // Kein Webhook konfiguriert + + const isOnline = status === 'online'; + const embed = { + title: `Status-Update: ${service.name}`, + url: service.adresse, + description: isOnline ? '✅ Der Server ist wieder online.' : '❌ Der Server ist nicht erreichbar.', + color: isOnline ? 0x31A24C : 0xE4606D, // Grün / Rot + timestamp: new Date().toISOString(), + fields: [ + { name: 'Status', value: status.toUpperCase(), inline: true }, + { name: 'Adresse', value: service.adresse, inline: true } + ] + }; + + if (isOnline && responseTime !== null) { + embed.fields.push({ name: 'Antwortzeit', value: `${responseTime} ms`, inline: true }); + } + + const payload = { + username: 'Uptime Monitor', + embeds: [embed] + }; + + try { + const response = await fetch(settings.discordWebhookUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload) + }); + if (!response.ok) { + console.error('Discord-Webhook fehlgeschlagen:', response.statusText, await response.text()); + } + } catch (error) { + console.error('Fehler beim Senden der Discord-Benachrichtigung:', error); + } +} + +// NEU: Funktion zum Senden einer Telegram-Benachrichtigung +async function sendTelegramNotification(service, status, responseTime = null) { + const settings = await chrome.storage.sync.get({ telegramBotToken: '', telegramChatId: '' }); + if (!settings.telegramBotToken || !settings.telegramChatId) return; // Nicht konfiguriert + + const isOnline = status === 'online'; + const emoji = isOnline ? '✅' : '❌'; + let message = `${emoji} *${service.name}*\nStatus: ${status.toUpperCase()}\nAdresse: ${service.adresse}`; + + if (isOnline && responseTime !== null) { + message += `\nAntwortzeit: ${responseTime} ms`; + } + + const url = `https://api.telegram.org/bot${settings.telegramBotToken}/sendMessage`; + + const payload = { + chat_id: settings.telegramChatId, + text: message, + parse_mode: 'Markdown' // Für Markdown-Formatierung + }; + + try { + const response = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload) + }); + if (!response.ok) { + const errorData = await response.json(); + console.error('Telegram-Bot API fehlgeschlagen:', response.statusText, errorData); + } + } catch (error) { + console.error('Fehler beim Senden der Telegram-Benachrichtigung:', error); + } +} + +// MODIFIZIERT: Funktion, um alle Dienste zu prüfen und Benachrichtigungen zu senden +async function checkAllServices() { + const data = await chrome.storage.sync.get({ services: [], notifyOnline: false }); + const services = data.services; + const notifyOnline = data.notifyOnline; + + if (services.length === 0) return; + + const lastStatusData = await chrome.storage.local.get({ serviceStatus: {} }); + const lastStatus = lastStatusData.serviceStatus; + + for (const service of services) { + const currentResult = await checkService(service); + const previousResult = lastStatus[service.name]; + lastStatus[service.name] = currentResult; + + // Benachrichtigung für Offline-Wechsel + if (previousResult?.status === 'online' && currentResult.status === 'offline') { + chrome.notifications.create({ + type: 'basic', + iconUrl: 'icons/notification_warning.png', + title: `Server "${service.name}" ist offline`, + message: 'Der Dienst antwortet nicht mehr.', + contextMessage: `Adresse: ${service.adresse}`, + priority: 1, + isClickable: true + }); + await sendDiscordNotification(service, 'offline'); + await sendTelegramNotification(service, 'offline'); // NEU + } + + // Benachrichtigung für Online-Wechsel (wenn aktiviert) + if (notifyOnline && previousResult?.status === 'offline' && currentResult.status === 'online') { + chrome.notifications.create({ + type: 'basic', + iconUrl: 'icons/notification_warning.png', + title: `Server "${service.name}" ist wieder online!`, + message: 'Der Dienst ist wieder erreichbar.', + contextMessage: `Adresse: ${service.adresse}`, + priority: 0, + isClickable: true + }); + await sendDiscordNotification(service, 'online', currentResult.responseTime); + await sendTelegramNotification(service, 'online', currentResult.responseTime); + } + + // Verlaufsdaten aktualisieren + await updateHistory(service.name, currentResult.status); + } + + await chrome.storage.local.set({ serviceStatus: lastStatus }); +} + +// Alarm und Setup-Logik +async function setupAlarm() { + const data = await chrome.storage.sync.get({ checkInterval: 1 }); + const intervalMinutes = data.checkInterval; + await chrome.alarms.clear('uptimeCheck'); + chrome.alarms.create('uptimeCheck', { periodInMinutes: intervalMinutes }); +} + +chrome.runtime.onInstalled.addListener(() => { setupAlarm(); }); +chrome.runtime.onStartup.addListener(() => { setupAlarm(); }); +chrome.alarms.onAlarm.addListener((alarm) => { if (alarm.name === 'uptimeCheck') checkAllServices(); }); + +// Nachrichtensystem für Einstellungen +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.type === 'updateInterval') { setupAlarm().then(() => sendResponse({ status: 'ok' })); return true; } + if (message.type === 'cleanupHistory') { cleanupHistory().then(() => sendResponse({ status: 'ok' })); return true; } +}); + +// Benachrichtigungs-Listener +chrome.notifications.onClicked.addListener((notificationId) => { + chrome.action.openPopup(); + chrome.notifications.clear(notificationId); }); \ No newline at end of file