From 1f92db702c95c3a2d60265be6a3d9cde5ba495fd Mon Sep 17 00:00:00 2001 From: ReWiG Date: Sun, 6 Jul 2025 11:57:57 +0300 Subject: [PATCH] Update notifications.md --- notifications.md | 1788 ++++++++++++++++++++++++++-------------------- 1 file changed, 1021 insertions(+), 767 deletions(-) diff --git a/notifications.md b/notifications.md index b90ee354..24b2a885 100644 --- a/notifications.md +++ b/notifications.md @@ -1,5 +1,5 @@ --- -git: e589c65973ef8668df016fc27f4f37e07d8abf26 +git: 8f8374ffe17babb2218ea0faec68d135f47e83de --- # Уведомления @@ -30,23 +30,27 @@ php artisan make:notification InvoicePaid Уведомления могут быть отправлены двумя способами: с использованием метода `notify` трейта `Notifiable` или с помощью [фасада](/docs/{{version}}/facades) `Notification`. Трейт `Notifiable` по умолчанию содержится в модели `App\Models\User` вашего приложения: - notify(new InvoicePaid($invoice)); +$user->notify(new InvoicePaid($invoice)); +``` > [!NOTE] > Помните, что вы можете использовать трейт `Notifiable` в любой из ваших моделей. Вы не ограничены использованием его только в модели `User`. @@ -56,13 +60,17 @@ php artisan make:notification InvoicePaid Как вариант, вы можете отправлять уведомления через [фасад](/docs/{{version}}/facades) `Notification`. Этот подход полезен при отправке уведомления нескольким уведомляемым объектам, например группе пользователей. Чтобы отправлять уведомления с помощью фасада, передайте все уведомляемые сущности и экземпляр уведомления методу `send`: - use Illuminate\Support\Facades\Notification; +```php +use Illuminate\Support\Facades\Notification; - Notification::send($users, new InvoicePaid($invoice)); +Notification::send($users, new InvoicePaid($invoice)); +``` Вы также можете немедленно отправлять уведомления, используя метод `sendNow`. Этот метод немедленно отправит уведомление, даже если оно реализует интерфейс `ShouldQueue`: - Notification::sendNow($developers, new DeploymentCompleted($deployment)); +```php +Notification::sendNow($developers, new DeploymentCompleted($deployment)); +``` ### Определение каналов доставки @@ -74,15 +82,17 @@ php artisan make:notification InvoicePaid Метод `via` получает экземпляр `$notifiable`, представляющий экземпляр класса, которому отправляется уведомление. Вы можете использовать `$notifiable`, чтобы определить, по каким каналам должно доставляться уведомление: - /** - * Получить каналы доставки уведомлений. - * - * @return array - */ - public function via(object $notifiable): array - { - return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database']; - } +```php +/** + * Получить каналы доставки уведомлений. + * + * @return array + */ +public function via(object $notifiable): array +{ + return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database']; +} +``` ### Очереди уведомлений @@ -92,24 +102,28 @@ php artisan make:notification InvoicePaid Отправка уведомлений может занять время, особенно если каналу необходимо выполнить внешний вызов API для доставки уведомления. Чтобы ускорить время отклика вашего приложения, поместите ваше уведомление в очередь, добавив интерфейс `ShouldQueue` и трейт `Queueable` в ваш класс. Интерфейс и трейт уже импортированы для всех уведомлений, сгенерированных с помощью команды `make:notification`, поэтому вы можете сразу добавить их в свой класс уведомлений: - notify(new InvoicePaid($invoice)); +```php +$user->notify(new InvoicePaid($invoice)); +``` При постановке уведомлений в очередь для каждого получателя и комбинации каналов будет создана задача в очереди. Например, если ваше уведомление имеет три получателя и два канала, в очередь будет отправлено шесть задач. @@ -118,32 +132,38 @@ php artisan make:notification InvoicePaid Если вы хотите отложить доставку уведомления, то вы можете вызвать метод `delay` экземпляра уведомления: - $delay = now()->addMinutes(10); +```php +$delay = now()->addMinutes(10); - $user->notify((new InvoicePaid($invoice))->delay($delay)); +$user->notify((new InvoicePaid($invoice))->delay($delay)); +``` Вы можете передать массив методу `delay`, чтобы указать величину задержки для определенных каналов: - $user->notify((new InvoicePaid($invoice))->delay([ - 'mail' => now()->addMinutes(5), - 'sms' => now()->addMinutes(10), - ])); +```php +$user->notify((new InvoicePaid($invoice))->delay([ + 'mail' => now()->addMinutes(5), + 'sms' => now()->addMinutes(10), +])); +``` Как альтернативу, вы можете определить метод `withDelay` непосредственно в классе уведомления. Метод `withDelay` должен возвращать массив с именами каналов и значениями задержек: - /** - * Определение задержки доставки уведомления. - * - * @return array - */ - public function withDelay(object $notifiable): array - { - return [ - 'mail' => now()->addMinutes(5), - 'sms' => now()->addMinutes(10), - // Задержки для других каналов - ]; - } +```php +/** + * Определение задержки доставки уведомления. + * + * @return array + */ +public function withDelay(object $notifiable): array +{ + return [ + 'mail' => now()->addMinutes(5), + 'sms' => now()->addMinutes(10), + // Задержки для других каналов + ]; +} +``` Этот подход позволяет централизованно управлять задержками для разных каналов в одном месте, что упрощает поддержку и модификацию кода. @@ -152,80 +172,88 @@ php artisan make:notification InvoicePaid По умолчанию, уведомления, помещенные в очередь, будут использовать стандартное соединение очереди вашего приложения. Если вы хотите указать другое соединение, которое должно использоваться для конкретного уведомления, вы можете вызвать метод `onConnection` в конструкторе вашего уведомления: - onConnection('redis'); - } - } +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; -Или, если вы хотите указать конкретное соединение с очередью, которое должно использоваться для каждого канала уведомлений, поддерживаемого уведомлением, вы можете определить метод `viaConnections` в вашем уведомлении. Этот метод должен возвращать массив пар имя канала / имя соединения с очередью: +class InvoicePaid extends Notification implements ShouldQueue +{ + use Queueable; /** - * Определение, какое соединение должно использоваться для каждого канала уведомлений. - * - * @return array + * Создание нового экземпляра уведомления. */ - public function viaConnections(): array + public function __construct() { - return [ - 'mail' => 'redis', - 'database' => 'sync', - ]; + $this->onConnection('redis'); } +} +``` + +Или, если вы хотите указать конкретное соединение с очередью, которое должно использоваться для каждого канала уведомлений, поддерживаемого уведомлением, вы можете определить метод `viaConnections` в вашем уведомлении. Этот метод должен возвращать массив пар имя канала / имя соединения с очередью: + +```php +/** + * Определение, какое соединение должно использоваться для каждого канала уведомлений. + * + * @return array + */ +public function viaConnections(): array +{ + return [ + 'mail' => 'redis', + 'database' => 'sync', + ]; +} +``` #### Изменение очереди канала уведомлений Если вы хотите указать конкретную очередь, которая должна использоваться для каждого канала уведомления, поддерживаемого уведомлением, то вы можете определить метод `viaQueues` в своем уведомлении. Этот метод должен возвращать массив пар имя канала / имя очереди: - /** - * Определить, какие очереди следует использовать для каждого канала уведомления. - * - * @return array - */ - public function viaQueues(): array - { - return [ - 'mail' => 'mail-queue', - 'slack' => 'slack-queue', - ]; - } +```php +/** + * Определить, какие очереди следует использовать для каждого канала уведомления. + * + * @return array + */ +public function viaQueues(): array +{ + return [ + 'mail' => 'mail-queue', + 'slack' => 'slack-queue', + ]; +} +``` #### Посредник для уведомлений в очереди Уведомления в очереди могут определять промежуточное программное обеспечение [так же, как задания в очереди](/docs/{{version}}/queues#job-middleware). Для начала определите метод `middleware` в своем классе уведомлений. Метод `middleware` получит переменные `$notifying` и `$channel`, которые позволят вам настроить возвращаемое промежуточное программное обеспечение в зависимости от места назначения уведомления: - use Illuminate\Queue\Middleware\RateLimited; +```php +use Illuminate\Queue\Middleware\RateLimited; - /** - * Get the middleware the notification job should pass through. - * - * @return array - */ - public function middleware(object $notifiable, string $channel) - { - return match ($channel) { - 'email' => [new RateLimited('postmark')], - 'slack' => [new RateLimited('slack')], - default => [], - }; - } +/** + * Get the middleware the notification job should pass through. + * + * @return array + */ +public function middleware(object $notifiable, string $channel) +{ + return match ($channel) { + 'email' => [new RateLimited('postmark')], + 'slack' => [new RateLimited('slack')], + default => [], + }; +} +``` #### Уведомления в очереди и транзакции в базе данных @@ -234,32 +262,36 @@ php artisan make:notification InvoicePaid Если для параметра `after_commit` конфигурации вашего соединения с очередью установлено значение `false`, то вы все равно можете указать, что конкретное отложенное уведомление должно быть отправлено после того, как все открытые транзакции базы данных были зафиксированы, путем вызова метода `afterCommit` при отправке уведомления: - use App\Notifications\InvoicePaid; +```php +use App\Notifications\InvoicePaid; - $user->notify((new InvoicePaid($invoice))->afterCommit()); +$user->notify((new InvoicePaid($invoice))->afterCommit()); +``` В качестве альтернативы вы можете вызвать метод`afterCommit` из конструктора вашего уведомления: - afterCommit(); - } + /** + * Create a new notification instance. + */ + public function __construct() + { + $this->afterCommit(); } +} +``` > [!NOTE] > Чтобы узнать больше о том, как обойти эти проблемы, просмотрите документацию, касающуюся [заданий в очереди и транзакций базы данных](/docs/{{version}}/queues#jobs-and-database-transactions). @@ -271,40 +303,48 @@ php artisan make:notification InvoicePaid Однако, если вы хотите окончательно определить, следует ли отправлять уведомление в очереди после его обработки работником очереди, вы можете определить метод `shouldSend` в классе уведомлений. Если этот метод возвращает `false`, уведомление не будет отправлено: - /** - * Определите, нужно ли отправлять уведомление. - */ - public function shouldSend(object $notifiable, string $channel): bool - { - return $this->invoice->isPaid(); - } +```php +/** + * Определите, нужно ли отправлять уведомление. + */ +public function shouldSend(object $notifiable, string $channel): bool +{ + return $this->invoice->isPaid(); +} +``` ### Уведомления по запросу По желанию можно отправить уведомление кому-то, кто не сохранен как «пользователь» вашего приложения. Используя метод `route` фасада `Notification`, вы можете указать информацию о маршрутизации специального уведомления перед отправкой уведомления: - use Illuminate\Broadcasting\Channel; - use Illuminate\Support\Facades\Notification; +```php +use Illuminate\Broadcasting\Channel; +use Illuminate\Support\Facades\Notification; - Notification::route('mail', 'taylor@example.com') - ->route('vonage', '5555555555') - ->route('slack', '#slack-channel') - ->route('broadcast', [new Channel('channel-name')]) - ->notify(new InvoicePaid($invoice)); +Notification::route('mail', 'taylor@example.com') + ->route('vonage', '5555555555') + ->route('slack', '#slack-channel') + ->route('broadcast', [new Channel('channel-name')]) + ->notify(new InvoicePaid($invoice)); +``` Если вы хотите указать имя получателя при отправке уведомления по запросу на маршрут `mail`, вы можете предоставить массив, содержащий адрес электронной почты в качестве ключа и имя в качестве значения первого элемента в массиве: - Notification::route('mail', [ - 'barrett@example.com' => 'Barrett Blair', - ])->notify(new InvoicePaid($invoice)); +```php +Notification::route('mail', [ + 'barrett@example.com' => 'Barrett Blair', +])->notify(new InvoicePaid($invoice)); +``` С помощью метода `routes` вы можете предоставить сразу несколько маршрутов для нескольких каналов уведомлений: - Notification::routes([ - 'mail' => ['barrett@example.com' => 'Barrett Blair'], - 'vonage' => '5555555555', - ])->notify(new InvoicePaid($invoice)); +```php +Notification::routes([ + 'mail' => ['barrett@example.com' => 'Barrett Blair'], + 'vonage' => '5555555555', +])->notify(new InvoicePaid($invoice)); +``` ## Почтовые уведомления @@ -316,20 +356,22 @@ php artisan make:notification InvoicePaid Класс `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!'); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +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!'); +} +``` > [!NOTE] > Обратите внимание, что мы используем `$this->invoice->id` в нашем методе `toMail`. Вы можете передать любые данные, которые необходимы вашему уведомлению для генерации сообщения, в конструктор уведомления. @@ -346,16 +388,18 @@ php artisan make:notification InvoicePaid Некоторые уведомления информируют пользователей об ошибках, таких как неудачный платеж по счету. Вы можете указать, что почтовое сообщение относится к ошибке, вызвав метод `error` при составлении вашего сообщения. При использовании метода `error` в почтовом сообщении кнопка действия будет красной, а не черной: - /** - * Получить почтовое представление уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage) - ->error() - ->subject('Invoice Payment Failed') - ->line('...'); - } +```php +/** + * Получить почтовое представление уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage) + ->error() + ->subject('Invoice Payment Failed') + ->line('...'); +} +``` Этот подход помогает ясно передать пользователю, что сообщение содержит информацию об ошибке, повышая визуальную восприимчивость и понимание сообщения. @@ -364,117 +408,131 @@ php artisan make:notification InvoicePaid Вместо определения «строк» текста в классе уведомления, вы можете использовать метод `view`, чтобы указать собственный шаблон, который следует использовать для отображения почтового уведомления: - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage)->view( - 'mail.invoice.paid', ['invoice' => $this->invoice] - ); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage)->view( + 'mail.invoice.paid', ['invoice' => $this->invoice] + ); +} +``` Вы можете определить текстовое содержимое для почтового сообщения, указав имя представления в качестве второго элемента массива, передаваемого методу `view`: - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage)->view( - ['mail.invoice.paid', 'mail.invoice.paid-text'], - ['invoice' => $this->invoice] - ); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage)->view( + ['mail.invoice.paid', 'mail.invoice.paid-text'], + ['invoice' => $this->invoice] + ); +} +``` Или, если ваше сообщение содержит только простой текст, вы можете использовать метод `text`: - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage)->text( - 'mail.invoice.paid-text', ['invoice' => $this->invoice] - ); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage)->text( + 'mail.invoice.paid-text', ['invoice' => $this->invoice] + ); +} +``` ### Изменение отправителя По умолчанию адрес отправителя электронного письма определяется в конфигурационном файле `config/mail.php`. Однако вы можете указать адрес отправителя для конкретного уведомления с помощью метода `from`: - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage) - ->from('barrett@example.com', 'Barrett Blair') - ->line('...'); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage) + ->from('barrett@example.com', 'Barrett Blair') + ->line('...'); +} +``` ### Изменение получателя При отправке уведомлений по каналу `mail` система уведомлений автоматически ищет свойство `email` уведомляемого объекта. Вы можете указать, какой адрес электронной почты будет использоваться для доставки уведомления, определив метод `routeNotificationForMail` объекта уведомления: - |string + */ + public function routeNotificationForMail(Notification $notification): array|string { - use Notifiable; - - /** - * Маршрутизация уведомлений для почтового канала. - * - * @return array|string - */ - public function routeNotificationForMail(Notification $notification): array|string - { - // Вернуть только адрес электронной почты... - return $this->email_address; + // Вернуть только адрес электронной почты... + return $this->email_address; - // Вернуть адрес электронной почты и имя... - return [$this->email_address => $this->name]; - } + // Вернуть адрес электронной почты и имя... + return [$this->email_address => $this->name]; } +} +``` ### Изменение темы сообщения По умолчанию темой электронного письма является название класса уведомления в регистре «Title Case». Итак, если ваш класс уведомлений называется `InvoicePaid`, то темой электронного письма будет «Invoice Paid». Если вы хотите указать другую тему для сообщения, то вы можете вызвать метод `subject` при создании своего сообщения: - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage) - ->subject('Notification Subject') - ->line('...'); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +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('...'); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage) + ->mailer('postmark') + ->line('...'); +} +``` ### Изменение почтовых шаблонов @@ -490,98 +548,110 @@ php artisan vendor:publish --tag=laravel-notifications Чтобы добавить вложения к почтовому уведомлению, используйте метод `attach` при создании сообщения. Метод `attach` принимает абсолютный путь к файлу в качестве своего первого аргумента: - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage) - ->greeting('Hello!') - ->attach('/path/to/file'); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage) + ->greeting('Hello!') + ->attach('/path/to/file'); +} +``` > [!NOTE] > Метод `attach`, предоставляемый почтовыми сообщениями уведомлений, также принимает [объекты, прикрепляемые к сообщению](/docs/{{version}}/mail#attachable-objects). Пожалуйста, ознакомьтесь с подробной [документацией об объектах, прикрепляемых к сообщениям](/docs/{{version}}/mail#attachable-objects), чтобы узнать больше. При прикреплении файлов к сообщению вы также можете указать отображаемое имя и / или MIME-тип, передав массив в качестве второго аргумента методу `attach`: - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage) - ->greeting('Hello!') - ->attach('/path/to/file', [ - 'as' => 'name.pdf', - 'mime' => 'application/pdf', - ]); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage) + ->greeting('Hello!') + ->attach('/path/to/file', [ + 'as' => 'name.pdf', + 'mime' => 'application/pdf', + ]); +} +``` В отличие от прикрепления файлов к почтовым отправлениям, вы не можете прикреплять файл непосредственно с диска файлового хранилища с помощью `attachFromStorage`. Лучше использовать метод `attach` с абсолютным путем к файлу на диске. В качестве альтернативы вы можете вернуть [отправление](/docs/{{version}}/mail#generating-mailables) из метода `toMail`: - use App\Mail\InvoicePaid as InvoicePaidMailable; +```php +use App\Mail\InvoicePaid as InvoicePaidMailable; - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): Mailable - { - return (new InvoicePaidMailable($this->invoice)) - ->to($notifiable->email) - ->attachFromStorage('/path/to/file'); - } +/** + * Получить содержимое почтового уведомления. + */ +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', - ], - ]); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +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', - ]); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +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); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage) + ->greeting('Comment Upvoted!') + ->tag('upvote') + ->metadata('comment_id', $this->comment->id); +} +``` Если ваше приложение использует драйвер Mailgun, вы можете обратиться к документации Mailgun для получения дополнительной информации о [тегах](https://documentation.mailgun.com/en/latest/user_manual.html#tagging-1) и [метаданных](https://documentation.mailgun.com/en/latest/user_manual.html#attaching-data-to-messages). Аналогично, документацию Postmark можно также проконсультировать для получения информации о их поддержке [тегов](https://postmarkapp.com/blog/tags-support-for-smtp) и [метаданных](https://postmarkapp.com/support/article/1125-custom-metadata-faq). @@ -592,74 +662,82 @@ php artisan vendor:publish --tag=laravel-notifications Метод `withSymfonyMessage` класса `MailMessage` позволяет зарегистрировать функцию обратного вызова, которая будет вызвана с экземпляром сообщения Symfony перед отправкой сообщения. Это дает вам возможность глубоко настроить сообщение перед его доставкой: - use Symfony\Component\Mime\Email; +```php +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' - ); - }); - } +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage) + ->withSymfonyMessage(function (Email $message) { + $message->getHeaders()->addTextHeader( + 'Custom-Header', 'Header Value' + ); + }); +} +``` ### Использование почтовых отправлений При необходимости вы можете вернуть полный [объект почтового отправления](/docs/{{version}}/mail) из метода `toMail` вашего уведомления. При возврате `Mailable` вместо `MailMessage` вам нужно будет указать получателя сообщения с помощью метода `to` объекта почтового отправления: - use App\Mail\InvoicePaid as InvoicePaidMailable; - use Illuminate\Mail\Mailable; +```php +use App\Mail\InvoicePaid as InvoicePaidMailable; +use Illuminate\Mail\Mailable; - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): Mailable - { - return (new InvoicePaidMailable($this->invoice)) - ->to($notifiable->email); - } +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): Mailable +{ + return (new InvoicePaidMailable($this->invoice)) + ->to($notifiable->email); +} +``` #### Почтовые отправления и уведомления по запросу Если вы отправляете [уведомление по запросу](#on-demand-notifications), то экземпляр `$notifiable`, переданный методу `toMail`, будет экземпляром `Illuminate\Notifications\AnonymousNotifiable`, содержащий метод `routeNotificationFor`, который можно использовать для получения адреса электронной почты для отправления уведомления по запросу: - use App\Mail\InvoicePaid as InvoicePaidMailable; - use Illuminate\Notifications\AnonymousNotifiable; - use Illuminate\Mail\Mailable; +```php +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; +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): Mailable +{ + $address = $notifiable instanceof AnonymousNotifiable + ? $notifiable->routeNotificationFor('mail') + : $notifiable->email; - return (new InvoicePaidMailable($this->invoice)) - ->to($address); - } + return (new InvoicePaidMailable($this->invoice)) + ->to($address); +} +``` ### Предварительный просмотр почтовых уведомлений При разработке шаблона почтового уведомления удобно быстро просмотреть визуализированное почтовое сообщение в браузере, как типичный шаблон Blade. По этой причине Laravel позволяет вам возвращать любое почтовое сообщение непосредственно из замыкания маршрута или контроллера. При возврате `MailMessage`, оно будет обработано и отображено в браузере, что позволит вам быстро просмотреть его дизайн без необходимости отправлять его на реальный адрес электронной почты: - use App\Models\Invoice; - use App\Notifications\InvoicePaid; +```php +use App\Models\Invoice; +use App\Notifications\InvoicePaid; - Route::get('/notification', function () { - $invoice = Invoice::find(1); +Route::get('/notification', function () { + $invoice = Invoice::find(1); - return (new InvoicePaid($invoice)) - ->toMail($invoice->user); - }); + return (new InvoicePaid($invoice)) + ->toMail($invoice->user); +}); +``` ## Почтовые уведомления с разметкой Markdown @@ -677,17 +755,19 @@ 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); +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + $url = url('/invoice/'.$this->invoice->id); - return (new MailMessage) - ->subject('Invoice Paid') - ->markdown('mail.invoice.paid', ['url' => $url]); - } + return (new MailMessage) + ->subject('Invoice Paid') + ->markdown('mail.invoice.paid', ['url' => $url]); +} +``` ### Написание сообщения @@ -709,6 +789,9 @@ Thanks,
``` +> [!NOTE] +> Не используйте избыточные отступы при написании писем Markdown. Согласно стандартам Markdown, парсеры Markdown будут отображать отступы в виде блоков кода. + #### Компонент Button @@ -765,16 +848,18 @@ php artisan vendor:publish --tag=laravel-mail Чтобы настроить тему для отдельного уведомления, вы можете вызвать метод `theme` при создании почтового сообщения уведомления. Метод `theme` принимает имя темы, которая должна использоваться при отправке уведомления: - /** - * Получить содержимое почтового уведомления. - */ - public function toMail(object $notifiable): MailMessage - { - return (new MailMessage) - ->theme('invoice') - ->subject('Invoice Paid') - ->markdown('mail.invoice.paid', ['url' => $url]); - } +```php +/** + * Получить содержимое почтового уведомления. + */ +public function toMail(object $notifiable): MailMessage +{ + return (new MailMessage) + ->theme('invoice') + ->subject('Invoice Paid') + ->markdown('mail.invoice.paid', ['url' => $url]); +} +``` ## Уведомления через канал `database` @@ -793,37 +878,51 @@ php artisan migrate ``` > [!NOTE] -> Если ваши модели с уведомлениями используют [UUID или ULID в качестве первичных ключей](/docs/{{version}}/eloquent#uuid-and-ulid-keys), вы должны заменить метод `morphs` на [`uuidMorphs`](/docs/{{version}}/migrations#column-method-uuidMorphs) или [`ulidMorphs`](/docs/{{version}}/migrations#column-method-ulidMorphs) в миграции таблицы уведомлений. +> Если ваши модели с уведомлениями используют [UUID или ULID в качестве первичных ключей](/docs/{{version}}/eloquent#uuid-and-ulid-keys), вы должны заменить метод `morphs` на [uuidMorphs](/docs/{{version}}/migrations#column-method-uuidMorphs) или [ulidMorphs](/docs/{{version}}/migrations#column-method-ulidMorphs) в миграции таблицы уведомлений. ### Формирование уведомлений канала `database` Чтобы уведомление было сохранено в таблице базы данных, вы должны определить метод `toDatabase` или `toArray` в классе уведомления. Каждый из этих методов получает объект `$notifiable` и должен возвращать простой массив PHP. Возвращенный массив будет закодирован как JSON и сохранен в столбце `data` вашей таблицы `notifications`. Давайте посмотрим на пример метода `toArray`: - /** - * Получить массив данных уведомления. - * - * @return array - */ - public function toArray(object $notifiable): array - { - return [ - 'invoice_id' => $this->invoice->id, - 'amount' => $this->invoice->amount, - ]; - } +```php +/** + * Получить массив данных уведомления. + * + * @return array + */ +public function toArray(object $notifiable): array +{ + return [ + 'invoice_id' => $this->invoice->id, + 'amount' => $this->invoice->amount, + ]; +} +``` -Когда уведомление сохраняется в базе данных вашего приложения, столбец `type` заполняется именем класса уведомления. Однако вы можете настроить это поведение, определив метод `databaseType` в вашем классе уведомления: +Когда уведомление сохраняется в базе данных вашего приложения, столбец `type` будет установлен на имя класса уведомления по умолчанию, а столбец `read_at` будет `null`. Однако вы можете настроить это поведение, определив методы `databaseType` и `initialDatabaseReadAtValue` в вашем классе уведомления: - /** - * Получить тип уведомления для базы данных. - * - * @return string - */ - public function databaseType(object $notifiable): string - { - return 'invoice-paid'; - } +```php +use Illuminate\Support\Carbon; + +/** + * Получить тип уведомления для базы данных. + * + * @return string + */ +public function databaseType(object $notifiable): string +{ + return 'invoice-paid'; +} + +/** + * Получить начальное значение для столбца «read_at». + */ +public function initialDatabaseReadAtValue(): ?Carbon +{ + return null; +} +``` Этот метод позволяет вам устанавливать пользовательский тип уведомления, который будет сохранен в столбце `type` в таблице уведомлений базы данных. Это может быть полезно для более удобного отслеживания и фильтрации уведомлений по типу. @@ -837,19 +936,23 @@ php artisan migrate После сохранения уведомления в базу данных, вам понадобится удобный способ доступа к нему из уведомляемых объектов. Трейт `Illuminate\Notifications\Notifiable`, который по умолчанию расположен в модели `App\Models\User` Laravel, содержит [отношение](/docs/{{version}}/eloquent-relationships) `notifications` Eloquent, возвращающее уведомления для объекта. Вы можете обратиться к этому методу, как и к любому другому отношению Eloquent, чтобы получить уведомления. По умолчанию уведомления будут упорядочены по столбцу `created_at` временной метки, причем самые последние уведомления будут помещены в начало коллекции: - $user = App\Models\User::find(1); +```php +$user = App\Models\User::find(1); - foreach ($user->notifications as $notification) { - echo $notification->type; - } +foreach ($user->notifications as $notification) { + echo $notification->type; +} +``` Для получения только «непрочитанных» уведомлений, используйте отношение `unreadNotifications`. Опять же, эти уведомления будут упорядочены по столбцу `created_at` временной метки с самыми последними уведомлениями в начале коллекции: - $user = App\Models\User::find(1); +```php +$user = App\Models\User::find(1); - foreach ($user->unreadNotifications as $notification) { - echo $notification->type; - } +foreach ($user->unreadNotifications as $notification) { + echo $notification->type; +} +``` > [!NOTE] > Чтобы получить доступ к уведомлениям в JavaScript-приложении на клиентской стороне, вы должны определить контроллер уведомлений для своего приложения, который возвращает уведомления для уведомляемого объекта, такого как текущий пользователь. Затем вы можете сделать HTTP-запрос к URL-адресу этого контроллера из своего JavaScript-приложения на клиентской стороне. @@ -859,25 +962,33 @@ php artisan migrate По желанию можно пометить уведомление как «прочитанное», когда пользователь его просматривает. Трейт `Illuminate\Notifications\Notifiable` содержит метод `markAsRead`, который обновляет столбец `read_at` записи уведомления в базе данных: - $user = App\Models\User::find(1); +```php +$user = App\Models\User::find(1); - foreach ($user->unreadNotifications as $notification) { - $notification->markAsRead(); - } +foreach ($user->unreadNotifications as $notification) { + $notification->markAsRead(); +} +``` Однако вместо того, чтобы перебирать каждое уведомление, вы можете использовать метод `markAsRead` непосредственно для коллекции уведомлений: - $user->unreadNotifications->markAsRead(); +```php +$user->unreadNotifications->markAsRead(); +``` Вы также можете выполнить запрос массового обновления, чтобы пометить все уведомления как прочитанные, не извлекая их из базы данных: - $user = App\Models\User::find(1); +```php +$user = App\Models\User::find(1); - $user->unreadNotifications()->update(['read_at' => now()]); +$user->unreadNotifications()->update(['read_at' => now()]); +``` Вы можете полностью удалить уведомления из таблицы, используя метод `delete`: - $user->notifications()->delete(); +```php +$user->notifications()->delete(); +``` ## Трансляция уведомлений @@ -892,76 +1003,160 @@ php artisan migrate Канал `broadcast` транслирует уведомления с использованием служб [трансляции событий](/docs/{{version}}/broadcasting) Laravel, что позволяет вашему JavaScript-приложению на клиентской стороне улавливать уведомления в режиме реального времени. Если уведомление поддерживает трансляцию, то вы должны определить метод `toBroadcast` в классе уведомления. Этот метод получит объект `$notifiable` и должен вернуть экземпляр` BroadcastMessage`. Если метод `toBroadcast` не существует, то метод `toArray` будет использоваться для сбора данных, которые следует транслировать. Возвращенные данные будут закодированы как JSON и переданы вашему JavaScript-приложению на клиентской стороне. Давайте посмотрим на пример метода `toBroadcast`: - use Illuminate\Notifications\Messages\BroadcastMessage; +```php +use Illuminate\Notifications\Messages\BroadcastMessage; - /** - * Получить содержимое транслируемого уведомления. - */ - public function toBroadcast(object $notifiable): BroadcastMessage - { - return new BroadcastMessage([ - 'invoice_id' => $this->invoice->id, - 'amount' => $this->invoice->amount, - ]); - } +/** + * Получить содержимое транслируемого уведомления. + */ +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'); +```php +return (new BroadcastMessage($data)) + ->onConnection('sqs') + ->onQueue('broadcasts'); +``` #### Изменение типа транслируемого уведомления В дополнение к указанным вами данным все транслируемые уведомления также имеют поле `type`, содержащее полное имя класса уведомления. Если вы хотите изменить `type` уведомления, то вы можете определить метод `broadcastType` в классе уведомления: - /** - * Получить тип транслируемого уведомления. - */ - public function broadcastType(): string - { - return 'broadcast.message'; - } +```php +/** + * Получить тип транслируемого уведомления. + */ +public function broadcastType(): string +{ + return 'broadcast.message'; +} +``` ### Прослушивание транслируемых уведомлений Уведомления будут транслироваться по частному каналу, в формате с использованием соглашения `{notifiable}.{id}`. Итак, если вы отправляете уведомление экземпляру `App\Models\User` с идентификатором `1`, то уведомление будет транслироваться по частному каналу `App.Models.User.1`. При использовании [Laravel Echo](/docs/{{version}}/broadcasting#client-side-installation) вы можете легко прослушивать уведомления канала, используя метод `notification`: - Echo.private('App.Models.User.' + userId) - .notification((notification) => { - console.log(notification.type); - }); +```js +Echo.private('App.Models.User.' + userId) + .notification((notification) => { + console.log(notification.type); + }); +``` + + +#### Использование React или Vue + +Laravel Echo включает хуки React и Vue, которые делают прослушивание уведомлений безболезненным. Чтобы начать, вызовите хук `useEchoNotification`, который используется для прослушивания уведомлений. Хук `useEchoNotification` автоматически покинет каналы, когда потребляющий компонент будет размонтирован: + +```js tab=React +import { useEchoNotification } from "@laravel/echo-react"; + +useEchoNotification( + `App.Models.User.${userId}`, + (notification) => { + console.log(notification.type); + }, +); +``` + +```vue tab=Vue + +``` + +По умолчанию хук прослушивает все уведомления. Чтобы указать типы уведомлений, которые вы хотите прослушивать, вы можете предоставить строку или массив типов для `useEchoNotification`: + +```js tab=React +import { useEchoNotification } from "@laravel/echo-react"; + +useEchoNotification( + `App.Models.User.${userId}`, + (notification) => { + console.log(notification.type); + }, + 'App.Notifications.InvoicePaid', +); +``` + +```vue tab=Vue + +``` + +Вы также можете указать форму данных полезной нагрузки уведомления, что обеспечивает большую безопасность типов и удобство редактирования: + +```ts +type InvoicePaidNotification = { + invoice_id: number; + created_at: string; +}; + +useEchoNotification( + `App.Models.User.${userId}`, + (notification) => { + console.log(notification.invoice_id); + console.log(notification.created_at); + console.log(notification.type); + }, + 'App.Notifications.InvoicePaid', +); +``` #### Изменение канала транслируемого уведомления Если вы хотите изменить канал, на котором транслируются уведомления объекта, то вы можете определить метод `receivesBroadcastNotificationsOn` объекта уведомления: - id; - } + /** + * Каналы, по которым пользователь получает рассылку уведомлений. + */ + public function receivesBroadcastNotificationsOn(): string + { + return 'users.'.$this->id; } +} +``` ## Уведомления через SMS @@ -971,106 +1166,120 @@ php artisan migrate Отправка SMS-уведомлений в Laravel обеспечивается [Vonage](https://www.vonage.com/) (бывший Nexmo). Прежде чем вы сможете отправлять уведомления через Vonage, вам необходимо установить пакеты `laravel/vonage-notification-channel` и `guzzlehttp/guzzle`: - composer require laravel/vonage-notification-channel guzzlehttp/guzzle +```shell +composer require laravel/vonage-notification-channel guzzlehttp/guzzle +``` Пакет включает в себя [файл конфигурации](https://github.com/laravel/vonage-notification-channel/blob/3.x/config/vonage.php). Однако вам не обязательно экспортировать этот файл конфигурации в ваше собственное приложение. Вы можете просто использовать переменные окружения `VONAGE_KEY` и `VONAGE_SECRET` для определения ваших публичного и секретного ключей Vonage. После определения ваших ключей, вы должны установить переменную окружения `VONAGE_SMS_FROM`, которая определяет номер телефона, с которого по умолчанию будут отправляться ваши SMS-сообщения. Вы можете сгенерировать этот номер телефона в панели управления Vonage: - VONAGE_SMS_FROM=15556666666 +```ini +VONAGE_SMS_FROM=15556666666 +``` ### Формирование уведомлений через SMS Если уведомление поддерживает отправку в виде SMS, то вы должны определить метод `toVonage` в классе уведомлений. Этот метод получит объект `$notifiable` и должен вернуть экземпляр `Illuminate\Notifications\Messages\NexmoMessage`: - use Illuminate\Notifications\Messages\VonageMessage; +```php +use Illuminate\Notifications\Messages\VonageMessage; - /** - * Получить SMS-представление уведомления. - */ - public function toVonage(object $notifiable): VonageMessage - { - return (new VonageMessage) - ->content('Your SMS message content'); - } +/** + * Получить 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; +```php +use Illuminate\Notifications\Messages\VonageMessage; - /** - * Получить SMS-представление уведомления. - */ - public function toVonage(object $notifiable): VonageMessage - { - return (new VonageMessage) - ->content('Your unicode message') - ->unicode(); - } +/** + * Получить SMS-представление уведомления. + */ +public function toVonage(object $notifiable): VonageMessage +{ + return (new VonageMessage) + ->content('Your unicode message') + ->unicode(); +} +``` ### Изменение номера отправителя Если вы хотите отправить уведомление с номера телефона, который отличается от номера телефона, указанного в вашем файле `config/services.php`, то вы можете вызвать метод `from` экземпляра `VonageMessage`: - use Illuminate\Notifications\Messages\VonageMessage; +```php +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-представление уведомления. + */ +public function toVonage(object $notifiable): VonageMessage +{ + return (new VonageMessage) + ->content('Your SMS message content') + ->from('15554443333'); +} +``` ### Добавление ссылки на клиента Если вы хотите отслеживать затраты на пользователя, команду или клиента, вы можете добавить в уведомление "ссылку на клиента". Vonage позволит вам создавать отчеты, используя эту ссылку клиента, чтобы вы могли лучше понять использование SMS конкретным клиентом. Ссылка на клиента может быть любой строкой до 40 символов: - use Illuminate\Notifications\Messages\VonageMessage; +```php +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'); - } +/** + * Получить Vonage / SMS-представление уведомления. + */ +public function toVonage(object $notifiable): VonageMessage +{ + return (new VonageMessage) + ->clientReference((string) $notifiable->id) + ->content('Your SMS message content'); +} +``` ### Маршрутизация SMS-уведомлений Для отправки уведомления с использованием Vonage на необходимый номер телефона, определите метод `routeNotificationForVonage` вашего уведомляемого объекта: - phone_number; - } + /** + * Маршрутизация уведомлений для канала Vonage. + */ + public function routeNotificationForVonage(Notification $notification): string + { + return $this->phone_number; } +} +``` ## Уведомления через Slack @@ -1086,16 +1295,18 @@ composer require laravel/slack-notification-channel Дополнительно, вы должны создать [Slack приложение](https://api.slack.com/apps?new_app=1) для вашего рабочего пространства Slack. -Если вам нужно отправлять уведомления только в то же рабочее пространство Slack, в котором создано приложение, убедитесь, что ваше приложение имеет разрешения `chat:write`, `chat:write.public` и `chat:write.customize`. Если вы хотите отправлять сообщения в качестве приложения Slack, вам следует убедиться, что ваше приложение также имеет область действия `chat:write:bot`. Эти разрешения можно добавить на вкладке "OAuth & Permissions" в управлении приложениями 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'), - ], +```php +'slack' => [ + 'notifications' => [ + 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'), + 'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'), ], +], +``` #### Распространение приложения Slack @@ -1107,70 +1318,74 @@ composer require laravel/slack-notification-channel Если уведомление поддерживает отправку в виде сообщения Slack, вы должны определить метод `toSlack` в классе уведомления. Этот метод получает сущность `$notifiable` и должен возвращать экземпляр `Illuminate\Notifications\Slack\SlackMessage`. Вы можете создавать богатые уведомления, используя [API Block Kit Slack](https://api.slack.com/block-kit). Следующий пример может быть предпросмотрен в [Block Kit Builder Slack](https://app.slack.com/block-kit-builder/T01KWS6K23Z#%7B%22blocks%22:%5B%7B%22type%22:%22header%22,%22text%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Invoice%20Paid%22%7D%7D,%7B%22type%22:%22context%22,%22elements%22:%5B%7B%22type%22:%22plain_text%22,%22text%22:%22Customer%20%231234%22%7D%5D%7D,%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22plain_text%22,%22text%22:%22An%20invoice%20has%20been%20paid.%22%7D,%22fields%22:%5B%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Invoice%20No:*%5Cn1000%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Invoice%20Recipient:*%5Cntaylor@laravel.com%22%7D%5D%7D,%7B%22type%22:%22divider%22%7D,%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22plain_text%22,%22text%22:%22Congratulations!%22%7D%7D%5D%7D): - 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; +```php +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:*\ntaylor@laravel.com")->markdown(); - }) - ->dividerBlock() - ->sectionBlock(function (SectionBlock $block) { - $block->text('Congratulations!'); - }); - } +/** + * Получить представление 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:*\ntaylor@laravel.com")->markdown(); + }) + ->dividerBlock() + ->sectionBlock(function (SectionBlock $block) { + $block->text('Congratulations!'); + }); +} +``` #### Использование шаблона Block Kit Builder Slack Вместо использования методов построителя сообщений для создания сообщения Block Kit вы можете передать необработанный JSON, сгенерированный Block Kit Builder Slack, методу usingBlockKitTemplate: - use Illuminate\Notifications\Slack\SlackMessage; - use Illuminate\Support\Str; +```php +use Illuminate\Notifications\Slack\SlackMessage; +use Illuminate\Support\Str; - /** - * Get the Slack representation of the notification. - */ - public function toSlack(object $notifiable): SlackMessage - { - $template = <<usingBlockKitTemplate($template); - } + return (new SlackMessage) + ->usingBlockKitTemplate($template); +} +``` ### Взаимодействие в Slack @@ -1179,81 +1394,87 @@ composer require laravel/slack-notification-channel В следующем примере, который использует метод `actionsBlock`, Slack отправит `POST` запрос на ваш "Request URL" с полезной нагрузкой, содержащей пользователя Slack, который нажал на кнопку, идентификатор нажатой кнопки и дополнительную информацию. Ваше приложение может затем определить, какое действие следует предпринять на основе полученной полезной нагрузки. Также вы должны [проверить подлинность запроса](https://api.slack.com/authentication/verifying-requests-from-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; +```php +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 defaults to "button_acknowledge_invoice"... - $block->button('Acknowledge Invoice')->primary(); - - // Manually configure the ID... - $block->button('Deny')->danger()->id('deny_invoice'); - }); - } +/** + * Получить представление 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 defaults to "button_acknowledge_invoice"... + $block->button('Acknowledge Invoice')->primary(); + + // Manually configure the 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'); - } - ); - }); - } +```php +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'); + } + ); + }); +} +``` #### Просмотр cтруктуры блоков Slack Если вы хотите быстро проверить структуру блоков, которые вы создали, вы можете использовать метод `dd` в экземпляре `SlackMessage`. Метод `dd` сгенерирует и выведет URL-адрес для [Block Kit Builder Slack](https://app.slack.com/block-kit-builder/), который отображает предварительный просмотр полезной нагрузки и уведомления в вашем браузере. Вы можете передать `true` методу `dd`, чтобы вывести сырую полезную нагрузку: - return (new SlackMessage) - ->text('Один из ваших счетов оплачен!') - ->headerBlock('Счет Оплачен') - ->dd(); // Это вызовет просмотр блоков в Block Kit Builder +```php +return (new SlackMessage) + ->text('Один из ваших счетов оплачен!') + ->headerBlock('Счет Оплачен') + ->dd(); // Это вызовет просмотр блоков в Block Kit Builder +``` Этот метод особенно полезен во время разработки, так как позволяет быстро и удобно проверить внешний вид и структуру ваших уведомлений в Slack, не отправляя их на самом деле. @@ -1268,26 +1489,28 @@ composer require laravel/slack-notification-channel Например, возвращение `#support-channel` из метода `routeNotificationForSlack` отправит уведомление в канал `#support-channel` рабочего пространства, связанного с OAuth токеном Bot User, расположенным в файле конфигурации `services.php` вашего приложения: - ### Уведомление во внешние рабочие пространства Slack @@ -1299,27 +1522,29 @@ composer require laravel/slack-notification-channel После получения токена бота и его сохранения в базе данных вашего приложения, вы можете использовать метод `SlackRoute::make` для направления уведомления в рабочее пространство пользователя. Кроме того, ваше приложение, скорее всего, должно предоставить пользователю возможность указать, в какой канал следует отправлять уведомления: - slack_channel, $this->slack_token); - } + /** + * Маршрутизация уведомлений для канала Slack. + */ + public function routeNotificationForSlack(Notification $notification): mixed + { + return SlackRoute::make($this->slack_channel, $this->slack_token); } +} +``` ## Локализация уведомлений @@ -1328,35 +1553,43 @@ Laravel позволяет отправлять уведомления, испо Для этого класс `Illuminate\Notifications\Notification` содержит метод `locale` для установки желаемого языка. Приложение изменит язык при анализе уведомления, а затем вернется к предыдущему языку, когда анализ будет завершен: - $user->notify((new InvoicePaid($invoice))->locale('es')); +```php +$user->notify((new InvoicePaid($invoice))->locale('es')); +``` Локализация нескольких уведомляемых записей также доступна через фасад `Notification`: - Notification::locale('es')->send( - $users, new InvoicePaid($invoice) - ); +```php +Notification::locale('es')->send( + $users, new InvoicePaid($invoice) +); +``` ### Предпочитаемые пользователем локализации Иногда приложения хранят предпочтительный язык каждого пользователя. Реализуя контракт `HasLocalePreference` в вашей уведомляемой модели, вы можете указать Laravel использовать этот сохраненный язык при отправке уведомления: - use Illuminate\Contracts\Translation\HasLocalePreference; +```php +use Illuminate\Contracts\Translation\HasLocalePreference; - class User extends Model implements HasLocalePreference +class User extends Model implements HasLocalePreference +{ + /** + * Получить предпочитаемую пользователем локализацию. + */ + public function preferredLocale(): string { - /** - * Получить предпочитаемую пользователем локализацию. - */ - public function preferredLocale(): string - { - return $this->locale; - } + return $this->locale; } +} +``` После того как вы реализовали интерфейс, Laravel будет автоматически использовать предпочтительный язык при отправке уведомлений и почтовых сообщений модели. Следовательно, при использовании этого интерфейса нет необходимости вызывать метод `locale`: - $user->notify(new InvoicePaid($invoice)); +```php +$user->notify(new InvoicePaid($invoice)); +``` ## Тестирование @@ -1432,28 +1665,34 @@ class ExampleTest extends TestCase Вы можете передать замыкание в методы `assertSentTo` или `assertNotSentTo`, чтобы проверить, что было отправлено уведомление, которое проходит заданный "тест истины". Если хотя бы одно уведомление было отправлено и прошло заданный тест, то утверждение будет успешным: - Notification::assertSentTo( - $user, - function (OrderShipped $notification, array $channels) use ($order) { - return $notification->order->id === $order->id; - } - ); +```php +Notification::assertSentTo( + $user, + function (OrderShipped $notification, array $channels) use ($order) { + return $notification->order->id === $order->id; + } +); +``` #### Уведомления по требованию Если код, который вы тестируете, отправляет [уведомления по требованию](#on-demand-notifications), вы можете проверить, что уведомление по требованию было отправлено с помощью метода `assertSentOnDemand`: - Notification::assertSentOnDemand(OrderShipped::class); +```php +Notification::assertSentOnDemand(OrderShipped::class); +``` Передав замыкание вторым аргументом метода `assertSentOnDemand`, вы можете определить, отправлено ли уведомление по требованию на правильный "маршрут": - Notification::assertSentOnDemand( - OrderShipped::class, - function (OrderShipped $notification, array $channels, object $notifiable) use ($user) { - return $notifiable->routes['mail'] === $user->email; - } - ); +```php +Notification::assertSentOnDemand( + OrderShipped::class, + function (OrderShipped $notification, array $channels, object $notifiable) use ($user) { + return $notifiable->routes['mail'] === $user->email; + } +); +``` ## События уведомления @@ -1463,71 +1702,81 @@ class ExampleTest extends TestCase При отправке уведомления, система уведомлений запускает событие `Illuminate\Notifications\Events\NotificationSending`. Он содержит «уведомляемый» объект и сам экземпляр уведомления. Вы можете создать [прослушиватели событий](/docs/{{version}}/events) для этого события в своем приложении: - use Illuminate\Notifications\Events\NotificationSending; +```php +use Illuminate\Notifications\Events\NotificationSending; - class CheckNotificationStatus +class CheckNotificationStatus +{ + /** + * Handle the given event. + */ + public function handle(NotificationSending $event): void { - /** - * Handle the given event. - */ - public function handle(NotificationSending $event): void - { - // ... - } + // ... } +} +``` Уведомление не будет отправлено, если прослушиватель событий NotificationSending возвращает `false` из своего метода `handle`: - /** - * Обработка данного события. - */ - public function handle(NotificationSending $event): bool - { - return false; - } +```php +/** + * Обработка данного события. + */ +public function handle(NotificationSending $event): bool +{ + return false; +} +``` В слушателе событий вы можете получить доступ к свойствам `notifiable`, `notification` и `channel` события, чтобы узнать больше о получателе уведомления или самом уведомлении: - /** - * Обработка данного события. - */ - public function handle(NotificationSending $event): void - { - // $event->channel - // $event->notifiable - // $event->notification - } +```php +/** + * Обработка данного события. + */ +public function handle(NotificationSending $event): void +{ + // $event->channel + // $event->notifiable + // $event->notification +} +``` #### Событие после отправки уведомления Когда уведомление отправлено, система уведомлений запускает [событие](/docs/{{version}}/events) `Illuminate\Notifications\Events\NotificationSent`. Событие содержит уведомляемую сущность и сам экземпляр уведомления. Вы можете создать [прослушиватели событий](/docs/{{version}}/events) для этого события в своем приложении: - use Illuminate\Notifications\Events\NotificationSent; - - class LogNotification - { - /** - * Обработать переданное событие. - */ - public function handle(NotificationSent $event): void - { - // ... - } - } - -В слушателе события вы можете получить доступ к свойствам `notifiable`, `notification`, `channel` и `response` события, чтобы узнать больше о получателе уведомления или самом уведомлении: +```php +use Illuminate\Notifications\Events\NotificationSent; +class LogNotification +{ /** * Обработать переданное событие. */ public function handle(NotificationSent $event): void { - // $event->channel - // $event->notifiable - // $event->notification - // $event->response + // ... } +} +``` + +В слушателе события вы можете получить доступ к свойствам `notifiable`, `notification`, `channel` и `response` события, чтобы узнать больше о получателе уведомления или самом уведомлении: + +```php +/** + * Обработать переданное событие. + */ +public function handle(NotificationSent $event): void +{ + // $event->channel + // $event->notifiable + // $event->notification + // $event->response +} +``` ## Пользовательские каналы уведомлений @@ -1536,54 +1785,59 @@ Laravel предлагает несколько каналов уведомле В методе `send` вы можете вызывать методы уведомления, чтобы получить объект сообщения, понятный вашему каналу, а затем отправить уведомление необходимому экземпляру `$notifiable`: - toVoice($notifiable); + $message = $notification->toVoice($notifiable); - // Отправка уведомления экземпляру `$notifiable`... - } + // Отправка уведомления экземпляру `$notifiable`... } +} +``` Как только ваш класс канала уведомления был определен, вы можете вернуть имя класса из метода `via` любого из ваших уведомлений. В этом примере метод вашего уведомления `toVoice` может возвращать любой объект для формирования голосовых сообщений. Например, вы можете определить свой собственный класс `VoiceMessage` для формирования таких сообщений: -