Идёт обновление сайта. Несколько дней возможны сбои в оформлении и переводах. Документация работает — если страница выглядит сломанной, обновите её позже.

Документация
L Laravel L intervention/image
Войти
Главная Laravel 10.x Уведомления

Уведомления

10.x 7 мар 2026 г.

#Введение

Помимо поддержки отправки электронной почты, Laravel предоставляет возможность отправлять уведомления через различные каналы доставки, включая электронную почту, SMS (через Vonage, ранее известный как Nexmo) и Slack. Кроме того, создано множество сообществом разработчиков каналов уведомлений для отправки уведомлений через десятки различных каналов! Уведомления также могут сохраняться в базе данных для отображения в вашем веб-интерфейсе.

Обычно уведомления должны быть короткими информационными сообщениями, которые информируют пользователей о событиях в вашем приложении. Например, если вы разрабатываете биллинговое приложение, вы можете отправить уведомление "Счет оплачен" пользователям через каналы электронной почты и SMS.

#Создание уведомлений

В Laravel каждое уведомление представлено отдельным классом, который обычно хранится в каталоге app/Notifications. Не беспокойтесь, если вы не видите этот каталог в вашем приложении — он будет создан автоматически при выполнении Artisan-команды make:notification:

php artisan make:notification InvoicePaid

Эта команда создаст новый класс уведомления в каталоге app/Notifications. Каждый класс уведомления содержит метод via и несколько методов для формирования сообщений, таких как toMail или toDatabase, которые преобразуют уведомление в сообщение, адаптированное для конкретного канала.

#Отправка уведомлений

#Использование трейта Notifiable

Уведомления можно отправлять двумя способами: используя метод notify из трейта Notifiable или используя фасад Notification facade. Трейт Notifiable по умолчанию включён в модель App\Models\User вашего приложения:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;
}

Метод notify, предоставляемый этим трейтoм, ожидает получить экземпляр уведомления:

use App\Notifications\InvoicePaid;

$user->notify(new InvoicePaid($invoice));
Примечание

Помните, что вы можете использовать трейт Notifiable в любых ваших моделях. Вы не ограничены только моделью User.

#Использование фасада Notification

В качестве альтернативы вы можете отправлять уведомления через фасад Notification facade. Этот подход полезен, когда нужно отправить уведомление нескольким получателям, например, коллекции пользователей. Для отправки уведомлений через фасад передайте все объекты, которые могут получать уведомления, и экземпляр уведомления в метод send:

use Illuminate\Support\Facades\Notification;

Notification::send($users, new InvoicePaid($invoice));

Вы также можете отправить уведомления немедленно с помощью метода sendNow. Этот метод отправит уведомление сразу, даже если уведомление реализует интерфейс ShouldQueue:

Notification::sendNow($developers, new DeploymentCompleted($deployment));

#Указание каналов доставки

Каждый класс уведомления содержит метод via, который определяет, через какие каналы будет доставлено уведомление. Уведомления могут отправляться через каналы mail, database, broadcast, vonage и slack.

Примечание

Если вы хотите использовать другие каналы доставки, такие как Telegram или Pusher, ознакомьтесь с сообществом на сайте Laravel Notification Channels.

Метод via получает экземпляр $notifiable, который является объектом класса, которому отправляется уведомление. Вы можете использовать $notifiable для определения каналов доставки уведомления:

/**
 * Получить каналы доставки уведомления.
 *
 * @return array<int, string>
 */
public function via(object $notifiable): array
{
    return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
}

#Очередь уведомлений

Внимание

Перед использованием очередей для уведомлений настройте очередь и запустите воркер.

Отправка уведомлений может занимать время, особенно если канал требует внешнего API-запроса для доставки. Чтобы ускорить отклик приложения, добавьте интерфейс ShouldQueue и трейт Queueable в ваш класс уведомления, чтобы оно отправлялось в очередь. Интерфейс и трейт уже импортированы во все уведомления, созданные с помощью команды make:notification, поэтому вы можете сразу добавить их в класс уведомления:

<?php

namespace App\Notifications;

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

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;

    // ...
}

После того как в ваше уведомление добавлен интерфейс ShouldQueue, вы можете отправлять уведомление как обычно. Laravel обнаружит интерфейс ShouldQueue в классе и автоматически поставит доставку уведомления в очередь:

$user->notify(new InvoicePaid($invoice));

При постановке уведомлений в очередь для каждого получателя и канала создаётся отдельная задача. Например, если у уведомления три получателя и два канала, в очередь будет отправлено шесть задач.

#Отложенная отправка уведомлений

Если вы хотите отложить доставку уведомления, можно вызвать метод delay при создании уведомления:

$delay = now()->addMinutes(10);

$user->notify((new InvoicePaid($invoice))->delay($delay));

#Отложенная отправка уведомлений по каналам

Вы можете передать массив в метод delay, чтобы указать время задержки для конкретных каналов:

$user->notify((new InvoicePaid($invoice))->delay([
    'mail' => now()->addMinutes(5),
    'sms' => now()->addMinutes(10),
]));

Вместо этого вы можете определить метод withDelay в самом классе уведомления. Метод withDelay должен возвращать массив названий каналов и значений задержки:

/**
 * Определить задержку доставки уведомления.
 *
 * @return array<string, \Illuminate\Support\Carbon>
 */
public function withDelay(object $notifiable): array
{
    return [
        'mail' => now()->addMinutes(5),
        'sms' => now()->addMinutes(10),
    ];
}

#Настройка подключения очереди уведомлений

По умолчанию уведомления ставятся в очередь с использованием подключения очереди по умолчанию вашего приложения. Если вы хотите указать другое подключение для конкретного уведомления, вызовите метод onConnection в конструкторе уведомления:

<?php

namespace App\Notifications;

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

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;

    /**
     * Создать новый экземпляр уведомления.
     */
    public function __construct()
    {
        $this->onConnection('redis');
    }
}

Или, если вы хотите указать конкретное подключение очереди для каждого канала уведомления, определите метод viaConnections в вашем уведомлении. Этот метод должен возвращать массив пар: имя канала и имя подключения очереди:

/**
 * Определить подключения очередей для каждого канала уведомления.
 *
 * @return array<string, string>
 */
public function viaConnections(): array
{
    return [
        'mail' => 'redis',
        'database' => 'sync',
    ];
}

#Настройка очередей каналов уведомлений

Если вы хотите указать конкретную очередь для каждого канала уведомления, определите метод viaQueues в вашем уведомлении. Этот метод должен возвращать массив пар: имя канала и имя очереди:

/**
 * Определить очереди для каждого канала уведомления.
 *
 * @return array<string, string>
 */
public function viaQueues(): array
{
    return [
        'mail' => 'mail-queue',
        'slack' => 'slack-queue',
    ];
}

#Очередь уведомлений и транзакции базы данных

Когда уведомления ставятся в очередь внутри транзакций базы данных, они могут быть обработаны очередью до того, как транзакция будет зафиксирована. В этом случае изменения моделей или записей базы данных, сделанные в транзакции, могут ещё не появиться в базе. Кроме того, модели или записи, созданные в транзакции, могут отсутствовать в базе. Если уведомление зависит от этих моделей, при обработке задачи отправки уведомления могут возникнуть неожиданные ошибки.

Если в настройках подключения очереди параметр after_commit установлен в false, вы всё равно можете указать, что конкретное уведомление должно быть отправлено после фиксации всех открытых транзакций базы данных, вызвав метод afterCommit при отправке уведомления:

use App\Notifications\InvoicePaid;

$user->notify((new InvoicePaid($invoice))->afterCommit());

Или вы можете вызвать метод afterCommit в конструкторе уведомления:

<?php

namespace App\Notifications;

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

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;

    /**
     * Создать новый экземпляр уведомления.
     */
    public function __construct()
    {
        $this->afterCommit();
    }
}
Примечание

Чтобы узнать больше о решении этих проблем, ознакомьтесь с документацией по очередям и транзакциям базы данных.

#Определение необходимости отправки уведомления из очереди

После постановки уведомления в очередь для фоновой обработки оно обычно принимается воркером очереди и отправляется получателю.

Однако, если вы хотите принять окончательное решение о необходимости отправки уведомления после начала его обработки воркером, вы можете определить метод shouldSend в классе уведомления. Если этот метод возвращает false, уведомление не будет отправлено:

/**
 * Определить, следует ли отправлять уведомление.
 */
public function shouldSend(object $notifiable, string $channel): bool
{
    return $this->invoice->isPaid();
}

#Уведомления по требованию

Иногда нужно отправить уведомление человеку, который не зарегистрирован как «пользователь» вашего приложения. Используя метод route фасада Notification, вы можете указать временную информацию маршрутизации перед отправкой уведомления:

use Illuminate\Broadcasting\Channel;
use Illuminate\Support\Facades\Notification;

Notification::route('mail', 'taylor@example.com')
            ->route('vonage', '5555555555')
            ->route('slack', '#slack-channel')
            ->route('broadcast', [new Channel('channel-name')])
            ->notify(new InvoicePaid($invoice));

Если вы хотите указать имя получателя при отправке уведомления по требованию через канал mail, можно передать массив, где ключ — адрес электронной почты, а значение — имя:

Notification::route('mail', [
    'barrett@example.com' => 'Barrett Blair',
])->notify(new InvoicePaid($invoice));

С помощью метода routes можно указать временную информацию маршрутизации сразу для нескольких каналов уведомлений:

Notification::routes([
    'mail' => ['barrett@example.com' => 'Barrett Blair'],
    'vonage' => '5555555555',
])->notify(new InvoicePaid($invoice));

#Уведомления по электронной почте

#Форматирование почтовых сообщений

Если уведомление поддерживает отправку по электронной почте, следует определить метод toMail в классе уведомления. Этот метод получает объект $notifiable и должен возвращать экземпляр Illuminate\Notifications\Messages\MailMessage.

Класс MailMessage содержит несколько простых методов для создания транзакционных email-сообщений. Почтовые сообщения могут содержать строки текста и кнопку с призывом к действию. Рассмотрим пример метода toMail:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    $url = url('/invoice/'.$this->invoice->id);

    return (new MailMessage)
                ->greeting('Hello!')
                ->line('One of your invoices has been paid!')
                ->lineIf($this->amount > 0, "Amount paid: {$this->amount}")
                ->action('View Invoice', $url)
                ->line('Thank you for using our application!');
}
Примечание

Обратите внимание, что в методе toMail используется $this->invoice->id. Вы можете передать любые данные, необходимые для формирования сообщения, через конструктор уведомления.

В этом примере мы добавляем приветствие, строку текста, призыв к действию и затем ещё одну строку текста. Эти методы, предоставляемые объектом MailMessage, позволяют быстро и просто форматировать небольшие транзакционные письма. Затем канал mail преобразует компоненты сообщения в красивый, адаптивный HTML-шаблон письма с текстовой альтернативой. Ниже приведён пример письма, сгенерированного каналом mail:

Примечание

При отправке почтовых уведомлений обязательно установите параметр name в конфигурационном файле config/app.php. Это значение будет использоваться в заголовке и подвале писем.

#Сообщения об ошибках

Некоторые уведомления информируют пользователей об ошибках, например, о неудачной оплате счета. Вы можете указать, что почтовое сообщение относится к ошибке, вызвав метод error при формировании сообщения. При использовании error кнопка призыва к действию будет красной вместо чёрной:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->error()
                ->subject('Invoice Payment Failed')
                ->line('...');
}

#Другие варианты форматирования почтовых уведомлений

Вместо определения строк текста в классе уведомления вы можете использовать метод view, чтобы указать собственный шаблон для рендеринга письма:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)->view(
        'mail.invoice.paid', ['invoice' => $this->invoice]
    );
}

Вы можете указать текстовый шаблон для письма, передав имя шаблона вторым элементом массива в метод view:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)->view(
        ['mail.invoice.paid', 'mail.invoice.paid-text'],
        ['invoice' => $this->invoice]
    );
}

Или, если у вашего сообщения есть только текстовый шаблон, можно использовать метод text:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)->text(
        'mail.invoice.paid-text', ['invoice' => $this->invoice]
    );
}

#Настройка отправителя

По умолчанию адрес отправителя электронной почты задаётся в конфигурационном файле config/mail.php. Однако вы можете указать адрес отправителя для конкретного уведомления с помощью метода from:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->from('barrett@example.com', 'Barrett Blair')
                ->line('...');
}

#Настройка получателя

При отправке уведомлений через канал mail система автоматически ищет свойство email у объекта, получающего уведомление. Вы можете настроить, какой адрес электронной почты использовать, определив метод routeNotificationForMail в этом объекте:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Маршрутизация уведомлений для канала mail.
     *
     * @return  array<string, string>|string
     */
    public function routeNotificationForMail(Notification $notification): array|string
    {
        // Вернуть только адрес электронной почты...
        return $this->email_address;

        // Вернуть адрес электронной почты и имя...
        return [$this->email_address => $this->name];
    }
}

#Настройка темы

По умолчанию тема письма — это имя класса уведомления, преобразованное в формат "Title Case". Например, если класс уведомления называется InvoicePaid, тема письма будет Invoice Paid. Если вы хотите указать другую тему, вызовите метод subject при формировании сообщения:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->subject('Notification Subject')
                ->line('...');
}

#Настройка почтового клиента

По умолчанию уведомление по электронной почте отправляется с использованием почтового клиента, заданного в конфигурационном файле config/mail.php. Однако вы можете указать другой почтовый клиент во время выполнения, вызвав метод mailer при формировании сообщения:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->mailer('postmark')
                ->line('...');
}

#Настройка шаблонов

Вы можете изменить HTML и текстовые шаблоны, используемые для почтовых уведомлений, опубликовав ресурсы пакета уведомлений. После выполнения этой команды шаблоны уведомлений будут находиться в каталоге resources/views/vendor/notifications:

php artisan vendor:publish --tag=laravel-notifications

#Вложения

Чтобы добавить вложения к почтовому уведомлению, используйте метод attach при формировании сообщения. Метод attach принимает абсолютный путь к файлу в качестве первого аргумента:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attach('/path/to/file');
}
Примечание

Метод attach, предоставляемый почтовыми уведомлениями, также поддерживает объекты для вложений. Пожалуйста, ознакомьтесь с подробной документацией по объектам вложений для получения дополнительной информации.

При прикреплении файлов к сообщению вы также можете указать отображаемое имя и/или MIME-тип, передав array в качестве второго аргумента методу attach:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attach('/path/to/file', [
                    'as' => 'name.pdf',
                    'mime' => 'application/pdf',
                ]);
}

В отличие от вложений в mailables, вы не можете прикрепить файл напрямую с диска хранения с помощью attachFromStorage. Вместо этого используйте метод attach с абсолютным путём к файлу на диске хранения. Либо вы можете вернуть mailable из метода toMail:

use App\Mail\InvoicePaid as InvoicePaidMailable;

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): Mailable
{
    return (new InvoicePaidMailable($this->invoice))
                ->to($notifiable->email)
                ->attachFromStorage('/path/to/file');
}

При необходимости к сообщению можно прикрепить несколько файлов с помощью метода attachMany:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attachMany([
                    '/path/to/forge.svg',
                    '/path/to/vapor.svg' => [
                        'as' => 'Logo.svg',
                        'mime' => 'image/svg+xml',
                    ],
                ]);
}

#Вложения с необработанными данными

Метод attachData может использоваться для прикрепления необработанной строки байтов в качестве вложения. При вызове метода attachData необходимо указать имя файла, которое будет присвоено вложению:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attachData($this->pdf, 'name.pdf', [
                    'mime' => 'application/pdf',
                ]);
}

#Добавление тегов и метаданных

Некоторые сторонние почтовые провайдеры, такие как Mailgun и Postmark, поддерживают "теги" и "метаданные" сообщений, которые могут использоваться для группировки и отслеживания писем, отправленных вашим приложением. Вы можете добавить теги и метаданные к почтовому сообщению с помощью методов tag и metadata:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->greeting('Comment Upvoted!')
                ->tag('upvote')
                ->metadata('comment_id', $this->comment->id);
}

Если ваше приложение использует драйвер Mailgun, вы можете ознакомиться с документацией Mailgun для получения дополнительной информации о тегах и метаданных. Аналогично, документация Postmark также доступна для изучения поддержки ими тегов и метаданных.

Если ваше приложение использует Amazon SES для отправки писем, следует использовать метод metadata для прикрепления тегов SES к сообщению.

#Настройка Symfony Message

Метод withSymfonyMessage класса MailMessage позволяет зарегистрировать замыкание, которое будет вызвано с экземпляром Symfony Message перед отправкой сообщения. Это дает возможность глубоко настроить сообщение перед его доставкой:

use Symfony\Component\Mime\Email;

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->withSymfonyMessage(function (Email $message) {
                    $message->getHeaders()->addTextHeader(
                        'Custom-Header', 'Header Value'
                    );
                });
}

#Использование Mailables

При необходимости вы можете вернуть полный объект mailable из метода toMail вашего уведомления. При возврате Mailable вместо MailMessage необходимо указать получателя сообщения с помощью метода to объекта mailable:

use App\Mail\InvoicePaid as InvoicePaidMailable;
use Illuminate\Mail\Mailable;

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): Mailable
{
    return (new InvoicePaidMailable($this->invoice))
                ->to($notifiable->email);
}

#Mailables и уведомления по требованию

Если вы отправляете уведомление по требованию, экземпляр $notifiable, передаваемый в метод toMail, будет экземпляром Illuminate\Notifications\AnonymousNotifiable, который предоставляет метод routeNotificationFor, позволяющий получить адрес электронной почты, на который должно быть отправлено уведомление по требованию:

use App\Mail\InvoicePaid as InvoicePaidMailable;
use Illuminate\Notifications\AnonymousNotifiable;
use Illuminate\Mail\Mailable;

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): Mailable
{
    $address = $notifiable instanceof AnonymousNotifiable
            ? $notifiable->routeNotificationFor('mail')
            : $notifiable->email;

    return (new InvoicePaidMailable($this->invoice))
                ->to($address);
}

#Предпросмотр почтовых уведомлений

При разработке шаблона почтового уведомления удобно быстро просмотреть сгенерированное сообщение в браузере, как обычный Blade-шаблон. Для этого Laravel позволяет возвращать любое почтовое сообщение, созданное уведомлением, напрямую из замыкания маршрута или контроллера. Если возвращается MailMessage, оно будет отрендерено и отображено в браузере, что позволяет быстро оценить дизайн без необходимости отправлять письмо на реальный адрес:

use App\Models\Invoice;
use App\Notifications\InvoicePaid;

Route::get('/notification', function () {
    $invoice = Invoice::find(1);

    return (new InvoicePaid($invoice))
                ->toMail($invoice->user);
});

#Markdown почтовые уведомления

Markdown почтовые уведомления позволяют использовать готовые шаблоны уведомлений, при этом предоставляя больше свободы для написания более длинных и кастомизированных сообщений. Поскольку сообщения написаны на Markdown, Laravel может сгенерировать красивые, адаптивные HTML-шаблоны, а также автоматически создать их текстовую версию.

#Генерация сообщения

Для генерации уведомления с соответствующим Markdown-шаблоном можно использовать опцию --markdown команды Artisan make:notification:

php artisan make:notification InvoicePaid --markdown=mail.invoice.paid

Как и все остальные почтовые уведомления, уведомления с Markdown-шаблонами должны определять метод toMail в классе уведомления. Однако вместо использования методов line и action для построения уведомления, используйте метод markdown, чтобы указать имя Markdown-шаблона. Массив данных, который вы хотите передать в шаблон, можно передать вторым аргументом метода:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    $url = url('/invoice/'.$this->invoice->id);

    return (new MailMessage)
                ->subject('Invoice Paid')
                ->markdown('mail.invoice.paid', ['url' => $url]);
}

#Написание сообщения

Markdown почтовые уведомления используют комбинацию Blade-компонентов и синтаксиса Markdown, что позволяет легко создавать уведомления, используя готовые компоненты Laravel:

<x-mail::message>
# Invoice Paid

Your invoice has been paid!

<x-mail::button :url="$url">
View Invoice
</x-mail::button>

Thanks,<br>
{{ config('app.name') }}
</x-mail::message>

#Компонент кнопки

Компонент кнопки отображает центрированную кнопку-ссылку. Компонент принимает два аргумента: url и необязательный color. Поддерживаемые цвета: primary, green и red. Вы можете добавить в уведомление любое количество кнопок:

<x-mail::button :url="$url" color="green">
View Invoice
</x-mail::button>

#Компонент панели

Компонент панели отображает заданный блок текста в панели с немного отличающимся фоном от остальной части уведомления. Это позволяет выделить определённый блок текста:

<x-mail::panel>
This is the panel content.
</x-mail::panel>

#Компонент таблицы

Компонент таблицы позволяет преобразовать Markdown-таблицу в HTML-таблицу. Компонент принимает Markdown-таблицу в качестве содержимого. Поддерживается выравнивание столбцов с использованием стандартного синтаксиса выравнивания Markdown-таблиц:

<x-mail::table>
| Laravel       | Table         | Example  |
| ------------- |:-------------:| --------:|
| Col 2 is      | Centered      | $10      |
| Col 3 is      | Right-Aligned | $20      |
</x-mail::table>

#Настройка компонентов

Вы можете экспортировать все компоненты Markdown-уведомлений в своё приложение для настройки. Для экспорта компонентов используйте команду Artisan vendor:publish для публикации тега ресурсов laravel-mail:

php artisan vendor:publish --tag=laravel-mail

Эта команда опубликует компоненты Markdown-почты в директорию resources/views/vendor/mail. В каталоге mail будут папки html и text, каждая из которых содержит соответствующие представления всех доступных компонентов. Вы можете свободно настраивать эти компоненты по своему усмотрению.

#Настройка CSS

После экспорта компонентов в директории resources/views/vendor/mail/html/themes появится файл default.css. Вы можете настроить CSS в этом файле, и ваши стили автоматически будут встроены в HTML-представления Markdown-уведомлений.

Если вы хотите создать полностью новую тему для Markdown-компонентов Laravel, вы можете поместить CSS-файл в директорию html/themes. После сохранения и именования файла обновите опцию theme в конфигурационном файле mail, чтобы указать имя вашей новой темы.

Чтобы настроить тему для отдельного уведомления, вызовите метод theme при построении почтового сообщения уведомления. Метод theme принимает имя темы, которая должна использоваться при отправке уведомления:

/**
 * Получить почтовое представление уведомления.
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->theme('invoice')
                ->subject('Invoice Paid')
                ->markdown('mail.invoice.paid', ['url' => $url]);
}

#Уведомления в базе данных

#Требования

Канал уведомлений database сохраняет информацию об уведомлении в таблице базы данных. Эта таблица содержит данные, такие как тип уведомления и JSON-структуру с описанием уведомления.

Вы можете выполнять запросы к этой таблице для отображения уведомлений в интерфейсе вашего приложения. Но для начала необходимо создать таблицу в базе данных для хранения уведомлений. Для этого можно использовать команду notifications:table, которая сгенерирует миграцию с нужной схемой таблицы:

php artisan notifications:table

php artisan migrate
Примечание

Если ваши модели, поддерживающие уведомления, используют UUID или ULID в качестве первичных ключей, следует заменить метод morphs в миграции таблицы уведомлений на uuidMorphs или ulidMorphs.

#Форматирование уведомлений для базы данных

Если уведомление поддерживает сохранение в базе данных, в классе уведомления следует определить метод toDatabase или toArray. Этот метод получает сущность $notifiable и должен возвращать простой PHP-массив. Возвращённый массив будет закодирован в JSON и сохранён в столбце data таблицы notifications. Рассмотрим пример метода toArray:

/**
 * Получить массивное представление уведомления.
 *
 * @return array<string, mixed>
 */
public function toArray(object $notifiable): array
{
    return [
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ];
}

При сохранении уведомления в базе данных столбец type будет заполнен именем класса уведомления. Однако вы можете изменить это поведение, определив метод databaseType в классе уведомления:

/**
 * Получить тип уведомления для базы данных.
 *
 * @return string
 */
public function databaseType(object $notifiable): string
{
    return 'invoice-paid';
}

#toDatabase против toArray

Метод toArray также используется каналом broadcast для определения данных, которые будут транслироваться на фронтенд на JavaScript. Если вы хотите иметь разные массивные представления для каналов database и broadcast, следует определить метод toDatabase вместо toArray.

#Доступ к уведомлениям

После сохранения уведомлений в базе данных вам нужен удобный способ доступа к ним из сущностей, поддерживающих уведомления. Трейт Illuminate\Notifications\Notifiable, который включён в стандартную модель App\Models\User Laravel, содержит Eloquent-связь notifications, возвращающую уведомления для сущности. Для получения уведомлений можно обращаться к этой связи как к любой другой Eloquent-связи. По умолчанию уведомления сортируются по времени создания created_at с самыми новыми в начале коллекции:

$user = App\Models\User::find(1);

foreach ($user->notifications as $notification) {
    echo $notification->type;
}

Если вы хотите получить только «непрочитанные» уведомления, вы можете использовать связь unreadNotifications. Эти уведомления будут отсортированы по метке времени created_at, при этом самые новые уведомления будут в начале коллекции:

$user = App\Models\User::find(1);

foreach ($user->unreadNotifications as $notification) {
    echo $notification->type;
}
Примечание

Для доступа к уведомлениям из JavaScript-клиента следует определить контроллер уведомлений в вашем приложении, который возвращает уведомления для сущности, поддерживающей уведомления, например, для текущего пользователя. Затем можно выполнять HTTP-запросы к URL этого контроллера из JavaScript.

#Пометка уведомлений как прочитанных

Обычно уведомление помечается как "прочитанное", когда пользователь его просматривает. Трейт Illuminate\Notifications\Notifiable предоставляет метод markAsRead, который обновляет столбец read_at в записи уведомления в базе данных:

$user = App\Models\User::find(1);

foreach ($user->unreadNotifications as $notification) {
    $notification->markAsRead();
}

Однако вместо перебора каждого уведомления можно вызвать метод markAsRead непосредственно на коллекции уведомлений:

$user->unreadNotifications->markAsRead();

Также можно выполнить массовое обновление, чтобы пометить все уведомления как прочитанные без их извлечения из базы:

$user = App\Models\User::find(1);

$user->unreadNotifications()->update(['read_at' => now()]);

Вы можете delete уведомления, чтобы полностью удалить их из таблицы:

$user->notifications()->delete();

#Broadcast уведомления

#Требования

Перед трансляцией уведомлений следует настроить и ознакомиться с сервисами event broadcasting Laravel. Трансляция событий позволяет реагировать на серверные события Laravel из вашего фронтенда на JavaScript.

#Форматирование broadcast уведомлений

Канал broadcast транслирует уведомления с помощью сервисов event broadcasting Laravel, позволяя вашему фронтенду на JavaScript получать уведомления в реальном времени. Если уведомление поддерживает трансляцию, в классе уведомления можно определить метод toBroadcast. Этот метод получает сущность $notifiable и должен возвращать экземпляр BroadcastMessage. Если метод toBroadcast отсутствует, будет использован метод toArray для получения данных, которые нужно транслировать. Возвращённые данные будут закодированы в JSON и отправлены на фронтенд. Рассмотрим пример метода toBroadcast:

use Illuminate\Notifications\Messages\BroadcastMessage;

/**
 * Получить представление уведомления для трансляции.
 */
public function toBroadcast(object $notifiable): BroadcastMessage
{
    return new BroadcastMessage([
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ]);
}

#Настройка очереди трансляций

Все broadcast уведомления ставятся в очередь для трансляции. Если вы хотите настроить соединение очереди или имя очереди, используемой для постановки задачи трансляции, можно использовать методы onConnection и onQueue объекта BroadcastMessage:

return (new BroadcastMessage($data))
                ->onConnection('sqs')
                ->onQueue('broadcasts');

#Настройка типа уведомления

Кроме данных, которые вы указываете, все транслируемые уведомления также имеют поле type, содержащее полное имя класса уведомления. Если вы хотите настроить type уведомления, вы можете определить метод broadcastType в классе уведомления:

/**
 * Получить тип уведомления для трансляции.
 */
public function broadcastType(): string
{
    return 'broadcast.message';
}

#Прослушивание уведомлений

Уведомления транслируются на приватный канал с именем в формате {notifiable}.{id}. Например, если уведомление отправляется пользователю App\Models\User с ID 1, оно будет транслироваться на приватный канал App.Models.User.1. При использовании Laravel Echo можно легко слушать уведомления на канале с помощью метода notification:

Echo.private('App.Models.User.' + userId)
    .notification((notification) => {
        console.log(notification.type);
    });

#Настройка канала уведомлений

Если вы хотите изменить канал, на котором транслируются уведомления сущности, можно определить метод receivesBroadcastNotificationsOn в этой сущности:

<?php

namespace App\Models;

use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Каналы, на которых пользователь получает трансляции уведомлений.
     */
    public function receivesBroadcastNotificationsOn(): string
    {
        return 'users.'.$this->id;
    }
}

#SMS уведомления

#Требования

Отправка SMS-уведомлений в Laravel осуществляется через Vonage (ранее Nexmo). Перед отправкой уведомлений через Vonage необходимо установить пакеты laravel/vonage-notification-channel и guzzlehttp/guzzle:

composer require laravel/vonage-notification-channel guzzlehttp/guzzle

Пакет содержит файл конфигурации. Однако экспортировать этот файл в своё приложение необязательно. Вы можете просто использовать переменные окружения VONAGE_KEY и VONAGE_SECRET для указания публичного и секретного ключей Vonage.

После указания ключей следует задать переменную окружения VONAGE_SMS_FROM, определяющую номер телефона, с которого по умолчанию будут отправляться SMS. Этот номер можно создать в панели управления Vonage:

VONAGE_SMS_FROM=15556666666

#Форматирование SMS уведомлений

Если уведомление поддерживает отправку SMS, в классе уведомления следует определить метод toVonage. Этот метод получает сущность $notifiable и должен возвращать экземпляр Illuminate\Notifications\Messages\VonageMessage:

use Illuminate\Notifications\Messages\VonageMessage;

/**
 * Получить представление уведомления для Vonage / SMS.
 */
public function toVonage(object $notifiable): VonageMessage
{
    return (new VonageMessage)
                ->content('Your SMS message content');
}

#Unicode содержимое

Если ваше SMS-сообщение содержит символы Unicode, следует вызвать метод unicode при создании экземпляра VonageMessage:

use Illuminate\Notifications\Messages\VonageMessage;

/**
 * Получить представление уведомления для Vonage / SMS.
 */
public function toVonage(object $notifiable): VonageMessage
{
    return (new VonageMessage)
                ->content('Your unicode message')
                ->unicode();
}

#Настройка номера отправителя

Если вы хотите отправлять некоторые уведомления с номера телефона, отличного от указанного в переменной окружения VONAGE_SMS_FROM, можно вызвать метод from у экземпляра VonageMessage:

use Illuminate\Notifications\Messages\VonageMessage;

/**
 * Получить представление уведомления для Vonage / SMS.
 */
public function toVonage(object $notifiable): VonageMessage
{
    return (new VonageMessage)
                ->content('Your SMS message content')
                ->from('15554443333');
}

#Добавление клиентской ссылки

Если вы хотите отслеживать расходы по пользователям, командам или клиентам, можно добавить "клиентскую ссылку" к уведомлению. Vonage позволит создавать отчёты с использованием этой ссылки, чтобы лучше понимать использование SMS конкретным клиентом. Клиентская ссылка может быть любой строкой длиной до 40 символов:

use Illuminate\Notifications\Messages\VonageMessage;

/**
 * Получить представление уведомления для Vonage / SMS.
 */
public function toVonage(object $notifiable): VonageMessage
{
    return (new VonageMessage)
                ->clientReference((string) $notifiable->id)
                ->content('Your SMS message content');
}

#Маршрутизация SMS уведомлений

Чтобы направлять уведомления Vonage на правильный номер телефона, определите метод routeNotificationForVonage в сущности, поддерживающей уведомления:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Маршрутизация уведомлений для канала Vonage.
     */
    public function routeNotificationForVonage(Notification $notification): string
    {
        return $this->phone_number;
    }
}

#Slack уведомления

#Требования

Перед отправкой Slack-уведомлений необходимо установить канал уведомлений Slack через Composer:

composer require laravel/slack-notification-channel

Кроме того, нужно создать Slack App для вашего Slack-рабочего пространства.

Если вам нужно отправлять уведомления только в то же Slack-рабочее пространство, где создано приложение, убедитесь, что у вашего приложения есть права chat:write, chat:write.public и chat:write.customize. Эти права можно добавить на вкладке управления приложением "OAuth & Permissions" в Slack.

Далее скопируйте "Bot User OAuth Token" приложения и поместите его в массив конфигурации slack в файле конфигурации services.php вашего приложения. Этот токен находится на вкладке "OAuth & Permissions" в Slack:

'slack' => [
    'notifications' => [
        'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'),
        'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
    ],
],

#Распространение приложения

Если ваше приложение будет отправлять уведомления во внешние Slack-рабочие пространства, принадлежащие пользователям вашего приложения, вам нужно "распространить" ваше приложение через Slack. Распространение управляется на вкладке "Manage Distribution" вашего приложения в Slack. После распространения вы можете использовать Socialite для получения Slack Bot токенов от имени пользователей вашего приложения.

#Форматирование Slack уведомлений

Если уведомление поддерживает отправку в виде сообщения Slack, вы должны определить метод toSlack в классе уведомления. Этот метод получит сущность $notifiable и должен вернуть экземпляр Illuminate\Notifications\Slack\SlackMessage. Вы можете создавать насыщенные уведомления с помощью Slack's Block Kit API. Следующий пример можно просмотреть в Slack's Block Kit builder:

use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
use Illuminate\Notifications\Slack\SlackMessage;

/**
 * Получить представление уведомления для Slack.
 */
public function toSlack(object $notifiable): SlackMessage
{
    return (new SlackMessage)
            ->text('Один из ваших счетов был оплачен!')
            ->headerBlock('Счет оплачен')
            ->contextBlock(function (ContextBlock $block) {
                $block->text('Клиент #1234');
            })
            ->sectionBlock(function (SectionBlock $block) {
                $block->text('Счет был оплачен.');
                $block->field("*Номер счета:*\n1000")->markdown();
                $block->field("*Получатель счета:*\ntaylor@laravel.com")->markdown();
            })
            ->dividerBlock()
            ->sectionBlock(function (SectionBlock $block) {
                $block->text('Поздравляем!');
            });
}

#Взаимодействие в Slack

Система уведомлений Slack Block Kit предоставляет мощные возможности для обработки взаимодействия пользователя. Чтобы использовать эти функции, ваше Slack-приложение должно иметь включённую опцию «Interactivity» и настроенный «Request URL», указывающий на URL, обслуживаемый вашим приложением. Эти настройки можно управлять во вкладке «Interactivity & Shortcuts» в панели управления приложением Slack.

В следующем примере, использующем метод actionsBlock, Slack отправит POST запрос на ваш «Request URL» с полезной нагрузкой, содержащей пользователя Slack, который нажал кнопку, ID нажатой кнопки и другие данные. Ваше приложение сможет определить, какое действие выполнить, исходя из этой нагрузки. Также следует проверять, что запрос действительно пришёл от Slack:

use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
use Illuminate\Notifications\Slack\SlackMessage;

/**
 * Получить представление уведомления для Slack.
 */
public function toSlack(object $notifiable): SlackMessage
{
    return (new SlackMessage)
            ->text('Один из ваших счетов был оплачен!')
            ->headerBlock('Счет оплачен')
            ->contextBlock(function (ContextBlock $block) {
                $block->text('Клиент #1234');
            })
            ->sectionBlock(function (SectionBlock $block) {
                $block->text('Счет был оплачен.');
            })
            ->actionsBlock(function (ActionsBlock $block) {
                 // ID по умолчанию "button_acknowledge_invoice"...
                $block->button('Подтвердить счет')->primary();

                // Ручная настройка ID...
                $block->button('Отклонить')->danger()->id('deny_invoice');
            });
}

#Модальные окна подтверждения

Если вы хотите, чтобы пользователи подтверждали действие перед его выполнением, вы можете вызвать метод confirm при определении кнопки. Метод confirm принимает сообщение и замыкание, которое получает экземпляр ConfirmObject:

use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
use Illuminate\Notifications\Slack\SlackMessage;

/**
 * Получить представление уведомления для Slack.
 */
public function toSlack(object $notifiable): SlackMessage
{
    return (new SlackMessage)
            ->text('Один из ваших счетов был оплачен!')
            ->headerBlock('Счет оплачен')
            ->contextBlock(function (ContextBlock $block) {
                $block->text('Клиент #1234');
            })
            ->sectionBlock(function (SectionBlock $block) {
                $block->text('Счет был оплачен.');
            })
            ->actionsBlock(function (ActionsBlock $block) {
                $block->button('Подтвердить счет')
                    ->primary()
                    ->confirm(
                        'Подтвердить оплату и отправить благодарственное письмо?',
                        function (ConfirmObject $dialog) {
                            $dialog->confirm('Да');
                            $dialog->deny('Нет');
                        }
                    );
            });
}

#Просмотр Slack Blocks

Если вы хотите быстро просмотреть созданные блоки, вы можете вызвать метод dd у экземпляра SlackMessage. Метод dd сгенерирует и выведет URL на Slack Block Kit Builder, который покажет предварительный просмотр полезной нагрузки и уведомления в вашем браузере. Вы можете передать true в метод dd, чтобы вывести необработанную полезную нагрузку:

return (new SlackMessage)
        ->text('Один из ваших счетов был оплачен!')
        ->headerBlock('Счет оплачен')
        ->dd();

#Маршрутизация Slack уведомлений

Чтобы направлять Slack уведомления в нужную команду и канал Slack, определите метод routeNotificationForSlack в вашей модели, которая может получать уведомления. Этот метод может возвращать одно из трёх значений:

  • null — маршрутизация будет делегирована каналу, настроенному в самом уведомлении. Вы можете использовать метод to при построении SlackMessage для настройки канала внутри уведомления.
  • Строку, указывающую канал Slack, куда отправлять уведомление, например, #support-channel.
  • Экземпляр SlackRoute, который позволяет указать OAuth токен и имя канала, например, SlackRoute::make($this->slack_channel, $this->slack_token). Этот метод следует использовать для отправки уведомлений во внешние рабочие пространства.

Например, возврат #support-channel из метода routeNotificationForSlack отправит уведомление в канал #support-channel в рабочем пространстве, связанном с OAuth токеном Bot User, указанным в конфигурационном файле services.php вашего приложения:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Маршрутизировать уведомления для Slack канала.
     */
    public function routeNotificationForSlack(Notification $notification): mixed
    {
        return '#support-channel';
    }
}

#Уведомления во внешние Slack рабочие пространства

Примечание

Перед отправкой уведомлений во внешние Slack рабочие пространства ваше Slack-приложение должно быть распространено.

Конечно, часто нужно отправлять уведомления в Slack рабочие пространства, принадлежащие пользователям вашего приложения. Для этого сначала необходимо получить Slack OAuth токен для пользователя. К счастью, Laravel Socialite включает драйвер Slack, который позволяет легко аутентифицировать пользователей вашего приложения через Slack и получить токен бота.

После получения токена бота и сохранения его в базе данных вашего приложения, вы можете использовать метод SlackRoute::make для маршрутизации уведомления в рабочее пространство пользователя. Кроме того, вашему приложению, вероятно, потребуется предоставить пользователю возможность указать, в какой канал отправлять уведомления:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Slack\SlackRoute;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Маршрутизировать уведомления для Slack канала.
     */
    public function routeNotificationForSlack(Notification $notification): mixed
    {
        return SlackRoute::make($this->slack_channel, $this->slack_token);
    }
}

#Локализация уведомлений

Laravel позволяет отправлять уведомления на языке, отличном от текущей локали HTTP-запроса, и даже запомнит эту локаль, если уведомление помещено в очередь.

Для этого класс Illuminate\Notifications\Notification предоставляет метод locale для установки нужного языка. Приложение переключится на эту локаль во время обработки уведомления и затем вернётся к предыдущей локали после завершения обработки:

$user->notify((new InvoicePaid($invoice))->locale('es'));

Локализацию для нескольких получателей можно также выполнить через фасад Notification:

Notification::locale('es')->send(
    $users, new InvoicePaid($invoice)
);

#Предпочитаемые локали пользователя

Иногда приложения хранят предпочитаемую локаль каждого пользователя. Реализовав контракт HasLocalePreference в вашей модели, которая получает уведомления, вы можете указать Laravel использовать эту локаль при отправке уведомлений:

use Illuminate\Contracts\Translation\HasLocalePreference;

class User extends Model implements HasLocalePreference
{
    /**
     * Получить предпочитаемую локаль пользователя.
     */
    public function preferredLocale(): string
    {
        return $this->locale;
    }
}

После реализации интерфейса Laravel автоматически будет использовать предпочитаемую локаль при отправке уведомлений и писем этой модели. Поэтому нет необходимости вызывать метод locale при использовании этого интерфейса:

$user->notify(new InvoicePaid($invoice));

#Тестирование

Вы можете использовать метод fake фасада Notification, чтобы предотвратить отправку уведомлений. Обычно отправка уведомлений не связана с тестируемым кодом. Чаще всего достаточно просто проверить, что Laravel был проинструктирован отправить определённое уведомление.

После вызова метода fake фасада Notification вы можете проверить, что уведомления были отправлены пользователям, и даже проверить данные, которые получили уведомления:

<?php

namespace Tests\Feature;

use App\Notifications\OrderShipped;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_orders_can_be_shipped(): void
    {
        Notification::fake();

        // Выполнить отправку заказа...

        // Проверить, что уведомления не были отправлены...
        Notification::assertNothingSent();

        // Проверить, что уведомление было отправлено указанным пользователям...
        Notification::assertSentTo(
            [$user], OrderShipped::class
        );

        // Проверить, что уведомление не было отправлено...
        Notification::assertNotSentTo(
            [$user], AnotherNotification::class
        );

        // Проверить, что было отправлено заданное количество уведомлений...
        Notification::assertCount(3);
    }
}

Вы можете передать замыкание в методы assertSentTo или assertNotSentTo, чтобы проверить, что было отправлено уведомление, удовлетворяющее определённому условию. Если хотя бы одно уведомление прошло проверку, утверждение будет успешным:

Notification::assertSentTo(
    $user,
    function (OrderShipped $notification, array $channels) use ($order) {
        return $notification->order->id === $order->id;
    }
);

#Уведомления по требованию

Если тестируемый код отправляет уведомления по требованию, вы можете проверить их отправку с помощью метода assertSentOnDemand:

Notification::assertSentOnDemand(OrderShipped::class);

Передав замыкание вторым аргументом методу assertSentOnDemand, вы можете проверить, что уведомление по требованию было отправлено на правильный адрес маршрута:

Notification::assertSentOnDemand(
    OrderShipped::class,
    function (OrderShipped $notification, array $channels, object $notifiable) use ($user) {
        return $notifiable->routes['mail'] === $user->email;
    }
);

#События уведомлений

#Событие отправки уведомления

Когда уведомление отправляется, система уведомлений генерирует событие Illuminate\Notifications\Events\NotificationSending event. Оно содержит сущность "notifiable" и сам экземпляр уведомления. Вы можете зарегистрировать слушатели этого события в EventServiceProvider вашего приложения:

use App\Listeners\CheckNotificationStatus;
use Illuminate\Notifications\Events\NotificationSending;

/**
 * Сопоставления слушателей событий для приложения.
 *
 * @var array
 */
protected $listen = [
    NotificationSending::class => [
        CheckNotificationStatus::class,
    ],
];

Уведомление не будет отправлено, если слушатель события NotificationSending вернёт false из метода handle:

use Illuminate\Notifications\Events\NotificationSending;

/**
 * Обработать событие.
 */
public function handle(NotificationSending $event): bool
{
    return false;
}

Внутри слушателя события вы можете получить доступ к свойствам notifiable, notification и channel объекта события, чтобы узнать больше о получателе уведомления или самом уведомлении:

/**
 * Обработать событие.
 */
public function handle(NotificationSending $event): void
{
    // $event->channel
    // $event->notifiable
    // $event->notification
}

#Событие отправленного уведомления

Когда уведомление отправлено, система уведомлений генерирует событие Illuminate\Notifications\Events\NotificationSent event. Оно содержит сущность "notifiable" и сам экземпляр уведомления. Вы можете зарегистрировать слушатели этого события в вашем EventServiceProvider:

use App\Listeners\LogNotification;
use Illuminate\Notifications\Events\NotificationSent;

/**
 * Сопоставления слушателей событий для приложения.
 *
 * @var array
 */
protected $listen = [
    NotificationSent::class => [
        LogNotification::class,
    ],
];
Примечание

После регистрации слушателей в вашем EventServiceProvider используйте Artisan-команду event:generate для быстрой генерации классов слушателей.

Внутри слушателя события вы можете получить доступ к свойствам notifiable, notification, channel и response объекта события, чтобы узнать больше о получателе уведомления или самом уведомлении:

/**
 * Обработать событие.
 */
public function handle(NotificationSent $event): void
{
    // $event->channel
    // $event->notifiable
    // $event->notification
    // $event->response
}

#Пользовательские каналы

Laravel поставляется с набором каналов уведомлений, но вы можете написать собственные драйверы для доставки уведомлений через другие каналы. Laravel упрощает этот процесс. Для начала определите класс с методом send. Метод должен принимать два аргумента: $notifiable и $notification.

Внутри метода send вы можете вызвать методы уведомления для получения объекта сообщения, понятного вашему каналу, а затем отправить уведомление экземпляру $notifiable любым удобным способом:

<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;

class VoiceChannel
{
    /**
     * Отправить указанное уведомление.
     */
    public function send(object $notifiable, Notification $notification): void
    {
        $message = $notification->toVoice($notifiable);

        // Отправить уведомление экземпляру $notifiable...
    }
}

После определения класса канала уведомлений вы можете вернуть имя класса из метода via любого вашего уведомления. В этом примере метод toVoice уведомления может возвращать любой объект, который вы выберете для представления голосовых сообщений. Например, вы можете определить собственный класс VoiceMessage для этих сообщений:

<?php

namespace App\Notifications;

use App\Notifications\Messages\VoiceMessage;
use App\Notifications\VoiceChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;

class InvoicePaid extends Notification
{
    use Queueable;

    /**
     * Получить каналы уведомления.
     */
    public function via(object $notifiable): string
    {
        return VoiceChannel::class;
    }

    /**
     * Получить голосовое представление уведомления.
     */
    public function toVoice(object $notifiable): VoiceMessage
    {
        // ...
    }
}