329 lines
8.8 KiB
Markdown
329 lines
8.8 KiB
Markdown
# Multi-Channel Notifications - Quick Start Guide
|
|||
|
|
|
||
|
|
## What's Been Completed
|
||
|
|
|
||
|
|
### ✅ Database Migration
|
||
|
|
- Migration created: `database/migrations/2026_01_18_123539_add_notification_channels_to_users_table.php`
|
||
|
|
- Adds fields for all notification channels to users table
|
||
|
|
- **Run with:** `./vendor/bin/sail artisan migrate`
|
||
|
|
|
||
|
|
### ✅ Packages Installed
|
||
|
|
```json
|
||
|
|
"laravel/slack-notification-channel": "^3.7",
|
||
|
|
"laravel-notification-channels/telegram": "^6.0",
|
||
|
|
"laravel-notification-channels/discord": "^1.7"
|
||
|
|
```
|
||
|
|
|
||
|
|
### ✅ User Model Updated
|
||
|
|
- Added fillable fields for all notification channels
|
||
|
|
- Added `notification_channels` JSON cast
|
||
|
|
- Added helper methods:
|
||
|
|
- `getNotificationChannelsFor($alertType)` - Get enabled channels for an alert type
|
||
|
|
- `routeNotificationForSlack()` - Slack webhook routing
|
||
|
|
- `routeNotificationForTelegram()` - Telegram chat ID routing
|
||
|
|
- `routeNotificationForDiscord()` - Discord webhook routing
|
||
|
|
|
||
|
|
## Quick Implementation Steps
|
||
|
|
|
||
|
|
### Step 1: Run Migration
|
||
|
|
```bash
|
||
|
|
./vendor/bin/sail artisan migrate
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 2: Create Notification Classes
|
||
|
|
|
||
|
|
All notification class templates are in `MULTI_CHANNEL_NOTIFICATIONS_GUIDE.md`. Copy them to:
|
||
|
|
- `app/Notifications/MonitorAlert.php` (base class)
|
||
|
|
- `app/Notifications/UptimeAlert.php`
|
||
|
|
- `app/Notifications/SslExpiryAlert.php`
|
||
|
|
- `app/Notifications/DomainExpiryAlert.php`
|
||
|
|
- `app/Notifications/SitemapAlert.php`
|
||
|
|
- `app/Notifications/PerformanceAlert.php`
|
||
|
|
|
||
|
|
### Step 3: Create Notification Settings Controller
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./vendor/bin/sail artisan make:controller NotificationSettingsController
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 4: Update Existing Jobs
|
||
|
|
|
||
|
|
Example - Update `CheckSitemap` job:
|
||
|
|
|
||
|
|
```php
|
||
|
|
// Replace the sendAlert method in app/Jobs/CheckSitemap.php
|
||
|
|
use App\Notifications\SitemapAlert;
|
||
|
|
|
||
|
|
protected function sendAlert(string $message): void
|
||
|
|
{
|
||
|
|
// Send via new notification system
|
||
|
|
$this->sitemap->site->user->notify(
|
||
|
|
new SitemapAlert(
|
||
|
|
$this->sitemap->site->name,
|
||
|
|
$this->sitemap->url,
|
||
|
|
$this->sitemap->last_error
|
||
|
|
)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 5: Add Environment Variables
|
||
|
|
|
||
|
|
Add to `.env`:
|
||
|
|
```env
|
||
|
|
# Telegram Bot (optional)
|
||
|
|
TELEGRAM_BOT_TOKEN=your_bot_token
|
||
|
|
|
||
|
|
# Twilio SMS (optional)
|
||
|
|
TWILIO_SID=your_sid
|
||
|
|
TWILIO_TOKEN=your_token
|
||
|
|
TWILIO_FROM=+1234567890
|
||
|
|
```
|
||
|
|
|
||
|
|
## Default Notification Channels Structure
|
||
|
|
|
||
|
|
The `notification_channels` JSON field stores preferences like this:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"uptime": ["email", "slack"],
|
||
|
|
"ssl": ["email", "telegram", "slack"],
|
||
|
|
"domain_expiry": ["email"],
|
||
|
|
"sitemap": ["database"],
|
||
|
|
"performance": ["slack"],
|
||
|
|
"dns": ["email", "database"],
|
||
|
|
"broken_links": ["database"],
|
||
|
|
"health_check": ["email", "slack"],
|
||
|
|
"tcp_port": ["database"]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Supported Channels
|
||
|
|
|
||
|
|
### Built-in (No Additional Setup)
|
||
|
|
- `mail` - Email notifications
|
||
|
|
- `database` - Store in notifications table
|
||
|
|
|
||
|
|
### Webhook-based (Requires URL)
|
||
|
|
- `slack` - Requires `slack_webhook_url`
|
||
|
|
- `discord` - Requires `discord_webhook_url`
|
||
|
|
- `telegram` - Requires `telegram_chat_id` and bot token
|
||
|
|
- `teams` - Requires `teams_webhook_url`
|
||
|
|
- `google_chat` - Requires `google_chat_webhook_url`
|
||
|
|
- `webhook` - Requires `webhook_url` (custom endpoint)
|
||
|
|
|
||
|
|
### API-based (Requires Credentials)
|
||
|
|
- `sms` - Requires Twilio/Vonage setup
|
||
|
|
- `opsgenie` - Requires `opsgenie_api_key`
|
||
|
|
- `pagerduty` - Requires `pagerduty_integration_key`
|
||
|
|
|
||
|
|
## Testing Notifications
|
||
|
|
|
||
|
|
Create a test route to verify notifications work:
|
||
|
|
|
||
|
|
```php
|
||
|
|
// In routes/web.php
|
||
|
|
Route::get('/test-notification', function () {
|
||
|
|
auth()->user()->notify(
|
||
|
|
new \App\Notifications\UptimeAlert(
|
||
|
|
'Test Site',
|
||
|
|
false, // not down
|
||
|
|
200,
|
||
|
|
'https://example.com',
|
||
|
|
150.5
|
||
|
|
)
|
||
|
|
);
|
||
|
|
|
||
|
|
return 'Notification sent! Check your configured channels.';
|
||
|
|
})->middleware('auth');
|
||
|
|
```
|
||
|
|
|
||
|
|
## Setting Up Notification Channels
|
||
|
|
|
||
|
|
### Slack
|
||
|
|
1. Go to https://api.slack.com/messaging/webhooks
|
||
|
|
2. Create an Incoming Webhook for your workspace
|
||
|
|
3. Copy the webhook URL
|
||
|
|
4. Save in user settings: `slack_webhook_url`
|
||
|
|
|
||
|
|
### Telegram
|
||
|
|
1. Talk to @BotFather on Telegram
|
||
|
|
2. Create a new bot with `/newbot`
|
||
|
|
3. Save the bot token to `.env` as `TELEGRAM_BOT_TOKEN`
|
||
|
|
4. Start a chat with your bot
|
||
|
|
5. Get your chat ID from @userinfobot
|
||
|
|
6. Save in user settings: `telegram_chat_id`
|
||
|
|
|
||
|
|
### Discord
|
||
|
|
1. Go to Server Settings → Integrations → Webhooks
|
||
|
|
2. Create New Webhook
|
||
|
|
3. Copy the Webhook URL
|
||
|
|
4. Save in user settings: `discord_webhook_url`
|
||
|
|
|
||
|
|
### Microsoft Teams
|
||
|
|
1. In Teams, go to channel → Connectors
|
||
|
|
2. Configure "Incoming Webhook"
|
||
|
|
3. Copy the webhook URL
|
||
|
|
4. Save in user settings: `teams_webhook_url`
|
||
|
|
|
||
|
|
## Notification Settings UI (To Be Created)
|
||
|
|
|
||
|
|
Create a settings page where users can:
|
||
|
|
1. Enable/disable channels per alert type
|
||
|
|
2. Configure webhook URLs and API keys
|
||
|
|
3. Test notification delivery
|
||
|
|
4. Set quiet hours
|
||
|
|
5. Configure notification preferences
|
||
|
|
|
||
|
|
## Integration with Existing Monitoring
|
||
|
|
|
||
|
|
Update these jobs to send notifications:
|
||
|
|
- `app/Jobs/CheckSitePing.php` → Use `UptimeAlert`
|
||
|
|
- `app/Jobs/CheckSslCertificate.php` → Use `SslExpiryAlert`
|
||
|
|
- `app/Jobs/CheckDomainExpiry.php` → Use `DomainExpiryAlert`
|
||
|
|
- `app/Jobs/CheckSitemap.php` → Use `SitemapAlert`
|
||
|
|
- `app/Jobs/CheckHealth.php` → Use `PerformanceAlert`
|
||
|
|
|
||
|
|
## Queue Configuration
|
||
|
|
|
||
|
|
Notifications are queued by default. Ensure queue worker is running:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./vendor/bin/sail artisan queue:work
|
||
|
|
```
|
||
|
|
|
||
|
|
Or configure supervisor in production.
|
||
|
|
|
||
|
|
## Notification Flow
|
||
|
|
|
||
|
|
```
|
||
|
|
Monitor Job Detects Issue
|
||
|
|
↓
|
||
|
|
Creates Notification Object
|
||
|
|
↓
|
||
|
|
User::notify(new Alert(...))
|
||
|
|
↓
|
||
|
|
Laravel checks via()
|
||
|
|
↓
|
||
|
|
Gets enabled channels from user preferences
|
||
|
|
↓
|
||
|
|
Dispatches to each channel
|
||
|
|
↓
|
||
|
|
Queues notification jobs
|
||
|
|
↓
|
||
|
|
Worker processes notifications
|
||
|
|
↓
|
||
|
|
Sends to: Email, Slack, Telegram, etc.
|
||
|
|
```
|
||
|
|
|
||
|
|
## Security Considerations
|
||
|
|
|
||
|
|
1. **Encrypt sensitive fields** - Consider encrypting webhook URLs and API keys
|
||
|
|
2. **Rate limiting** - Prevent notification spam
|
||
|
|
3. **Validate webhooks** - Verify webhook URLs before saving
|
||
|
|
4. **Sanitize data** - Clean user input in notifications
|
||
|
|
5. **HTTPS only** - Only allow HTTPS webhook URLs
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Notifications not sending
|
||
|
|
1. Check queue worker is running: `ps aux | grep queue`
|
||
|
|
2. Check failed jobs: `./vendor/bin/sail artisan queue:failed`
|
||
|
|
3. Review logs: `storage/logs/laravel.log`
|
||
|
|
4. Verify user has configured channels
|
||
|
|
5. Test with simple email notification first
|
||
|
|
|
||
|
|
### Channel-specific issues
|
||
|
|
|
||
|
|
**Slack:** "Invalid webhook URL"
|
||
|
|
- Verify URL format: https://hooks.slack.com/services/...
|
||
|
|
- Check workspace hasn't revoked webhook
|
||
|
|
|
||
|
|
**Telegram:** "Bad Request: chat not found"
|
||
|
|
- Verify chat ID is correct
|
||
|
|
- Ensure bot token is valid
|
||
|
|
- Start conversation with bot first
|
||
|
|
|
||
|
|
**Discord:** "Webhook not found"
|
||
|
|
- Check webhook wasn't deleted
|
||
|
|
- Verify URL hasn't expired
|
||
|
|
|
||
|
|
## Performance Tips
|
||
|
|
|
||
|
|
1. **Use queues** - Always queue notifications
|
||
|
|
2. **Batch similar alerts** - Group notifications when possible
|
||
|
|
3. **Debounce** - Prevent rapid repeated notifications
|
||
|
|
4. **Cache user preferences** - Cache notification_channels
|
||
|
|
5. **Async webhooks** - Don't wait for webhook responses
|
||
|
|
|
||
|
|
## Next Steps
|
||
|
|
|
||
|
|
1. **Create UI** - Build notification settings interface
|
||
|
|
2. **Add more channels** - Implement Teams, Google Chat, etc.
|
||
|
|
3. **Test thoroughly** - Test each channel
|
||
|
|
4. **Update docs** - Document for your team
|
||
|
|
5. **Monitor** - Track notification success rates
|
||
|
|
|
||
|
|
## Example: Full Integration
|
||
|
|
|
||
|
|
Here's how to fully integrate with an existing job:
|
||
|
|
|
||
|
|
```php
|
||
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Jobs;
|
||
|
|
|
||
|
|
use App\Models\Site;
|
||
|
|
use App\Notifications\UptimeAlert;
|
||
|
|
use Illuminate\Bus\Queueable;
|
||
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||
|
|
use Illuminate\Queue\InteractsWithQueue;
|
||
|
|
use Illuminate\Queue\SerializesModels;
|
||
|
|
use Illuminate\Support\Facades\Http;
|
||
|
|
|
||
|
|
class CheckSiteUptime implements ShouldQueue
|
||
|
|
{
|
||
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||
|
|
|
||
|
|
public function __construct(
|
||
|
|
public Site $site
|
||
|
|
) {
|
||
|
|
}
|
||
|
|
|
||
|
|
public function handle(): void
|
||
|
|
{
|
||
|
|
$response = Http::timeout(10)->get($this->site->url);
|
||
|
|
|
||
|
|
$isDown = !$response->successful();
|
||
|
|
$statusCode = $response->status();
|
||
|
|
$responseTime = $response->transferStats->getTransferTime() * 1000;
|
||
|
|
|
||
|
|
// Check if status changed
|
||
|
|
$previousStatus = $this->site->latestUptimeCheck->is_online ?? true;
|
||
|
|
|
||
|
|
// Send notification if status changed
|
||
|
|
if ($isDown !== !$previousStatus) {
|
||
|
|
$this->site->user->notify(
|
||
|
|
new UptimeAlert(
|
||
|
|
$this->site->name,
|
||
|
|
$isDown,
|
||
|
|
$statusCode,
|
||
|
|
$this->site->url,
|
||
|
|
$responseTime
|
||
|
|
)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Save check result...
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Resources
|
||
|
|
|
||
|
|
- Laravel Notifications: https://laravel.com/docs/notifications
|
||
|
|
- Slack API: https://api.slack.com/
|
||
|
|
- Telegram Bot API: https://core.telegram.org/bots/api
|
||
|
|
- Discord Webhooks: https://discord.com/developers/docs/resources/webhook
|