Skip to content
赞助商
虚位以待
赞助商
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

通知

介绍

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

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

创建通知

在 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\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;
}

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

php
use App\Notifications\InvoicePaid;

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

NOTE

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

使用 Notification Facade

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

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

指定发送渠道

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

NOTE

如果您想使用其他发送渠道,如 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'];
}

队列通知

NOTE

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

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

php
<?php

namespace App\Notifications;

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

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;

    // ...
}

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

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

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

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

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

自定义通知渠道队列

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

php
/**
 * 确定每个通知渠道应使用的队列。
 *
 * @return array
 */
public function viaQueues()
{
    return [
        'mail' => 'mail-queue',
        'slack' => 'slack-queue',
    ];
}

按需通知

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

php
Notification::route('mail', 'taylor@example.com')
            ->route('nexmo', '5555555555')
            ->route('slack', 'https://hooks.slack.com/services/...')
            ->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!');
}

NOTE

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

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

NOTE

发送邮件通知时,请确保在 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]
    );
}

您可以通过将视图名称作为数组的第二个元素传递给 MailMessageview 方法来为邮件消息指定一个纯文本视图:

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

此外,您还可以从 toMail 方法返回一个完整的邮件对象

php
use App\Mail\InvoicePaid as Mailable;

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

错误消息

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

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

自定义发件人

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

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

自定义收件人

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

php
<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * 为邮件渠道路由通知。
     *
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return array|string
     */
    public function routeNotificationForMail($notification)
    {
        // 仅返回电子邮件地址...
        return $this->email_address;

        // 返回名称和电子邮件地址...
        return [$this->email_address => $this->name];
    }
}

自定义主题

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

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

自定义邮件程序

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

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

自定义模板

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

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

预览邮件通知

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

php
Route::get('mail', function () {
    $invoice = App\Invoice::find(1);

    return (new App\Notifications\InvoicePaid($invoice))
                ->toMail($invoice->user);
});

Markdown 邮件通知

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

生成消息

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

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

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

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 和一个 text 目录,每个目录都包含其各自的可用组件表示。您可以随意自定义这些组件。

自定义 CSS

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

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

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

php
/**
 * 获取通知的邮件表示。
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->theme('invoice')
                ->subject('Invoice Paid')
                ->markdown('mail.invoice.paid', ['url' => $url]);
}

数据库通知

先决条件

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

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

php
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;
}

NOTE

要从 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 实例。如果 toBroadcast 方法不存在,将使用 toArray 方法来收集应广播的数据。返回的数据将被编码为 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');

自定义通知类型

除了您指定的数据外,所有广播通知还具有一个 type 字段,其中包含通知的完整类名。如果您想自定义提供给 JavaScript 客户端的通知 type,可以在通知类上定义一个 broadcastType 方法:

php
use Illuminate\Notifications\Messages\BroadcastMessage;

/**
 * 获取广播的通知类型。
 *
 * @return string
 */
public function broadcastType()
{
    return 'broadcast.message';
}

监听通知

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

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

自定义通知频道

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

php
<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

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

短信通知

先决条件

在 Laravel 中发送短信通知由 Nexmo 提供支持。在通过 Nexmo 发送通知之前,您需要安装 laravel/nexmo-notification-channel Composer 包:

php
composer require laravel/nexmo-notification-channel

这也将安装 nexmo/laravel 包。此包包含其自己的配置文件。您可以使用 NEXMO_KEYNEXMO_SECRET 环境变量来设置您的 Nexmo 公钥和密钥。

接下来,您需要在 config/services.php 配置文件中添加一个配置选项。您可以复制以下示例配置以开始:

php
'nexmo' => [
    'sms_from' => '15556666666',
],

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

格式化短信通知

如果通知支持以短信形式发送,您应该在通知类上定义一个 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');
}

格式化短码通知

Laravel 还支持发送短码通知,这些通知是您 Nexmo 帐户中的预定义消息模板。您可以指定通知的类型(alert2famarketing),以及将填充模板的自定义值:

php
/**
 * 获取通知的 Nexmo/Shortcode 表示。
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function toShortcode($notifiable)
{
    return [
        'type' => 'alert',
        'custom' => [
            'code' => 'ABC123',
        ];
    ];
}

NOTE

路由短信通知一样,您应该在可通知模型上实现 routeNotificationForShortcode 方法。

Unicode 内容

如果您的短信消息将包含 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 通知路由到正确的电话号码,请在可通知实体上定义一个 routeNotificationForNexmo 方法:

php
<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

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

Slack 通知

先决条件

在通过 Slack 发送通知之前,您必须通过 Composer 安装通知渠道:

php
composer require laravel/slack-notification-channel

您还需要为您的 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/img/favicon/favicon.ico')
                ->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\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

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',
    ],
];

NOTE

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 App\Channels\Messages\VoiceMessage;
use App\Channels\VoiceChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;

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)
    {
        // ...
    }
}