Может войдёшь?
Черновики Написать статью Профиль

Уведомления

перевод документация 5.х

  1. 1. Введение
  2. 2. Создание уведомлений
  3. 3. Отправка уведомлений
    1. 3.1. С помощью типажа Notifiable
    2. 3.2. С помощью фасада Notification
    3. 3.3. Указание каналов доставки
    4. 3.4. Постановка уведомлений в очередь
  4. 4. Почтовые уведомления
    1. 4.1. Форматирование почтовых сообщений
    2. 4.2. Изменение получателя
    3. 4.3. Изменение темы
    4. 4.4. Изменение шаблонов
    5. 4.5. Сообщения об ошибках
  5. 5. Уведомления для БД
    1. 5.1. Требования
    2. 5.2. Форматирование уведомлений для БД
    3. 5.3. Обращение к уведомлениям
    4. 5.4. Пометка прочитанного уведомления
  6. 6. Вещание уведомлений
    1. 6.1. Требования
    2. 6.2. Форматирование уведомлений для вещания
    3. 6.3. Прослушивание уведомлений
  7. 7. SMS уведомления
    1. 7.1. Требования
    2. 7.2. Форматирование SMS уведомлений
    3. 7.3. Изменение номера «From»
    4. 7.4. Изменение получателя SMS
  8. 8. Уведомления Slack
    1. 8.1. Требования
    2. 8.2. Форматирование уведомлений Slack
    3. 8.3. Изменение получателя уведомлений Slack
  9. 9. События уведомлений
  10. 10. Другие каналы
Этот перевод актуален для англоязычной документации на (ветка 5.3). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

Вдобавок к поддержке отправки email Laravel поддерживает отправку уведомлений по разным каналам доставки, включая почту, SMS (через Nexmo) и Slack. Уведомления также можно сохранять в БД, чтобы выводить их в вашем веб-интерфейсе.

Обычно уведомления — это короткие информационные сообщения для пользователей о том, что в приложении что-то произошло. Например, при создании биллингового приложения вы можете посылать пользователям уведомления «Счёт оплачен» по email и SMS каналам.

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

В Laravel каждое уведомление представлено одним классом (обычно хранящимся в папке app/Notifications). Если у вас в приложении нет такой папки — не беда, она будет создана для вас при выполнении Artisan-команды shmake:notification:

shphp artisan make:notification InvoicePaid

Эта команда поместит новый класс уведомления в папку app/Notifications. Класс каждого уведомления содержит метод PHPvia() и разное число методов создания сообщения (таких как PHPtoMail() и PHPtoDatabase()), которые конвертируют уведомление в сообщение, оптимизированное под определённый канал.

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

С помощью типажа Notifiable

Уведомления можно отправлять двумя способами: используя метод PHPnotify() типажа Notifiable, или используя фасад Notification. Сначала попробуем типаж Notifiable. Этот типаж использует стандартной моделью App\User и содержит один метод, который можно использовать для отправки уведомлений — PHPnotify(). Этот метод принимает экземпляр уведомления:

PHP
use App\Notifications\InvoicePaid;

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

Запомните, вы можете использовать типаж Illuminate\Notifications\Notifiable на любой из ваших моделей. Никто не принуждает вас включать его только в модель User.

С помощью фасада Notification

Или вы можете отправлять уведомления через фасад Notification. Это особенно полезно при необходимости отправки уведомления нескольким уведомляемым сущностям, таким как коллекция пользователей. Для отправки уведомлений через фасад передайте все уведомляемые сущности и экземпляр уведомления в метод PHPsend():

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

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

Класс каждого уведомления содержит метод PHPvia(), который определяет, по каким каналам будет доставляться уведомление. Изначально уведомления можно отправлять через каналы mail, database, broadcast, nexmo и slack.

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

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

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

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

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

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

PHP
<?php

namespace App\Notifications;

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

class 
InvoicePaid extends Notification implements ShouldQueue
{
  use 
Queueable;

  
// ...
}

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

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

Если вы хотите отложить доставку уведомления, вы можете прицепить метод PHPdelay() к созданию экземпляра уведомления:

PHP
$when Carbon::now()->addMinutes(10);

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

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

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

Чтобы уведомление поддерживало отправку по email, вам надо определить метод PHPtoMail() в классе уведомления. Этот метод получает сущность PHP$notifiable и должен возвращать экземпляр Illuminate\Notifications\Messages\MailMessage. Почтовые сообщения могут содержать строки текста, а также «вызовы действий». Давайте посмотрим на пример метода PHPtoMail():

PHP
/**
 * Получить представление уведомления в виде письма.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
  
$url url('/invoice/'.$this->invoice->id);

  return (new 
MailMessage)
            ->
greeting('Привет!')
            ->
line('Один из ваших счетов оплачен!')
            ->
action('Посмотреть счёт'$url)
            ->
line('Спасибо за использование нашего приложения!');
}

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

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

/packages/proger/habravel/uploads/756-notification-example.png

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

Изменение получателя

При отправке уведомлений по каналу mail система уведомлений будет автоматически искать свойство PHPemail в уведомляемой сущности. Вы можете изменить адрес email, используемый для доставки уведомления, определив метод PHProuteNotificationForMail() на сущности:

PHP
<?php

namespace App;

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

class 
User extends Authenticatable
{
  use 
Notifiable;

  
/**
   * Направление уведомлений для почтового канала.
   *
   * @return string
   */
  
public function routeNotificationForMail()
  {
    return 
$this->email_address;
  }
}

Изменение темы

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

PHP
/**
 * Получить представление уведомления в виде письма.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
  return (new 
MailMessage)
            ->
subject('Тема уведомления')
            ->
line('...');
}

Изменение шаблонов

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

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

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

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

PHP
/**
 * Получить представление уведомления в виде письма.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Message
 */
public function toMail($notifiable)
{
  return (new 
MailMessage)
            ->
error()
            ->
subject('Тема уведомления')
            ->
line('...');
}

Уведомления для БД

Требования

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

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

shphp artisan notifications:table

php artisan migrate

Форматирование уведомлений для БД

Чтобы уведомление поддерживало сохранение в БД, вам надо определить метод PHPtoDatabase() или метод PHPtoArray() в классе уведомления. Этот метод получает сущность PHP$notifiable и должен возвращать простой PHP-массив. Возвращённый массив будет закодирован в JSON и сохранён в столбец data вашей таблицы notifications. Давайте посмотрим на пример метода PHPtoArray():

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

PHPtoDatabase() или PHPtoArray()

Метод PHPtoArray() также используется каналом broadcast для определения того, какие данные вещать вашему JavaScript-клиенту. Если вы хотите иметь два разных представления в виде массива для каналов database и broadcast, вам надо определить метод PHPtoDatabase() вместо метода PHPtoArray().

Обращение к уведомлениям

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

PHP
$user App\User::find(1);

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

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

PHP
$user App\User::find(1);

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

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

Пометка прочитанного уведомления

Обычно надо отметить уведомление «прочитанным», когда пользователь просмотрел его. Типаж Illuminate\Notifications\Notifiable предоставляет метод PHPmarkAsRead(), который изменяет поле read_at записи уведомления в БД:

PHP
$user App\User::find(1);

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

Но вместо перебора всех уведомлений вы можете использовать метод PHPmarkAsRead() прямо на коллекции уведомлений:

PHP
$user->unreadNotifications->markAsRead();

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

PHP
$user App\User::find(1);

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

Само собой, вы можете удалить уведомления из таблицы целиком:

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

Вещание уведомлений

Требования

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

Форматирование уведомлений для вещания

Канал broadcast вещает уведомления с помощью сервисов вещания событий Laravel, позволяя вашему JavaScript-клиенту получать уведомления в реальном времени. Чтобы уведомление поддерживало вещание, вам надо определить метод PHP()toBroadcast или метод PHP()toArray в классе уведомления. Этот метод принимает сущность PHP$notifiable и должен возвращать простой PHP-массив. Возвращённый массив будет закодирован в JSON и будет вещаться JavaScript-клиенту. Давайте посмотрим на пример метода PHPtoArray():

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

В добавок к указанным вами данным вещание уведомлений будет также содержать поле type, содержащее имя класса уведомления.

PHPtoBroadcast() или PHPtoArray()

Метод PHPtoArray() также используется каналом database для определения того, какие данные сохранять в таблицу БД. Если вы хотите иметь два разных представления в виде массива для каналов database и broadcast, вам надо определить метод PHPtoBroadcast() вместо метода PHPtoArray().

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

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

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

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

Требования

Отправка SMS уведомлений в Laravel обеспечивается с помощью Nexmo. Перед отправкой уведомлений через Nexmo, вам надо установить Composer-пакет nexmo/client и добавить несколько параметров в файл настроек config/services.php. Вы можете скопировать этот пример настройки:

conf'nexmo' => [
  'key' => env('NEXMO_KEY'),
  'secret' => env('NEXMO_SECRET'),
  'sms_from' => '15556666666',
],

Параметр sms_from — телефонный номер, с которого будут отправляться ваши SMS сообщения. Вам надо сгенерировать этот номер для своего приложения в панели управления Nexmo.

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

Чтобы уведомление поддерживало отправку по SMS, вам надо определить метод PHP()toNexmo в классе уведомления. Этот метод принимает сущность PHP$notifiable и должен возвращать экземпляр Illuminate\Notifications\Messages\NexmoMessage:

PHP
/**
 * Получить представления уведомления в виде Nexmo / SMS.
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
  return (new 
NexmoMessage)
            ->
content('Содержимое вашего SMS сообщения');
}

Изменение номера «From»

Если вы хотите отправлять некоторые уведомления с номера, отличающегося от указанного в вашем файле config/services.php, вы можете использовать метод PHPfrom() на экземпляре NexmoMessage:

PHP
/**
 * Получить представления уведомления в виде Nexmo / SMS.
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
  return (new 
NexmoMessage)
            ->
content('Содержимое вашего SMS сообщения')
            ->
from('15554443333');
}

Изменение получателя SMS

При отправке уведомлений по каналу nexmo система уведомлений автоматически будет искать атрибут phone_number в уведомляемой сущности. Если вы хотите изменить телефонный номер для доставки уведомления, определите метод PHProuteNotificationForNexmo() на сущности:

PHP
<?php

namespace App;

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

class 
User extends Authenticatable
{
  use 
Notifiable;

  
/**
   * Направление уведомлений для канала Nexmo.
   *
   * @return string
   */
  
public function routeNotificationForNexmo()
  {
    return 
$this->phone;
  }
}

Уведомления Slack

Требования

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

shcomposer require guzzlehttp/guzzle

Также вам надо настроить интеграцию с «Входящим Webhook» для вашей Slack-команды. Эта интеграция предоставит вам URL, который можно использовать при направлении уведомлений Slack.

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

Чтобы уведомление поддерживало отправку в виде Slack-сообщения, вам надо определить метод PHP()toSlack в классе уведомления. Этот метод принимает сущность PHP$notifiable и должен возвращать экземпляр Illuminate\Notifications\Messages\SlackMessage. В Slack-сообщении может быть текстовое содержимое, а также «attachment» (вложение), которое форматирует дополнительный текст или массив полей. Давайте посмотрим на пример метода PHPtoSlack():

PHP
/**
 * Получить представление уведомления для Slack.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
  return (new 
SlackMessage)
            ->
content('Один из ваших счетов оплачен!');
}

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

/packages/proger/habravel/uploads/756-basic-slack-notification.png

Вложения Slack

Также вы можете добавлять вложения в Slack-сообщения. Вложения обеспечивают более широкие возможности форматирования, чем простые текстовые сообщения. В этом примере мы отправим уведомление об ошибке — об исключении в приложении со ссылкой для просмотра подробной информации об исключении:

PHP
/**
 * Получить представление уведомления для Slack.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
  
$url url('/exceptions/'.$this->exception->id);

  return (new 
SlackMessage)
            ->
error()
            ->
content('Упс! Что-то пошло не так.')
            ->
attachment(function ($attachment) use ($url) {
              
$attachment->title('Исключение: файл не найден'$url)
                       ->
content('Файл [background.jpg] не найден.');
            });
}

Этот пример создаст такое Slack-сообщение:

/packages/proger/habravel/uploads/756-basic-slack-attachment.png

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

PHP
/**
 * Получить представление уведомления для Slack.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
  
$url url('/invoices/'.$this->invoice->id);

  return (new 
SlackMessage)
              ->
success()
              ->
content('Один из ваших счетов оплачен!')
              ->
attachment(function ($attachment) use ($url) {
                
$attachment->title('Счёт 1322'$url)
                          ->
fields([
                            
'Title' => 'Оплата сервера',
                            
'Amount' => '$1,234',
                            
'Via' => 'American Express',
                            
'Was Overdue' => ':-1:',
                          ]);
              });
}

Этот пример создаст такое Slack-сообщение:

/packages/proger/habravel/uploads/756-slack-fields-attachment.png

Изменение отправителя и получателя

Вы можете использовать методы PHPfrom() и PHPto() для изменения отправителя и получателя. Метод PHPfrom() принимает имя пользователя и идентификатор emoji, а метод PHPto() принимает имя канала или пользователя:

PHP
/**
 * Получить представление уведомления для Slack.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
  return (new 
SlackMessage)
            ->
from('Призрак'':ghost:')
            ->
to('#other')
            ->
content('Это будет отправлено #other');
}

Изменение получателя уведомлений Slack

Для направления уведомлений Slack в нужное место определите метод PHProuteNotificationForSlack() на уведомляемой сущности. Он должен возвращать URL того webhook, которому должно быть доставлено уведомление. Webhook URL можно генерировать с помощью добавления сервиса «Входящий Webhook» в вашу Slack-команду:

PHP
<?php

namespace App;

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

class 
User extends Authenticatable
{
  use 
Notifiable;

  
/**
   * Направление уведомлений для канала Slack.
   *
   * @return string
   */
  
public function routeNotificationForSlack()
  {
    return 
$this->slack_webhook_url;
  }
}

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

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

PHP
/**
 * Привязка слушателей события для приложения.
 *
 * @var array
 */
protected $listen = [
  
'Illuminate\Notifications\Events\NotificationSent' => [
    
'App\Listeners\LogNotification',
  ],
];

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

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

PHP
/**
 * Обработка события.
 *
 * @param  NotificationSent  $event
 * @return void
 */
public function handle(NotificationSent $event)
{
  
// $event->channel
  // $event->notifiable
  // $event->notification
}

Другие каналы

Laravel поставляется с набором каналов для уведомлений, но вы можете написать свой собственный драйвер для доставки уведомлений по другим каналам. В Laravel это делается просто. Сначала определите класс с методом PHPsend(). Метод должен получать два аргумента: PHP$notifiable и PHP$notification:

PHP
<?php

namespace App\Channels;

use 
Illuminate\Notifications\Notification;

class 
VoiceChannel
{
  
/**
   * Отправить данное уведомление.
   *
   * @param  mixed  $notifiable
   * @param  \Illuminate\Notifications\Notification  $notification
   * @return void
   */
  
public function send($notifiableNotification $notification)
  {
            
$message $notification->toVoice($notifiable);

            
// Send notification to the $notifiable instance...
        
}
    }

После определения класса канала уведомлений вы можете просто вернуть имя класса из метода PHPvia() любого из ваших уведомлений:

PHP
<?php

namespace App\Notifications;

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

class 
InvoicePaid extends Notification
{
  use 
Queueable;

  
/**
   * Получить каналы уведомлений.
   *
   * @param  mixed  $notifiable
   * @return array|string
   */
  
public function via($notifiable)
  {
    return [
VoiceChannel::class];
  }

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

Как вы считаете, полезен ли этот материал? Да Нет

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.