Search code examples
laravel-4listeners

Laravel Mail Listener (Before Send - Ability to Cancel)


Is there a way to use Laravel's "Event" class to run some code before every email is sent? I'd also like the ability to cancel the Mail::send();.

Of course I could do this before I send an email:

Event::fire('email.beforeSend');

And then I could listen this way:

Event::listen('email.beforeSend', function()
{
    //my code here
});

The problem with this is that I have to remember to run Event::fire() which I'd rather not do. In my case I'm bouncing the email address against an unsubscribe list to make sure that I don't send any spam.


Solution

  • For Laravel 5 you can listen to the Illuminate\Mail\Events\MessageSending event and return false if you want to cancel sending the message.

    Add this to your EventServiceProvider

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\Facades\Event;
    use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
    
    class EventServiceProvider extends ServiceProvider
    {
        /**
         * The event listener mappings for the application.
         *
         * @var array
         */
        protected $listen = [
            'Illuminate\Mail\Events\MessageSending' => [
                'App\Listeners\CheckEmailPreferences',
            ],
        ];
    }
    

    Here is my event listener at App\Listeners\CheckEmailPreferences

    <?php
    
    namespace App\Listeners;
    
    use App\User;
    use Illuminate\Mail\Events\MessageSending;
    use Illuminate\Support\Facades\App;
    
    class CheckEmailPreferences
    {
        public function handle( MessageSending $event )
        {
            //if app is in prod and we don't want to send any emails
            if(App::environment() === 'production' && ! env('SEND_MAIL_TO_CUSTOMERS')){
                return false;
            }
    
            //you can check if the user wants to receive emails here
        }
    }