Laravel 8 Email verification is not queued by the default. To queue it, you need to override the /vendor/ functions (not modify them directly).
Basically we need to add both the ShouldQueue interface and the Queueable trait to the "SendEmailVerificationNotification" listener.
The problem is that we can't go ahead and edit it, since it's located right in the framework source code (/vendor/laravel/framework/src/Illuminate/Auth/Listeners/).
The reason is that when you execute the "composer update", your changes will simply be overriden should the "laravel/framework" be updated.
The steps are
1.- Open and take a look at the "/vendor/laravel/framework/src/Illuminate/Contracts/Auth/MustVerifyEmail.php" interface file.
It has several methods that you can use basically inside the User.php model file to customize (override) them.
That's why those methods are empty and are part of an Interface class.
2.- Create our own "VerifyEmail" notification.
$ php artisan make:notification Auth/VerifyEmailNow open the "/vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php", copy all the contents and paste them inside your new "app/Notifications/Auth/VerifyEmail"
It should look like:
<?php namespace App\Notifications\Auth; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Lang; use Illuminate\Support\Facades\URL; class VerifyEmail extends Notification implements ShouldQueue { use Queueable; /** * The callback that should be used to create the verify email URL. * * @var \Closure|null */ public static $createUrlCallback; /** * The callback that should be used to build the mail message. * * @var \Closure|null */ public static $toMailCallback; /** * Get the notification's channels. * * @param mixed $notifiable * @return array|string */ public function via($notifiable) { return ['mail']; } /** * Build the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ public function toMail($notifiable) { $verificationUrl = $this->verificationUrl($notifiable); if (static::$toMailCallback) { return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl); } return $this->buildMailMessage($verificationUrl); } /** * Get the verify email notification mail message for the given URL. * * @param string $url * @return \Illuminate\Notifications\Messages\MailMessage */ protected function buildMailMessage($url) { return (new MailMessage) ->subject(Lang::get('Verify Email Address')) ->line(Lang::get('Please click the button below to verify your email address.')) ->action(Lang::get('Verify Email Address'), $url) ->line(Lang::get('If you did not create an account, no further action is required.')); } /** * Get the verification URL for the given notifiable. * * @param mixed $notifiable * @return string */ protected function verificationUrl($notifiable) { if (static::$createUrlCallback) { return call_user_func(static::$createUrlCallback, $notifiable); } return URL::temporarySignedRoute( 'verification.verify', Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)), [ 'id' => $notifiable->getKey(), 'hash' => sha1($notifiable->getEmailForVerification()), ] ); } /** * Set a callback that should be used when creating the email verification URL. * * @param \Closure $callback * @return void */ public static function createUrlUsing($callback) { static::$createUrlCallback = $callback; } /** * Set a callback that should be used when building the notification mail message. * * @param \Closure $callback * @return void */ public static function toMailUsing($callback) { static::$toMailCallback = $callback; } }
3.- Copy the following from that "MustVerifyEmail.php interface function:
<?php //... /** * Send the email verification notification. * * @return void */ public function sendEmailVerificationNotification();
4.- Paste it somewhere, maybe at the end, inside the app/Models/User.php Model file and set the following:
<?php //... use App\Notifications\Auth\VerifyEmail; //... /** ....... * Send the email verification notification. * * @return void */ public function sendEmailVerificationNotification() { try { $this->notify(new VerifyEmail); } catch (\Swift_TransportException $exception){ return redirect()->route('home')->with('error','馃槦 Could not send the email: '.$exception->getMessage().' ❌')->send(); } }
5. If you want to store the queued jobs in the database, like I do. Then you need to configure additional settings.
Create the `jobs` table for Laravel 8 Jetstream
$ php artisan queue:tablewhich will create a new migration file called "create job batches table":
Run the migration
$ php artisan migrate6.- Test it now.
Go ahead and register a new user. You will get a message that a verification email has been sent. Open your mailhog client at http://localhost:8025/ .
You will find your email box empty. This is because that task has been queued.
7.- To run the pending queues execute the command:
$ php artisan queue:work
It will display the jobs pending and it will start processing them.
$ php artisan queue:work
[2021-03-30 03:48:09][1] Processing: App\Notifications\Auth\VerifyEmail
[2021-03-30 03:48:09][1] Processed: App\Notifications\Auth\VerifyEmail
So far so good.
Now you may find useful queueing the password reset notification as well.
1.- Create a new notification:
$ php artisan make:notification Auth/ResetPassword2.- Open that file and paste the code found in "vendor/laravel/framework/src/Illuminate/Auth/Notifications/ResetPassword.php" into this newly created file "app/Auth/ResetPassword.php" where you basically want to add the ShouldQueue implementation and the Queueable bus:
<?php namespace App\Notifications\Auth; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; use Illuminate\Support\Facades\Lang; class ResetPassword extends Notification implements ShouldQueue { use Queueable; /** * The password reset token. * * @var string */ public $token; /** * The callback that should be used to create the reset password URL. * * @var \Closure|null */ public static $createUrlCallback; /** * The callback that should be used to build the mail message. * * @var \Closure|null */ public static $toMailCallback; /** * Create a notification instance. * * @param string $token * @return void */ public function __construct($token) { $this->token = $token; } /** * Get the notification's channels. * * @param mixed $notifiable * @return array|string */ public function via($notifiable) { return ['mail']; } /** * Build the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ public function toMail($notifiable) { if (static::$toMailCallback) { return call_user_func(static::$toMailCallback, $notifiable, $this->token); } if (static::$createUrlCallback) { $url = call_user_func(static::$createUrlCallback, $notifiable, $this->token); } else { $url = url(route('password.reset', [ 'token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset(), ], false)); } return $this->buildMailMessage($url); } /** * Get the reset password notification mail message for the given URL. * * @param string $url * @return \Illuminate\Notifications\Messages\MailMessage */ protected function buildMailMessage($url) { return (new MailMessage) ->subject(Lang::get('Reset Password Notification')) ->line(Lang::get('You are receiving this email because we received a password reset request for your account.')) ->action(Lang::get('Reset Password'), $url) ->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')])) ->line(Lang::get('If you did not request a password reset, no further action is required.')); } /** * Set a callback that should be used when creating the reset password button URL. * * @param \Closure $callback * @return void */ public static function createUrlUsing($callback) { static::$createUrlCallback = $callback; } /** * Set a callback that should be used when building the notification mail message. * * @param \Closure $callback * @return void */ public static function toMailUsing($callback) { static::$toMailCallback = $callback; } }
3.- Go to the User.php model and add the following method, which is found in the "vendor/laravel/framework/src/Illuminate/Contracts/Auth/CanResetPassword.php" interface:
<?php //.. use App\Notifications\Auth\ResetPassword; //.. /** * Send the password reset notification. * * @param string $token * @return void */ public function sendPasswordResetNotification($token) { try{ $this->notify(new ResetPassword($token)); }catch (\Swift_TransportException $exception){ return redirect()->route('home')->with('error','馃槦 Could not send the email: '.$exception->getMessage().' ❌')->send(); } }
4.- Try it now by clicking on "forgot password?", and then execute
$ php artisan queue:work
[2021-03-30 04:25:37][2] Processing: App\Notifications\Auth\ResetPassword
[2021-03-30 04:25:38][2] Processed: App\Notifications\Auth\ResetPassword
That is pretty much it



