Search by

a2zwebltd / laravel-email-sequences

dawid-makowski

A portable Laravel drip / lifecycle email-sequence engine — enrol users on registration, schedule time-delayed emails (onboarding, trial nurture, win-back), deliver them on a cron with pluggable eligibility rules, and manage everything from Nova.

Package info

github.com/a2zwebltd/laravel-email-sequences

pkg:composer/a2zwebltd/laravel-email-sequences

Statistics

Installs: 57

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.3.0 2026-09-23 07:00 UTC

This package is auto-updated.

Last update: 2026-09-23 07:00:30 UTC


README

Packagist Version Downloads PHP Laravel

A portable Laravel drip / lifecycle email engine. Enrol users into time-delayed email sequences (onboarding, trial nurture, win-back, feedback), deliver them on a cron, and stop a user's sequence the moment they convert — all driven by config and pluggable eligibility rules, with ready-made Nova admin resources.

Designed to drop into any Laravel app while leaving the host in control of its user model, eligibility rules, branding and notifications.

Requirements

  • PHP 8.2+
  • Laravel 11 / 12 / 13
  • laravel/nova ^5 (optional — auto-registers Nova resources when present)

Installation

composer require a2zwebltd/laravel-email-sequences
php artisan migrate
php artisan vendor:publish --tag=email-sequences-config   # optional
php artisan vendor:publish --tag=email-sequences-views     # optional, to rebrand emails

Add the trait to your User model:

use A2ZWeb\EmailSequences\Concerns\HasEmailSequences;

class User extends Authenticatable
{
    use HasEmailSequences;
}

That's it — with auto_enroll on (the default), every newly registered user is enrolled into all sequences and delivery runs hourly.

How it works

  1. Configure your sequences in config/email-sequences.php (code, delay, subject, view). They seed the email_sequences table on the first migrate; after that, run php artisan email-sequences:sync whenever you change them.
  2. Enrolment — new users are auto-enrolled (or call $user->enrollInEmailSequences() yourself). Each sequence is scheduled relative to the user's registration date.
  3. Delivery — the emails:deliver-sequences command (scheduled hourly) sends every due message, fires SequenceDelivered, and marks it sent.
  4. Eligibility — should_enroll gates who gets enrolled; should_continue stops a user's remaining deliveries (e.g. once they upgrade to a paid plan). A sequence entry may also define its own should_send gate — when it returns false at delivery time, that single message is skipped (marked sent, never retried) while the rest of the user's sequence continues (e.g. skip a "make your first call" nudge for users who already called the API).

Use emails:backfill-enrollments to enrol users that pre-date installation. It only picks up users with no deliveries at all, and schedules from each user's created_at, so long-standing users get every overdue email on the next run.

Changing sequences after the first migrate

Enrolment reads name and days_delay from the email_sequences table, not from config. After adding, renaming, re-timing or removing a sequence, push the config into the table:

php artisan email-sequences:sync --dry-run   # preview
php artisan email-sequences:sync             # add missing codes, update name/days_delay
php artisan email-sequences:sync --prune     # also soft-delete codes removed from config

The command is idempotent: it matches rows by sequence_code, updates only the oldest live row per code (the one enrolment uses), revives a soft-deleted row instead of inserting a new one, and never creates duplicates. By default it leaves already-scheduled deliveries alone; add --reschedule to shift pending deliveries by the change in days_delay. Existing users are not enrolled into a newly added sequence; schedule those deliveries yourself if you want them.

Configuration

See config/email-sequences.php:

Key Purpose
user_model The model enrolled into sequences
sequences The sequence set: code => [name, days_delay, subject, view, should_send?]
sequences.*.should_send fn ($user) => bool — skip just this message when false (invokable class-string recommended so the config stays cacheable)
auto_enroll Enrol every newly-created user automatically
should_enroll fn ($user) => bool — gate enrolment
should_continue fn ($user) => bool — stop a user's sequence when false
schedule.deliver / schedule.cron Self-scheduling of the delivery command
schedule.without_overlapping Skip a tick while the previous delivery run is still going (default true)
schedule.on_one_server Run the delivery on one server only; needs a cache store with atomic locks (default false)
nova.group / nova.user_resource Nova menu group and User resource for relations

Events

Event When
SequenceDelivered A sequence email was delivered (in-app notifications, analytics)

Commands

Command Purpose
emails:deliver-sequences Deliver all due sequence emails (self-scheduled hourly)
emails:backfill-enrollments Enrol users that have no deliveries yet
email-sequences:sync Sync email_sequences rows from config (--prune, --reschedule, --dry-run)

AI agents (Laravel Boost)

The package ships Laravel Boost resources: a short guideline that is always loaded, and an email-sequences-development skill loaded on demand. Boost 2 or newer is required. In the host app:

composer require laravel/boost --dev
php artisan boost:install            # first time
php artisan boost:update --discover  # already using Boost

Select a2zwebltd/laravel-email-sequences when prompted.

Testing

composer test

License

MIT — see LICENSE file.