{"id":21008418,"url":"https://github.com/binarcode/laravel-mailator","last_synced_at":"2025-04-12T18:38:54.479Z","repository":{"id":44502352,"uuid":"238884094","full_name":"BinarCode/laravel-mailator","owner":"BinarCode","description":"Email scheduler for Laravel","archived":false,"fork":false,"pushed_at":"2024-07-03T10:45:21.000Z","size":1850,"stargazers_count":226,"open_issues_count":4,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-24T19:43:30.044Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BinarCode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-07T09:16:30.000Z","updated_at":"2024-10-26T18:30:37.000Z","dependencies_parsed_at":"2024-12-02T19:29:51.232Z","dependency_job_id":"74a2212a-7e39-4bbd-8dcc-198d912fc997","html_url":"https://github.com/BinarCode/laravel-mailator","commit_stats":{"total_commits":5017,"total_committers":9,"mean_commits":557.4444444444445,"dds":0.0081722144707993,"last_synced_commit":"a7553a42216418f2975fd16bd6317e97cec0d801"},"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinarCode%2Flaravel-mailator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinarCode%2Flaravel-mailator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinarCode%2Flaravel-mailator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinarCode%2Flaravel-mailator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BinarCode","download_url":"https://codeload.github.com/BinarCode/laravel-mailator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247061892,"owners_count":20877176,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T09:12:29.019Z","updated_at":"2025-04-03T19:16:59.380Z","avatar_url":"https://github.com/BinarCode.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://github.com/BinarCode/laravel-mailator/blob/master/docs/logo.png\"\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/binarcode/laravel-mailator\"\u003e\u003cimg src=\"https://github.com/binarcode/laravel-mailator/workflows/Tests/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/binarcode/laravel-mailator\"\u003e\u003cimg src=\"https://poser.pugx.org/binarcode/laravel-mailator/v\" alt=\"Latest Stable Version.\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/binarcode/laravel-mailator\"\u003e\u003cimg src=\"https://img.shields.io/packagist/dt/binarcode/laravel-mailator\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/binarcode/laravel-mailator\"\u003e\u003cimg src=\"https://poser.pugx.org/binarcode/laravel-mailator/license\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nLaravel Mailator provides a featherweight system for configure email scheduler and email templates based on application\nevents.\n\n## Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require binarcode/laravel-mailator\n```\n\n## Publish\n\nPublish migrations: `php artisan vendor:publish --tag=mailator-migrations`\n\nPublish config: `php artisan vendor:publish --tag=mailator-config`\n\n## Usage\n\nIt has mainly 2 directions of usage:\n\n1. Schedule emails sending (or actions triggering)\n\n2. Email Templates \u0026 Placeholders\n\n## Scheduler\n\nTo set up a mail to be sent after or before an event, you can do this by using the `Scheduler` facade.\n\nHere is an example of how to send the `invoice reminder email` `3 days` before the `$invoice-\u003edue_date`:\n\n```php\nuse Binarcode\\LaravelMailator\\Tests\\Fixtures\\InvoiceReminderMailable;\nuse Binarcode\\LaravelMailator\\Tests\\Fixtures\\SerializedConditionCondition;\n\nBinarcode\\LaravelMailator\\Scheduler::init('Invoice reminder.')\n    -\u003emailable(new InvoiceReminderMailable($invoice))\n    -\u003erecipients('foo@binarcode.com', 'baz@binarcode.com')\n    -\u003econstraint(new SerializedConditionCondition($invoice))\n    -\u003edays(3)\n    -\u003ebefore($invoice-\u003edue_date)\n    -\u003esave();\n```\n\nLet's explain what each line means.\n\n### Mailable\n\nThis should be an instance of laravel `Mailable`.\n\n### Recipients\n\nThis should be a list or valid emails where the email will be sent.\n\nIt could be an array of emails as well.\n\n### Weeks\n\nThis should be a number of weeks the email should be delayed. \n\n### Days\n\nThis should be a number of days the email should be delayed. \n\n### Hours\n\nInstead of `days()` you can use `hours()` as well.\n\n### Minutes\n\nIf your scheduler run by minute, you can also use `minutes()` to delay the email.\n\n### Before\n\nThe `before` constraint accept a `CarbonInterface` and indicates from when scheduler should start run the mail or action. For instance:\n\n```php\n    -\u003edays(1)\n    -\u003ebefore(Carbon::make('2021-02-06'))\n```\n\nsays, send this email `1 day before 02 June 2021`, so basically the email will be scheduled for `01 June 2021`.\n\n### After\n\nThe `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:\n\n```php\n    -\u003eweeks(1)\n    -\u003eafter($order-\u003ecreated_at)\n```\n\n### Precision\nHour Precision\n\nThe `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:\n```php\n    -\u003emany()\n    -\u003eprecision([3-4])\n```\nThis will schedule the email dispatch between '03:00:00' AM and '04:59:59' AM.\n\nor\n```php\n    -\u003eonce()\n    -\u003eprecision([1])\n```\nThis will schedule the email dispatch between '01:00:00' AM and '01:59:59'.\n\nYou can continue this pattern to specify the desired hour(s) within the range of 1 to 24.\n\n**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.**\n### Constraint\n\nThe `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.\n\nThe `constraint()` method could be called many times, and each constraint will be stored. \n\nSince 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.\n\nLet's assume we have this `BeforeInvoiceExpiresConstraint` constraint:\n\n```php\nclass BeforeInvoiceExpiresConstraint implements SendScheduleConstraint\n{\n    public function canSend(MailatorSchedule $mailatorSchedule, Collection $log): bool\n    {\n        // your conditions\n        return true;\n    }\n}\n```\n\n### Constraintable\n\nInstead of defining the `constraint` from the mail definition, sometimes it could be more readable if you define it directly into the `mailable` class: \n\n```php\nuse Binarcode\\LaravelMailator\\Constraints\\Constraintable;\n\nclass InvoiceReminderMailable extends Mailable implements Constraintable\n{\n    public function constraints(): array\n    {\n        return [\n            new DynamicContraint\n        ];\n    }\n}\n\n```\n\n### Action\n\nUsing `Scheduler` you can even define your custom action:\n\n```php\n$scheduler = Scheduler::init('Invoice reminder.')\n    -\u003edays(1)\n    -\u003ebefore(now()-\u003eaddWeek())\n    -\u003eactionClass(CustomAction::class)\n    -\u003esave();\n```\n\nThe `CustomAction` should implement the `Binarcode\\LaravelMailator\\Actions\\Action` class.\n\n### Target\n\nYou can link the scheduler with any entity like this:\n\n```php\n        Scheduler::init('Invoice reminder.')\n            -\u003emailable(new InvoiceReminderMailable())\n            -\u003edays(1)\n            -\u003etarget($invoice)\n            -\u003esave();\n```\n\nand then in the `Invoice` model you can get all emails related to it: \n\n```php\n// app/Models/Invoice.php\npublic function schedulers() \n{\n    return $this-\u003emorphMany(Binarcode\\LaravelMailator\\Models\\MailatorSchedule::class, 'targetable');\n}\n...\n```\n\nMailator provides the `Binarcode\\LaravelMailator\\Models\\Concerns\\HasMailatorSchedulers` trait you can put in your Invoice model, so the relations will be loaded.\n\n### Daily\n\nBy 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:\n\n```php\nuse Binarcode\\LaravelMailator\\Scheduler;\n\n// 2021-20-06 - 20 June 2021\n$expirationDate = $invoice-\u003eexpire_at;\n\nScheduler::init('Invoice reminder')\n-\u003emailable(new InvoiceReminderMailable())\n-\u003edaily()\n-\u003eweeks(1)\n-\u003ebefore($expirationDate)\n```\n\nThis scheduler will send the `InvoiceReminderMailable` email daily starting with `13 June 2021` (one week before the expiration date).\n\nHow to stop the email sending if the invoice was paid meanwhile? Simply adding a constraint that will do not send it: \n\n```php\n-\u003econstraint(new InvoicePaidConstraint($invoice))\n```\n\nand the constraint handle method could be something like this: \n\n```php\nclass InvoicePaidConstraint implements SendScheduleConstraint\n{\n    use SerializesModels;\n    \n    public function __construct(\n        private Invoice $invoice\n    ) { }\n\n    public function canSend(MailatorSchedule $schedule, Collection $logs): bool\n    {\n        return is_null($this-\u003einvoice-\u003epaid_at);\n    }\n}\n```\n\n## Stop conditions\n\nThere are few ways email stop to be sent.\n\nThe 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`.\n\nAny successfully sent mail, that should be sent only once, will be marked as `completed_at`.\n\n\n### Stopable\n\nYou 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`.\n\n\nTo do so, you can use the `stopable()` method.\n\n### Unique\n\nYou can configure your scheduler to store a unique relationship with the target class for mailable by specifying: \n\n```php\n-\u003eunique()\n```\n\nie: \n\n```php\nScheduler::init()\n    -\u003emailable(new InvoiceReminderMailable())\n    -\u003etarget($user)\n    -\u003eunique()\n    -\u003esave();\n    \nScheduler::init()\n    -\u003emailable(new InvoiceReminderMailable())\n    -\u003etarget($user)\n    -\u003eunique()\n    -\u003esave();\n```\n\nThis will store a single scheduler for the `$user`. \n\n## Events\n\nMailator has few events you can use. \n\nIf 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. \n\nIf 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.\n\n\nAnd latest, after each mail has being sent, mailator will fire the `Binarcode\\LaravelMailator\\Events\\ScheduleMailSentEvent` event, so you can listen for it.\n\n## Run\n\nNow you have to run a scheduler command in your Kernel, and call:\n\n```php\nBinarcode\\LaravelMailator\\Scheduler::run();\n```\n\nPackage provides the `Binarcode\\LaravelMailator\\Console\\MailatorSchedulerCommand` command you can put in your Console Kernel: \n\n```php\n$schedule-\u003ecommand(MailatorSchedulerCommand::class)-\u003eeveryThirtyMinutes();\n```\n\n\n## Templating\n\nTo create an email template:\n\n``` php\n$template = Binarcode\\LaravelMailator\\Models\\MailTemplate::create([\n    'name' =\u003e 'Welcome Email.',\n    'from_email' =\u003e 'from@bar.com',\n    'from_name' =\u003e 'From Bar',\n    'subject' =\u003e 'Welcome to Mailator.',\n    'html' =\u003e '\u003ch1\u003eWelcome to the party!\u003c/h1\u003e',\n]);\n```\n\nAdding some placeholders with description to this template:\n\n```php\n$template-\u003eplaceholders()-\u003ecreate(\n    [\n        'name' =\u003e '::name::',\n        'description' =\u003e 'Name',\n    ],\n);\n```\n\nTo use the template, you simply have to add the `WithMailTemplate` trait to your mailable.\n\nThis will enforce you to implement the `getReplacers` method, this should return an array of replacers to your template.\nThe array may contain instances of `Binarcode\\LaravelMailator\\Replacers\\Replacer` or even `Closure` instances.\n\nMailator shipes with a builtin replacer `ModelAttributesReplacer`, it will automaticaly replace attributes from the\nmodel you provide to placeholders.\n\nThe last step is how to say to your mailable what template to use. This could be done into the build method as shown\nbellow:\n\n```php\nclass WelcomeMailatorMailable extends Mailable\n{\n    use Binarcode\\LaravelMailator\\Support\\WithMailTemplate;\n    \n    private Model $user;\n    \n    public function __construct(Model $user)\n    {\n        $this-\u003euser = $user;\n    }\n    \n    public function build()\n    {\n        return $this-\u003etemplate(MailTemplate::firstWhere('name', 'Welcome Email.'));\n    }\n\n    public function getReplacers(): array\n    {\n        return [\n            Binarcode\\LaravelMailator\\Replacers\\ModelAttributesReplacer::makeWithModel($this-\u003euser),\n\n            function($html) {\n                //\n            }       \n        ];\n    }\n}\n```\n\n### Testing\n\n``` bash\ncomposer test\n```\n\n### Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n### Security\n\nIf you discover any security related issues, please email eduard.lupacescu@binarcode.com or [message me on twitter](https://twitter.com/LupacescuEuard) instead of using the issue tracker.\n\n## Credits\n\n- [Eduard Lupacescu](https://github.com/binaryk)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinarcode%2Flaravel-mailator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinarcode%2Flaravel-mailator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinarcode%2Flaravel-mailator/lists"}