testmonitor / notify-floodgate
A Laravel package to buffer notifications and prevent notification floods.
Requires
- php: ^8.4
- illuminate/contracts: ^12.0|^13.0
- illuminate/notifications: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.29
- orchestra/testbench: ^10.0
- phpunit/phpunit: ^11.0
- squizlabs/php_codesniffer: ^4.0
This package is auto-updated.
Last update: 2026-08-06 08:33:59 UTC
README
A Laravel package that prevents notification floods by buffering queued notifications within a time window. When a single notification arrives, it is sent as-is. When multiple notifications of the same type arrive within the window, they are grouped into a single summary notification.
Table of Contents
Installation
This package can be installed through Composer:
composer require testmonitor/notify-floodgate
The package will register itself automatically via Laravel's package discovery.
Publish the configuration file:
php artisan vendor:publish --tag=floodgate-config
Configuration
The configuration file is located at config/floodgate.php:
return [ /* * The number of seconds to wait before flushing a notification buffer. * During this window, additional notifications of the same type are * grouped and sent as a single summary. */ 'delay' => 10, /* * Cache store and key prefix used to hold buffered notifications. * The store must support atomic locks (e.g. Redis, Memcached, database). */ 'cache' => [ 'store' => null, 'prefix' => 'floodgate', ], ];
Usage
Preparing Your Notification
Add the Gateable trait and a middleware method to any queued notification you want to throttle:
use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Notification; use TestMonitor\Floodgate\Concerns\Gateable; use TestMonitor\Floodgate\Middleware\ThrottlesNotifications; class IssueAssigned extends Notification implements ShouldQueue { use Queueable, Gateable; public function middleware(): array { return [new ThrottlesNotifications]; } // ... }
That's all the setup required. The floodgate will now buffer notifications within the configured delay window and send a summary when the threshold is exceeded.
Sending a Summary
Implement toSummary on your notification to define what the summary looks like. It receives all buffered notification instances plus the $channels this particular batch was buffered for, and should return a regular notification — write it exactly like any other notification class, with its own via(), toMail(), toArray(), and so on:
use Illuminate\Notifications\Notification; public function toSummary(array $notifications, array $channels): Notification { return new IssueActivitySummary($notifications, $channels); }
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; use TestMonitor\Floodgate\Concerns\SummarizesNotifications; class IssueActivitySummary extends Notification { use SummarizesNotifications; public function __construct(public array $notifications, public array $channels) {} public function toMail(mixed $notifiable): MailMessage { return (new MailMessage) ->subject('Your issue activity summary') ->line(__(':count issues have been assigned to you', ['count' => count($this->notifications)])) ->action('View Issues', route('issues.index')); } public function toArray(mixed $notifiable): array { return ['count' => count($this->notifications)]; } }
The SummarizesNotifications trait is optional and just saves you the boilerplate of adding the $notifications/$channels properties and a via() returning $this->channels. Return $channels rather than hardcoding them: each channel is buffered and flushed independently, so toSummary is called once per channel batch, and hardcoding e.g. ['mail', 'database'] would double-send whichever flushes second.
Customizing the Buffer Window
Pass a custom delay in seconds to ThrottlesNotifications to override the configured default:
public function middleware(): array { return [new ThrottlesNotifications(delay: 60)]; }
Customizing the Threshold
By default, a summary is sent whenever more than one notification is buffered. Raise the threshold to allow a number of originals through before switching to a summary:
public function middleware(): array { return [new ThrottlesNotifications(threshold: 3)]; }
With a threshold of 3, up to three notifications are delivered individually. A fourth within the same window triggers a summary instead.
Bypassing the Floodgate
Send a notification immediately, skipping the buffer entirely, by calling withoutThrottling():
$user->notify((new IssueAssigned($issue))->withoutThrottling());
Tests
The package contains a full test suite. Run it using:
composer test
Changelog
Refer to CHANGELOG for more information.
Contributing
Refer to CONTRIBUTING for contributing details.
Credits
- Thijs Kok - Lead developer - ThijsKok
- Stephan Grootveld - Developer - Stefanius
- Frank Keulen - Developer - FrankIsGek
License
The MIT License (MIT). Please see License File for more information.