## Getting Started
### Minimal Setup
1. **Installation**
Add the bundle via Composer:
```bash
composer require austral/notify-bundle
Register the bundle in config/bundles.php:
Austral\NotifyBundle\AustralNotifyBundle::class => ['all' => true],
Publish Config Publish the default configuration:
php artisan vendor:publish --tag="notify-bundle-config"
This generates config/notify.php with Mercure and push notification settings.
First Use Case: Sending a Notification
Use the NotifyManager service to dispatch notifications:
use Austral\NotifyBundle\Manager\NotifyManager;
class MyController extends Controller
{
public function __construct(private NotifyManager $notifyManager) {}
public function sendNotification()
{
$this->notifyManager->push(
'user_id', // Target user ID
'channel_name', // Notification channel (e.g., 'inbox')
[
'title' => 'New Message',
'message' => 'You have a new message!',
'data' => ['url' => '/messages/123']
]
);
}
}
Mercure Integration
Enable Mercure in config/notify.php:
'mercure' => [
'enabled' => true,
'url' => env('MERCURE_URL', 'http://localhost:.3000/.well-known/mercure'),
'public_key' => env('MERCURE_PUBLIC_KEY'),
'private_key' => env('MERCURE_PRIVATE_KEY'),
],
Ensure your frontend subscribes to the Mercure hub URL (e.g., http://localhost:.3000/.well-known/mercure).
Push Notifications
notifyManager->push($userId, $channel, $data).$userIds = User::where('role', 'admin')->pluck('id');
foreach ($userIds as $userId) {
$this->notifyManager->push($userId, 'admin-alerts', $data);
}
Mercure Integration
https://yourdomain.com/.well-known/mercure?topic=notify:user_id:channel_name.const eventSource = new EventSource(
'http://localhost:.3000/.well-known/mercure?topic=notify:123:inbox'
);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('New notification:', data);
};
Config-Driven Customization
Austral\NotifyBundle\Enum\PushType::WEB or PushType::MOBILE to filter notifications.config/notify.php without code changes.Event-Driven Notifications
Created, Updated) and dispatch notifications:
use Austral\NotifyBundle\Manager\NotifyManager;
use Illuminate\Queue\Events\JobProcessed;
class MyEventListener
{
public function __construct(private NotifyManager $notifyManager) {}
public function handle(JobProcessed $event)
{
$this->notifyManager->push(
$event->job->data['user_id'],
'job-complete',
['job_id' => $event->job->id]
);
}
}
$this->notifyManager->push($userId, 'channel', $data)->onQueue('notifications');
$validator = Validator::make($data, [
'title' => 'required|string|max:255',
'message' => 'required|string',
]);
if ($validator->fails()) {
throw new \InvalidArgumentException('Invalid notification data');
}
NotifyManager in tests:
$mock = Mockery::mock(NotifyManager::class);
$mock->shouldReceive('push')->once()->withArgs([1, 'test', ['key' => 'value']]);
$this->app->instance(NotifyManager::class, $mock);
Mercure Configuration
MERCURE_PUBLIC_KEY or MERCURE_PRIVATE_KEY are missing, Mercure will fail silently. Enable debug mode in config/notify.php to log errors:
'debug' => env('APP_DEBUG', false),
.env:
MERCURE_ALLOW_ORIGINS=http://localhost:3000,https://yourdomain.com
Push Type Constants
PushType constants (e.g., PushType::WEB). If the enum changes in future versions, update your code to use the new constants or methods.Channel Naming
notifications) to prevent unintended overlaps. Use namespaced channels like user:123:messages.Database Overhead
$data = array_intersect_key($data, array_flip(['title', 'message', 'url']));
Log Notifications
Enable logging in config/notify.php:
'log' => [
'enabled' => true,
'channel' => 'single',
'level' => 'debug',
],
Check logs in storage/logs/laravel.log for pushed notifications.
Mercure Debugging
var/log/mercure.log) for subscription/publish errors.curl http://localhost:.3000/.well-known/mercure?topic=notify:123:inbox
Frontend Debugging
error events on the frontend to catch Mercure connection issues:
eventSource.onerror = (error) => {
console.error('Mercure error:', error);
};
Extending the Bundle
class CustomChannelProvider extends AbstractChannelProvider
{
public function handle($userId, $data)
{
// Custom logic for 'custom-channel'
if ($data['type'] === 'urgent') {
$this->sendSms($userId, $data['message']);
}
}
}
Register it in config/notify.php:
'channels' => [
'custom-channel' => \App\Providers\CustomChannelProvider::class,
],
Rate Limiting
'mercure' => [
'rate_limit' => 10, // Max publishes per second
],
Environment-Specific Config
// config/notify.php (testing)
'mercure' => [
'enabled' => env('MERCURE_ENABLED', false),
],
Type Safety
#[Attribute]
class NotificationData
{
public function __construct(
public string $title,
public string $message,
public ?string $url = null,
) {}
}
Validate in your controller:
$data = new NotificationData(...);
$this->notifyManager->push($userId, 'channel', $data);
Fallback Mechanisms
$this->notify
How can I help you explore Laravel packages today?