get(); foreach ($apis as $api) { $name = $api->name; $url = $api->url; $key = $api->key; $status = $api->value; // 0 = up, 1 = down try { Log::info("Checking API Health: {$name} ({$url})"); $response = Http::timeout(5)->get($url); if ($response->successful()) { // If it was down before → now it's back if ($status == 1) { DB::table('system_statuses') ->where('key', $key) ->update([ 'value' => false, 'updated_at' => now(), ]); Log::info("✅ {$name} recovered, DB flag reset."); $this->sendRecoveryNotification($name); } $this->info("✅ {$name} is working fine."); continue; } } catch (\Exception $e) { Log::error("❌ API Health FAILED: {$name} ({$url}) | Error: " . $e->getMessage()); } // If it was already down → don't send another notification if ($status == 1) { Log::warning("⚠️ {$name} still down, alerts already sent. Skipping..."); continue; } // First time going down DB::table('system_statuses') ->where('key', $key) ->update([ 'value' => true, 'last_triggered_at' => Carbon::now(), 'updated_at' => now(), ]); $this->sendDownNotification($name); // $this->sendCall($name); } } private function sendDownNotification($apiName) { $users = User::all(); foreach ($users as $user) { $placeholder = new NotificationPlaceholder(); $placeholder->setRecipient($user); $placeholder->setAuthorUser($user); $placeholder->setAuthor("System"); $placeholder->setColor('bg-red'); $placeholder->setIcon('alert-triangle'); $placeholder->setContent("🚨 {$apiName} is down!"); $placeholder->setUrl(url('/')); $user->notify(new GenericNotification($placeholder)); } $this->info("🚨 Notifications sent for {$apiName} DOWN to all users."); } private function sendRecoveryNotification($apiName) { $users = User::all(); foreach ($users as $user) { $placeholder = new NotificationPlaceholder(); $placeholder->setRecipient($user); $placeholder->setAuthorUser($user); $placeholder->setAuthor("System"); $placeholder->setColor('bg-green'); $placeholder->setIcon('check-circle'); $placeholder->setContent("✅ {$apiName} has recovered!"); $placeholder->setUrl(url('/')); $user->notify(new GenericNotification($placeholder)); } $this->info("✅ Notifications sent for {$apiName} RECOVERY to all users."); } private function sendCall($apiName) { return false; // Disable call for now, re-enable when needed $options = [ 'host' => env('AMI_HOST', '127.0.0.1'), 'scheme' => env('AMI_SCHEME', 'tcp://'), 'port' => env('AMI_PORT', 5038), 'username' => env('AMI_USERNAME', ''), 'secret' => env('AMI_SECRET', ''), 'connect_timeout' => env('AMI_CONNECT_TIMEOUT', 10), 'read_timeout' => env('AMI_READ_TIMEOUT', 60), ]; $a = new ClientImpl($options); $eventListener = new TestEv($a); $a->registerEventListener($eventListener); $a->open(); $num = "01283932691"; $actionid = md5(uniqid()); $response = $a->send(new StatusAction()); $originateMsg = new OriginateAction("local/$num@from-internal"); $originateMsg->setContext('ext-did'); $originateMsg->setExtension('700'); $originateMsg->setPriority('1'); $originateMsg->setCallerId(config('app.didNum')); $originateMsg->setAsync(true); $originateMsg->setActionID($actionid); $orgresp = $a->send($originateMsg); $orgStatus = $orgresp->getKeys()['response'] ?? null; if (!empty($orgStatus) && $orgStatus == 'Success') { Log::debug("✅ {$apiName}: $num dialed successfully"); } else { Log::debug("❌ {$apiName}: $num not dialed, status: $orgStatus"); } $this->info("Call sent for {$apiName}."); } }