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.
This package can be installed through Composer:
composer require testmonitor/notify-floodgateThe package will register itself automatically via Laravel's package discovery.
Publish the configuration file:
php artisan vendor:publish --tag=floodgate-configThe 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,
/*
* The notification class used to send a summary when multiple notifications
* are buffered. Swap this for your own class to fully customize the output.
*/
'summary' => \TestMonitor\Floodgate\Notifications\SummaryNotification::class,
/*
* 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',
],
];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.
Implement toSummary on your notification to define what the summary looks like. It receives all buffered notification instances and should return an array shaped like your toArray method:
public function toSummary(array $items): array
{
return [
'message' => ':count issues have been assigned to you',
'url' => route('issues.index'),
'icon' => 'exclamation-circle',
'properties' => ['count' => count($items)],
];
}When a summary is sent, the toArray method on each individual notification is passed to the summary mail view as $items, allowing you to include per-item detail alongside the grouped summary.
Pass a custom delay in seconds to ThrottlesNotifications to override the configured default:
public function middleware(): array
{
return [new ThrottlesNotifications(delay: 60)];
}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.
Send a notification immediately, skipping the buffer entirely, by calling withoutThrottling():
$user->notify((new IssueAssigned($issue))->withoutThrottling());The default SummaryNotification renders a mail view with $summary and $items variables. Publish the view to customise it:
php artisan vendor:publish --tag=floodgate-viewsFor full control, replace the summary class in the configuration:
'summary' => App\Notifications\IssueSummaryNotification::class,Your custom class receives $summary, $notifications, and $channels in its constructor. Extend the default to override only what you need:
use TestMonitor\Floodgate\Notifications\SummaryNotification;
class IssueSummaryNotification extends SummaryNotification
{
protected function subject(): string
{
return 'Your issue activity summary';
}
}The package contains a full test suite. Run it using:
composer testRefer to CHANGELOG for more information.
Refer to CONTRIBUTING for contributing details.
- Thijs Kok - Lead developer - ThijsKok
- Stephan Grootveld - Developer - Stefanius
- Frank Keulen - Developer - FrankIsGek
The MIT License (MIT). Please see License File for more information.