跳至内容

通知

介绍

除了支持发送电子邮件之外,Laravel 还支持通过多种渠道发送通知,包括电子邮件、短信(通过Vonage(以前称为 Nexmo))和Slack 。此外,社区还创建了各种通知渠道,可以通过数十种不同的渠道发送通知!通知还可以存储在数据库中,以便显示在您的 Web 界面中。

通常,通知应该是简短的信息性消息,用于告知用户应用中发生的事件。例如,如果您正在编写一个计费应用,则可以通过电子邮件和短信渠道向用户发送“发票已付”通知。

生成通知

在 Laravel 中,每个通知都由一个类表示,该类通常存储在app/Notifications目录中。如果您在应用程序中没有看到此目录,请不要担心 - 它会在您运行make:notificationArtisan 命令时为您创建:

1php artisan make:notification InvoicePaid

app/Notifications此命令将在您的目录中放置一个新的通知类。每个通知类包含一个via方法和数量不定的消息构建方法(例如toMailtoDatabase),这些方法将通知转换为针对特定渠道定制的消息。

发送通知

使用 Notifiable Trait

通知可以通过两种方式发送:使用traitnotify的方法Notifiable或使用Notification Facade。该trait默认Notifiable包含在应用程序的模型中:App\Models\User

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7 
8class User extends Authenticatable
9{
10 use Notifiable;
11}

notify此特征提供的方法期望接收通知实例

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

请记住,您可以在任何模型上使用该Notifiable特征。您不仅限于将其包含在您的User模型中。

使用通知外观

Notification 或者,您可以通过Facade发送通知。当您需要向多个可通知实体(例如一组用户)发送通知时,此方法非常有用。要使用 Facade 发送通知,请将所有可通知实体和通知实例传递给该send方法:

1use Illuminate\Support\Facades\Notification;
2 
3Notification::send($users, new InvoicePaid($invoice));

您还可以使用该方法立即发送通知sendNow。即使通知实现了以下ShouldQueue接口,此方法也会立即发送通知:

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

指定交付渠道

每个通知类都有一个via方法来确定通知将在哪些渠道上传递。通知可以通过maildatabasebroadcastvonageslack渠道发送。

如果您想使用其他传送渠道(例如 Telegram 或 Pusher),请查看社区驱动的Laravel 通知渠道网站

via方法接收一个$notifiable实例,该实例是接收通知的类的实例。您可以使用它$notifiable来确定通知应该通过哪些渠道传递:

1/**
2 * Get the notification's delivery channels.
3 *
4 * @return array<int, string>
5 */
6public function via(object $notifiable): array
7{
8 return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
9}

排队通知

在排队通知之前,您应该配置队列并启动一个工作者

发送通知可能需要一些时间,尤其是在渠道需要调用外部 API 来传递通知的情况下。为了加快应用程序的响应时间,请将ShouldQueue接口和Queueable特性添加到您的类中,以便将通知加入队列。所有使用该命令生成的通知都已导入接口和特性make:notification,因此您可以立即将它们添加到您的通知类中:

1<?php
2 
3namespace App\Notifications;
4 
5use Illuminate\Bus\Queueable;
6use Illuminate\Contracts\Queue\ShouldQueue;
7use Illuminate\Notifications\Notification;
8 
9class InvoicePaid extends Notification implements ShouldQueue
10{
11 use Queueable;
12 
13 // ...
14}

ShouldQueue将接口添加到通知后,您可以像平常一样发送通知。Laravel 会检测ShouldQueue类上的接口,并自动将通知的传递加入队列:

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

将通知排队时,系统会为每个收件人和渠道组合创建一个排队作业。例如,如果您的通知有三个收件人和两个渠道,则会将六个作业分派到队列中。

延迟通知

如果您想要延迟通知的传递,您可以将该delay方法链接到通知实例中:

1$delay = now()->addMinutes(10);
2 
3$user->notify((new InvoicePaid($invoice))->delay($delay));

您可以将数组传递给delay方法来指定特定通道的延迟量:

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

或者,你可以withDelay在通知类本身上定义一个方法。该withDelay方法应该返回一个包含通道名称和延迟值的数组:

1/**
2 * Determine the notification's delivery delay.
3 *
4 * @return array<string, \Illuminate\Support\Carbon>
5 */
6public function withDelay(object $notifiable): array
7{
8 return [
9 'mail' => now()->addMinutes(5),
10 'sms' => now()->addMinutes(10),
11 ];
12}

自定义通知队列连接

默认情况下,排队通知将使用应用程序的默认队列连接进行排队。如果您想为特定通知指定其他连接,可以onConnection从通知的构造函数中调用该方法:

1<?php
2 
3namespace App\Notifications;
4 
5use Illuminate\Bus\Queueable;
6use Illuminate\Contracts\Queue\ShouldQueue;
7use Illuminate\Notifications\Notification;
8 
9class InvoicePaid extends Notification implements ShouldQueue
10{
11 use Queueable;
12 
13 /**
14 * Create a new notification instance.
15 */
16 public function __construct()
17 {
18 $this->onConnection('redis');
19 }
20}

或者,如果您想为通知支持的每个通知渠道指定一个特定的队列连接,您可以viaConnections在通知中定义一个方法。此方法应返回一个由渠道名称/队列连接名称对组成的数组:

1/**
2 * Determine which connections should be used for each notification channel.
3 *
4 * @return array<string, string>
5 */
6public function viaConnections(): array
7{
8 return [
9 'mail' => 'redis',
10 'database' => 'sync',
11 ];
12}

自定义通知渠道队列

如果您希望为通知支持的每个通知渠道指定一个特定的队列,您可以viaQueues在通知中定义一个方法。此方法应返回一个由渠道名称/队列名称对组成的数组:

1/**
2 * Determine which queues should be used for each notification channel.
3 *
4 * @return array<string, string>
5 */
6public function viaQueues(): array
7{
8 return [
9 'mail' => 'mail-queue',
10 'slack' => 'slack-queue',
11 ];
12}

排队通知中间件

队列通知可以像队列作业一样定义中间件。首先,middleware在通知类中定义一个方法。该middleware方法将接收$notifiable$channel变量,这些变量允许您根据通知的目的地自定义返回的中间件:

1use Illuminate\Queue\Middleware\RateLimited;
2 
3/**
4 * Get the middleware the notification job should pass through.
5 *
6 * @return array<int, object>
7 */
8public function middleware(object $notifiable, string $channel)
9{
10 return match ($channel) {
11 'mail' => [new RateLimited('postmark')],
12 'slack' => [new RateLimited('slack')],
13 default => [],
14 };
15}

排队通知和数据库事务

当队列通知在数据库事务中调度时,它们可能会在数据库事务提交之前就被队列处理。发生这种情况时,您在数据库事务期间对模型或数据库记录所做的任何更新可能尚未反映在数据库中。此外,在事务中创建的任何模型或数据库记录可能都不存在于数据库中。如果您的通知依赖于这些模型,则在处理发送队列通知的作业时可能会发生意外错误。

如果您的队列连接的after_commit配置选项设置为,您仍然可以通过在发送通知时false调用方法来指示在提交所有打开的数据库事务后应分派特定的排队通知:afterCommit

1use App\Notifications\InvoicePaid;
2 
3$user->notify((new InvoicePaid($invoice))->afterCommit());

或者,您可以afterCommit从通知的构造函数中调用该方法:

1<?php
2 
3namespace App\Notifications;
4 
5use Illuminate\Bus\Queueable;
6use Illuminate\Contracts\Queue\ShouldQueue;
7use Illuminate\Notifications\Notification;
8 
9class InvoicePaid extends Notification implements ShouldQueue
10{
11 use Queueable;
12 
13 /**
14 * Create a new notification instance.
15 */
16 public function __construct()
17 {
18 $this->afterCommit();
19 }
20}

确定是否应发送排队通知

在将排队通知分派给队列进行后台处理后,它通常会被队列工作者接受并发送给其预期的接收者。

但是,如果您想在队列工作器处理完队列通知后,最终决定是否发送该通知,则可以shouldSend在通知类中定义一个方法。如果此方法返回false,则不会发送通知:

1/**
2 * Determine if the notification should be sent.
3 */
4public function shouldSend(object $notifiable, string $channel): bool
5{
6 return $this->invoice->isPaid();
7}

按需通知

有时你可能需要向未存储为应用程序“用户”的用户发送通知。使用Notification外观层的route方法,你可以在发送通知之前指定临时通知路由信息:

1use Illuminate\Broadcasting\Channel;
2use Illuminate\Support\Facades\Notification;
3 
4Notification::route('mail', 'taylor@example.com')
5 ->route('vonage', '5555555555')
6 ->route('slack', '#slack-channel')
7 ->route('broadcast', [new Channel('channel-name')])
8 ->notify(new InvoicePaid($invoice));

如果您想在向路由发送按需通知时提供收件人的姓名mail,您可以提供一个数组,该数组包含电子邮件地址作为键,名称作为数组中第一个元素的值:

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

使用该routes方法,您可以同时为多个通知渠道提供临时路由信息:

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

邮件通知

格式化邮件消息

如果通知支持以电子邮件形式发送,则应toMail在通知类上定义一个方法。此方法将接收一个$notifiable实体并返回一个Illuminate\Notifications\Messages\MailMessage实例。

该类MailMessage包含一些简单的方法,可帮助您构建事务性电子邮件。邮件消息可能包含多行文本以及“行动号召”。我们来看一个示例toMail方法:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 $url = url('/invoice/'.$this->invoice->id);
7 
8 return (new MailMessage)
9 ->greeting('Hello!')
10 ->line('One of your invoices has been paid!')
11 ->lineIf($this->amount > 0, "Amount paid: {$this->amount}")
12 ->action('View Invoice', $url)
13 ->line('Thank you for using our application!');
14}

$this->invoice->id注意,我们是在方法中 使用toMail。您可以将通知生成消息所需的任何数据传递到通知的构造函数中。

在此示例中,我们注册了问候语、一行文本、行动号召以及另一行文本。MailMessage对象提供的这些方法使格式化小型事务性电子邮件变得简单快捷。然后,邮件通道会将这些消息组件转换为美观、响应式的 HTML 电子邮件模板,并附带纯文本副本。以下是该通道生成的电子邮件示例mail

name发送邮件通知时,请务必在配置文件中 设置配置选项config/app.php。此值将用于邮件通知消息的页眉和页脚。

错误消息

某些通知会告知用户错误,例如发票付款失败。您可以error在构建邮件时调用该方法,以指示邮件消息与错误有关。error在邮件消息中使用该方法时,行动号召按钮将显示为红色,而不是黑色:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->error()
8 ->subject('Invoice Payment Failed')
9 ->line('...');
10}

其他邮件通知格式选项

您无需在通知类中定义文本“行”,而是可以使用该view方法指定用于呈现通知电子邮件的自定义模板:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)->view(
7 'mail.invoice.paid', ['invoice' => $this->invoice]
8 );
9}

您可以通过将视图名称作为提供给该方法的数组的第二个元素来为邮件消息指定纯文本视图view

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)->view(
7 ['mail.invoice.paid', 'mail.invoice.paid-text'],
8 ['invoice' => $this->invoice]
9 );
10}

或者,如果您的消息只有纯文本视图,您可以使用该text方法:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)->text(
7 'mail.invoice.paid-text', ['invoice' => $this->invoice]
8 );
9}

自定义发件人

默认情况下,电子邮件的发件人/发件人地址已在config/mail.php配置文件中定义。但是,您可以使用以下命令为特定通知指定发件人地址from

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->from('barrett@example.com', 'Barrett Blair')
8 ->line('...');
9}

自定义收件人

通过渠道发送通知时mail,通知系统会自动查找可通知实体上的属性。您可以通过在可通知实体上email定义方法来自定义用于发送通知的电子邮件地址:routeNotificationForMail

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7use Illuminate\Notifications\Notification;
8 
9class User extends Authenticatable
10{
11 use Notifiable;
12 
13 /**
14 * Route notifications for the mail channel.
15 *
16 * @return array<string, string>|string
17 */
18 public function routeNotificationForMail(Notification $notification): array|string
19 {
20 // Return email address only...
21 return $this->email_address;
22 
23 // Return email address and name...
24 return [$this->email_address => $this->name];
25 }
26}

自定义主题

默认情况下,电子邮件的主题是通知类名,并采用“标题大小写”格式。因此,如果您的通知类名为InvoicePaid,则电子邮件的主题将为Invoice Paid。如果您想为邮件指定其他主题,可以subject在构建邮件时调用该方法:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->subject('Notification Subject')
8 ->line('...');
9}

自定义邮件程序

默认情况下,电子邮件通知将使用配置文件中定义的默认邮件程序发送。但是,您可以在运行时通过在构建消息时config/mail.php调用以下方法来指定其他邮件程序:mailer

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->mailer('postmark')
8 ->line('...');
9}

自定义模板

您可以通过发布通知包的资源来修改邮件通知使用的 HTML 和纯文本模板。运行此命令后,邮件通知模板将位于以下resources/views/vendor/notifications目录中:

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

附件

要将附件添加到电子邮件通知,请attach在构建消息时使用该方法。该attach方法接受文件的绝对路径作为其第一个参数:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Hello!')
8 ->attach('/path/to/file');
9}

attach通知邮件提供的方法也接受附加对象。请参阅可附加对象的完整文档以了解更多信息。

将文件附加到消息时,您还可以通过将array作为第二个参数传递给attach方法来指定显示名称和/或 MIME 类型:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Hello!')
8 ->attach('/path/to/file', [
9 'as' => 'name.pdf',
10 'mime' => 'application/pdf',
11 ]);
12}

与在可邮寄对象中附加文件不同,您不能使用 直接从存储磁盘附加文件attachFromStorage。您应该使用attach方法来附加存储磁盘上文件的绝对路径。或者,您可以从方法来返回一个可邮寄对象toMail

1use App\Mail\InvoicePaid as InvoicePaidMailable;
2 
3/**
4 * Get the mail representation of the notification.
5 */
6public function toMail(object $notifiable): Mailable
7{
8 return (new InvoicePaidMailable($this->invoice))
9 ->to($notifiable->email)
10 ->attachFromStorage('/path/to/file');
11}

必要时,可以使用下列方法将多个文件附加到一条消息中attachMany

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Hello!')
8 ->attachMany([
9 '/path/to/forge.svg',
10 '/path/to/vapor.svg' => [
11 'as' => 'Logo.svg',
12 'mime' => 'image/svg+xml',
13 ],
14 ]);
15}

原始数据附件

attachData方法可用于将原始字节字符串作为附件附加。调用该attachData方法时,应提供分配给附件的文件名:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Hello!')
8 ->attachData($this->pdf, 'name.pdf', [
9 'mime' => 'application/pdf',
10 ]);
11}

添加标签和元数据

一些第三方电子邮件提供商(例如 Mailgun 和 Postmark)支持邮件“标签”和“元数据”,可用于对应用程序发送的邮件进行分组和跟踪。您可以通过tagmetadata方法向电子邮件消息添加标签和元数据:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Comment Upvoted!')
8 ->tag('upvote')
9 ->metadata('comment_id', $this->comment->id);
10}

如果您的应用程序使用的是 Mailgun 驱动程序,您可以查阅 Mailgun 的文档以获取有关标签元数据的更多信息。同样,您也可以查阅 Postmark 文档以获取有关其对标签元数据的支持的更多信息

如果您的应用程序使用 Amazon SES 发送电子邮件,您应该使用该方法将SES“标签”metadata附加到消息中。

自定义 Symfony 消息

withSymfonyMessage该类的方法允许MailMessage你注册一个闭包,该闭包将在发送消息之前由 Symfony Message 实例调用。这让你有机会在消息传递之前对其进行深度自定义:

1use Symfony\Component\Mime\Email;
2 
3/**
4 * Get the mail representation of the notification.
5 */
6public function toMail(object $notifiable): MailMessage
7{
8 return (new MailMessage)
9 ->withSymfonyMessage(function (Email $message) {
10 $message->getHeaders()->addTextHeader(
11 'Custom-Header', 'Header Value'
12 );
13 });
14}

使用 Mailables

如果需要,您可以从通知的方法中返回一个完整的可邮寄对象toMail。当返回 而Mailable不是 时MailMessage,您需要使用可邮寄对象的to方法指定消息收件人:

1use App\Mail\InvoicePaid as InvoicePaidMailable;
2use Illuminate\Mail\Mailable;
3 
4/**
5 * Get the mail representation of the notification.
6 */
7public function toMail(object $notifiable): Mailable
8{
9 return (new InvoicePaidMailable($this->invoice))
10 ->to($notifiable->email);
11}

邮件和按需通知

如果您要发送按需通知,则$notifiable赋予该toMail方法的实例将是的实例Illuminate\Notifications\AnonymousNotifiable,它提供了一种routeNotificationFor可用于检索应将按需通知发送到的电子邮件地址的方法:

1use App\Mail\InvoicePaid as InvoicePaidMailable;
2use Illuminate\Notifications\AnonymousNotifiable;
3use Illuminate\Mail\Mailable;
4 
5/**
6 * Get the mail representation of the notification.
7 */
8public function toMail(object $notifiable): Mailable
9{
10 $address = $notifiable instanceof AnonymousNotifiable
11 ? $notifiable->routeNotificationFor('mail')
12 : $notifiable->email;
13 
14 return (new InvoicePaidMailable($this->invoice))
15 ->to($address);
16}

预览邮件通知

在设计邮件通知模板时,像典型的 Blade 模板一样,在浏览器中快速预览渲染后的邮件消息非常方便。因此,Laravel 允许你直接从路由闭包或控制器返回由邮件通知生成的任何邮件消息。MailMessage返回后,它将被渲染并显示在浏览器中,让你可以快速预览其设计,而无需将其发送到实际的电子邮件地址:

1use App\Models\Invoice;
2use App\Notifications\InvoicePaid;
3 
4Route::get('/notification', function () {
5 $invoice = Invoice::find(1);
6 
7 return (new InvoicePaid($invoice))
8 ->toMail($invoice->user);
9});

Markdown 邮件通知

Markdown 邮件通知让您能够充分利用预置的邮件通知模板,同时还能让您更自由地编写更长、更个性化的消息。由于消息以 Markdown 编写,Laravel 能够为消息渲染美观、响应式的 HTML 模板,并自动生成纯文本版本。

生成消息

要使用相应的 Markdown 模板生成通知,您可以使用Artisan 命令--markdown的选项make:notification

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

与所有其他邮件通知一样,使用 Markdown 模板的通知应toMail在其通知类中定义一个方法。但是,与其使用lineaction方法来构造通知,不如使用markdown方法来指定应使用的 Markdown 模板的名称。你希望提供给模板的数据数组可以作为该方法的第二个参数传递:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 $url = url('/invoice/'.$this->invoice->id);
7 
8 return (new MailMessage)
9 ->subject('Invoice Paid')
10 ->markdown('mail.invoice.paid', ['url' => $url]);
11}

撰写信息

Markdown 邮件通知使用 Blade 组件和 Markdown 语法的组合,允许您轻松构建通知,同时利用 Laravel 预先制作的通知组件:

1<x-mail::message>
2# Invoice Paid
3 
4Your invoice has been paid!
5 
6<x-mail::button :url="$url">
7View Invoice
8</x-mail::button>
9 
10Thanks,<br>
11{{ config('app.name') }}
12</x-mail::message>

撰写 Markdown 电子邮件时,请勿使用过多的缩进。根据 Markdown 标准,Markdown 解析器会将缩进的内容渲染为代码块。

按钮组件

按钮组件渲染一个居中的按钮链接。该组件接受两个参数:url和一个可选的color。支持的颜色包括primarygreenred。您可以根据需要向通知添加任意数量的按钮组件:

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

面板组件

面板组件会将指定的文本块渲染到一个面板中,该面板的背景颜色与通知的其余部分略有不同。这可以让你更好地吸引用户对指定文本块的注意力:

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

表格组件

表格组件允许您将 Markdown 表格转换为 HTML 表格。该组件接受 Markdown 表格作为其内容。表格列对齐支持使用默认的 Markdown 表格对齐语法:

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

自定义组件

你可以将所有 Markdown 通知组件导出到你自己的应用程序中,以便进行自定义。要导出组件,请使用vendor:publishArtisan 命令发布laravel-mail资源标签:

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

此命令会将 Markdown 邮件组件发布到resources/views/vendor/mail目录。该mail目录将包含一个html和一个text目录,每个目录包含每个可用组件的对应表示。您可以随意自定义这些组件。

自定义 CSS

导出组件后,resources/views/vendor/mail/html/themes目录将包含一个default.css文件。您可以自定义此文件中的 CSS,您的样式将自动内联到 Markdown 通知的 HTML 表示中。

如果您想为 Laravel 的 Markdown 组件构建一个全新的主题,您可以在该html/themes目录中放置一个 CSS 文件。命名并保存 CSS 文件后,更新配置文件theme的选项mail以匹配新主题的名称。

要自定义单个通知的主题,您可以theme在构建通知邮件消息时调用该方法。该theme方法接受发送通知时应使用的主题名称:

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->theme('invoice')
8 ->subject('Invoice Paid')
9 ->markdown('mail.invoice.paid', ['url' => $url]);
10}

数据库通知

先决条件

通知渠道database将通知信息存储在数据库表中。该表将包含通知类型等信息以及描述通知的 JSON 数据结构。

您可以查询该表以在应用程序的用户界面中显示通知。但是,在此之前,您需要创建一个数据库表来保存通知。您可以使用以下make:notifications-table命令生成具有正确表架构的迁移:

1php artisan make:notifications-table
2 
3php artisan migrate

如果您的可通知模型使用UUID 或 ULID 主键,则应在通知表迁移中将该morphs方法替换为uuidMorphsulidMorphs 。

格式化数据库通知

如果通知支持存储在数据库表中,则应在通知类中定义一个toDatabase或方法。此方法将接收一个实体并返回一个纯 PHP 数组。返回的数组将被编码为 JSON 并存储在表的列中。我们来看一个示例方法:toArray$notifiabledatanotificationstoArray

1/**
2 * Get the array representation of the notification.
3 *
4 * @return array<string, mixed>
5 */
6public function toArray(object $notifiable): array
7{
8 return [
9 'invoice_id' => $this->invoice->id,
10 'amount' => $this->invoice->amount,
11 ];
12}

当通知存储在应用程序的数据库中时,type列默认将设置为通知的类名,read_at列将为。但是,您可以通过在通知类中null定义databaseType和方法来自定义此行为:initialDatabaseReadAtValue

1use Illuminate\Support\Carbon;
1/**
2 * Get the notification's database type.
3 */
4public function databaseType(object $notifiable): string
5{
6 return 'invoice-paid';
7}
8 
9/**
10 * Get the initial value for the "read_at" column.
11 */
12public function initialDatabaseReadAtValue(): ?Carbon
13{
14 return null;
15}

toDatabase对比toArray

toArray方法也被broadcast通道用来决定向 JavaScript 前端广播哪些数据。如果您希望为databasebroadcast通道使用两种不同的数组表示,则应该定义一个toDatabase方法,而不是一个toArray方法。

访问通知

将通知存储到数据库中后,您需要一种便捷的方式从可通知实体中访问它们。LaravelIlluminate\Notifications\Notifiable默认App\Models\User模型中包含的 trait 包含一个notifications Eloquent 关联,用于返回实体的通知。要获取通知,您可以像访问其他 Eloquent 关联一样访问此方法。默认情况下,通知将按created_at时间戳排序,最新的通知位于集合的开头:

1$user = App\Models\User::find(1);
2 
3foreach ($user->notifications as $notification) {
4 echo $notification->type;
5}

如果您只想检索“未读”通知,可以使用该unreadNotifications关系。同样,这些通知将按created_at时间戳排序,最新通知位于集合的开头:

1$user = App\Models\User::find(1);
2 
3foreach ($user->unreadNotifications as $notification) {
4 echo $notification->type;
5}

要从 JavaScript 客户端访问通知,您需要为应用定义一个通知控制器,该控制器返回可通知实体(例如当前用户)的通知。然后,您可以从 JavaScript 客户端向该控制器的 URL 发出 HTTP 请求。

将通知标记为已读

通常,当用户查看通知时,你会希望将其标记为“已读”。traitIlluminate\Notifications\Notifiable提供了一个markAsRead方法,用于更新read_at通知数据库记录中的相应列:

1$user = App\Models\User::find(1);
2 
3foreach ($user->unreadNotifications as $notification) {
4 $notification->markAsRead();
5}

markAsRead但是,您可以直接在通知集合上使用该方法,而不是循环遍历每个通知:

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

您还可以使用批量更新查询将所有通知标记为已读,而无需从数据库中检索它们:

1$user = App\Models\User::find(1);
2 
3$user->unreadNotifications()->update(['read_at' => now()]);

您可以delete通知他们从表中完全删除:

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

广播通知

先决条件

在广播通知之前,您应该配置并熟悉 Laravel 的事件广播服务。事件广播提供了一种从 JavaScript 前端响应服务器端 Laravel 事件的方法。

格式化广播通知

broadcast频道使用 Laravel 的事件广播服务来广播通知,从而使你基于 JavaScript 的前端能够实时捕获通知。如果通知支持广播,你可以toBroadcast在通知类中定义一个方法。该方法将接收一个$notifiable实体并返回一个BroadcastMessage实例。如果该toBroadcast方法不存在,则该toArray方法将用于收集需要广播的数据。返回的数据将被编码为 JSON 并广播到你基于 JavaScript 的前端。我们来看一个示例toBroadcast方法:

1use Illuminate\Notifications\Messages\BroadcastMessage;
2 
3/**
4 * Get the broadcastable representation of the notification.
5 */
6public function toBroadcast(object $notifiable): BroadcastMessage
7{
8 return new BroadcastMessage([
9 'invoice_id' => $this->invoice->id,
10 'amount' => $this->invoice->amount,
11 ]);
12}

广播队列配置

所有广播通知都会被加入队列等待广播。如果您想配置用于将广播操作排队的队列连接或队列名称,可以使用 的onConnectiononQueue方法BroadcastMessage

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

自定义通知类型

除了你指定的数据之外,所有广播通知还包含一个type字段,其中包含通知的完整类名。如果你想自定义通知type,可以broadcastType在通知类上定义一个方法:

1/**
2 * Get the type of the notification being broadcast.
3 */
4public function broadcastType(): string
5{
6 return 'broadcast.message';
7}

监听通知

通知将通过约定格式的私有频道进行广播。因此,如果您向 ID 为 的实例{notifiable}.{id}发送通知,该通知将通过私有频道进行广播。使用Laravel Echo时,您可以使用以下方法轻松地在频道上监听通知App\Models\User1App.Models.User.1notification

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

自定义通知渠道

如果您想自定义实体的广播通知在哪个频道上广播,您可以receivesBroadcastNotificationsOn在可通知实体上定义一个方法:

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Broadcasting\PrivateChannel;
6use Illuminate\Foundation\Auth\User as Authenticatable;
7use Illuminate\Notifications\Notifiable;
8 
9class User extends Authenticatable
10{
11 use Notifiable;
12 
13 /**
14 * The channels the user receives notification broadcasts on.
15 */
16 public function receivesBroadcastNotificationsOn(): string
17 {
18 return 'users.'.$this->id;
19 }
20}

短信通知

先决条件

Laravel 中的短信通知功能由Vonage(原名 Nexmo)提供支持。在通过 Vonage 发送通知之前,您需要安装laravel/vonage-notification-channel以下guzzlehttp/guzzle软件包:

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

该软件包包含一个配置文件。但是,您无需将此配置文件导出到您自己的应用程序中。您只需使用VONAGE_KEYVONAGE_SECRET环境变量来定义您的 Vonage 公钥和密钥即可。

定义密钥后,您应该设置一个VONAGE_SMS_FROM环境变量,该变量定义默认发送短信的电话号码。您可以在 Vonage 控制面板中生成此电话号码:

1VONAGE_SMS_FROM=15556666666

格式化短信通知

如果通知支持短信发送,则应toVonage在通知类中定义一个方法。此方法将接收一个$notifiable实体并返回一个Illuminate\Notifications\Messages\VonageMessage实例:

1use Illuminate\Notifications\Messages\VonageMessage;
2 
3/**
4 * Get the Vonage / SMS representation of the notification.
5 */
6public function toVonage(object $notifiable): VonageMessage
7{
8 return (new VonageMessage)
9 ->content('Your SMS message content');
10}

Unicode 内容

如果您的短信包含unicode字符,您应该unicode在构造VonageMessage实例时调用该方法:

1use Illuminate\Notifications\Messages\VonageMessage;
2 
3/**
4 * Get the Vonage / SMS representation of the notification.
5 */
6public function toVonage(object $notifiable): VonageMessage
7{
8 return (new VonageMessage)
9 ->content('Your unicode message')
10 ->unicode();
11}

自定义“发件人”号码

如果您想从与环境变量指定的电话号码不同的电话号码发送一些通知VONAGE_SMS_FROM,您可以在实例上调用该from方法VonageMessage

1use Illuminate\Notifications\Messages\VonageMessage;
2 
3/**
4 * Get the Vonage / SMS representation of the notification.
5 */
6public function toVonage(object $notifiable): VonageMessage
7{
8 return (new VonageMessage)
9 ->content('Your SMS message content')
10 ->from('15554443333');
11}

添加客户参考

如果您想跟踪每个用户、团队或客户的成本,您可以在通知中添加“客户参考号”。Vonage 允许您使用此客户参考号生成报告,以便您更好地了解特定客户的短信使用情况。客户参考号可以是最多 40 个字符的任意字符串:

1use Illuminate\Notifications\Messages\VonageMessage;
2 
3/**
4 * Get the Vonage / SMS representation of the notification.
5 */
6public function toVonage(object $notifiable): VonageMessage
7{
8 return (new VonageMessage)
9 ->clientReference((string) $notifiable->id)
10 ->content('Your SMS message content');
11}

路由短信通知

要将 Vonage 通知路由到正确的电话号码,请routeNotificationForVonage在可通知实体上定义一种方法:

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7use Illuminate\Notifications\Notification;
8 
9class User extends Authenticatable
10{
11 use Notifiable;
12 
13 /**
14 * Route notifications for the Vonage channel.
15 */
16 public function routeNotificationForVonage(Notification $notification): string
17 {
18 return $this->phone_number;
19 }
20}

Slack 通知

先决条件

在发送 Slack 通知之前,您应该通过 Composer 安装 Slack 通知频道:

1composer require laravel/slack-notification-channel

此外,您必须为您的 Slack 工作区创建一个Slack 应用程序。

如果您只需要将通知发送到创建应用的同一 Slack 工作区,则应确保您的应用具有chat:writechat:write.publicchat:write.customize作用域。您可以从 Slack 中的“OAuth 与权限”应用管理选项卡中添加这些作用域。

接下来,复制应用程序的“机器人用户 OAuth 令牌”,并将其放入slack应用程序services.php配置文件的配置数组中。此令牌可以在 Slack 的“OAuth 和权限”选项卡中找到:

1'slack' => [
2 'notifications' => [
3 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'),
4 'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
5 ],
6],

应用分发

如果您的应用程序将向应用程序用户拥有的外部 Slack 工作区发送通知,则需要通过 Slack 分发您的应用程序。您可以通过 Slack 中的“管理分发”选项卡管理应用程序的分发。应用程序分发完成后,您可以使用Socialite代表应用程序用户获取Slack Bot 令牌。

格式化 Slack 通知

如果通知支持以 Slack 消息形式发送,则应toSlack在通知类中定义一个方法。此方法将接收一个$notifiable实体并返回一个实例。您可以使用Slack 的 Block Kit APIIlluminate\Notifications\Slack\SlackMessage构建富文本通知。以下示例可在Slack 的 Block Kit 构建器中预览:

1use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
2use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
3use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
4use Illuminate\Notifications\Slack\SlackMessage;
5 
6/**
7 * Get the Slack representation of the notification.
8 */
9public function toSlack(object $notifiable): SlackMessage
10{
11 return (new SlackMessage)
12 ->text('One of your invoices has been paid!')
13 ->headerBlock('Invoice Paid')
14 ->contextBlock(function (ContextBlock $block) {
15 $block->text('Customer #1234');
16 })
17 ->sectionBlock(function (SectionBlock $block) {
18 $block->text('An invoice has been paid.');
19 $block->field("*Invoice No:*\n1000")->markdown();
20 $block->field("*Invoice Recipient:*\ntaylor@laravel.com")->markdown();
21 })
22 ->dividerBlock()
23 ->sectionBlock(function (SectionBlock $block) {
24 $block->text('Congratulations!');
25 });
26}

使用 Slack 的 Block Kit Builder 模板

您可以不使用流畅的消息构建器方法来构造 Block Kit 消息,而是将 Slack 的 Block Kit Builder 生成的原始 JSON 有效负载提供给该usingBlockKitTemplate方法:

1use Illuminate\Notifications\Slack\SlackMessage;
2use Illuminate\Support\Str;
3 
4/**
5 * Get the Slack representation of the notification.
6 */
7public function toSlack(object $notifiable): SlackMessage
8{
9 $template = <<<JSON
10 {
11 "blocks": [
12 {
13 "type": "header",
14 "text": {
15 "type": "plain_text",
16 "text": "Team Announcement"
17 }
18 },
19 {
20 "type": "section",
21 "text": {
22 "type": "plain_text",
23 "text": "We are hiring!"
24 }
25 }
26 ]
27 }
28 JSON;
29 
30 return (new SlackMessage)
31 ->usingBlockKitTemplate($template);
32}

Slack 交互

Slack 的 Block Kit 通知系统提供了强大的功能来处理用户交互。要使用这些功能,您的 Slack 应用应启用“交互”功能,并配置指向您应用所提供服务的 URL 的“请求 URL”。您可以在 Slack 的应用管理选项卡中管理这些设置。

在以下使用该方法的示例中actionsBlock,Slack 将向POST您的“请求 URL”发送一个请求,其中包含点击按钮的 Slack 用户、被点击按钮的 ID 等信息。您的应用程序可以根据该信息确定要执行的操作。您还应该验证该请求是否由 Slack 发出:

1use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
2use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
3use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
4use Illuminate\Notifications\Slack\SlackMessage;
5 
6/**
7 * Get the Slack representation of the notification.
8 */
9public function toSlack(object $notifiable): SlackMessage
10{
11 return (new SlackMessage)
12 ->text('One of your invoices has been paid!')
13 ->headerBlock('Invoice Paid')
14 ->contextBlock(function (ContextBlock $block) {
15 $block->text('Customer #1234');
16 })
17 ->sectionBlock(function (SectionBlock $block) {
18 $block->text('An invoice has been paid.');
19 })
20 ->actionsBlock(function (ActionsBlock $block) {
21 // ID defaults to "button_acknowledge_invoice"...
22 $block->button('Acknowledge Invoice')->primary();
23 
24 // Manually configure the ID...
25 $block->button('Deny')->danger()->id('deny_invoice');
26 });
27}

确认模式

如果您希望用户在执行操作之前需要确认,则可以confirm在定义按钮时调用该方法。该confirm方法接受一条消息和一个接收ConfirmObject实例的闭包:

1use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
2use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
3use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
4use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
5use Illuminate\Notifications\Slack\SlackMessage;
6 
7/**
8 * Get the Slack representation of the notification.
9 */
10public function toSlack(object $notifiable): SlackMessage
11{
12 return (new SlackMessage)
13 ->text('One of your invoices has been paid!')
14 ->headerBlock('Invoice Paid')
15 ->contextBlock(function (ContextBlock $block) {
16 $block->text('Customer #1234');
17 })
18 ->sectionBlock(function (SectionBlock $block) {
19 $block->text('An invoice has been paid.');
20 })
21 ->actionsBlock(function (ActionsBlock $block) {
22 $block->button('Acknowledge Invoice')
23 ->primary()
24 ->confirm(
25 'Acknowledge the payment and send a thank you email?',
26 function (ConfirmObject $dialog) {
27 $dialog->confirm('Yes');
28 $dialog->deny('No');
29 }
30 );
31 });
32}

检查 Slack Blocks

如果您想快速检查已构建的块,可以在实例dd上调用该方法SlackMessage。该方法将生成并转储指向 Slack 的Block Kit Builder 的ddURL ,该 URL 会在您的浏览器中显示有效负载和通知的预览。您可以传递给该方法以转储原始有效负载:truedd

1return (new SlackMessage)
2 ->text('One of your invoices has been paid!')
3 ->headerBlock('Invoice Paid')
4 ->dd();

路由 Slack 通知

要将 Slack 通知定向到相应的 Slack 团队和频道,请routeNotificationForSlack在可通知模型上定义一个方法。此方法可以返回以下三个值之一:

  • null- 这会将路由延迟到通知本身中配置的渠道。您可以to在构建通知时使用此方法SlackMessage来配置通知中的渠道。
  • 指定要发送通知的 Slack 频道的字符串,例如#support-channel
  • 一个SlackRoute实例,允许您指定 OAuth 令牌和通道名称,例如SlackRoute::make($this->slack_channel, $this->slack_token)。此方法应用于向外部工作区发送通知。

例如,#support-channelrouteNotificationForSlack方法返回将把通知发送到#support-channel与位于应用程序services.php配置文件中的 Bot User OAuth 令牌关联的工作区中的频道:

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7use Illuminate\Notifications\Notification;
8 
9class User extends Authenticatable
10{
11 use Notifiable;
12 
13 /**
14 * Route notifications for the Slack channel.
15 */
16 public function routeNotificationForSlack(Notification $notification): mixed
17 {
18 return '#support-channel';
19 }
20}

通知外部 Slack 工作区

在向外部 Slack 工作区发送通知之前,必须先分发您的 Slack 应用程序。

当然,您经常需要向应用程序用户的 Slack 工作区发送通知。为此,您首先需要为用户获取 Slack OAuth 令牌。值得庆幸的是,Laravel Socialite包含一个 Slack 驱动程序,可让您轻松地使用 Slack 对应用程序用户进行身份验证并获取机器人令牌

获取机器人令牌并将其存储在应用程序数据库中后,即可使用该SlackRoute::make方法将通知路由到用户工作区。此外,您的应用程序可能需要为用户提供指定通知发送渠道的机会:

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7use Illuminate\Notifications\Notification;
8use Illuminate\Notifications\Slack\SlackRoute;
9 
10class User extends Authenticatable
11{
12 use Notifiable;
13 
14 /**
15 * Route notifications for the Slack channel.
16 */
17 public function routeNotificationForSlack(Notification $notification): mixed
18 {
19 return SlackRoute::make($this->slack_channel, $this->slack_token);
20 }
21}

本地化通知

Laravel 允许您使用 HTTP 请求的当前语言环境以外的语言环境发送通知,并且如果通知已排队,甚至会记住此语言环境。

为了实现这一点,Illuminate\Notifications\Notification该类提供了一个locale方法来设置所需的语言。应用程序将在评估通知时切换到此语言环境,然后在评估完成后恢复到先前的语言环境:

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

多个可通知条目的本地化也可以通过Notification外观实现:

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

用户首选语言环境

有时,应用程序会存储每个用户的首选语言环境。通过HasLocalePreference在可通知模型上实现此约定,您可以指示 Laravel 在发送通知时使用此存储的语言环境:

1use Illuminate\Contracts\Translation\HasLocalePreference;
2 
3class User extends Model implements HasLocalePreference
4{
5 /**
6 * Get the user's preferred locale.
7 */
8 public function preferredLocale(): string
9 {
10 return $this->locale;
11 }
12}

locale实现该接口后,Laravel 会在向模型发送通知和邮件时自动使用首选语言环境。因此,使用此接口时无需调用该方法:

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

测试

您可以使用Notification外观层的fake方法阻止发送通知。通常,发送通知与您实际测试的代码无关。通常情况下,只需断言 Laravel 已收到指示发送指定通知即可。

调用Notification外观的fake方法后,您可以断言已指示将通知发送给用户,甚至检查通知收到的数据:

1<?php
2 
3use App\Notifications\OrderShipped;
4use Illuminate\Support\Facades\Notification;
5 
6test('orders can be shipped', function () {
7 Notification::fake();
8 
9 // Perform order shipping...
10 
11 // Assert that no notifications were sent...
12 Notification::assertNothingSent();
13 
14 // Assert a notification was sent to the given users...
15 Notification::assertSentTo(
16 [$user], OrderShipped::class
17 );
18 
19 // Assert a notification was not sent...
20 Notification::assertNotSentTo(
21 [$user], AnotherNotification::class
22 );
23 
24 // Assert that a given number of notifications were sent...
25 Notification::assertCount(3);
26});
1<?php
2 
3namespace Tests\Feature;
4 
5use App\Notifications\OrderShipped;
6use Illuminate\Support\Facades\Notification;
7use Tests\TestCase;
8 
9class ExampleTest extends TestCase
10{
11 public function test_orders_can_be_shipped(): void
12 {
13 Notification::fake();
14 
15 // Perform order shipping...
16 
17 // Assert that no notifications were sent...
18 Notification::assertNothingSent();
19 
20 // Assert a notification was sent to the given users...
21 Notification::assertSentTo(
22 [$user], OrderShipped::class
23 );
24 
25 // Assert a notification was not sent...
26 Notification::assertNotSentTo(
27 [$user], AnotherNotification::class
28 );
29 
30 // Assert that a given number of notifications were sent...
31 Notification::assertCount(3);
32 }
33}

你可以将闭包传递给assertSentToassertNotSentTo方法,以断言已发送的通知是否通过了给定的“真实性测试”。如果至少有一个通知通过了给定的真实性测试,则断言成功:

1Notification::assertSentTo(
2 $user,
3 function (OrderShipped $notification, array $channels) use ($order) {
4 return $notification->order->id === $order->id;
5 }
6);

按需通知

如果您正在测试的代码发送按需通知,则可以通过该方法测试按需通知是否已发送assertSentOnDemand

1Notification::assertSentOnDemand(OrderShipped::class);

通过将闭包作为第二个参数传递给assertSentOnDemand方法,您可以确定按需通知是否已发送到正确的“路由”地址:

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

通知事件

通知发送事件

当通知发送时,Illuminate\Notifications\Events\NotificationSending通知系统会调度相应事件。该事件包含“可通知”实体和通知实例本身。您可以在应用中为该事件创建事件监听器:

1use Illuminate\Notifications\Events\NotificationSending;
2 
3class CheckNotificationStatus
4{
5 /**
6 * Handle the event.
7 */
8 public function handle(NotificationSending $event): void
9 {
10 // ...
11 }
12}

如果事件的事件监听器从其方法NotificationSending返回,则不会发送通知falsehandle

1/**
2 * Handle the event.
3 */
4public function handle(NotificationSending $event): bool
5{
6 return false;
7}

在事件监听器中,您可以访问事件的notifiablenotification和属性来了解有关通知接收者或通知本身的更多信息:channel

1/**
2 * Handle the event.
3 */
4public function handle(NotificationSending $event): void
5{
6 // $event->channel
7 // $event->notifiable
8 // $event->notification
9}

通知已发送事件

发送通知时,通知系统会调度Illuminate\Notifications\Events\NotificationSent 相应事件。该事件包含“可通知”实体和通知实例本身。您可以在应用中为该事件创建事件监听器:

1use Illuminate\Notifications\Events\NotificationSent;
2 
3class LogNotification
4{
5 /**
6 * Handle the event.
7 */
8 public function handle(NotificationSent $event): void
9 {
10 // ...
11 }
12}

在事件监听器中,您可以访问事件的notifiablenotificationchannel和属性来了解有关通知接收者或通知本身的更多信息:response

1/**
2 * Handle the event.
3 */
4public function handle(NotificationSent $event): void
5{
6 // $event->channel
7 // $event->notifiable
8 // $event->notification
9 // $event->response
10}

自定义频道

Laravel 附带了一些通知渠道,但您可能希望编写自己的驱动程序以通过其他渠道发送通知。Laravel 让这一切变得简单。首先,定义一个包含send方法的类。该方法应该接收两个参数: a$notifiable和 a $notification

在该send方法中,您可以调用通知上的方法来检索您的频道理解的消息对象,然后$notifiable按照您希望的方式将通知发送到实例:

1<?php
2 
3namespace App\Notifications;
4 
5use Illuminate\Notifications\Notification;
6 
7class VoiceChannel
8{
9 /**
10 * Send the given notification.
11 */
12 public function send(object $notifiable, Notification $notification): void
13 {
14 $message = $notification->toVoice($notifiable);
15 
16 // Send notification to the $notifiable instance...
17 }
18}

定义通知渠道类后,您可以从via任何通知的方法中返回类名。在此示例中,toVoice通知的方法可以返回您选择的任何对象来表示语音消息。例如,您可以定义自己的VoiceMessage类来表示这些消息:

1<?php
2 
3namespace App\Notifications;
4 
5use App\Notifications\Messages\VoiceMessage;
6use App\Notifications\VoiceChannel;
7use Illuminate\Bus\Queueable;
8use Illuminate\Contracts\Queue\ShouldQueue;
9use Illuminate\Notifications\Notification;
10 
11class InvoicePaid extends Notification
12{
13 use Queueable;
14 
15 /**
16 * Get the notification channels.
17 */
18 public function via(object $notifiable): string
19 {
20 return VoiceChannel::class;
21 }
22 
23 /**
24 * Get the voice representation of the notification.
25 */
26 public function toVoice(object $notifiable): VoiceMessage
27 {
28 // ...
29 }
30}