# Domain Expiration Monitoring Setup This feature allows you to monitor domain expiration dates and receive alerts when domains are expiring soon. ## Features Implemented ### 1. Database Migration - **Table:** `domains` - **Columns:** - `id` - Primary key - `site_id` - Foreign key to sites table - `domain` - Domain name (e.g., example.com) - `expires_at` - Domain expiration date - `last_checked_at` - Last WHOIS check timestamp - `is_active` - Enable/disable monitoring - `created_at`, `updated_at` - Timestamps ### 2. Models & Relationships - **Domain Model** (`app/Models/Domain.php`) - Belongs to Site - Helper methods: - `isExpiringSoon()` - Check if expiring within 30 days - `isExpired()` - Check if already expired - `daysUntilExpiration()` - Get days remaining - **Site Model** updated with `domains()` relationship ### 3. Background Job - **Job:** `CheckDomainExpiry` (`app/Jobs/CheckDomainExpiry.php`) - Performs WHOIS lookup via API - Updates domain expiration date - Creates notifications for expiring domains (within 30 days) - Logs errors for monitoring ### 4. Artisan Command - **Command:** `monitor:domains` - Dispatches `CheckDomainExpiry` job for all active domains - Shows progress bar - Run manually: `php artisan monitor:domains` ### 5. Scheduled Task - **Schedule:** Daily at midnight (configurable in `routes/console.php`) - Automatically runs `monitor:domains` command - Logs output to `storage/logs/domain-monitoring.log` ### 6. Web Interface #### Routes - `GET /domains` - List all domains - `GET /domains/create` - Add new domain form - `POST /domains` - Store new domain - `GET /domains/{domain}` - View domain details - `GET /domains/{domain}/edit` - Edit domain form - `PUT /domains/{domain}` - Update domain - `DELETE /domains/{domain}` - Delete domain - `POST /domains/{domain}/check` - Manually trigger WHOIS check #### Views - `resources/views/domains/index.blade.php` - Domain list with status badges - `resources/views/domains/create.blade.php` - Add new domain - `resources/views/domains/edit.blade.php` - Edit domain - `resources/views/domains/show.blade.php` - Domain details and expiration info ## Setup Instructions ### 1. Configure WHOIS API The system uses **WHOIS XML API** (https://www.whoisxmlapi.com/) by default. You can use alternatives like: - WhoisFreaks (https://whoisfreaks.com/) - Domainr (https://domainr.com/) **Add to `.env` file:** ```env WHOIS_API_KEY=your_api_key_here ``` **Get a free API key:** 1. Visit https://www.whoisxmlapi.com/ 2. Sign up for a free account 3. Get your API key from the dashboard 4. Free tier includes 500 requests/month ### 2. Run the Migration If not already run: ```bash ./vendor/bin/sail artisan migrate ``` ### 3. Start the Queue Worker The domain checking jobs run in the background queue: ```bash ./vendor/bin/sail artisan queue:work ``` Or if you're already running the queue worker, it will automatically pick up these jobs. ### 4. Set Up Scheduled Tasks Make sure your Laravel scheduler is running. In production, add this to your crontab: ``` * * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1 ``` In development with Sail, the scheduler should run automatically if you started with `composer dev`. ### 5. Test the System 1. **Add a domain:** - Navigate to `/domains` - Click "Add Domain" - Select a site and enter a domain name - Save 2. **Manual check:** - View the domain details - Click "Check Expiry Now" - The job will queue and process in the background 3. **Test the command:** ```bash ./vendor/bin/sail artisan monitor:domains ``` ## Usage ### Adding Domains 1. Go to "Domain Monitoring" in your application 2. Click "Add Domain" 3. Select the associated site 4. Enter the domain name (without http://) 5. Save - the system will automatically check expiration ### Monitoring - **Automatic:** Runs daily via scheduled task - **Manual:** Click "Check Now" on any domain - **Command:** Run `php artisan monitor:domains` anytime ### Notifications When a domain is expiring within 30 days or has expired: - A notification is created in the system - Shows in your alerts/notifications section - Contains domain name, expiration date, and days remaining ### Status Badges - **Active** (Green) - Domain valid, not expiring soon - **Expiring Soon** (Yellow) - Expires within 30 days - **Expired** (Red) - Domain has expired - **Unknown** (Gray) - Not yet checked ## Alternative WHOIS APIs If you want to use a different WHOIS provider, modify `app/Jobs/CheckDomainExpiry.php`: ### WhoisFreaks Example: ```php $response = Http::timeout(30) ->get('https://api.whoisfreaks.com/v1.0/whois', [ 'apiKey' => config('services.whois.api_key'), 'whois' => $this->domain->domain, ]); // Parse response differently based on provider's format ``` ### Free WHOIS API: You can also use a free WHOIS lookup service, but be aware of rate limits and reliability. ## Troubleshooting ### Jobs not processing - Check queue worker is running: `ps aux | grep queue` - Check failed jobs: `./vendor/bin/sail artisan queue:failed` - Restart queue: `./vendor/bin/sail artisan queue:restart` ### WHOIS API errors - Verify API key is set in `.env` - Check API quota/limits - Review logs: `storage/logs/laravel.log` ### Schedule not running - Development: Ensure scheduler is part of your dev command - Production: Verify cron job is set up - Test manually: `./vendor/bin/sail artisan schedule:run` ## File Structure ``` app/ ├── Console/Commands/ │ └── MonitorDomains.php # Artisan command ├── Http/Controllers/ │ └── DomainController.php # Web controller ├── Jobs/ │ └── CheckDomainExpiry.php # Background job └── Models/ ├── Domain.php # Domain model └── Site.php # Updated with domains relationship config/ └── services.php # WHOIS API config database/migrations/ └── 2026_01_18_120803_create_domains_table.php resources/views/domains/ ├── index.blade.php # List view ├── create.blade.php # Create form ├── edit.blade.php # Edit form └── show.blade.php # Detail view routes/ ├── console.php # Scheduled tasks └── web.php # Web routes ``` ## API Response Format The job expects WHOIS API responses with expiry date in these formats: - `WhoisRecord.registryData.expiresDate` - `WhoisRecord.expiresDate` - `expiresDate` Dates can be in any format parseable by Carbon (ISO 8601, RFC 2822, etc.) ## Future Enhancements Consider adding: - Email notifications for expiring domains - Slack/Discord webhooks - Configurable warning thresholds (7, 14, 30, 60 days) - Domain auto-renewal reminders - Historical tracking of expiration checks - Bulk import from CSV - Integration with domain registrars