query("SELECT setting_value FROM settings WHERE setting_key = 'telegram_token'"); $token = $stmt->fetchColumn(); $stmt = db()->query("SELECT setting_value FROM settings WHERE setting_key = 'telegram_chat_id'"); $chatId = $stmt->fetchColumn(); if (!$token || !$chatId) return false; $url = "https://api.telegram.org/bot$token/sendMessage"; $data = [ 'chat_id' => $chatId, 'text' => "🔔 *Uptime Alert*\n" . $text, 'parse_mode' => 'Markdown' ]; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; $context = stream_context_create($options); return file_get_contents($url, false, $context); } catch (Exception $e) { return false; } } echo "Yumee Panels Background Worker Started (v1.1)... "; while (true) { try { $start_time = microtime(true); // Fetch monitors $stmt = db()->query("SELECT * FROM monitors"); $monitors = $stmt->fetchAll(); if (!empty($monitors)) { $mh = curl_multi_init(); $handles = []; foreach ($monitors as $m) { $ch = curl_init($m['url']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'YumeePinger-Worker/1.1'); curl_multi_add_handle($mh, $ch); $handles[$m['id']] = ['ch' => $ch, 'data' => $m]; } $running = null; do { curl_multi_exec($mh, $running); usleep(5000); } while ($running); foreach ($handles as $id => $h) { $ch = $h['ch']; $m = $h['data']; $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $latency = round(curl_getinfo($ch, CURLINFO_TOTAL_TIME) * 1000); curl_multi_remove_handle($mh, $ch); curl_close($ch); $is_up = ($http_code >= 200 && $http_code < 400); $prev_status = $m['last_status']; $prev_notified = $m['last_notified_status']; // Update monitor $upd = db()->prepare("UPDATE monitors SET last_status = ?, last_latency = ? WHERE id = ?"); $upd->execute([$http_code, $latency, $id]); // Log entry $log = db()->prepare("INSERT INTO monitor_logs (monitor_id, status_code, latency) VALUES (?, ?, ?)"); $log->execute([$id, $http_code, $latency]); // Notification logic: only notify on transition if ($prev_notified !== null) { $prev_was_up = ($prev_notified >= 200 && $prev_notified < 400); if ($is_up !== $prev_was_up) { $status_str = $is_up ? "✅ UP" : "❌ DOWN"; $msg = "Monitor *{$m['name']}* is now $status_str\nURL: {$m['url']}\nStatus: $http_code\nLatency: {$latency}ms"; sendTelegramMessage($msg); // Update last notified status $upd_notify = db()->prepare("UPDATE monitors SET last_notified_status = ? WHERE id = ?"); $upd_notify->execute([$http_code, $id]); } } else { // Initial notification status set $upd_notify = db()->prepare("UPDATE monitors SET last_notified_status = ? WHERE id = ?"); $upd_notify->execute([$http_code, $id]); } } curl_multi_close($mh); } // Record heartbeat in settings for UI to check db()->prepare("INSERT INTO settings (setting_key, setting_value) VALUES ('worker_heartbeat', UNIX_TIMESTAMP()) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)")->execute(); $end_time = microtime(true); $execution_time = ($end_time - $start_time); $sleep_time = max(0.1, 1 - $execution_time); usleep($sleep_time * 1000000); } catch (Exception $e) { echo "Error: " . $e->getMessage() . "\n"; sleep(2); } }