coka/notifier-server-bundle
Install the Bundle
composer require coka/notifier-server-bundle
Register the bundle in config/bundles.php:
CedrickOka\NotifierServerBundle\CedrickOkaNotifierServerBundle::class => ['all' => true],
Publish Configuration
php artisan vendor:publish --provider="CedrickOka\NotifierServerBundle\CedrickOkaNotifierServerBundle" --tag="config"
This generates config/notifier_server.php. Configure your notification channels (e.g., email, sms, slack) under channels.
First Use Case: Sending a Notification
Inject the NotifierServer service into a controller or command:
use CedrickOka\NotifierServerBundle\NotifierServer;
class ExampleController extends Controller
{
public function __construct(private NotifierServer $notifier)
{
}
public function sendNotification()
{
$this->notifier->send(
to: 'user@example.com', // Recipient (format depends on channel)
channel: 'email', // Channel name from config
data: [
'subject' => 'Hello!',
'message' => 'This is a test notification.',
]
);
}
}
Verify Configuration
Check config/notifier_server.php for channel-specific settings (e.g., API keys, endpoints). Example for Slack:
'channels' => [
'slack' => [
'webhook_url' => env('SLACK_WEBHOOK_URL'),
'default_icon' => ':robot_face:',
],
],
Define Channels
Extend the bundle by adding custom channels in config/notifier_server.php:
'channels' => [
'custom_webhook' => [
'url' => env('CUSTOM_WEBHOOK_URL'),
'method' => 'POST',
],
],
Dynamic Recipients Use arrays for multi-recipient notifications:
$this->notifier->send(
to: ['user1@example.com', 'user2@example.com'],
channel: 'email',
data: ['subject' => 'Group Alert']
);
Async Processing Queue notifications for background processing:
$this->notifier->queue(
to: 'user@example.com',
channel: 'sms',
data: ['message' => 'Your OTP is 1234']
);
Ensure the notifier:send queue listener is set up (check app/Console/Kernel.php).
Event Listeners Attach listeners to notifications for logging or analytics:
// In a service provider
$this->app->make('notifier')->extend('email', function ($app) {
return new class($app['notifier.transport.email']) {
public function send($to, $data)
{
// Pre-send logic (e.g., log)
$result = $this->transport->send($to, $data);
// Post-send logic
return $result;
}
};
});
Templates Use Twig or Blade templates for dynamic content:
$this->notifier->send(
to: 'user@example.com',
channel: 'email',
data: [
'template' => 'emails.welcome', // Path to Twig/Blade template
'variables' => ['name' => 'John'],
]
);
Laravel Notifications Bridge
If using Laravel’s built-in Notification system, create a custom channel:
// app/Providers/NotifierServiceProvider.php
public function register()
{
$this->app->bind('notifier.channel.email', function ($app) {
return new class($app['mailer']) {
public function send($to, $data)
{
return $this->mailer->send(new \App\Notifications\CustomNotification($data), $to);
}
};
});
}
Testing
Mock the NotifierServer in tests:
$notifier = Mockery::mock(NotifierServer::class);
$notifier->shouldReceive('send')->once();
$this->app->instance(NotifierServer::class, $notifier);
Rate Limiting Implement rate limiting per channel using middleware:
// config/notifier_server.php
'middleware' => [
'email' => \CedrickOka\NotifierServerBundle\Middleware\RateLimit::class,
],
Channel Configuration Mismatch
channel in send() doesn’t match config/notifier_server.php.NotifierServer class.Missing Queue Setup
notifier:send queue listener is missing.app/Console/Kernel.php:
protected function schedule(Schedule $schedule)
{
$schedule->job(new \CedrickOka\NotifierServerBundle\Jobs\SendNotification)->everyMinute();
}
Data Serialization
json_encode() explicitly:
$this->notifier->send(
to: env('SLACK_WEBHOOK_URL'),
channel: 'slack',
data: ['text' => json_encode(['blocks' => [...]])]
);
Environment Variables
.env.env() in config/notifier_server.php:
'channels' => [
'slack' => [
'webhook_url' => env('SLACK_WEBHOOK_URL', 'default_url'),
],
],
Error Handling
// In NotifierServer.php
try {
$response = $this->getTransport($channel)->send($to, $data);
} catch (\Exception $e) {
Log::error("Notification failed for {$channel}: " . $e->getMessage());
throw new \RuntimeException("Notification failed", 0, $e);
}
Enable Debug Mode
Set debug: true in config/notifier_server.php to log raw payloads:
'debug' => env('NOTIFIER_DEBUG', false),
Check Queue Jobs Monitor queued notifications:
php artisan queue:work --queue=notifier
Inspect Payloads Log the final payload before sending:
// In NotifierServer.php
if ($this->config['debug']) {
Log::debug('Notification payload', [
'channel' => $channel,
'to' => $to,
'data' => $data,
]);
}
Custom Transports
Extend the TransportInterface to add new channels:
namespace App\Notifier;
use CedrickOka\NotifierServerBundle\Transport\TransportInterface;
class CustomTransport implements TransportInterface
{
public function send($to, $data)
{
// Custom logic (e.g., HTTP request to a custom API)
return ['success' => true];
}
}
Register it in config/notifier_server.php:
'transports' => [
'custom' => App\Notifier\CustomTransport::class,
],
Override Default Behavior
Replace the NotifierServer class entirely by binding it in a service provider:
$this->app->bind(NotifierServer::class, function ($app) {
return new \App\Services\CustomNotifierServer(
$app['notifier.config'],
$app['notifier.transport.factory']
);
});
Add Validation Validate notification data before sending:
// In NotifierServer.php
public function send($to, $channel, $data)
{
if (!$this->validateData($channel, $data)) {
throw new \InvalidArgumentException("Invalid data for {$channel}");
}
// ... rest of the logic
}
How can I help you explore Laravel packages today?