1. Глубже в детали
  2. Уведомления

Введение

Помимо поддержки отправки электронной почты, 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. Трейт 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, предоставляемый этим трейтом, ожидает получения экземпляра уведомления:

use App\Notifications\InvoicePaid;
 
$user->notify(new InvoicePaid($invoice));

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

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

В качестве альтернативы вы можете отправлять уведомления через фасад Notification. Этот подход полезен, когда вам нужно отправить уведомление нескольким сущностям, таким как коллекция пользователей. Чтобы отправить уведомления с использованием фасада, передайте все сущности и экземпляр уведомления методу 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', '[email protected]')
->route('vonage', '5555555555')
->route('slack', '#slack-channel')
->route('broadcast', [new Channel('channel-name')])
->notify(new InvoicePaid($invoice));

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

Notification::route('mail', [
'[email protected]' => 'Barrett Blair',
])->notify(new InvoicePaid($invoice));

Почтовые уведомления

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

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

Класс MailMessage содержит несколько простых методов, чтобы помочь вам создавать транзакционные сообщения электронной почты. Письменные сообщения могут содержать строки текста, а также "призыв к действию". Давайте рассмотрим пример метода 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!');
}

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

В этом примере мы регистрируем приветствие, строку текста, призыв к действию, а затем еще одну строку текста. Эти методы, предоставленные объектом MailMessage, делают простым и быстрым форматирование небольших транзакционных электронных писем. Затем канал электронной почты преобразует компоненты сообщения в красивый, адаптивный 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(
'emails.name', ['invoice' => $this->invoice]
);
}

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

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

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

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

/**
* Получить почтовое представление уведомления.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->from('[email protected]', '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;
 
/**
* Маршрутизировать уведомления для канала почты.
*
* @return array<string, string>|string
*/
public function routeNotificationForMail(Notification $notification): array|string
{
// Вернуть только адрес электронной почты...
return $this->email_address;
 
// Вернуть адрес электронной почты и имя...
return [$this->email_address => $this->name];
}
}

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

По умолчанию тема электронной почты - это имя класса уведомления, форматированное как "заглавные буквы". Таким образом, если ваш класс уведомления назван 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, передав массив вторым аргументом методу attach:

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

В отличие от прикрепления файлов в объектах отправляемых сообщений, вы не можете прикрепить файл напрямую с хранилища, используя attachFromStorage. Вы должны вместо этого использовать метод attach с абсолютным путем к файлу на диске хранилища. В противном случае вы можете вернуть отправляемое сообщение из метода 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

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

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. После названия и сохранения вашего файла CSS обновите опцию 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,
];
}

toDatabase Vs. toArray

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

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

Как только уведомления сохранены в базе данных, вам нужен удобный способ получения к ним доступа из ваших сущностей, поддерживающих уведомления. Трейт Illuminate\Notifications\Notifiable, включенный в модель App\Models\User по умолчанию в Laravel, включает в себя отношение notifications Eloquent, возвращающее уведомления для сущности. Чтобы получить уведомления, вы можете получить доступ к этому методу, как к любому другому отношению 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();

Трансляция уведомлений

Предпосылки

Перед тем как транслировать уведомления, вы должны настроить и быть знакомыми с сервисами трансляции событий Laravel. Событийная трансляция предоставляет способ реагировать на события Laravel на стороне сервера из вашего веб-интерфейса, работающего на JavaScript.

Форматирование транслируемых уведомлений

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

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

Конфигурация очереди трансляции

Все транслируемые уведомления поставляются в очередь на трансляцию. Если вы хотите настроить соединение с очередью или имя очереди, используемое для постановки трансляционной операции в очередь, вы можете использовать методы 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 с идентификатором 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
{
}
}

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 для вашего рабочего пространства 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. Распределение приложения можно управлять на вкладке "Управление распространением" вашего приложения в Slack. После распространения вашего приложения вы можете использовать Socialite для получения токенов Slack Bot от имени пользователей вашего приложения.

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

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

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('One of your invoices has been paid!')
->headerBlock('Invoice Paid')
->contextBlock(function (ContextBlock $block) {
$block->text('Customer #1234');
})
->sectionBlock(function (SectionBlock $block) {
$block->text('An invoice has been paid.');
$block->field("*Invoice No:*\n1000")->markdown();
$block->field("*Invoice Recipient:*\n[email protected]")->markdown();
})
->dividerBlock()
->sectionBlock(function (SectionBlock $block) {
$block->text('Congratulations!');
});
}

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

Система уведомлений Block Kit Slack предоставляет мощные функции для обработки взаимодействия с пользователем. Чтобы использовать эти функции, ваше приложение Slack должно иметь включенную "Интерактивность" и настроенный "URL запроса", указывающий на URL, обслуживаемый вашим приложением. Эти настройки можно управлять на вкладке "Интерактивность и ярлыки" в управлении приложением Slack.

В следующем примере, использующем метод actionsBlock, Slack отправит запрос POST на ваш "URL запроса" с полезной нагрузкой, содержащей Slack-пользователя, который нажал кнопку, идентификатор нажатой кнопки и другие данные. Ваше приложение затем может определить действие на основе полезной нагрузки. Вы также должны проверить запрос был сделан 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('One of your invoices has been paid!')
->headerBlock('Invoice Paid')
->contextBlock(function (ContextBlock $block) {
$block->text('Customer #1234');
})
->sectionBlock(function (SectionBlock $block) {
$block->text('An invoice has been paid.');
})
->actionsBlock(function (ActionsBlock $block) {
// ID по умолчанию - "button_acknowledge_invoice"...
$block->button('Acknowledge Invoice')->primary();
 
// Настроить ID вручную...
$block->button('Deny')->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('One of your invoices has been paid!')
->headerBlock('Invoice Paid')
->contextBlock(function (ContextBlock $block) {
$block->text('Customer #1234');
})
->sectionBlock(function (SectionBlock $block) {
$block->text('An invoice has been paid.');
})
->actionsBlock(function (ActionsBlock $block) {
$block->button('Acknowledge Invoice')
->primary()
->confirm(
'Acknowledge the payment and send a thank you email?',
function (ConfirmObject $dialog) {
$dialog->confirm('Yes');
$dialog->deny('No');
}
);
});
}

Инспектирование блоков Slack

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

return (new SlackMessage)
->text('One of your invoices has been paid!')
->headerBlock('Invoice Paid')
->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 в рабочей области, связанной с токеном Bot User OAuth, указанным в файле конфигурации вашего приложения 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;
 
/**
* Handle the event.
*/
public function handle(NotificationSending $event): bool
{
return false;
}

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

/**
* Handle the event.
*/
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 события для получения дополнительной информации о получателе уведомления или самом уведомлении:

/**
* Handle the event.
*/
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
{
// ...
}
}