spatie/laravel-discord-alerts
Send Discord alerts from Laravel via a simple facade. Configure a Discord webhook URL and queue messages via a job so your app won’t fail if Discord is down. Ideal for notifying you about noteworthy events (errors, signups, deploys).
Installation:
composer require spatie/laravel-discord-alerts
Publish the config file:
php artisan vendor:publish --provider="Spatie\DiscordAlerts\DiscordAlertsServiceProvider"
Configuration:
Edit .env and config/discord-alerts.php:
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your-webhook-url
return [
'webhook_url' => env('DISCORD_WEBHOOK_URL'),
'default_channel' => env('DISCORD_DEFAULT_CHANNEL', null),
'default_username' => env('DISCORD_DEFAULT_USERNAME', 'Laravel App'),
'default_avatar_url' => env('DISCORD_DEFAULT_AVATAR_URL', null),
];
First Use Case: Send a basic message in a controller or command:
use Spatie\DiscordAlerts\Facades\DiscordAlert;
DiscordAlert::message("Your app just deployed successfully!");
Basic Alerts:
// Simple message
DiscordAlert::message("User {$user->name} signed up!");
// With embeds (rich formatting)
DiscordAlert::embed(function ($embed) use ($user) {
$embed->title("New User")
->description("{$user->name} ({$user->email})")
->color('green')
->addField('Role', $user->role)
->timestamp(now());
});
Contextual Alerts: Attach data to alerts for debugging/logging:
DiscordAlert::message("Payment failed for {$order->id}", [
'order_id' => $order->id,
'amount' => $order->amount,
'user_id' => $order->user_id,
]);
Conditional Alerts: Use in exception handlers or middleware:
try {
// Risky operation
} catch (\Exception $e) {
DiscordAlert::message("Error in Order Processing", [
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
}
Scheduled Alerts: Dispatch alerts via Laravel’s scheduler:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule) {
$schedule->call(function () {
DiscordAlert::message("Nightly backup started at " . now()->format('H:i'));
})->daily();
}
Dynamic Webhook Routing: Override the default webhook per alert:
DiscordAlert::message("Critical alert!", [], [
'webhook_url' => 'https://discord.com/api/webhooks/critical-alerts'
]);
Laravel Events:
Bind alerts to events in EventServiceProvider:
protected $listen = [
'OrderShipped' => [
function ($event) {
DiscordAlert::message("Order #{$event->order->id} shipped to {$event->order->customer}");
},
],
];
Queue Workers: Ensure the queue worker is running to handle async Discord calls:
php artisan queue:work
For production, use supervisor or foreman.
Testing: Mock the facade in tests:
DiscordAlert::shouldReceive('message')
->once()
->with('Test alert');
Environment-Specific Config:
Use .env to toggle alerts in staging/production:
DISCORD_WEBHOOK_URL=production?https://prod-webhook:https://staging-webhook
Webhook Rate Limits: Discord enforces rate limits. If alerts fail silently, check:
DiscordAlert::catch(function ($exception) {
Log::error("Discord alert failed: " . $exception->getMessage());
});
Async Failures:
Since alerts run in the background, use fail() to handle sync failures:
try {
DiscordAlert::message("Critical alert!");
} catch (\Exception $e) {
// Handle sync failure (e.g., queue misconfigured)
abort(503, "Alerts disabled");
}
Embed Limitations: Discord embeds have strict limits. Validate:
Webhook Permissions: Ensure your bot/user has permissions to send messages in the target channel. Test with:
DiscordAlert::message("Test message", [], [
'webhook_url' => 'https://discord.com/api/webhooks/test-url'
]);
Queue Logs:
Check storage/logs/laravel.log for queue job failures. Enable debug mode:
config(['discord-alerts.debug' => true]);
Webhook Validation: Use Discord’s webhook tester to verify your webhook URL.
Common Errors:
401 Unauthorized: Invalid webhook URL or token.403 Forbidden: Missing permissions or rate-limited.429 Too Many Requests: Exceeding rate limits (add delays or batch alerts).Custom Alert Classes:
Extend Spatie\DiscordAlerts\Alert for reusable alert types:
namespace App\Alerts;
use Spatie\DiscordAlerts\Alert;
class DeploymentAlert extends Alert {
public function __construct(string $environment, string $status) {
$this->message = "Deployment to {$environment}: {$status}";
$this->embed(function ($embed) {
$embed->color($status === 'success' ? 'green' : 'red');
});
}
}
Usage:
app()->make(DeploymentAlert::class, ['environment' => 'production', 'status' => 'success']);
Middleware:
Add alert logic to middleware (e.g., HandleInactiveUsers):
public function handle($request, Closure $next) {
if ($user->isInactive()) {
DiscordAlert::message("User {$user->name} inactive for 30 days");
}
return $next($request);
}
Dynamic Content: Use Blade-like syntax for dynamic messages:
DiscordAlert::message(view('discord.alerts.order_created', ['order' => $order])->render());
Local Testing: Use ngrok to expose a local webhook for testing:
ngrok http 8000
Configure .env:
DISCORD_WEBHOOK_URL=http://localhost:8000/webhook
How can I help you explore Laravel packages today?