eugenefvdm/notification-subscriptions

A Laravel package for managing email subscriptions, repeat emails, and delayed sending

v0.4 2025-06-02 12:49 UTC

This package is auto-updated.

Last update: 2025-06-09 13:44:21 UTC


README

Tests Downloads

Notification Subscriptions is a Laravel package that may be used to keep track of repeat emails, delayed emails, and unsubscribing of email notifications.

The package makes use of Laravel's built-in event listeners NotificationSending and NotificationSent to automatically subscribe and to determine if and when a message should be sent.

Categorization of emails and model specific subscriptions are possible.

Installation

composer require eugenefvdm/notification-subscriptions

After installing the package, publish and run the migrations:

php artisan vendor:publish --tag="notification-subscriptions-migrations"
php artisan migrate

This will create the notification_templates and notification_subscriptions tables.

If you want to customize the unsubscribe link, publish the view component:

php artisan vendor:publish --tag="notification-subscriptions-views"

User Model

Add the HasNotificationSubscriptions trait to your User model:

use Eugenefvdm\NotificationSubscriptions\Traits\HasNotificationSubscriptions;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;
    use HasNotificationSubscriptions;

Usage

Generate notifications as per usual using php artisan:

php artisan make:notification DailyReminder --markdown=reminders.daily

Extend the newly created notification with the BaseNotification class:

use Eugenefvdm\NotificationSubscriptions\Notifications\BaseNotification;

class DailyReminder extends BaseNotification
{
    use Queueable;

Repeat Settings

In your notification class, add any or all of the following variables to do repeated notifications:

use Eugenefvdm\NotificationSubscriptions\Enums\RepeatFrequency;
use Eugenefvdm\NotificationSubscriptions\Notifications\BaseNotification;

class DailyReminder extends BaseNotification
{
    use Queueable;

    public static ?string $repeatFrequency = RepeatFrequency::Daily;
    public static ?int $repeatInterval = 4; // optional
    public static ?int $maxRepeats = 3; // optional defaults to 1

Delayed Sending

To wait a certain amount of time before sending a notification, set initialDelay in your constructor:

use Eugenefvdm\NotificationSubscriptions\Notifications\BaseNotification;

class DailyReminder extends BaseNotification
{
    use Queueable;

    public static ?Carbon $initialDelay = null;

    /**
     * Create a new notification instance.
     */
    public function __construct()
    {        
        self::$initialDelay = Carbon::now()->addWeek();
    }

Categorization

All new messages without an explicit category assignment will be assigned to the default category in the database.

To specify a custom category, use $category:

use Eugenefvdm\NotificationSubscriptions\Notifications\BaseNotification;

class DailyReminder extends BaseNotification
{
    use Queueable;

    public static ?string $category = 'reminders';

Model Specific Subscriptions

Notifications are typically tied to a user, but at times one wants to associate a notification to both a user and another model. For example, you might have a products table, and you want a user to be subscribed to a price notification for specific Product models. Here's how:

use Eugenefvdm\NotificationSubscriptions\Notifications\BaseNotification;
use Illuminate\Database\Eloquent\Model;
use App\Models\Product;

class ProductPriceNotification extends BaseNotification
{
    use Queueable;

    public ?Model $customModel; // Override $customModel

    public function __construct(Product $product) // Type-hint Product in constructor
    {
        $this->customModel = $product;
    }

    public function toMail(object $notifiable): MailMessage
    {
        /** @var Product $product */
        $product = $this->customModel;

        return (new MailMessage)
            ->subject("Price Update for {$product->name}")
            ->markdown('notification.product-price-update', [
                'product' => $product,
                'subscription' => $this->getSubscriptionFromNotifiable($notifiable)
            ]);
    }
}

Unsubscribe

Any new notification will be automatically subscribed when used the first time.

Unsubscribe Links in Blades

For unsubscribe links, modify the toMail method in the notification class:

/**
 * Get the mail representation of the notification.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
        ->markdown('notification.reminders.max-count', [
            'subscription' => $this->getSubscriptionFromNotifiable($notifiable)
        ]);
}

Then add this to your blade:

<x-notification-subscriptions::unsubscribe :subscription="$subscription" />

The default controller action for unsubscribe is to redirect back with a session variable value of error or status.

Testing

composer test

License

The MIT License (MIT). Please see License File for more information.

Alternatives

  • mail-tracker - A Laravel package that injects tracking code into outgoing emails and provides an interface to view sent emails, track opens, and monitor link clicks.