Как поставить в очередь отправку письма с подтверждением электронной почты Laravel 5.7

Включенная в Laravel 5.7 функция «проверки электронной почты» работает хорошо, но асинхронная отправка электронной почты (во время регистрации пользователя или страницы повторной отправки ссылки) не идеальна.

Есть ли способ отправить электронное письмо с подтверждением электронной почты через очередь без перезаписи всей проверки электронной почты в Laravel 5.7?


person François    schedule 04.10.2018    source источник
comment
Я не думаю, что на данный момент это возможно. Новый трейт отправляет это электронное письмо , который в настоящее время не может быть поставлен в очередь.   -  person Jerodev    schedule 04.10.2018


Ответы (4)


Нет встроенного способа, но вы можете легко это сделать, расширив и переопределив.

Сначала создайте новое уведомление, которое расширяет встроенное уведомление, а также реализует контракт ShouldQueue (для включения очереди). В следующем классе предполагается, что вы создали уведомление в app/Notifications/VerifyEmailQueued.php:

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\VerifyEmail;

class VerifyEmailQueued extends VerifyEmail implements ShouldQueue
{
    use Queueable;

    // Nothing else needs to go here unless you want to customize
    // the notification in any way.
}

Теперь вам нужно указать фреймворку использовать ваше настраиваемое уведомление вместо уведомления по умолчанию. Это можно сделать, переопределив sendEmailVerificationNotification() в своей User модели. Это просто меняет тип отправляемого уведомления.

public function sendEmailVerificationNotification()
{
    $this->notify(new \App\Notifications\VerifyEmailQueued);
}
person patricus    schedule 04.10.2018
comment
Работал как мультик! - person Mfoo; 27.11.2018
comment
это намного проще, чем принятый ответ, и он работает - person AaronHS; 15.02.2019
comment
Это работает, но при нажатии на ссылку подтверждения (отправленную по электронной почте) происходит перенаправление на страницу 403, недействительная подпись. (Laravel 6) - person Irfan Gondal; 27.04.2021
comment
@IrfanGondal Теперь уведомление будет помещено в очередь, поэтому URL-адрес в уведомлении будет построен с использованием вашего APP_URL в файле среды. Этот APP_URL должен соответствовать окончательному URL-адресу. Так, например, если ваш сайт находится на https, вам необходимо убедиться, что ваш APP_URL также https. - person patricus; 28.04.2021

Да! Возможно. И для этого вам придется переписать sendEmailVerificationNotification в вашем App\User. Этот метод предоставляется трейтом Illuminate\Auth\MustVerfiyEmail. Метод sendEmailVerificationNotification уведомляет созданный user, отправляя электронное письмо, как определено в классе Illuminate\Auth\Notifications\VerifyEmail Notification.

// This is the code defined in the sendEmailVerificationNotification
public function sendEmailVerificationNotification()
{
    $this->notify(new Notifications\VerifyEmail);
}

Вы можете изменить этот метод, чтобы не уведомлять пользователя напрямую. Вам нужно будет определить Job, который вы будете отправлять в методе sendEmailVerificationNotification вместо уведомления созданного пользователя.

В классе Job вы создадите метод handle, с помощью которого вы можете отправить электронное письмо на user, но вы должны предоставить $user заданию, которое можно выполнить, передав его в качестве параметра методу dispatch следующим образом:

public function sendEmailVerificationNotification()
{
    VerifyEmail::dispatch($this);
}

$this представляет собой созданное user, а задание App\Jobs\VerififyEmail (которое вы создадите) получит все параметры, переданные dispatch в его __construct

Код VerifyEmail будет выглядеть так:

namespace App\Jobs;

use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Auth\Notifications\VerifyEmail;

class VerifyEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

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

    public function handle()
    {
        // Here the email verification will be sent to the user
        $this->user->notify(new VerifyEmail);
    }
}
person Yves Kipondo    schedule 04.10.2018
comment
спасибо за ответ, работает! просто пришлось переименовать класс Job QueuedVerifyEmail из-за двойного объявления имени класса. - person François; 04.10.2018
comment
Добро пожаловать. Даже если оба класса имеют одинаковое имя, потому что они находятся в разных пространствах имен App\Jobs\VerifyEmail и Illuminate\Auth\Notification\VerifyEmail, это не вызовет никаких проблем. - person Yves Kipondo; 04.10.2018
comment
Вы могли бы использовать то же имя класса, присвоив классу Laravel другое имя, например: use Illuminate\Auth\Notifications\VerifyEmail as VerifyEmailNotification;, и в handle методе $this->user->notify(new VerifyEmailNotification);. На мой взгляд, это немного чище, но это просто придирки. - person Ben V.; 22.03.2019

Мое решение - если вы собираетесь вручную регистрировать пользователя в контроллере. Laravel уже создал зарегистрированное событие и его прослушиватель SendEmailVerificationNotification.

-сначала настроить очередь в приложении в обновлении файла .env QUEUE_CONNECTION=database. для получения дополнительной документации по очереди прочтите https://laravel.com/docs/6.x/queues

  • опубликовать таблицу очереди от php artisan queue:table

  • php artisan migrate

  • php artisan make:job EmailVerificationJob

  • в EmailVerificationJob.php добавить общедоступную переменную

    общедоступный пользователь $;

  • в конструкторе EmailVerificationJob.php

    публичная функция __construct (User $ user) {$ this- ›user = $ user; }

  • в функции дескриптора EmailVerificationJob.php напишите event(new Registered($this->user)).

  • в вашем контроллере, если пользователь успешно создал, добавьте этот код для работы.

    EmailVerificationJob :: dispatch ($ user) - ›delay (now () -› addSeconds (5)); здесь задержка задания на 5 секунд.

  • в конце вы должны запустить php artisan queue:work --tries=3 работник очереди. здесь пытается означает, сколько раз очередь должна пытаться выполнить задание.

Обновление # 1

это решение я использовал в Laravel 8.

сначала создайте класс уведомлений SendEmailVerificationNotification

php artisan make:notification SendEmailVerificationNotification

Это будет содержимое файла app / Notifications / SendEmailVerificationNotification.php. здесь мы собираемся расширить класс Laravel по умолчанию SendEmailVerificationNotification и реализовать очередь

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class SendEmailVerificationNotification extends \Illuminate\Auth\Listeners\SendEmailVerificationNotification implements ShouldQueue
{
    use Queueable;
}

последний шаг - это редактирование массива $ listen класса EventServiceProvider. Закомментируйте уведомление по умолчанию о зарегистрированном событии и добавьте собственное уведомление, которое мы создали.

use App\Notifications\SendEmailVerificationNotification as QueuedSendEmailVerificationNotification;
use Illuminate\Auth\Events\Registered;
//use Illuminate\Auth\Listeners\SendEmailVerificationNotification;

protected $listen = [
        Registered::class => [
//            SendEmailVerificationNotification::class,
            QueuedSendEmailVerificationNotification::class
        ],

];

person Ozal Zarbaliyev    schedule 30.10.2019

Решение довольно простое:

Steps:

  1. Настроить драйвер очереди

  2. Перейдите в -> Illuminate \ Auth \ Notifications \ VerifyEmail.

  3. Реализуйте интерфейс ShouldQueue и добавьте черту Queueable в вышеупомянутый класс, например, VerifyEmail, например:

class VerifyEmail extends Notification реализует ShouldQueue {использует Queueable;

.... .... ... }

3. вот и все

Путь интерфейса и трейта: используйте Illuminate \ Contracts \ Queue \ ShouldQueue; используйте Illuminate \ Bus \ Queueable;

Также проверьте документы: https://laravel.com/docs/5.7/notifications#queueing-notifications

person Naveed Ali    schedule 26.11.2018
comment
Не лучшая идея изменять классы laravel, поэтому приведенные выше решения предлагают делать это путем расширения и переопределения. - person François; 28.11.2018
comment
Не рекомендуется вносить изменения в файлы в папке поставщика laravel, потому что при следующей команде обновления композитора ваши изменения в файлах в папке поставщика будут удалены. - person Ozal Zarbaliyev; 27.01.2020