Уведомления
- Введение
- Создание уведомлений
- Отправка уведомлений
- Почтовые уведомления
- Почтовые уведомления Markdown
- Уведомления базы данных
- Уведомления о трансляциях
- SMS-уведомления
- Уведомления в Slack
- Локализация уведомлений
- Уведомления о событиях
- Пользовательские каналы
Введение
Помимо поддержки отправки электронной почты, Laravel поддерживает отправку уведомлений по различным каналам доставки, включая электронную почту, SMS (через Vonage, ранее известный как Nexmo) и Slack. Кроме того, было создано множество каналов уведомлений, созданных сообществом для отправки уведомлений по десяткам различных каналов! Уведомления также могут храниться в базе данных, чтобы они могли отображаться в вашем веб-интерфейсе.
Как правило, уведомления должны быть короткими информационными сообщениями, уведомляющими пользователей о том, что произошло в вашем приложении. Например, если вы пишете приложение для выставления счетов, вы можете отправить своим пользователям уведомление «Счет оплачен» по электронной почте и через SMS-каналы.
Создание уведомлений
В Laravel каждое уведомление представлено одним классом, который обычно хранится в каталоге app/Notifications
. Не волнуйтесь, если вы не видите этот каталог в своем приложении — он будет создан для вас, когда вы запустите Artisan-команду make:notification
:
php artisan make:notification InvoicePaid
Эта команда поместит новый класс уведомлений в ваш каталог app/Notifications
. Каждый класс уведомлений содержит метод via
и переменное количество методов создания сообщений, таких как toMail
или toDatabase
, которые преобразуют уведомление в сообщение, предназначенное для данного конкретного канала.
Отправка уведомлений
Использование трейта уведомлений
Уведомления можно отправлять двумя способами: с помощью метода 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
, предоставляемый этим трейтом, ожидает получения экземпляра уведомления:
use App\Notifications\InvoicePaid; $user->notify(new InvoicePaid($invoice));
{tip} Помните, что вы можете использовать трейт
Notifiable
в любой из ваших моделей. Вы не ограничены только включением его в свою модельUser
.
Использование фасада уведомлений
Кроме того, вы можете отправлять уведомления через 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
, nexmo
и slack
.
{tip} Если вы хотите использовать другие каналы доставки, такие как Telegram или Pusher, посетите сайт сообщества веб-сайт каналов уведомлений Laravel.
Метод via
получает экземпляр $notifiable
, который будет экземпляром класса, которому отправляется уведомление. Вы можете использовать $notifiable
, чтобы определить, по каким каналам должно быть доставлено уведомление:
/** * Get the notification's delivery channels. * * @param mixed $notifiable * @return array */public function via($notifiable){ return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];}
Очередь уведомлений
{note} Прежде чем ставить уведомления в очередь, вы должны настроить свою очередь и запустить воркер.
Отправка уведомлений может занять некоторое время, особенно если каналу необходимо выполнить внешний вызов 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),]));
При постановке уведомлений в очередь задание в очереди будет создано для каждой комбинации получателя и канала. Например, шесть заданий будут отправлены в очередь, если у вашего уведомления три получателя и два канала.
Настройка подключения очереди уведомлений
По умолчанию уведомления в очереди будут поставлены в очередь с использованием подключения к очереди вашего приложения по умолчанию. Если вы хотите указать другое соединение, которое должно использоваться для определенного уведомления, вы можете определить свойство $connection
в классе уведомлений:
/** * The name of the queue connection to use when queueing the notification. * * @var string */public $connection = 'redis';
Настройка очередей каналов уведомлений
Если вы хотите указать конкретную очередь, которая должна использоваться для каждого канала уведомления, поддерживаемого уведомлением, вы можете определить метод viaQueues
в своем уведомлении. Этот метод должен возвращать массив пар имя канала/имя очереди:
/** * Determine which queues should be used for each notification channel. * * @return array */public function viaQueues(){ 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; /** * Create a new notification instance. * * @return void */ public function __construct() { $this->afterCommit(); }}
{tip} Чтобы узнать больше о том, как обойти эти проблемы, ознакомьтесь с документацией по заданиям, поставленным в очередь, и транзакциям базы данных.
Определение того, следует ли отправлять уведомление в очереди
После отправки уведомления из очереди для фоновой обработки оно обычно принимается обработчиком очереди и отправляется предполагаемому получателю.
Однако, если вы хотите принять окончательное решение о том, следует ли отправлять уведомление из очереди после того, как оно будет обработано обработчиком очереди, вы можете определить метод shouldSend
в классе уведомлений. Если этот метод возвращает false
, уведомление не будет отправлено:
/** * Determine if the notification should be sent. * * @param mixed $notifiable * @param string $channel * @return bool */public function shouldSend($notifiable, $channel){ return $this->invoice->isPaid();}
Уведомления по запросу
Иногда вам может понадобиться отправить уведомление кому-то, кто не сохранен как «пользователь» вашего приложения. Используя метод route
фасада Notification
, вы можете указать специальную информацию о маршрутизации уведомлений перед отправкой уведомления:
Notification::route('mail', 'taylor@example.com') ->route('nexmo', '5555555555') ->route('slack', 'https://hooks.slack.com/services/...') ->notify(new InvoicePaid($invoice));
Если вы хотите указать имя получателя при отправке уведомления по запросу на маршрут mail
, вы можете предоставить массив, содержащий адрес электронной почты в качестве ключа и имя в качестве значения первого элемента в массиве:
Notification::route('mail', [ 'barrett@example.com' => 'Barrett Blair',])->notify(new InvoicePaid($invoice));
Почтовые уведомления
Форматирование почтовых сообщений
Если уведомление поддерживает отправку по электронной почте, вы должны определить метод toMail
в классе уведомлений. Этот метод получит сущность $notifiable
и должен вернуть экземпляр Illuminate\Notifications\Messages\MailMessage
.
Класс MailMessage
содержит несколько простых методов, помогающих создавать транзакционные электронные сообщения. Почтовые сообщения могут содержать строки текста, а также «призыв к действию». Давайте рассмотрим пример метода toMail
:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ $url = url('/invoice/'.$this->invoice->id); return (new MailMessage) ->greeting('Hello!') ->line('One of your invoices has been paid!') ->action('View Invoice', $url) ->line('Thank you for using our application!');}
{tip} Обратите внимание, что мы используем
$this->invoice->id
в нашем методеtoMail
. Вы можете передать любые данные, необходимые вашему уведомлению для создания сообщения, в конструктор уведомления.
В этом примере мы регистрируем приветствие, строку текста, призыв к действию, а затем еще одну строку текста. Эти методы, предоставляемые объектом MailMessage
, упрощают и ускоряют форматирование небольших транзакционных электронных писем. Затем почтовый канал преобразует компоненты сообщения в красивый, отзывчивый HTML-шаблон электронной почты с аналогом в виде обычного текста. Вот пример электронного письма, сгенерированного каналом mail
:

{tip} При отправке почтовых уведомлений обязательно установите параметр конфигурации
name
в файле конфигурацииconfig/app.php
. Это значение будет использоваться в верхнем и нижнем колонтитулах ваших почтовых уведомлений.
Другие параметры форматирования почтовых уведомлений
Вместо того, чтобы определять «строки» текста в классе уведомлений, вы можете использовать метод view
, чтобы указать собственный шаблон, который следует использовать для отображения электронного письма с уведомлением:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ return (new MailMessage)->view( 'emails.name', ['invoice' => $this->invoice] );}
Вы можете указать простое текстовое представление для почтового сообщения, передав имя представления в качестве второго элемента массива, переданного методу view
:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ return (new MailMessage)->view( ['emails.name.html', 'emails.name.plain'], ['invoice' => $this->invoice] );}
Сообщения об ошибках
Некоторые уведомления информируют пользователей об ошибках, например о неудачной оплате счета. Вы можете указать, что почтовое сообщение касается ошибки, вызвав метод error
при построении сообщения. При использовании метода error
в почтовом сообщении кнопка призыва к действию будет красной, а не черной:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Message */public function toMail($notifiable){ return (new MailMessage) ->error() ->subject('Notification Subject') ->line('...');}
Настройка отправителя
По умолчанию адрес отправителя/отправителя электронной почты определяется в файле конфигурации config/mail.php
. Однако вы можете указать адрес отправителя для конкретного уведомления, используя метод from
:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ 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; class User extends Authenticatable{ use Notifiable; /** * Route notifications for the mail channel. * * @param \Illuminate\Notifications\Notification $notification * @return array|string */ public function routeNotificationForMail($notification) { // Return email address only... return $this->email_address; // Return email address and name... return [$this->email_address => $this->name]; }}
Настройка темы
По умолчанию тема электронного письма представляет собой имя класса уведомления в формате «Заглавный регистр». Таким образом, если ваш класс уведомлений называется InvoicePaid
, тема электронного письма будет Invoice Paid
. Если вы хотите указать другую тему для сообщения, вы можете вызвать метод subject
при создании сообщения:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ return (new MailMessage) ->subject('Notification Subject') ->line('...');}
Настройка Mailer
По умолчанию уведомление по электронной почте будет отправлено с использованием почтовой программы по умолчанию, определенной в файле конфигурации config/mail.php
. Однако вы можете указать другую почтовую программу во время выполнения, вызвав метод mailer
при создании сообщения:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ return (new MailMessage) ->mailer('postmark') ->line('...');}
Настройка шаблонов
Вы можете изменить шаблон HTML и обычный текст, используемый почтовыми уведомлениями, опубликовав ресурсы пакета уведомлений. После запуска этой команды шаблоны почтовых уведомлений будут расположены в каталоге resources/views/vendor/notifications
:
php artisan vendor:publish --tag=laravel-notifications
Вложения
Чтобы добавить вложения к уведомлению по электронной почте, используйте метод attach
при создании сообщения. Метод attach
принимает абсолютный путь к файлу в качестве первого аргумента:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ return (new MailMessage) ->greeting('Hello!') ->attach('/path/to/file');}
При прикреплении файлов к сообщению вы также можете указать отображаемое имя и/или тип MIME, передав array
в качестве второго аргумента методу attach
:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ return (new MailMessage) ->greeting('Hello!') ->attach('/path/to/file', [ 'as' => 'name.pdf', 'mime' => 'application/pdf', ]);}
В отличие от прикрепления файлов в почтовых объектах, вы не можете прикрепить файл непосредственно с диска с помощью attachFromStorage
. Лучше использовать метод attach
с абсолютным путем к файлу на диске хранения. Кроме того, вы можете вернуть mailable из метода toMail
:
use App\Mail\InvoicePaid as InvoicePaidMailable; /** * Get the mail representation of the notification. * * @param mixed $notifiable * @return Mailable */public function toMail($notifiable){ return (new InvoicePaidMailable($this->invoice)) ->to($notifiable->email) ->attachFromStorage('/path/to/file');}
Вложения необработанных данных
Метод attachData
может использоваться для присоединения необработанной строки байтов в качестве вложения. При вызове метода attachData
вы должны указать имя файла, которое должно быть присвоено вложению:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ return (new MailMessage) ->greeting('Hello!') ->attachData($this->pdf, 'name.pdf', [ 'mime' => 'application/pdf', ]);}
Использование Mailables
При необходимости вы можете вернуть полный отправляемый по почте объект из метода toMail
вашего уведомления. При возврате Mailable
вместо MailMessage
вам нужно будет указать получателя сообщения, используя метод to
почтового объекта:
use App\Mail\InvoicePaid as InvoicePaidMailable; /** * Get the mail representation of the notification. * * @param mixed $notifiable * @return Mailable */public function toMail($notifiable){ return (new InvoicePaidMailable($this->invoice)) ->to($notifiable->email);}
Рассылки и уведомления по запросу
Если вы отправляете уведомление по запросу, экземпляр $notifiable
, переданный методу toMail
, будет экземпляром Illuminate\Notifications\AnonymousNotifiable
, который предлагает routeNotificationFor
, который может использоваться для получения адреса электронной почты, на который должно быть отправлено уведомление по запросу:
use App\Mail\InvoicePaid as InvoicePaidMailable;use Illuminate\Notifications\AnonymousNotifiable; /** * Get the mail representation of the notification. * * @param mixed $notifiable * @return Mailable */public function toMail($notifiable){ $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, который следует использовать. Массив данных, который вы хотите сделать доступным для шаблона, может быть передан в качестве второго аргумента метода:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ $url = url('/invoice/'.$this->invoice->id); return (new MailMessage) ->subject('Invoice Paid') ->markdown('mail.invoice.paid', ['url' => $url]);}
Написание сообщения
Почтовые уведомления Markdown используют комбинацию компонентов Blade и синтаксиса Markdown, которые позволяют легко создавать уведомления, используя предварительно созданные компоненты уведомлений Laravel:
@component('mail::message')# Invoice Paid Your invoice has been paid! @component('mail::button', ['url' => $url])View Invoice@endcomponent Thanks,<br>{{ config('app.name') }}@endcomponent
Компонент кнопки
Компонент кнопки отображает центрированную ссылку кнопки. Компонент принимает два аргумента: url
и необязательный color
. Поддерживаемые цвета: primary
, green
и red
. Вы можете добавить в уведомление любое количество кнопок:
@component('mail::button', ['url' => $url, 'color' => 'green'])View Invoice@endcomponent
Компонент панели
Компонент панели отображает данный блок текста на панели, цвет фона которой немного отличается от остального уведомления. Это позволяет привлечь внимание к заданному блоку текста:
@component('mail::panel')This is the panel content.@endcomponent
Табличный компонент
Компонент таблицы позволяет преобразовать таблицу Markdown в таблицу HTML. Компонент принимает таблицу Markdown в качестве своего содержимого. Выравнивание столбцов таблицы поддерживается с использованием синтаксиса выравнивания таблиц Markdown по умолчанию:
@component('mail::table')| Laravel | Таблица | Пример || ------------- |:-------------:| --------:|| Col 2 is | Centered | $10 || Col 3 is | Right-Aligned | $20 |@endcomponent
Настройка компонентов
Вы можете экспортировать все компоненты уведомлений 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.
Если вы хотите создать совершенно новую тему для компонентов Laravel Markdown, вы можете поместить файл CSS в каталог html/themes
. После присвоения имени и сохранения файла CSS обновите параметр theme
файла конфигурации mail
, чтобы он соответствовал имени вашей новой темы.
Чтобы настроить тему для отдельного уведомления, вы можете вызвать метод theme
при создании почтового сообщения уведомления. Метод theme
принимает имя темы, которое следует использовать при отправке уведомления:
/** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */public function toMail($notifiable){ 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
Форматирование уведомлений базы данных
Если уведомление поддерживает сохранение в таблице базы данных, вы должны определить метод toDatabase
или toArray
в классе уведомления. Этот метод получит объект $notifiable
и должен вернуть простой массив PHP. Возвращенный массив будет закодирован как JSON и сохранен в столбце data
вашей таблицы notifications
. Давайте рассмотрим пример метода toArray
:
/** * Get the array representation of the notification. * * @param mixed $notifiable * @return array */public function toArray($notifiable){ return [ 'invoice_id' => $this->invoice->id, 'amount' => $this->invoice->amount, ];}
toDatabase
против toArray
Метод toArray
также используется каналом broadcast
, чтобы определить, какие данные транслировать в ваш интерфейс на основе JavaScript. Если вы хотите иметь два разных представления массива для каналов database
и broadcast
, вы должны определить метод toDatabase
вместо метода toArray
.
Доступ к уведомлениям
После того, как уведомления сохранены в базе данных, вам нужен удобный способ доступа к ним из уведомляемых объектов. Трейт Illuminate\Notifications\Notifiable
, включенный в стандартную модель Laravel App\Models\User
, включает в себя notifications
Eloquent relationship, которая возвращает уведомления для объекта. Чтобы получать уведомления, вы можете получить доступ к этому методу, как и к любому другому отношению 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;}
{tip} Чтобы получить доступ к вашим уведомлениям из вашего клиента 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 event broadcasting, позволяя вашему внешнему интерфейсу на JavaScript перехватывать уведомления в режиме реального времени. Если уведомление поддерживает широковещательную рассылку, вы можете определить метод toBroadcast
в классе уведомлений. Этот метод получит объект $notifiable
и должен вернуть экземпляр BroadcastMessage
. Если метод toBroadcast
не существует, для сбора данных, которые должны быть переданы, будет использоваться метод toArray
. Возвращаемые данные будут закодированы как JSON и переданы в ваш интерфейс на основе JavaScript. Давайте рассмотрим пример метода toBroadcast
:
use Illuminate\Notifications\Messages\BroadcastMessage; /** * Get the broadcastable representation of the notification. * * @param mixed $notifiable * @return BroadcastMessage */public function toBroadcast($notifiable){ 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
в классе уведомлений:
use Illuminate\Notifications\Messages\BroadcastMessage; /** * Get the type of the notification being broadcast. * * @return string */public function broadcastType(){ 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; /** * The channels the user receives notification broadcasts on. * * @return string */ public function receivesBroadcastNotificationsOn() { return 'users.'.$this->id; }}
SMS-уведомления
Предварительные условия
Отправка SMS-уведомлений в Laravel поддерживается Vonage (ранее известной как Nexmo). Прежде чем вы сможете отправлять уведомления через Vonage, вам необходимо установить Composer пакеты laravel/nexmo-notification-channel
и nexmo/laravel
composer require laravel/nexmo-notification-channel nexmo/laravel
Пакет nexmo/laravel
включает в себя собственный файл конфигурации. Однако вы не обязаны экспортировать этот файл конфигурации в свое собственное приложение. Вы можете просто использовать переменные среды NEXMO_KEY
и NEXMO_SECRET
, чтобы установить открытый и секретный ключ Vonage.
Затем вам нужно будет добавить запись конфигурации nexmo
в ваш файл конфигурации config/services.php
. Вы можете скопировать приведенный ниже пример конфигурации, чтобы начать:
'nexmo' => [ 'sms_from' => '15556666666',],
Опция sms_from
— это номер телефона, с которого будут отправляться ваши SMS-сообщения. Вы должны сгенерировать номер телефона для своего приложения в панели управления Vonage.
Форматирование SMS-уведомлений
Если уведомление поддерживает отправку в виде SMS, вы должны определить метод toNexmo
в классе уведомлений. Этот метод получит объект $notifiable
и должен вернуть экземпляр Illuminate\Notifications\Messages\NexmoMessage
:
/** * Get the Vonage / SMS representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\NexmoMessage */public function toNexmo($notifiable){ return (new NexmoMessage) ->content('Your SMS message content');}
Юникод-контент
Если ваше SMS-сообщение будет содержать символы Юникода, вам следует вызвать метод unicode
при создании экземпляра NexmoMessage
:
/** * Get the Vonage / SMS representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\NexmoMessage */public function toNexmo($notifiable){ return (new NexmoMessage) ->content('Your unicode message') ->unicode();}
Форматирование уведомлений о шорткодах
Laravel также поддерживает отправку уведомлений с коротким кодом, которые представляют собой заранее определенные шаблоны сообщений в вашей учетной записи Vonage. Чтобы отправить SMS-уведомление с коротким кодом, вы должны определить метод toShortcode
в своем классе уведомлений. Из этого метода вы можете вернуть массив, указывающий тип уведомления (alert
, 2fa
или marketing
), а также пользовательские значения, которые будут заполнять шаблон:
/** * Get the Vonage / Shortcode representation of the notification. * * @param mixed $notifiable * @return array */public function toShortcode($notifiable){ return [ 'type' => 'alert', 'custom' => [ 'code' => 'ABC123', ], ];}
{tip} Как и маршрутизация SMS-уведомлений, вы должны реализовать метод
routeNotificationForShortcode
в своей уведомляемой модели.
Настройка номера "From"
Если вы хотите отправлять некоторые уведомления с номера телефона, который отличается от номера телефона, указанного в вашем файле config/services.php
, вы можете вызвать метод from
для экземпляра NexmoMessage
:
/** * Get the Vonage / SMS representation of the notification. * * @param mixed $notifiable * @return NexmoMessage */public function toNexmo($notifiable){ return (new NexmoMessage) ->content('Your SMS message content') ->from('15554443333');}
Добавление клиентской ссылки
Если вы хотите отслеживать затраты на пользователя, команду или клиента, вы можете добавить в уведомление «ссылку на клиента». Vonage позволит вам создавать отчеты, используя эту ссылку на клиента, чтобы вы могли лучше понять использование SMS конкретным клиентом. Ссылка клиента может быть любой строкой до 40 символов:
/** * Get the Vonage / SMS representation of the notification. * * @param mixed $notifiable * @return NexmoMessage */public function toNexmo($notifiable){ return (new NexmoMessage) ->clientReference((string) $notifiable->id) ->content('Your SMS message content');}
Маршрутизация SMS-уведомлений
Чтобы перенаправлять уведомления Vonage на правильный номер телефона, определите метод routeNotificationForNexmo
для вашего уведомляемого объекта:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable;use Illuminate\Notifications\Notifiable; class User extends Authenticatable{ use Notifiable; /** * Route notifications for the Nexmo channel. * * @param \Illuminate\Notifications\Notification $notification * @return string */ public function routeNotificationForNexmo($notification) { return $this->phone_number; }}
Уведомления в Slack
Предварительные условия
Прежде чем вы сможете отправлять уведомления через Slack, вы должны установить канал уведомлений Slack через Composer:
composer require laravel/slack-notification-channel
Вам также потребуется создать Slack App для своей команды. После создания приложения вы должны настроить "Incoming Webhook" для рабочей области. Затем Slack предоставит вам URL-адрес веб-перехватчика, который вы можете использовать при маршрутизации уведомлений Slack.
Форматирование уведомлений Slack
Если уведомление поддерживает отправку в виде сообщения Slack, вы должны определить метод toSlack
в классе уведомлений. Этот метод получит сущность $notifiable
и должен вернуть экземпляр Illuminate\Notifications\Messages\SlackMessage
. Сообщения Slack могут содержать текстовое содержимое, а также «вложение», которое форматирует дополнительный текст или массив полей. Давайте взглянем на базовый пример toSlack
:
/** * Get the Slack representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\SlackMessage */public function toSlack($notifiable){ return (new SlackMessage) ->content('One of your invoices has been paid!');}
Вложения Slack
Вы также можете добавлять «вложения» к сообщениям Slack. Вложения предоставляют более широкие возможности форматирования, чем простые текстовые сообщения. В этом примере мы отправим уведомление об исключении, которое произошло в приложении, включая ссылку для просмотра более подробной информации об исключении:
/** * Get the Slack representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\SlackMessage */public function toSlack($notifiable){ $url = url('/exceptions/'.$this->exception->id); return (new SlackMessage) ->error() ->content('Whoops! Something went wrong.') ->attachment(function ($attachment) use ($url) { $attachment->title('Exception: File Not Found', $url) ->content('File [background.jpg] was not found.'); });}
Вложения также позволяют указать массив данных, которые должны быть представлены пользователю. Данные будут представлены в виде таблицы для удобства чтения:
/** * Get the Slack representation of the notification. * * @param mixed $notifiable * @return SlackMessage */public function toSlack($notifiable){ $url = url('/invoices/'.$this->invoice->id); return (new SlackMessage) ->success() ->content('One of your invoices has been paid!') ->attachment(function ($attachment) use ($url) { $attachment->title('Invoice 1322', $url) ->fields([ 'Title' => 'Server Expenses', 'Amount' => '$1,234', 'Via' => 'American Express', 'Was Overdue' => ':-1:', ]); });}
Содержимое прикрепленного файла Markdown
Если некоторые из ваших полей вложений содержат Markdown, вы можете использовать метод markdown
, чтобы указать Slack анализировать и отображать данные поля вложений в виде текста в формате Markdown. Значения, принимаемые этим методом: pretext
, text
и/или fields
. Дополнительные сведения о форматировании вложений Slack смотрите в документации Slack API:
/** * Get the Slack representation of the notification. * * @param mixed $notifiable * @return SlackMessage */public function toSlack($notifiable){ $url = url('/exceptions/'.$this->exception->id); return (new SlackMessage) ->error() ->content('Whoops! Something went wrong.') ->attachment(function ($attachment) use ($url) { $attachment->title('Exception: File Not Found', $url) ->content('File [background.jpg] was *not found*.') ->markdown(['text']); });}
Маршрутизация Slack-уведомлений
Чтобы направить уведомления Slack в соответствующую команду и канал Slack, определите метод routeNotificationForSlack
для вашего объекта, который может быть уведомлен. Это должно вернуть URL-адрес веб-перехватчика, на который должно быть доставлено уведомление. URL-адреса веб-перехватчиков можно сгенерировать, добавив службу «Входящий веб-перехватчик» в вашу команду Slack:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable;use Illuminate\Notifications\Notifiable; class User extends Authenticatable{ use Notifiable; /** * Route notifications for the Slack channel. * * @param \Illuminate\Notifications\Notification $notification * @return string */ public function routeNotificationForSlack($notification) { return 'https://hooks.slack.com/services/...'; }}
Локализация уведомлений
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{ /** * Get the user's preferred locale. * * @return string */ public function preferredLocale() { return $this->locale; }}
После того, как вы реализовали интерфейс, Laravel будет автоматически использовать предпочтительную локаль при отправке уведомлений и почтовых сообщений в модель. Поэтому нет необходимости вызывать метод locale
при использовании этого интерфейса:
$user->notify(new InvoicePaid($invoice));
Уведомления о событиях
Событие отправки уведомления
При отправке уведомления система уведомлений отправляет Illuminate\Notifications\Events\NotificationSending
событие. Он содержит «уведомляемый» объект и сам экземпляр уведомления. Вы можете зарегистрировать слушателей для этого события в EventServiceProvider
вашего приложения:
/** * The event listener mappings for the application. * * @var array */protected $listen = [ 'Illuminate\Notifications\Events\NotificationSending' => [ 'App\Listeners\CheckNotificationStatus', ],];
Уведомление не будет отправлено, если прослушиватель событий для события NotificationSending
возвращает false
из своего метода handle
:
use Illuminate\Notifications\Events\NotificationSending; /** * Handle the event. * * @param \Illuminate\Notifications\Events\NotificationSending $event * @return void */public function handle(NotificationSending $event){ return false;}
В прослушивателе событий вы можете получить доступ к свойствам события notifiable
, notification
и channel
, чтобы узнать больше о получателе уведомления или о самом уведомлении:
/** * Handle the event. * * @param \Illuminate\Notifications\Events\NotificationSending $event * @return void */public function handle(NotificationSending $event){ // $event->channel // $event->notifiable // $event->notification}
Событие отправлено уведомлением
При отправке уведомления система уведомлений отправляет Illuminate\Notifications\Events\NotificationSent
событие. Он содержит «уведомляемый» объект и сам экземпляр уведомления. Вы можете зарегистрировать слушателей для этого события в вашем EventServiceProvider
:
/** * The event listener mappings for the application. * * @var array */protected $listen = [ 'Illuminate\Notifications\Events\NotificationSent' => [ 'App\Listeners\LogNotification', ],];
{tip} После регистрации слушателей в
EventServiceProvider
, используйте Artisan-командуevent:generate
для быстрого создания классов слушателей.
В прослушивателе событий вы можете получить доступ к свойствам событий notifiable
, notification
, channel
и response
, чтобы узнать больше о получателе уведомления или самом уведомлении:
/** * Handle the event. * * @param \Illuminate\Notifications\Events\NotificationSent $event * @return void */public function handle(NotificationSent $event){ // $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{ /** * Send the given notification. * * @param mixed $notifiable * @param \Illuminate\Notifications\Notification $notification * @return void */ public function send($notifiable, Notification $notification) { $message = $notification->toVoice($notifiable); // Send notification to the $notifiable instance... }}
После определения класса канала уведомлений вы можете вернуть имя класса из метода 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; /** * Get the notification channels. * * @param mixed $notifiable * @return array|string */ public function via($notifiable) { return [VoiceChannel::class]; } /** * Get the voice representation of the notification. * * @param mixed $notifiable * @return VoiceMessage */ public function toVoice($notifiable) { // ... }}