143 lines
4.2 KiB
PHP
143 lines
4.2 KiB
PHP
<?php
|
|||
|
|
|
||
|
|
namespace App\Jobs;
|
||
|
|
|
||
|
|
use App\Models\Domain;
|
||
|
|
use App\Models\Notification;
|
||
|
|
use Carbon\Carbon;
|
||
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||
|
|
use Illuminate\Foundation\Queue\Queueable;
|
||
|
|
use Illuminate\Support\Facades\Http;
|
||
|
|
use Illuminate\Support\Facades\Log;
|
||
|
|
|
||
|
|
class CheckDomainExpiry implements ShouldQueue
|
||
|
|
{
|
||
|
|
use Queueable;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new job instance.
|
||
|
|
*/
|
||
|
|
public function __construct(
|
||
|
|
public Domain $domain
|
||
|
|
) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Execute the job.
|
||
|
|
*/
|
||
|
|
public function handle(): void
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
// Use WHOIS API to check domain expiry
|
||
|
|
// We'll use the WHOIS XML API (https://www.whoisxmlapi.com/)
|
||
|
|
// You can also use other providers like whoisfreaks.com or domainr.com
|
||
|
|
|
||
|
|
$apiKey = config('services.whois.api_key');
|
||
|
|
|
||
|
|
if (!$apiKey) {
|
||
|
|
Log::warning('WHOIS API key not configured');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$response = Http::timeout(30)
|
||
|
|
->get('https://www.whoisxmlapi.com/whoisserver/WhoisService', [
|
||
|
|
'apiKey' => $apiKey,
|
||
|
|
'domainName' => $this->domain->domain,
|
||
|
|
'outputFormat' => 'JSON',
|
||
|
|
]);
|
||
|
|
|
||
|
|
if ($response->successful()) {
|
||
|
|
$data = $response->json();
|
||
|
|
|
||
|
|
// Parse expiry date from WHOIS response
|
||
|
|
$expiryDate = $this->parseExpiryDate($data);
|
||
|
|
|
||
|
|
if ($expiryDate) {
|
||
|
|
$this->domain->update([
|
||
|
|
'expires_at' => $expiryDate,
|
||
|
|
'last_checked_at' => Carbon::now(),
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Check if domain is expiring soon (within 30 days)
|
||
|
|
if ($this->domain->isExpiringSoon()) {
|
||
|
|
$this->sendExpiryAlert();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
Log::error('WHOIS API request failed', [
|
||
|
|
'domain' => $this->domain->domain,
|
||
|
|
'status' => $response->status(),
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->domain->update([
|
||
|
|
'last_checked_at' => Carbon::now(),
|
||
|
|
]);
|
||
|
|
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
Log::error('Error checking domain expiry', [
|
||
|
|
'domain' => $this->domain->domain,
|
||
|
|
'error' => $e->getMessage(),
|
||
|
|
]);
|
||
|
|
|
||
|
|
throw $e; // Re-throw to allow job retry
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parse expiry date from WHOIS response
|
||
|
|
*/
|
||
|
|
protected function parseExpiryDate(array $data): ?Carbon
|
||
|
|
{
|
||
|
|
// Try multiple possible fields where expiry date might be
|
||
|
|
$possibleFields = [
|
||
|
|
'WhoisRecord.registryData.expiresDate',
|
||
|
|
'WhoisRecord.expiresDate',
|
||
|
|
'expiresDate',
|
||
|
|
];
|
||
|
|
|
||
|
|
foreach ($possibleFields as $field) {
|
||
|
|
$value = data_get($data, $field);
|
||
|
|
|
||
|
|
if ($value) {
|
||
|
|
try {
|
||
|
|
return Carbon::parse($value);
|
||
|
|
} catch (\Exception $e) {
|
||
|
|
Log::warning('Failed to parse date', [
|
||
|
|
'field' => $field,
|
||
|
|
'value' => $value,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Send alert notification for expiring domain
|
||
|
|
*/
|
||
|
|
protected function sendExpiryAlert(): void
|
||
|
|
{
|
||
|
|
$daysUntilExpiry = $this->domain->daysUntilExpiration();
|
||
|
|
|
||
|
|
$message = $this->domain->isExpired()
|
||
|
|
? "Domain '{$this->domain->domain}' has expired!"
|
||
|
|
: "Domain '{$this->domain->domain}' expires in {$daysUntilExpiry} days (on {$this->domain->expires_at->format('Y-m-d')})";
|
||
|
|
|
||
|
|
Notification::create([
|
||
|
|
'user_id' => $this->domain->site->user_id,
|
||
|
|
'type' => 'domain_expiry',
|
||
|
|
'message' => $message,
|
||
|
|
'data' => json_encode([
|
||
|
|
'domain_id' => $this->domain->id,
|
||
|
|
'site_id' => $this->domain->site_id,
|
||
|
|
'domain' => $this->domain->domain,
|
||
|
|
'expires_at' => $this->domain->expires_at,
|
||
|
|
'days_until_expiry' => $daysUntilExpiry,
|
||
|
|
]),
|
||
|
|
'read_at' => null,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
}
|