Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Notification Inbox Laravel Package

amjadiqbal/laravel-notification-inbox

amjadiqbal/laravel-notification-inbox is a database-backed notification inbox for Laravel. It helps you store, retrieve, mark as read, and organize user notifications, making it easier to build in-app notification centers with a clean, simple API and read/unread status handling.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package and publish its config and migrations, then migrate:
    composer require <vendor>/laravel-notification-inbox
    php artisan vendor:publish --tag="notification-inbox-config"
    php artisan vendor:publish --tag="notification-inbox-migrations"
    php artisan migrate
    
  2. Open config/notification-inbox.php first. The three things you will touch day to day are the gate name (manageNotificationInbox), the redaction lists (redact, redact_containing), and the pruning knobs (prune_lottery).
  3. Define the gate. Since v0.1.2 the package checks a separate manageNotificationInbox ability before rendering delete/clear actions, and that ability is local-only by default. In a non-local environment nothing is deletable until you define it:
    // AppServiceProvider::boot()
    Gate::define('manageNotificationInbox', fn (User $user) => $user->isAdmin());
    
    Viewing the inbox does not grant deletion; plan for two audiences (support reading, admins clearing).
  4. First use case: send a notification you would normally route to Slack/SMS from a local page or php artisan tinker, then open the inbox route. The notification is captured instead of delivered on non-mail channels, so you can iterate on formatting and copy without touching a real webhook.

Implementation Patterns

Use it as a local channel sandbox. Point your notification's via() at the channels you actually use in production and let the package catch them locally. You keep the real toSlack(), toVonage(), etc. code paths under test, and inspect the rendered payload in the inbox instead of a third-party dashboard. Google Chat was added to the channel table in v0.1.2, so if you thought a channel was unsupported, re-check the README table.

Assert against the inbox in tests rather than faking channels. Capture a notification by dispatching it in a feature test and asserting on what the inbox stored. This exercises your toArray()/payload builders and catches redaction regressions in one place.

Tune redaction in two layers. Keep redact for exact key names you know are sensitive, and put the broad families in redact_containing — v0.1.2 already masks keys containing password, passcode, secret, token, otp, code, private_key, and webhook. Add your domain-specific terms (e.g. api_key, session_id, card) to the substring list rather than enumerating every variant.

Turn on code masking only where it makes sense. mask_codes_in_text (NOTIFICATION_INBOX_MASK_CODES) is opt-in and masks 4–8 digit codes inside message text. Enable it in shared or screenshot-friendly environments; leave it off locally when the OTP is the thing you are debugging.

Schedule pruning explicitly. Pruning is opportunistic — roughly one capture in fifty triggers it — so it is not a substitute for a scheduled run. Add the command to your schedule (and to any environment where the inbox is not local-only):

$schedule->command('notification-inbox:prune')->daily();

Then set prune_lottery deliberately: 0 (or a very high denominator) on development machines where you want every capture retained, a low value in shared staging.

Place your own NotificationSending listeners in boot(). The package registers its interception listener in register(), which now runs ahead of listeners added in a provider's boot() and the app's own. Treat the package listener as the first link in the chain and put logging/telemetry listeners after it.

Gotchas and Tips

  • Only non-mail channels are intercepted. Mail and database notifications are still delivered, and your own toX() code still runs. Do not use the inbox as a guarantee that nothing left the machine — an HTTP call you make inside toX() still fires.
  • A listener returning non-null false still blocks delivery. v0.1.2 fixed ordering so an earlier listener can no longer silently pre-empt interception, but if your own NotificationSending listener returns false the notification stops before capture. Debug "missing from inbox" by logging listener order first, config second.
  • Over-redaction from substring matching is the most likely new surprise. code matches country_code, status_code, promo_code, error_code; token matches tokenized. Payloads that used to be readable for debugging will now show ***. If a field disappears, check redact_containing before assuming a bug — and remember config:clear after editing, since a cached config silently keeps old lists.
  • Route strings are never code-masked. If your message text embeds a URL containing a numeric ID or code, mask_codes_in_text will leave it visible. Sanitise URLs in the notification itself if they are sensitive.
  • Deleting is now gated separately. Buttons are hidden without manageNotificationInbox, but hidden UI is not authorization. If you build your own delete endpoint or call the package's action from a controller, verify the gate server-side. Local-only default means staging/production inboxes become read-only until you define the gate.
  • Pruning is a lottery, not a schedule. On a low-traffic app you may capture hundreds of entries before a single opportunistic prune fires. If you rely on it, schedule the command; if you rely on the lottery, verify prune_lottery is not set to 0.
  • Prefer the published config over env overrides where possible. NOTIFICATION_INBOX_MASK_CODES and friends are documented, but every new env key is another thing to remember in CI; set defaults in the published config and override per environment.
  • Extension checklist before you build on top: the gate name, the config keys (redact, redact_containing, mask_codes_in_text, prune_lottery), the notification-inbox:prune command, and the README's channel table — those four are where behaviour changed in v0.1.2 and where your day-to-day tuning will happen.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console