composer require coka/notifier-bundle
config/bundles.php:
return [
// ...
CedrickOka\NotifierBundle\OkaNotifierBundle::class => ['all' => true],
];
config/packages/oka_notifier.yaml:
oka_notifier:
notifiers:
default:
type: 'webhook' # or 'email', 'slack', etc.
config:
url: 'https://your-webhook-endpoint.com'
use CedrickOka\NotifierBundle\Notifier\NotifierInterface;
class SomeService {
public function __construct(private NotifierInterface $notifier) {}
public function sendAlert() {
$this->notifier->notify('default', [
'message' => 'Test notification',
'priority' => 'high'
]);
}
}
Service Discovery:
oka_notifier.yaml under notifiers key.NotifierInterface and call notify($name, $payload).Payload Structure:
message, priority (e.g., low, medium, high), and optional metadata.$this->notifier->notify('slack', [
'message' => 'Deployment failed',
'priority' => 'critical',
'metadata' => ['commit' => 'abc123', 'env' => 'production']
]);
Dynamic Notifier Switching:
# config/packages/oka_notifier.yaml
oka_notifier:
notifiers:
production: { type: 'slack', config: { ... } }
staging: { type: 'email', config: { ... } }
Event-Driven Notifications:
job.failed) and trigger notifications:
use Illuminate\Queue\Events\JobFailed;
Event::listen(JobFailed::class, function (JobFailed $event) {
$notifier->notify('slack', [
'message' => 'Job failed: ' . $event->job->payload['command'],
'priority' => 'high'
]);
});
Custom Notifier Types:
AbstractNotifier to create new notifier types (e.g., PushoverNotifier).oka_notifier.yaml:
oka_notifier:
notifiers:
pushover:
type: 'pushover'
config: { token: '...', user: '...' }
Missing Configuration:
oka_notifier.yaml will throw RuntimeException.Command or ServiceProvider constructor).Payload Validation:
webhook may ignore priority.Dependency Injection:
NotifierInterface directly, ensure the correct notifier is bound in the container.Rate Limiting:
Queue or RateLimiter decorator around the notifier.Testing:
$notifier = $this->createMock(NotifierInterface::class);
$notifier->expects($this->once())
->method('notify')
->with('slack', ['message' => 'Test']);
$this->app->instance(NotifierInterface::class, $notifier);
Log Payloads:
Add a LoggerNotifier decorator to log all notifications:
class LoggerNotifier implements NotifierInterface {
public function __construct(private NotifierInterface $notifier, private LoggerInterface $logger) {}
public function notify(string $name, array $payload): void {
$this->logger->info('Notifier: ' . $name, ['payload' => $payload]);
$this->notifier->notify($name, $payload);
}
}
Register it in services.yaml:
services:
CedrickOka\NotifierBundle\Notifier\NotifierInterface:
class: App\Notifier\LoggerNotifier
arguments:
$notifier: '@oka_notifier.notifier.default'
$logger: '@logger'
Check HTTP Responses:
For webhook notifiers, inspect HTTP responses to debug failures:
$client = new \GuzzleHttp\Client();
$response = $client->post($config['url'], [
'json' => $payload,
'headers' => ['Authorization' => 'Bearer ' . $config['token']]
]);
if ($response->getStatusCode() !== 200) {
throw new \RuntimeException('Notification failed: ' . $response->getBody());
}
Environment-Specific Config:
Use Symfony’s %env% or Laravel’s .env for sensitive config:
oka_notifier:
notifiers:
slack:
type: 'slack'
config:
token: '%env(SLACK_TOKEN)%'
channel: '%env(SLACK_CHANNEL)%'
Custom Notifier Logic:
Override AbstractNotifier::send() to add retries or fallback logic:
class RetryNotifier extends AbstractNotifier {
public function send(array $payload): void {
$retries = 3;
while ($retries--) {
try {
parent::send($payload);
return;
} catch (\Exception $e) {
if ($retries === 0) throw $e;
sleep(2 ** $retries); // Exponential backoff
}
}
}
}
Priority-Based Routing:
Route notifications based on priority to different notifiers:
class PriorityNotifier implements NotifierInterface {
public function __construct(
private NotifierInterface $highPriorityNotifier,
private NotifierInterface $lowPriorityNotifier
) {}
public function notify(string $name, array $payload): void {
if ($payload['priority'] === 'high') {
$this->highPriorityNotifier->notify($name, $payload);
} else {
$this->lowPriorityNotifier->notify($name, $payload);
}
}
}
Template-Based Messages: Use Twig or Blade templates for dynamic messages:
$this->notifier->notify('email', [
'subject' => '{{ event }} failed',
'body' => 'Check logs at {{ url }}',
'context' => [
'event' => 'Deployment',
'url' => 'https://example.com/logs'
]
]);
Note: Requires custom notifier implementation to render templates.
How can I help you explore Laravel packages today?