Skip to content

通知

介绍

除了支持发送电子邮件外,Laravel 还支持通过多种传递渠道发送通知,包括邮件、SMS(通过 Nexmo)和 Slack。通知也可以存储在数据库中,以便在您的 Web 界面中显示。

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

创建通知

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

php
php artisan make:notification InvoicePaid

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

发送通知

使用 Notifiable Trait

通知可以通过两种方式发送:使用 Notifiable trait 的 notify 方法或使用 Notification facade。首先,让我们探索使用 trait:

php
<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;
}

此 trait 被默认的 App\User 模型使用,并包含一个可用于发送通知的方法:notifynotify 方法期望接收一个通知实例:

php
use App\Notifications\InvoicePaid;

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

请记住,您可以在任何模型上使用 Illuminate\Notifications\Notifiable trait。您不必仅限于在 User 模型上包含它。

使用 Notification Facade

或者,您可以通过 Notification facade 发送通知。这主要在您需要向多个可通知实体(如用户集合)发送通知时有用。要使用 facade 发送通知,请将所有可通知实体和通知实例传递给 send 方法:

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

指定传递渠道

每个通知类都有一个 via 方法,用于确定通知将在哪些渠道上传递。开箱即用,通知可以通过 maildatabasebroadcastnexmoslack 渠道发送。

lightbulb

如果您想使用其他传递渠道,如 Telegram 或 Pusher,请查看社区驱动的 Laravel Notification Channels 网站

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

php
/**
 * 获取通知的传递渠道。
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function via($notifiable)
{
    return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];
}

队列通知

exclamation

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

发送通知可能需要时间,尤其是当渠道需要外部 API 调用来传递通知时。为了加快应用程序的响应时间,可以通过在类中添加 ShouldQueue 接口和 Queueable trait 来让通知排队。接口和 trait 已经为所有使用 make:notification 生成的通知导入,因此您可以立即将它们添加到通知类中:

php
<?php

namespace App\Notifications;

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

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;

    // ...
}

一旦将 ShouldQueue 接口添加到通知中,您可以像往常一样发送通知。Laravel 将检测类上的 ShouldQueue 接口并自动将通知的传递排队:

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

如果您想延迟通知的传递,可以在通知实例化时链接 delay 方法:

php
$when = now()->addMinutes(10);

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

按需通知

有时您可能需要向不是应用程序“用户”的人发送通知。使用 Notification::route 方法,您可以在发送通知之前指定临时通知路由信息:

php
Notification::route('mail', 'taylor@example.com')
            ->route('nexmo', '5555555555')
            ->notify(new InvoicePaid($invoice));

邮件通知

格式化邮件消息

如果通知支持以电子邮件形式发送,您应该在通知类上定义一个 toMail 方法。此方法将接收一个 $notifiable 实体,并应返回一个 Illuminate\Notifications\Messages\MailMessage 实例。邮件消息可以包含文本行以及“行动呼吁”。让我们看看一个 toMail 方法的示例:

php
/**
 * 获取通知的邮件表示。
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    $url = url('/invoice/'.$this->invoice->id);

    return (new MailMessage)
                ->greeting('Hello!')
                ->line('One of your invoices has been paid!')
                ->action('View Invoice', $url)
                ->line('Thank you for using our application!');
}
lightbulb

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

在此示例中,我们注册了一个问候语、一行文本、一项行动呼吁,然后是另一行文本。MailMessage 对象提供的方法使格式化小型事务性电子邮件变得简单快捷。邮件渠道将把消息组件转换为漂亮的响应式 HTML 电子邮件模板,并带有纯文本副本。以下是 mail 渠道生成的电子邮件示例:

lightbulb

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

其他通知格式选项

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

php
/**
 * 获取通知的邮件表示。
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)->view(
        'emails.name', ['invoice' => $this->invoice]
    );
}

此外,您可以从 toMail 方法返回一个 mailable 对象

php
use App\Mail\InvoicePaid as Mailable;

/**
 * 获取通知的邮件表示。
 *
 * @param  mixed  $notifiable
 * @return Mailable
 */
public function toMail($notifiable)
{
    return (new Mailable($this->invoice))->to($this->user->email);
}

错误消息

某些通知会通知用户错误,例如发票支付失败。您可以通过在构建消息时调用 error 方法来指示邮件消息与错误有关。使用 error 方法时,行动呼吁按钮将是红色而不是蓝色:

php
/**
 * 获取通知的邮件表示。
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Message
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->error()
                ->subject('Notification Subject')
                ->line('...');
}

自定义收件人

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

php
<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * 为邮件渠道路由通知。
     *
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return string
     */
    public function routeNotificationForMail($notification)
    {
        return $this->email_address;
    }
}

自定义主题

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

php
/**
 * 获取通知的邮件表示。
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject('Notification Subject')
                ->line('...');
}

自定义模板

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

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

Markdown 邮件通知

Markdown 邮件通知允许您利用邮件通知的预构建模板,同时为您提供更多自由来撰写更长的自定义消息。由于消息是用 Markdown 编写的,Laravel 能够为消息渲染漂亮的响应式 HTML 模板,同时自动生成纯文本副本。

生成消息

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

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

与所有其他邮件通知一样,使用 Markdown 模板的通知应在其通知类上定义一个 toMail 方法。然而,与使用 lineaction 方法构建通知不同,使用 markdown 方法指定应使用的 Markdown 模板的名称:

php
/**
 * 获取通知的邮件表示。
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    $url = url('/invoice/'.$this->invoice->id);

    return (new MailMessage)
                ->subject('Invoice Paid')
                ->markdown('mail.invoice.paid', ['url' => $url]);
}

撰写消息

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

php
@component('mail::message')
# Invoice Paid

Your invoice has been paid!

@component('mail::button', ['url' => $url])
View Invoice
@endcomponent

Thanks,<br>
{{ config('app.name') }}
@endcomponent

按钮组件

按钮组件呈现一个居中的按钮链接。该组件接受两个参数,一个 url 和一个可选的 color。支持的颜色有 bluegreenred。您可以在通知中添加任意数量的按钮组件:

php
@component('mail::button', ['url' => $url, 'color' => 'green'])
View Invoice
@endcomponent

面板组件

面板组件在背景颜色与通知其余部分略有不同的面板中呈现给定的文本块。这使您可以引起对给定文本块的注意:

php
@component('mail::panel')
This is the panel content.
@endcomponent

表格组件

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

php
@component('mail::table')
| Laravel       | Table         | Example  |
| ------------- |:-------------:| --------:|
| Col 2 is      | Centered      | $10      |
| Col 3 is      | Right-Aligned | $20      |
@endcomponent

自定义组件

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

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

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

自定义 CSS

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

lightbulb

如果您想为 Markdown 组件构建一个全新的主题,请在 html/themes 目录中编写一个新的 CSS 文件,并更改 mail 配置文件的 theme 选项。

数据库通知

先决条件

database 通知渠道将通知信息存储在数据库表中。此表将包含通知类型以及描述通知的自定义 JSON 数据。

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

php
php artisan notifications:table

php artisan migrate

格式化数据库通知

如果通知支持存储在数据库表中,您应该在通知类上定义一个 toDatabasetoArray 方法。此方法将接收一个 $notifiable 实体,并应返回一个简单的 PHP 数组。返回的数组将被编码为 JSON 并存储在 notifications 表的 data 列中。让我们看看一个 toArray 方法的示例:

php
/**
 * 获取通知的数组表示。
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function toArray($notifiable)
{
    return [
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ];
}

toDatabasetoArray

toArray 方法也被 broadcast 渠道用于确定要广播到 JavaScript 客户端的数据。如果您希望为 databasebroadcast 渠道提供两个不同的数组表示,您应该定义一个 toDatabase 方法而不是 toArray 方法。

访问通知

一旦通知存储在数据库中,您需要一种方便的方法从可通知实体中访问它们。Illuminate\Notifications\Notifiable trait(包含在 Laravel 的默认 App\User 模型中)包括一个 notifications Eloquent 关系,该关系返回实体的通知。要获取通知,您可以像访问任何其他 Eloquent 关系一样访问此方法。默认情况下,通知将按 created_at 时间戳排序:

php
$user = App\User::find(1);

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

如果您只想检索“未读”通知,可以使用 unreadNotifications 关系。同样,这些通知将按 created_at 时间戳排序:

php
$user = App\User::find(1);

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

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

标记通知为已读

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

php
$user = App\User::find(1);

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

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

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

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

php
$user = App\User::find(1);

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

您可以 delete 通知以将其从表中完全删除:

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

广播通知

先决条件

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

格式化广播通知

broadcast 渠道使用 Laravel 的事件广播服务广播通知,允许您的 JavaScript 客户端实时捕获通知。如果通知支持广播,您应该在通知类上定义一个 toBroadcast 方法。此方法将接收一个 $notifiable 实体,并应返回一个 BroadcastMessage 实例。返回的数据将被编码为 JSON 并广播到您的 JavaScript 客户端。让我们看看一个 toBroadcast 方法的示例:

php
use Illuminate\Notifications\Messages\BroadcastMessage;

/**
 * 获取通知的可广播表示。
 *
 * @param  mixed  $notifiable
 * @return BroadcastMessage
 */
public function toBroadcast($notifiable)
{
    return new BroadcastMessage([
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ]);
}

广播队列配置

所有广播通知都排队等待广播。如果您想配置用于排队广播操作的队列连接或队列名称,可以使用 BroadcastMessageonConnectiononQueue 方法:

php
return (new BroadcastMessage($data))
                ->onConnection('sqs')
                ->onQueue('broadcasts');
lightbulb

除了您指定的数据外,广播通知还将包含一个 type 字段,其中包含通知的类名。

监听通知

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

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

自定义通知频道

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

php
<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * 用户接收通知广播的频道。
     *
     * @return string
     */
    public function receivesBroadcastNotificationsOn()
    {
        return 'users.'.$this->id;
    }
}

短信通知

先决条件

在 Laravel 中发送 SMS 通知由 Nexmo 提供支持。在通过 Nexmo 发送通知之前,您需要安装 nexmo/client Composer 包,并在 config/services.php 配置文件中添加一些配置选项。您可以复制以下示例配置以开始:

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

sms_from 选项是您的 SMS 消息将从中发送的电话号码。您应该在 Nexmo 控制面板中为您的应用程序生成一个电话号码。

格式化短信通知

如果通知支持以 SMS 形式发送,您应该在通知类上定义一个 toNexmo 方法。此方法将接收一个 $notifiable 实体,并应返回一个 Illuminate\Notifications\Messages\NexmoMessage 实例:

php
/**
 * 获取 Nexmo / SMS 表示。
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your SMS message content');
}

Unicode 内容

如果您的 SMS 消息将包含 Unicode 字符,您应该在构建 NexmoMessage 实例时调用 unicode 方法:

php
/**
 * 获取 Nexmo / SMS 表示。
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your unicode message')
                ->unicode();
}

自定义“发件人”号码

如果您想从与 config/services.php 文件中指定的电话号码不同的电话号码发送某些通知,可以在 NexmoMessage 实例上使用 from 方法:

php
/**
 * 获取 Nexmo / SMS 表示。
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your SMS message content')
                ->from('15554443333');
}

路由短信通知

通过 nexmo 渠道发送通知时,通知系统将自动查找可通知实体上的 phone_number 属性。如果您想自定义通知的接收电话号码,请在实体上定义 routeNotificationForNexmo 方法:

php
<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * 为 Nexmo 渠道路由通知。
     *
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return string
     */
    public function routeNotificationForNexmo($notification)
    {
        return $this->phone;
    }
}

Slack 通知

先决条件

在通过 Slack 发送通知之前,您必须通过 Composer 安装 Guzzle HTTP 库:

bash
composer require guzzlehttp/guzzle

您还需要为您的 Slack 团队配置一个"Incoming Webhook"集成。此集成将为您提供一个 URL,您可以在路由 Slack 通知时使用。

格式化 Slack 通知

如果通知支持以 Slack 消息形式发送,您应该在通知类上定义一个 toSlack 方法。此方法将接收一个 $notifiable 实体,并应返回一个 Illuminate\Notifications\Messages\SlackMessage 实例。Slack 消息可以包含文本内容以及格式化附加文本或字段数组的“附件”。让我们看看一个基本的 toSlack 示例:

php
/**
 * 获取 Slack 表示。
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->content('One of your invoices has been paid!');
}

在此示例中,我们只是向 Slack 发送一行文本,这将创建如下所示的消息:

自定义发件人和收件人

您可以使用 fromto 方法自定义发件人和收件人。from 方法接受用户名和表情符号标识符,而 to 方法接受频道或用户名:

php
/**
 * 获取 Slack 表示。
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->from('Ghost', ':ghost:')
                ->to('#other')
                ->content('This will be sent to #other');
}

您还可以使用图像作为徽标而不是表情符号:

php
/**
 * 获取 Slack 表示。
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->from('Laravel')
                ->image('https://laravel.com/favicon.png')
                ->content('This will display the Laravel logo next to the message');
}

Slack 附件

您还可以向 Slack 消息添加“附件”。附件提供比简单文本消息更丰富的格式选项。在此示例中,我们将发送有关应用程序中发生的异常的错误通知,包括一个链接以查看有关异常的更多详细信息:

php
/**
 * 获取 Slack 表示。
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/exceptions/'.$this->exception->id);

    return (new SlackMessage)
                ->error()
                ->content('Whoops! Something went wrong.')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Exception: File Not Found', $url)
                               ->content('File [background.jpg] was not found.');
                });
}

上面的示例将生成如下所示的 Slack 消息:

附件还允许您指定应呈现给用户的数据数组。给定的数据将以表格样式格式呈现,以便于阅读:

php
/**
 * 获取 Slack 表示。
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/invoices/'.$this->invoice->id);

    return (new SlackMessage)
                ->success()
                ->content('One of your invoices has been paid!')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Invoice 1322', $url)
                               ->fields([
                                    'Title' => 'Server Expenses',
                                    'Amount' => '$1,234',
                                    'Via' => 'American Express',
                                    'Was Overdue' => ':-1:',
                                ]);
                });
}

上面的示例将创建如下所示的 Slack 消息:

Markdown 附件内容

如果您的某些附件字段包含 Markdown,您可以使用 markdown 方法指示 Slack 解析并将给定的附件字段显示为 Markdown 格式的文本。此方法接受的值为:pretexttext 和 / 或 fields。有关 Slack 附件格式的更多信息,请查看 Slack API 文档

php
/**
 * 获取 Slack 表示。
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/exceptions/'.$this->exception->id);

    return (new SlackMessage)
                ->error()
                ->content('Whoops! Something went wrong.')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Exception: File Not Found', $url)
                               ->content('File [background.jpg] was *not found*.')
                               ->markdown(['text']);
                });
}

路由 Slack 通知

要将 Slack 通知路由到正确的位置,请在可通知实体上定义一个 routeNotificationForSlack 方法。这应该返回通知应传递到的 webhook URL。Webhook URL 可以通过向您的 Slack 团队添加“Incoming Webhook”服务生成:

php
<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * 为 Slack 渠道路由通知。
     *
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return string
     */
    public function routeNotificationForSlack($notification)
    {
        return 'https://hooks.slack.com/services/...';
    }
}

本地化通知

Laravel 允许您以当前语言以外的语言发送通知,并且即使通知排队也会记住此语言。

为此,Illuminate\Notifications\Notification 类提供了一个 locale 方法来设置所需的语言。应用程序将在格式化通知时切换到此语言,然后在格式化完成后恢复到先前的语言:

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

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

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

用户首选语言

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

php
use Illuminate\Contracts\Translation\HasLocalePreference;

class User extends Model implements HasLocalePreference
{
    /**
     * 获取用户的首选语言。
     *
     * @return string
     */
    public function preferredLocale()
    {
        return $this->locale;
    }
}

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

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

通知事件

发送通知时,通知系统会触发 Illuminate\Notifications\Events\NotificationSent 事件。这包含“可通知”实体和通知实例本身。您可以在 EventServiceProvider 中注册此事件的监听器:

php
/**
 * 应用程序的事件监听器映射。
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Notifications\Events\NotificationSent' => [
        'App\Listeners\LogNotification',
    ],
];
lightbulb

EventServiceProvider 中注册监听器后,使用 event:generate Artisan 命令快速生成监听器类。

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

php
/**
 * 处理事件。
 *
 * @param  NotificationSent  $event
 * @return void
 */
public function handle(NotificationSent $event)
{
    // $event->channel
    // $event->notifiable
    // $event->notification
    // $event->response
}

自定义渠道

Laravel 附带了一些通知渠道,但您可能希望编写自己的驱动程序通过其他渠道传递通知。Laravel 使其变得简单。要开始,请定义一个包含 send 方法的类。该方法应接收两个参数:$notifiable$notification

php
<?php

namespace App\Channels;

use Illuminate\Notifications\Notification;

class VoiceChannel
{
    /**
     * 发送给定的通知。
     *
     * @param  mixed  $notifiable
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return void
     */
    public function send($notifiable, Notification $notification)
    {
        $message = $notification->toVoice($notifiable);

        // 向 $notifiable 实例发送通知...
    }
}

一旦定义了通知渠道类,您可以从任何通知的 via 方法返回类名:

php
<?php

namespace App\Notifications;

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

class InvoicePaid extends Notification
{
    use Queueable;

    /**
     * 获取通知渠道。
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return [VoiceChannel::class];
    }

    /**
     * 获取通知的语音表示。
     *
     * @param  mixed  $notifiable
     * @return VoiceMessage
     */
    public function toVoice($notifiable)
    {
        // ...
    }
}