liberusoftware / module-cms-notifications
Notifications module for Liberu CMS: turns CMS events into queued notifications delivered through channels (mail, log).
Package info
github.com/liberusoftware/module-cms-notifications
Type:liberu-module
pkg:composer/liberusoftware/module-cms-notifications
Requires
- php: ^8.5
- filament/filament: ^5.11.0
- illuminate/bus: ^13.38.0
- illuminate/contracts: ^13.38.0
- illuminate/database: ^13.38.0
- illuminate/queue: ^13.38.0
- illuminate/support: ^13.38.0
- liberusoftware/module-cms-contracts: ^0.1
- liberusoftware/module-cms-core: ^0.1
- psr/log: ^3.0.2
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-14 19:55:27 UTC
README
Repository
Source, issues, and release history: https://github.com/liberusoftware/module-cms-notifications
Composer package: https://packagist.org/packages/liberusoftware/module-cms-notifications
Turns CMS events into notifications. It listens on the event bus and, for each configured subscription, records an audit log row and queues delivery on a channel — so the module that emitted the event never knows a notification was sent.
How it works
- A module emits a
CmsEvent(e.g.FormSubmitted,ContentPublished). - For each subscription on that event's name, a
NotificationLogrow is written (status = pending) and a queuedSendNotificationjob is dispatched with that row's id. - The job delivers the message on its channel and marks the row
sent.
Delivery reliability (at-least-once)
SendNotification is hardened for a real queue, where a job can run more than
once:
- Retries. Explicit
triesandbackoff(config('cms-notifications.queue'), default 3 tries at 10/30/60s). A transient channel failure (e.g. SMTP blip) is retried rather than lost. - Idempotency guard. The job is keyed on its
NotificationLogrow: if the row is alreadysent, a retry returns without re-delivering — so a duplicate email, the one user-visible duplicate, is avoided. NoShouldBeUnique, no generic dedup layer (there is exactly one queued job). - Failure is observable. After the retries are exhausted,
failed()marks the rowfailedand emits anotification.failedmetric (tagged by channel) through the metrics seam,bound()-guarded so it is inert without observability.
failed_jobs retention
Exhausted jobs land in Laravel's failed_jobs table (the framework
0001_01_01_000002_create_jobs_table migration — present, no action needed).
Prune it on a schedule in production, e.g. php artisan queue:prune-failed --hours=168 (keep one week). Worker supervision and this retention schedule are
covered by the production/ops checklist.
Subscriptions
Configure in config('cms-notifications.subscriptions'), keyed by event name:
'forms.submitted' => [ ['channel' => 'mail', 'to' => 'team@example.com', 'subject' => 'New form submission'], ], 'content.published' => [ ['channel' => 'log', 'subject' => 'Content published'], ],
Built-in events: forms.submitted, content.published. Defaults use the log
channel so the module works with no configuration; switch to mail and set to
to deliver email.
Channels
- mail — plain-text email to the subscription's recipients.
- log — writes to the application log.
Add a channel by implementing NotificationChannelInterface and registering it
on the ChannelManager.
Config
Publish with php artisan vendor:publish --tag=cms-notifications-config.