Installation:
composer require laravel-notification-channels/pagerduty
Publish the config file (if needed):
php artisan vendor:publish --provider="NotificationChannels\PagerDuty\PagerDutyServiceProvider"
Configuration:
Add your PagerDuty API key to .env:
PAGERDUTY_API_KEY=your_api_key_here
Configure the channel in config/services.php:
'pagerduty' => [
'api_key' => env('PAGERDUTY_API_KEY'),
'default_event_action' => 'trigger', // or 'resolve', 'acknowledge'
],
First Use Case: Send a basic incident trigger via a notification:
use NotificationChannels\PagerDuty\PagerDutyChannel;
use NotificationChannels\PagerDuty\PagerDutyMessage;
// In your notification class:
public function via($notifiable)
{
return [PagerDutyChannel::class];
}
public function toPagerDuty($notifiable)
{
return (new PagerDutyMessage)
->subject('Server Down')
->body('Database server is unresponsive')
->severity('critical')
->source('laravel-app')
->component('database');
}
Trigger the notification:
$user->notify(new YourNotificationClass);
Dynamic Event Actions: Use conditional logic to determine event type (trigger/resolve/acknowledge):
public function toPagerDuty($notifiable)
{
$message = (new PagerDutyMessage)
->subject('Incident Update')
->body($notifiable->status)
->source('monitoring');
if ($notifiable->isCritical()) {
$message->severity('critical')->action('trigger');
} else {
$message->severity('warning')->action('resolve');
}
return $message;
}
Linking to Incidents:
Attach notifications to existing incidents via incident_key:
return (new PagerDutyMessage)
->incidentKey('P12345')
->action('acknowledge')
->body('Investigating...');
Custom Fields:
Add metadata via customDetails:
return (new PagerDutyMessage)
->customDetails([
'ticket_id' => $ticket->id,
'priority' => $ticket->priority,
]);
Batch Processing: Queue notifications for efficiency:
$user->routeNotificationFor('pagerduty', $user->pagerdutyEmail)
->notify(new YourNotificationClass)
->onQueue('high');
Event Mapping:
Map Laravel events (e.g., job.failed) to PagerDuty actions in a service class:
class PagerDutyDispatcher
{
public function handleJobFailure(JobFailed $event)
{
$user = User::find($event->userId);
$user->notify(new JobFailedNotification($event));
}
}
Rate Limiting:
Use Laravel’s throttle middleware to avoid API rate limits:
Route::middleware(['throttle:10,1'])->group(function () {
// PagerDuty-triggering routes
});
Testing: Mock the channel in tests:
$this->actingAs($user)
->fake()
->expectsNotificationsCount(1)
->notify(new YourNotificationClass);
API Key Exposure:
config() or environment variables.Idempotency:
incidentKey for updates to avoid duplicate triggers.Rate Limits:
Event Timeouts:
Severity Mapping:
severity must be one of: critical, error, warning, or info. Invalid values will fail silently.Enable Logging:
Add this to config/pagerduty.php:
'log' => env('PAGERDUTY_LOG', false),
Check storage/logs/laravel.log for API responses.
HTTP Client Errors: If requests fail, inspect the raw response:
try {
$this->send($notifiable, $message);
} catch (\GuzzleHttp\Exception\RequestException $e) {
\Log::error('PagerDuty API Error:', [
'response' => $e->getResponse()->getBody(),
'request' => $e->getRequest(),
]);
}
Validation Errors:
PagerDuty returns 400 for invalid payloads. Validate your PagerDutyMessage before sending:
$message->validate(); // Throws \InvalidArgumentException on errors
Custom HTTP Client: Override the default Guzzle client in a service provider:
$this->app->singleton(\GuzzleHttp\Client::class, function () {
return new \GuzzleHttp\Client([
'timeout' => 10,
'headers' => [
'User-Agent' => 'YourApp/1.0',
],
]);
});
Event Transformers: Create a transformer to normalize Laravel events into PagerDuty format:
class PagerDutyTransformer
{
public static function transform($event)
{
return [
'summary' => $event->summary,
'severity' => self::mapSeverity($event->level),
// ...
];
}
}
Webhook Validation: For incoming PagerDuty webhooks, validate signatures:
use NotificationChannels\PagerDuty\WebhookValidator;
$validator = new WebhookValidator(request()->header('X-PagerDuty-Signature'));
if (!$validator->isValid()) {
abort(403);
}
Retry Logic: Implement exponential backoff for failed requests:
use NotificationChannels\PagerDuty\RetryablePagerDutyChannel;
class YourNotification extends Notification
{
public function via($notifiable)
{
return [RetryablePagerDutyChannel::class];
}
}
Use customDetails for Context:
Attach user IDs, ticket references, or debug data:
->customDetails([
'user_id' => $user->id,
'trace_id' => request()->header('X-Trace-ID'),
]);
Leverage PagerDuty’s links:
Include contextual links for faster resolution:
->links([
'dashboard' => url('/admin/dashboard'),
'logs' => url("/logs/{$logId}"),
]);
Monitor Delivery: Use PagerDuty’s API to track sent events:
$events = \Http::withToken(config('services.pagerduty.api_key'))
->get('https://api.pagerduty.com/events');
How can I help you explore Laravel packages today?