PHPackages                             binarcode/laravel-mailator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. binarcode/laravel-mailator

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

binarcode/laravel-mailator
==========================

Laravel email scheduler

6.2.0(1y ago)247293.8k—0.5%14[1 issues](https://github.com/BinarCode/laravel-mailator/issues)[2 PRs](https://github.com/BinarCode/laravel-mailator/pulls)MITPHPPHP ^8.2CI failing

Since Jul 22Pushed 1y ago4 watchersCompare

[ Source](https://github.com/BinarCode/laravel-mailator)[ Packagist](https://packagist.org/packages/binarcode/laravel-mailator)[ Docs](https://github.com/binarcode/laravel-mailator)[ RSS](/packages/binarcode-laravel-mailator/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (60)Used By (0)

[![](https://github.com/BinarCode/laravel-mailator/raw/master/docs/logo.png)](https://github.com/BinarCode/laravel-mailator/blob/master/docs/logo.png)

[![Build Status](https://github.com/binarcode/laravel-mailator/workflows/Tests/badge.svg)](https://github.com/binarcode/laravel-mailator)[![Latest Stable Version.](https://camo.githubusercontent.com/aa4b49ecc4b193d17629d4e874745116acb9eb47d6d8c19b409c0b6a630fe6d0/68747470733a2f2f706f7365722e707567782e6f72672f62696e6172636f64652f6c61726176656c2d6d61696c61746f722f76)](https://github.com/binarcode/laravel-mailator)[![Total Downloads](https://camo.githubusercontent.com/ca9f69a43dfe20137e7d620662335e6e44bbba0ac8b4fcdb26da72b0b4debdc9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f62696e6172636f64652f6c61726176656c2d6d61696c61746f72)](https://packagist.org/packages/binarcode/laravel-mailator)[![License](https://camo.githubusercontent.com/a6131b3757514e8b40a26ccdc7a620239bb3711f80891a058c6ee569ccd6137f/68747470733a2f2f706f7365722e707567782e6f72672f62696e6172636f64652f6c61726176656c2d6d61696c61746f722f6c6963656e7365)](https://packagist.org/packages/binarcode/laravel-mailator)

Laravel Mailator provides a featherweight system for configure email scheduler and email templates based on application events.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require binarcode/laravel-mailator
```

Publish
-------

[](#publish)

Publish migrations: `php artisan vendor:publish --tag=mailator-migrations`

Publish config: `php artisan vendor:publish --tag=mailator-config`

Usage
-----

[](#usage)

It has mainly 2 directions of usage:

1. Schedule emails sending (or actions triggering)
2. Email Templates &amp; Placeholders

Scheduler
---------

[](#scheduler)

To set up a mail to be sent after or before an event, you can do this by using the `Scheduler` facade.

Here is an example of how to send the `invoice reminder email` `3 days` before the `$invoice->due_date`:

```
use Binarcode\LaravelMailator\Tests\Fixtures\InvoiceReminderMailable;
use Binarcode\LaravelMailator\Tests\Fixtures\SerializedConditionCondition;

Binarcode\LaravelMailator\Scheduler::init('Invoice reminder.')
    ->mailable(new InvoiceReminderMailable($invoice))
    ->recipients('foo@binarcode.com', 'baz@binarcode.com')
    ->constraint(new SerializedConditionCondition($invoice))
    ->days(3)
    ->before($invoice->due_date)
    ->save();
```

Let's explain what each line means.

### Mailable

[](#mailable)

This should be an instance of laravel `Mailable`.

### Recipients

[](#recipients)

This should be a list or valid emails where the email will be sent.

It could be an array of emails as well.

### Weeks

[](#weeks)

This should be a number of weeks the email should be delayed.

### Days

[](#days)

This should be a number of days the email should be delayed.

### Hours

[](#hours)

Instead of `days()` you can use `hours()` as well.

### Minutes

[](#minutes)

If your scheduler run by minute, you can also use `minutes()` to delay the email.

### Before

[](#before)

The `before` constraint accept a `CarbonInterface` and indicates from when scheduler should start run the mail or action. For instance:

```
    ->days(1)
    ->before(Carbon::make('2021-02-06'))
```

says, send this email `1 day before 02 June 2021`, so basically the email will be scheduled for `01 June 2021`.

### After

[](#after)

The `after` constraint accept a `CarbonInterface` as well. The difference, is that it inform scheduler to send it `after` the specified timestamp. Say we want to send a survey email `1 week` after the order is placed:

```
    ->weeks(1)
    ->after($order->created_at)
```

### Precision

[](#precision)

Hour Precision

The `precision` method provides fine-grained control over when emails are sent using MailatorSchedule. It allows you to specify specific hours or intervals within a 24-hour period. Here's an example of how to use the precision method:

```
    ->many()
    ->precision([3-4])
```

This will schedule the email dispatch between '03:00:00' AM and '04:59:59' AM.

or

```
    ->once()
    ->precision([1])
```

This will schedule the email dispatch between '01:00:00' AM and '01:59:59'.

You can continue this pattern to specify the desired hour(s) within the range of 1 to 24.

**Important: When using the precision feature in the Mailator scheduler, it is recommended to set the scheduler to run at intervals that are less than an hour. You can choose intervals such as every 5 minutes, 10 minutes, 30 minutes, or any other desired duration.**

### Constraint

[](#constraint)

The `constraint()` method accept an instance of `Binarcode\LaravelMailator\Constraints\SendScheduleConstraint`. Each constraint will be called when the scheduler will try to send the email. If all constraints return true, the email will be sent.

The `constraint()` method could be called many times, and each constraint will be stored.

Since each constraint will be serialized, it's very indicated to use `Illuminate\Queue\SerializesModels` trait, so the serialized models will be loaded properly, and the data stored in your storage system will be much less.

Let's assume we have this `BeforeInvoiceExpiresConstraint` constraint:

```
class BeforeInvoiceExpiresConstraint implements SendScheduleConstraint
{
    public function canSend(MailatorSchedule $mailatorSchedule, Collection $log): bool
    {
        // your conditions
        return true;
    }
}
```

### Constraintable

[](#constraintable)

Instead of defining the `constraint` from the mail definition, sometimes it could be more readable if you define it directly into the `mailable` class:

```
use Binarcode\LaravelMailator\Constraints\Constraintable;

class InvoiceReminderMailable extends Mailable implements Constraintable
{
    public function constraints(): array
    {
        return [
            new DynamicContraint
        ];
    }
}
```

### Action

[](#action)

Using `Scheduler` you can even define your custom action:

```
$scheduler = Scheduler::init('Invoice reminder.')
    ->days(1)
    ->before(now()->addWeek())
    ->actionClass(CustomAction::class)
    ->save();
```

The `CustomAction` should implement the `Binarcode\LaravelMailator\Actions\Action` class.

### Target

[](#target)

You can link the scheduler with any entity like this:

```
        Scheduler::init('Invoice reminder.')
            ->mailable(new InvoiceReminderMailable())
            ->days(1)
            ->target($invoice)
            ->save();
```

and then in the `Invoice` model you can get all emails related to it:

```
// app/Models/Invoice.php
public function schedulers()
{
    return $this->morphMany(Binarcode\LaravelMailator\Models\MailatorSchedule::class, 'targetable');
}
...
```

Mailator provides the `Binarcode\LaravelMailator\Models\Concerns\HasMailatorSchedulers` trait you can put in your Invoice model, so the relations will be loaded.

### Daily

[](#daily)

By default, scheduler run the action, or send the email only once. You can change that, and use a daily reminder till the constraint returns a truth condition:

```
use Binarcode\LaravelMailator\Scheduler;

// 2021-20-06 - 20 June 2021
$expirationDate = $invoice->expire_at;

Scheduler::init('Invoice reminder')
->mailable(new InvoiceReminderMailable())
->daily()
->weeks(1)
->before($expirationDate)
```

This scheduler will send the `InvoiceReminderMailable` email daily starting with `13 June 2021` (one week before the expiration date).

How to stop the email sending if the invoice was paid meanwhile? Simply adding a constraint that will do not send it:

```
->constraint(new InvoicePaidConstraint($invoice))
```

and the constraint handle method could be something like this:

```
class InvoicePaidConstraint implements SendScheduleConstraint
{
    use SerializesModels;

    public function __construct(
        private Invoice $invoice
    ) { }

    public function canSend(MailatorSchedule $schedule, Collection $logs): bool
    {
        return is_null($this->invoice->paid_at);
    }
}
```

Stop conditions
---------------

[](#stop-conditions)

There are few ways email stop to be sent.

The first condition, is that if for some reason sending email fails 3 times, the `MailatorSchedule` will be marked as `completed_at`. Number of times could be configured in the config file `mailator.scheduler.mark_complete_after_fails_count`.

Any successfully sent mail, that should be sent only once, will be marked as `completed_at`.

### Stopable

[](#stopable)

You can configure your scheduler to be marked as `completed_at` if in the you custom constraint returns a falsy condition. Back to our `InvoiceReminderMailable`, say the invoice expires on `20 June`, we send the first reminder on `13 June`, then the second reminder on `14 June`, if the client pay the invoice on `14 June` the `InvoicePaidConstraint` will return a falsy value, so there is no reason to try to send the invoice reminder on `15 June` again. So the system could mark this scheduler as `completed_at`.

To do so, you can use the `stopable()` method.

### Unique

[](#unique)

You can configure your scheduler to store a unique relationship with the target class for mailable by specifying:

```
->unique()
```

ie:

```
Scheduler::init()
    ->mailable(new InvoiceReminderMailable())
    ->target($user)
    ->unique()
    ->save();

Scheduler::init()
    ->mailable(new InvoiceReminderMailable())
    ->target($user)
    ->unique()
    ->save();
```

This will store a single scheduler for the `$user`.

Events
------

[](#events)

Mailator has few events you can use.

If your mailable class extends the `Binarcode\LaravelMailator\Contracts\Beforable`, you will be able to inject the `before` method, that will be called right before the sending the email.

If your mailable class extends the `Binarcode\LaravelMailator\Contracts\Afterable`, you will be able to inject the `after` method, that will be called right after the mail has being sent.

And latest, after each mail has being sent, mailator will fire the `Binarcode\LaravelMailator\Events\ScheduleMailSentEvent` event, so you can listen for it.

Run
---

[](#run)

Now you have to run a scheduler command in your Kernel, and call:

```
Binarcode\LaravelMailator\Scheduler::run();
```

Package provides the `Binarcode\LaravelMailator\Console\MailatorSchedulerCommand` command you can put in your Console Kernel:

```
$schedule->command(MailatorSchedulerCommand::class)->everyThirtyMinutes();
```

Templating
----------

[](#templating)

To create an email template:

```
$template = Binarcode\LaravelMailator\Models\MailTemplate::create([
    'name' => 'Welcome Email.',
    'from_email' => 'from@bar.com',
    'from_name' => 'From Bar',
    'subject' => 'Welcome to Mailator.',
    'html' => 'Welcome to the party!',
]);
```

Adding some placeholders with description to this template:

```
$template->placeholders()->create(
    [
        'name' => '::name::',
        'description' => 'Name',
    ],
);
```

To use the template, you simply have to add the `WithMailTemplate` trait to your mailable.

This will enforce you to implement the `getReplacers` method, this should return an array of replacers to your template. The array may contain instances of `Binarcode\LaravelMailator\Replacers\Replacer` or even `Closure` instances.

Mailator shipes with a builtin replacer `ModelAttributesReplacer`, it will automaticaly replace attributes from the model you provide to placeholders.

The last step is how to say to your mailable what template to use. This could be done into the build method as shown bellow:

```
class WelcomeMailatorMailable extends Mailable
{
    use Binarcode\LaravelMailator\Support\WithMailTemplate;

    private Model $user;

    public function __construct(Model $user)
    {
        $this->user = $user;
    }

    public function build()
    {
        return $this->template(MailTemplate::firstWhere('name', 'Welcome Email.'));
    }

    public function getReplacers(): array
    {
        return [
            Binarcode\LaravelMailator\Replacers\ModelAttributesReplacer::makeWithModel($this->user),

            function($html) {
                //
            }
        ];
    }
}
```

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

### Security

[](#security)

If you discover any security related issues, please email  or [message me on twitter](https://twitter.com/LupacescuEuard) instead of using the issue tracker.

Credits
-------

[](#credits)

- [Eduard Lupacescu](https://github.com/binaryk)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

55

—

FairBetter than 98% of packages

Maintenance49

Moderate activity, may be stable

Popularity52

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity81

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 99.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~31 days

Recently: every ~77 days

Total

56

Last Release

377d ago

Major Versions

1.3.0 → 2.0.02021-03-09

2.x-dev → 3.0.02021-06-07

3.11.0 → 4.0.02022-02-10

4.1.2 → 5.0.02023-02-17

4.1.2.x-dev → 6.0.02024-07-03

PHP version history (6 changes)1.0.0PHP ^7.4

1.3.0PHP ^7.4|^8.0

2.x-devPHP ^8.0

5.0.0PHP ^8.0|^8.1

4.1.2.x-devPHP ^8.0|^8.1|^8.2

6.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/dfbb03bb93526135d948c1232c28938180a944e65362263dda08545afa3fee6d?d=identicon)[binaryk](/maintainers/binaryk)

---

Top Contributors

[![binaryk](https://avatars.githubusercontent.com/u/6833714?v=4)](https://github.com/binaryk "binaryk (5051 commits)")[![maloun96](https://avatars.githubusercontent.com/u/8277264?v=4)](https://github.com/maloun96 "maloun96 (8 commits)")[![arthurkirkosa](https://avatars.githubusercontent.com/u/1099791?v=4)](https://github.com/arthurkirkosa "arthurkirkosa (7 commits)")[![CaReS0107](https://avatars.githubusercontent.com/u/32643188?v=4)](https://github.com/CaReS0107 "CaReS0107 (2 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (2 commits)")[![JaberWiki](https://avatars.githubusercontent.com/u/55241455?v=4)](https://github.com/JaberWiki "JaberWiki (1 commits)")[![MrMage](https://avatars.githubusercontent.com/u/117466?v=4)](https://github.com/MrMage "MrMage (1 commits)")

---

Tags

binarcodelaravel-mailator

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/binarcode-laravel-mailator/health.svg)

```
[![Health](https://phpackages.com/badges/binarcode-laravel-mailator/health.svg)](https://phpackages.com/packages/binarcode-laravel-mailator)
```

###  Alternatives

[mckenziearts/laravel-notify

Flexible flash notifications for Laravel

1.7k1.1M5](/packages/mckenziearts-laravel-notify)[s-ichikawa/laravel-sendgrid-driver

This library adds a 'sendgrid' mail driver to Laravel.

4139.3M1](/packages/s-ichikawa-laravel-sendgrid-driver)[laravel-notification-channels/apn

Apple APN Push Notification Channel

2021.9M4](/packages/laravel-notification-channels-apn)[laravel-notification-channels/microsoft-teams

A Laravel Notification Channel for Microsoft Teams

1603.0M7](/packages/laravel-notification-channels-microsoft-teams)[laravel-notification-channels/discord

Laravel notification driver for Discord.

2371.3M11](/packages/laravel-notification-channels-discord)[illuminate/mail

The Illuminate Mail package.

5910.1M391](/packages/illuminate-mail)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
