background.js aktualisiert

This commit is contained in:
2025-12-06 15:13:40 +00:00
parent f78de6f2ff
commit 43699a210f

View File

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