├── src ├── NotificationLog.php ├── Facades │ └── NotificationHistory.php ├── Exceptions │ ├── InvalidActionClass.php │ ├── InvalidExtraContent.php │ └── InvalidNotifiable.php ├── NotificationLogServiceProvider.php ├── Support │ ├── Config.php │ └── NotificationHistoryQueryBuilder.php ├── Models │ ├── Concerns │ │ ├── HasHistory.php │ │ └── HasNotifiableHistory.php │ └── NotificationLogItem.php ├── NotificationEventSubscriber.php └── Actions │ └── ConvertNotificationSendingEventToLogItemAction.php ├── database └── migrations │ └── create_notification_log_items_table.php ├── LICENSE.md ├── config └── notification-log.php ├── composer.json ├── README.md └── CHANGELOG.md /src/NotificationLog.php: -------------------------------------------------------------------------------- 1 | name('laravel-notification-log') 16 | ->hasConfigFile() 17 | ->hasMigration('create_notification_log_items_table'); 18 | } 19 | 20 | public function bootingPackage(): void 21 | { 22 | $eventSubscriberClass = Config::eventSubscriberClass(); 23 | 24 | Event::subscribe($eventSubscriberClass); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/migrations/create_notification_log_items_table.php: -------------------------------------------------------------------------------- 1 | id(); 13 | $table->string('notification_type'); 14 | $table->unsignedBigInteger('notifiable_id')->nullable(); 15 | $table->string('notifiable_type')->nullable(); 16 | $table->string('channel'); 17 | $table->string('fingerprint')->nullable(); 18 | $table->json('extra')->nullable(); 19 | $table->json('anonymous_notifiable_properties')->nullable(); 20 | $table->dateTime('confirmed_at')->nullable(); 21 | $table->timestamps(); 22 | 23 | $table->index(['notifiable_type', 'notifiable_id']); 24 | $table->index(['created_at']); 25 | }); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) spatie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Support/Config.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public static function notificationLogModelClass(): string 16 | { 17 | return config('notification-log.model'); 18 | } 19 | 20 | public static function convertEventToModelAction(): ConvertNotificationSendingEventToLogItemAction 21 | { 22 | $actionClass = config('notification-log.actions.convertEventToModel'); 23 | 24 | if (! is_a($actionClass, ConvertNotificationSendingEventToLogItemAction::class, true)) { 25 | throw InvalidActionClass::make('convertEventToModel', ConvertNotificationSendingEventToLogItemAction::class); 26 | } 27 | 28 | return app($actionClass); 29 | } 30 | 31 | /** 32 | * @return class-string 33 | */ 34 | public static function eventSubscriberClass(): string 35 | { 36 | return config('notification-log.event_subscriber'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /config/notification-log.php: -------------------------------------------------------------------------------- 1 | Spatie\NotificationLog\Models\NotificationLogItem::class, 8 | 9 | /* 10 | * Log items older than this number of days will be automatically be removed. 11 | * 12 | * This feature uses Laravel's native pruning feature: 13 | * https://laravel.com/docs/12.x/eloquent#pruning-models 14 | */ 15 | 'prune_after_days' => 30, 16 | 17 | /* 18 | * If this is set to true, any notification that does not have a 19 | * `shouldLog` method will be logged. 20 | */ 21 | 'log_all_by_default' => config('notification-log.log_all_by_default'), 22 | 23 | /* 24 | * By overriding these actions, you can make low level customizations. You can replace 25 | * these classes by a class of your own that extends the original. 26 | * 27 | */ 28 | 'actions' => [ 29 | 'convertEventToModel' => Spatie\NotificationLog\Actions\ConvertNotificationSendingEventToLogItemAction::class, 30 | ], 31 | 32 | /* 33 | * The event subscriber that will listen for the notification events fire by Laravel. 34 | * In most cases, you don't need to touch this. You could replace this by 35 | * a class of your own that extends the original. 36 | */ 37 | 'event_subscriber' => Spatie\NotificationLog\NotificationEventSubscriber::class, 38 | ]; 39 | -------------------------------------------------------------------------------- /src/Models/Concerns/HasHistory.php: -------------------------------------------------------------------------------- 1 | ensureNotifiableIsModel($notifiable); 14 | 15 | return new NotificationHistoryQueryBuilder( 16 | $this, 17 | $notifiable, 18 | shouldExist: true, 19 | withSameFingerprint: $withSameFingerprint 20 | ); 21 | } 22 | 23 | public function wasNotSentTo( 24 | $notifiable, 25 | $withSameFingerprint = false 26 | ): NotificationHistoryQueryBuilder { 27 | $this->ensureNotifiableIsModel($notifiable); 28 | 29 | return new NotificationHistoryQueryBuilder( 30 | $this, 31 | $notifiable, 32 | shouldExist: false, 33 | withSameFingerprint: $withSameFingerprint, 34 | ); 35 | } 36 | 37 | protected function ensureNotifiableIsModel($notifiable): void 38 | { 39 | if (! $notifiable instanceof Model) { 40 | throw InvalidNotifiable::shouldBeAModel(); 41 | } 42 | 43 | if (! in_array(HasNotifiableHistory::class, class_uses_recursive($notifiable))) { 44 | throw InvalidNotifiable::shouldUseTrait($notifiable); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Models/Concerns/HasNotifiableHistory.php: -------------------------------------------------------------------------------- 1 | latestLoggedNotificationQuery(...func_get_args())->first(); 23 | } 24 | 25 | public function latestLoggedNotificationQuery( 26 | ?string $fingerprint = null, 27 | string|array|null $notificationTypes = null, 28 | ?Carbon $before = null, 29 | ?Carbon $after = null, 30 | string|array|null $channel = null, 31 | ): Builder { 32 | $notificationLogClass = Config::notificationLogModelClass(); 33 | 34 | return $notificationLogClass::latestForQuery( 35 | $this, 36 | ...func_get_args(), 37 | ); 38 | } 39 | 40 | public function notificationLogItems(): MorphMany 41 | { 42 | $notificationLogClass = Config::notificationLogModelClass(); 43 | 44 | $logKeyName = (new $notificationLogClass)->getKeyName(); 45 | 46 | return $this->morphMany($notificationLogClass, 'notifiable') 47 | ->orderByDesc('created_at') 48 | ->orderByDesc($logKeyName); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/NotificationEventSubscriber.php: -------------------------------------------------------------------------------- 1 | shouldLog($event)) { 24 | return; 25 | } 26 | 27 | $convertEventToModelAction = Config::convertEventToModelAction(); 28 | 29 | $logItem = $convertEventToModelAction->execute($event); 30 | 31 | if ($logItem) { 32 | self::$sentNotifications[$event->notification] = $logItem; 33 | } 34 | } 35 | 36 | public function handleNotificationSent(NotificationSent $event): void 37 | { 38 | if (! self::$sentNotifications->offsetExists($event->notification)) { 39 | return; 40 | } 41 | 42 | self::$sentNotifications[$event->notification]->markAsSent(); 43 | } 44 | 45 | protected function shouldLog(NotificationSending $event): bool 46 | { 47 | $notification = $event->notification; 48 | 49 | if (method_exists($notification, 'shouldLog')) { 50 | return $notification->shouldLog($event); 51 | } 52 | 53 | return config('notification-log.log_all_by_default') ?? true; 54 | } 55 | 56 | public function subscribe(): array 57 | { 58 | return [ 59 | NotificationSending::class => 'handleNotificationSending', 60 | NotificationSent::class => 'handleNotificationSent', 61 | ]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Support/NotificationHistoryQueryBuilder.php: -------------------------------------------------------------------------------- 1 | getNotificationTypeForNotification($this->notification, $this->notifiable); 22 | 23 | $this->query = $this->notifiable 24 | ->latestLoggedNotificationQuery( 25 | notificationTypes: $type, 26 | ); 27 | } 28 | 29 | public function onChannel(string $channel): static 30 | { 31 | $this->query 32 | ->where('channel', $channel); 33 | 34 | return $this; 35 | } 36 | 37 | public function inThePastMinutes(?int $numberOfMinutes): bool 38 | { 39 | $query = $this->query 40 | ->when($numberOfMinutes !== null, function (Builder $query) use ($numberOfMinutes) { 41 | $query->where('created_at', '>=', now()->subMinutes($numberOfMinutes)); 42 | }) 43 | ->when($this->withSameFingerprint, function (Builder $query) { 44 | $action = Config::convertEventToModelAction(); 45 | 46 | $fingerprint = $action->getFingerprintForNotification( 47 | $this->notification, 48 | $this->notifiable, 49 | ); 50 | 51 | if ($fingerprint === null) { 52 | return; 53 | } 54 | 55 | $query->where('fingerprint', $fingerprint); 56 | }); 57 | 58 | return $this->shouldExist 59 | ? $query->exists() 60 | : $query->doesntExist(); 61 | } 62 | 63 | public function inThePast(): bool 64 | { 65 | return $this->inThePastMinutes(null); 66 | } 67 | 68 | public function query(): Builder 69 | { 70 | return $this->query; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spatie/laravel-notification-log", 3 | "description": "Log notifications sent by your Laravel app", 4 | "keywords": [ 5 | "spatie", 6 | "laravel", 7 | "laravel-notification-log" 8 | ], 9 | "homepage": "https://github.com/spatie/laravel-notification-log", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Freek Van der Herten", 14 | "email": "freek@spatie.be", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^8.1|^8.2", 20 | "illuminate/contracts": "^10.0|^11.0|^12.0", 21 | "spatie/laravel-package-tools": "^1.14.0", 22 | "spatie/test-time": "^1.3" 23 | }, 24 | "require-dev": { 25 | "laravel/pint": "^1.0", 26 | "nunomaduro/collision": "^7.0|^8.1", 27 | "orchestra/testbench": "^8.0|^10.0", 28 | "pestphp/pest": "^2.0|^3.7", 29 | "pestphp/pest-plugin-arch": "^2.0|^3.0", 30 | "pestphp/pest-plugin-laravel": "^2.0|^3.1", 31 | "spatie/laravel-ray": "^1.26" 32 | }, 33 | "autoload": { 34 | "psr-4": { 35 | "Spatie\\NotificationLog\\": "src", 36 | "Spatie\\NotificationLog\\Database\\Factories\\": "database/factories" 37 | } 38 | }, 39 | "autoload-dev": { 40 | "psr-4": { 41 | "Spatie\\NotificationLog\\Tests\\": "tests" 42 | } 43 | }, 44 | "scripts": { 45 | "post-autoload-dump": "@php ./vendor/bin/testbench package:discover --ansi", 46 | "analyse": "vendor/bin/phpstan analyse", 47 | "test": "vendor/bin/pest", 48 | "test-coverage": "vendor/bin/pest --coverage", 49 | "format": "vendor/bin/pint" 50 | }, 51 | "config": { 52 | "sort-packages": true, 53 | "allow-plugins": { 54 | "pestphp/pest-plugin": true, 55 | "phpstan/extension-installer": true 56 | } 57 | }, 58 | "extra": { 59 | "laravel": { 60 | "providers": [ 61 | "Spatie\\NotificationLog\\NotificationLogServiceProvider" 62 | ], 63 | "aliases": { 64 | "NotificationLog": "NotificationHistory" 65 | } 66 | } 67 | }, 68 | "minimum-stability": "dev", 69 | "prefer-stable": true 70 | } 71 | -------------------------------------------------------------------------------- /src/Models/NotificationLogItem.php: -------------------------------------------------------------------------------- 1 | 'array', 22 | 'anonymous_notifiable_properties' => 'array', 23 | 'confirmed_at' => 'datetime', 24 | ]; 25 | 26 | /** 27 | * @return Builder 28 | */ 29 | public function prunable(): Builder 30 | { 31 | $threshold = config('notification-log.prune_after_days'); 32 | 33 | return static::query() 34 | ->where('created_at', '<=', now()->subDays($threshold)); 35 | } 36 | 37 | public function notifiable(): MorphTo 38 | { 39 | return $this->morphTo('notifiable'); 40 | } 41 | 42 | public function wasSentInPastMinutes(int $minutes = 1): bool 43 | { 44 | return $this->created_at > now()->subMinutes($minutes); 45 | } 46 | 47 | public function markAsSent(): self 48 | { 49 | $this->update([ 50 | 'confirmed_at' => now(), 51 | ]); 52 | 53 | return $this; 54 | } 55 | 56 | public static function latestFor( 57 | $notifiable, 58 | ?string $fingerprint = null, 59 | string|array|null $notificationType = null, 60 | ?Carbon $before = null, 61 | ?Carbon $after = null, 62 | string|array|null $channel = null, 63 | ): ?NotificationLogItem { 64 | return static::latestForQuery(...func_get_args())->first(); 65 | } 66 | 67 | public static function latestForQuery( 68 | $notifiable, 69 | ?string $fingerprint = null, 70 | string|array|null $notificationType = null, 71 | ?Carbon $before = null, 72 | ?Carbon $after = null, 73 | string|array|null $channel = null, 74 | ): Builder { 75 | /** @var Builder $query */ 76 | $query = static::query() 77 | ->where('notifiable_type', $notifiable->getMorphClass()) 78 | ->where('notifiable_id', $notifiable->getKey()) 79 | ->when($fingerprint !== null, fn (Builder $query) => $query->where('fingerprint', $fingerprint)) 80 | ->when($notificationType !== null, function (Builder $query) use ($notificationType) { 81 | $query->whereIn('notification_type', Arr::wrap($notificationType)); 82 | }) 83 | ->when($channel !== null, function (Builder $query) use ($channel) { 84 | $query->whereIn('channel', Arr::wrap($channel)); 85 | }) 86 | ->when($before, function (Builder $query) use ($before) { 87 | $query->where('created_at', '<', $before->toDateTimeString()); 88 | }) 89 | ->when($after, function (Builder $query) use ($after) { 90 | $query->where('created_at', '>', $after->toDateTimeString()); 91 | }); 92 | 93 | $keyName = $query->getModel()->getKeyName(); 94 | 95 | return $query 96 | ->orderByDesc('created_at') 97 | ->orderByDesc($keyName); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/Actions/ConvertNotificationSendingEventToLogItemAction.php: -------------------------------------------------------------------------------- 1 | $this->getNotificationType($event), 21 | 'notifiable_type' => $this->getNotifiableType($event), 22 | 'notifiable_id' => $this->getNotifiableKey($event), 23 | 'channel' => $event->channel, 24 | 'fingerprint' => $this->getFingerPrint($event), 25 | 'extra' => $this->getExtra($event), 26 | 'anonymous_notifiable_properties' => $this->getAnonymousNotifiableProperties($event), 27 | ]); 28 | } 29 | 30 | protected function getNotifiableType(NotificationSending $event): ?string 31 | { 32 | /** @var Model|AnonymousNotifiable $notifiable */ 33 | $notifiable = $event->notifiable; 34 | 35 | return $notifiable instanceof Model 36 | ? $notifiable->getMorphClass() 37 | : null; 38 | } 39 | 40 | protected function getNotifiableKey(NotificationSending $event): mixed 41 | { 42 | /** @var Model|AnonymousNotifiable $notifiable */ 43 | $notifiable = $event->notifiable; 44 | 45 | return $notifiable instanceof Model 46 | ? $notifiable->getKey() 47 | : null; 48 | } 49 | 50 | protected function getNotificationType(NotificationSending $event): string 51 | { 52 | $notification = $event->notification; 53 | 54 | return $this->getNotificationTypeForNotification($notification, $event->notifiable); 55 | } 56 | 57 | public function getNotificationTypeForNotification(Notification $notification, $notifiable) 58 | { 59 | if (method_exists($notification, 'logType')) { 60 | return $notification->logType($notifiable); 61 | } 62 | 63 | return get_class($notification); 64 | } 65 | 66 | /** 67 | * @return class-string 68 | */ 69 | protected function getModelClass(NotificationSending $event): string 70 | { 71 | return config('notification-log.model'); 72 | } 73 | 74 | protected function getFingerprint(NotificationSending $event): ?string 75 | { 76 | $notification = $event->notification; 77 | 78 | return $this->getFingerprintForNotification($notification, $event->notifiable); 79 | } 80 | 81 | public function getFingerprintForNotification(Notification $notification, $notifiable) 82 | { 83 | if (method_exists($notification, 'fingerprint')) { 84 | return $notification->fingerprint($notifiable); 85 | } 86 | 87 | return null; 88 | } 89 | 90 | protected function getExtra(NotificationSending $event): array 91 | { 92 | $notification = $event->notification; 93 | 94 | if (method_exists($notification, 'logExtra')) { 95 | $extra = $notification->logExtra($event); 96 | 97 | if (! is_array($extra)) { 98 | throw InvalidExtraContent::make($notification); 99 | } 100 | 101 | return $extra; 102 | } 103 | 104 | return []; 105 | } 106 | 107 | protected function getAnonymousNotifiableProperties(NotificationSending $event): ?array 108 | { 109 | if (! $event->notifiable instanceof AnonymousNotifiable) { 110 | return null; 111 | } 112 | 113 | return $event->notifiable->routes; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | Logo for laravel-notification-log 6 | 7 | 8 | 9 |

Log notifications sent by your Laravel app

10 | 11 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-notification-log.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-notification-log) 12 | [![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-notification-log/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/spatie/laravel-notification-log/actions?query=workflow%3Arun-tests+branch%3Amain) 13 | [![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-notification-log/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/spatie/laravel-notification-log/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain) 14 | [![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-notification-log.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-notification-log) 15 | 16 |
17 | 18 | This package will log all the notifications sent by your app. This will allow you to write logic based on the notifications your app has sent. 19 | 20 | If you want to create a list of all notifications sent to a user 21 | 22 | ```php 23 | // returns a collection of `NotificationLogItem` models 24 | $sentNotifications = $user->loggedNotifications(); 25 | ``` 26 | 27 | In a view, you could write this: 28 | 29 | ```blade 30 |
    31 | @foreach($sentNotifications as $sentNotification) 32 |
  • {{ $sentNotification->type }} at {{ $sentNotification->created_at->format('Y-m-d H:i:s') }}
  • 33 | @endforeach 34 |
35 | ``` 36 | 37 | The package also contains handy methods that allow you to make decisions based on the notifications sent. Here's an example, where we use the `wasAlreadySentTo` method provided by the package in a `shouldSent` method of a notification. 38 | 39 | ```php 40 | // in a notification 41 | 42 | public function shouldSend($notifiable) 43 | { 44 | return ! $this 45 | ->wasAlreadySentTo($notifiable) 46 | ->inThePastMinutes(60); 47 | } 48 | ``` 49 | 50 | You can fully customize which notifications get logged and how they get logged. 51 | 52 | ## Support us 53 | 54 | [](https://spatie.be/github-ad-click/laravel-notification-log) 55 | 56 | We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). 57 | 58 | We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). 59 | 60 | ## Documentation 61 | 62 | All documentation is available [on our documentation site](https://spatie.be/docs/laravel-notification-log). 63 | 64 | ## Testing 65 | 66 | ```bash 67 | composer test 68 | ``` 69 | 70 | ## Changelog 71 | 72 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 73 | 74 | ## Contributing 75 | 76 | Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details. 77 | 78 | ## Security Vulnerabilities 79 | 80 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 81 | 82 | ## Credits 83 | 84 | - [Freek Van der Herten](https://github.com/freekmurze) 85 | - [All Contributors](../../contributors) 86 | 87 | ## License 88 | 89 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 90 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `laravel-notification-log` will be documented in this file. 4 | 5 | ## 1.3.3 - 2025-11-14 6 | 7 | ### What's Changed 8 | 9 | * Update introduction.md by @WillTorres10 in https://github.com/spatie/laravel-notification-log/pull/45 10 | * Update issue template by @AlexVanderbist in https://github.com/spatie/laravel-notification-log/pull/50 11 | * Fix typo by @chrysanthos in https://github.com/spatie/laravel-notification-log/pull/52 12 | * Fix notification history builder return types by @imhayatunnabi in https://github.com/spatie/laravel-notification-log/pull/53 13 | * Bump stefanzweifel/git-auto-commit-action from 5 to 7 by @dependabot[bot] in https://github.com/spatie/laravel-notification-log/pull/51 14 | * Bump actions/checkout from 3 to 5 by @dependabot[bot] in https://github.com/spatie/laravel-notification-log/pull/48 15 | * Bump aglipanci/laravel-pint-action from 2.5 to 2.6 by @dependabot[bot] in https://github.com/spatie/laravel-notification-log/pull/47 16 | * update pruning documentation for Laravel 11+ compatibility by @lukasleitsch in https://github.com/spatie/laravel-notification-log/pull/49 17 | 18 | ### New Contributors 19 | 20 | * @WillTorres10 made their first contribution in https://github.com/spatie/laravel-notification-log/pull/45 21 | * @AlexVanderbist made their first contribution in https://github.com/spatie/laravel-notification-log/pull/50 22 | * @chrysanthos made their first contribution in https://github.com/spatie/laravel-notification-log/pull/52 23 | * @imhayatunnabi made their first contribution in https://github.com/spatie/laravel-notification-log/pull/53 24 | * @lukasleitsch made their first contribution in https://github.com/spatie/laravel-notification-log/pull/49 25 | 26 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.3.2...1.3.3 27 | 28 | ## 1.3.2 - 2025-02-19 29 | 30 | ### What's Changed 31 | 32 | * Improve documentation section Using your own notification log model by @gisostallenberg in https://github.com/spatie/laravel-notification-log/pull/40 33 | * Bump aglipanci/laravel-pint-action from 2.3.1 to 2.5 by @dependabot in https://github.com/spatie/laravel-notification-log/pull/43 34 | * Laravel 12.x Compatibility by @laravel-shift in https://github.com/spatie/laravel-notification-log/pull/44 35 | 36 | ### New Contributors 37 | 38 | * @gisostallenberg made their first contribution in https://github.com/spatie/laravel-notification-log/pull/40 39 | * @laravel-shift made their first contribution in https://github.com/spatie/laravel-notification-log/pull/44 40 | 41 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.3.1...1.3.2 42 | 43 | ## 1.3.1 - 2024-03-28 44 | 45 | ### What's Changed 46 | 47 | * Remove unnecessary method call in HasHistory by @andreasnij in https://github.com/spatie/laravel-notification-log/pull/35 48 | 49 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.3.0...1.3.1 50 | 51 | ## 1.3.0 - 2024-03-15 52 | 53 | ### What's Changed 54 | 55 | * Update composer.json for L11 compatibility by @axtg in https://github.com/spatie/laravel-notification-log/pull/39 56 | 57 | ### New Contributors 58 | 59 | * @axtg made their first contribution in https://github.com/spatie/laravel-notification-log/pull/39 60 | 61 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.2.1...1.3.0 62 | 63 | ## 1.2.1 - 2024-03-01 64 | 65 | ### What's Changed 66 | 67 | * Don't put falsey log item in map by @kohenkatz in https://github.com/spatie/laravel-notification-log/pull/38 68 | 69 | ### New Contributors 70 | 71 | * @kohenkatz made their first contribution in https://github.com/spatie/laravel-notification-log/pull/38 72 | 73 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.2.0...1.2.1 74 | 75 | ## 1.2.0 - 2024-01-18 76 | 77 | ### What's Changed 78 | 79 | * Update docs to add missing event parameter by @FrancisMawn in https://github.com/spatie/laravel-notification-log/pull/26 80 | * fix typo in file name by @aminetiyal in https://github.com/spatie/laravel-notification-log/pull/28 81 | * Remove unused exception_message db column by @andreasnij in https://github.com/spatie/laravel-notification-log/pull/32 82 | * Update introduction.md by @dwightwatson in https://github.com/spatie/laravel-notification-log/pull/33 83 | * Bump aglipanci/laravel-pint-action from 2.3.0 to 2.3.1 by @dependabot in https://github.com/spatie/laravel-notification-log/pull/34 84 | * Bump stefanzweifel/git-auto-commit-action from 4 to 5 by @dependabot in https://github.com/spatie/laravel-notification-log/pull/31 85 | * Add history builder inThePast() method by @andreasnij in https://github.com/spatie/laravel-notification-log/pull/36 86 | 87 | ### New Contributors 88 | 89 | * @aminetiyal made their first contribution in https://github.com/spatie/laravel-notification-log/pull/28 90 | * @andreasnij made their first contribution in https://github.com/spatie/laravel-notification-log/pull/32 91 | * @dwightwatson made their first contribution in https://github.com/spatie/laravel-notification-log/pull/33 92 | 93 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.1.1...1.2.0 94 | 95 | ## 1.1.1 - 2023-08-10 96 | 97 | ### What's Changed 98 | 99 | - Fix HasNotifiableHistory trait not using the configured model class by @FrancisMawn in https://github.com/spatie/laravel-notification-log/pull/25 100 | 101 | ### New Contributors 102 | 103 | - @FrancisMawn made their first contribution in https://github.com/spatie/laravel-notification-log/pull/25 104 | - @dependabot made their first contribution in https://github.com/spatie/laravel-notification-log/pull/20 105 | 106 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.1.0...1.1.1 107 | 108 | ## 1.1.0 - 2023-07-17 109 | 110 | ### What's Changed 111 | 112 | - Add option to query channels by @pxlrbt in https://github.com/spatie/laravel-notification-log/pull/23 113 | 114 | ### New Contributors 115 | 116 | - @pxlrbt made their first contribution in https://github.com/spatie/laravel-notification-log/pull/23 117 | 118 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.0.4...1.1.0 119 | 120 | ## 1.0.4 - 2023-05-12 121 | 122 | ### What's Changed 123 | 124 | - Fix docs by @ao-jhelmich in https://github.com/spatie/laravel-notification-log/pull/13 125 | - use semicolon instead of comma at the end of line by @mhfereydouni in https://github.com/spatie/laravel-notification-log/pull/17 126 | - Added Get Config Variable by @stijnvanouplines in https://github.com/spatie/laravel-notification-log/pull/18 127 | 128 | ### New Contributors 129 | 130 | - @ao-jhelmich made their first contribution in https://github.com/spatie/laravel-notification-log/pull/13 131 | - @mhfereydouni made their first contribution in https://github.com/spatie/laravel-notification-log/pull/17 132 | - @stijnvanouplines made their first contribution in https://github.com/spatie/laravel-notification-log/pull/18 133 | 134 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.0.3...1.0.4 135 | 136 | ## 1.0.3 - 2023-03-14 137 | 138 | ### What's Changed 139 | 140 | - correct mistake in fingerprint docs by @ceejayoz in https://github.com/spatie/laravel-notification-log/pull/8 141 | - add default indexes to created_at and notifiable by @ceejayoz in https://github.com/spatie/laravel-notification-log/pull/11 142 | 143 | ### New Contributors 144 | 145 | - @ceejayoz made their first contribution in https://github.com/spatie/laravel-notification-log/pull/8 146 | 147 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.0.2...1.0.3 148 | 149 | ## 1.0.2 - 2023-02-28 150 | 151 | ### What's Changed 152 | 153 | - Match cast field name to migration by @patrickomeara in https://github.com/spatie/laravel-notification-log/pull/4 154 | 155 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.0.1...1.0.2 156 | 157 | ## 1.0.1 - 2023-02-28 158 | 159 | ### What's Changed 160 | 161 | - Use subDays to determine what should be pruned by @patrickomeara in https://github.com/spatie/laravel-notification-log/pull/3 162 | 163 | ### New Contributors 164 | 165 | - @patrickomeara made their first contribution in https://github.com/spatie/laravel-notification-log/pull/3 166 | 167 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/1.0.0...1.0.1 168 | 169 | ## 1.0.0 - 2023-02-26 170 | 171 | - stable release 172 | 173 | ## 0.0.4 - 2023-02-26 174 | 175 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/0.0.3...0.0.4 176 | 177 | ## 0.0.3 - 2023-02-25 178 | 179 | ### What's Changed 180 | 181 | - Fixing the CONTRIBUTING.MD link in README.md by @raksbisht in https://github.com/spatie/laravel-notification-log/pull/1 182 | 183 | ### New Contributors 184 | 185 | - @raksbisht made their first contribution in https://github.com/spatie/laravel-notification-log/pull/1 186 | 187 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/0.0.2...0.0.3 188 | 189 | ## 0.0.2 - 2023-02-24 190 | 191 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/compare/0.0.1...0.0.2 192 | 193 | ## 0.0.1 - 2023-02-24 194 | 195 | **Full Changelog**: https://github.com/spatie/laravel-notification-log/commits/0.0.1 196 | --------------------------------------------------------------------------------