# 消息通知
- [简介](#introduction)
- [创建通知](#creating-notifications)
- [发送通知](#sending-notifications)
- [使用 Notifiable Trait](#using-the-notifiable-trait)
- [使用 Notification Facade](#using-the-notification-facade)
- [指定发送频道](#specifying-delivery-channels)
- [通知队列化](#queueing-notifications)
- [按需通知](#on-demand-notifications)
- [邮件通知](#mail-notifications)
- [格式化邮件信息](#formatting-mail-messages)
- [自定义接收者](#customizing-the-recipient)
- [自定义主题](#customizing-the-subject)
- [自定义模板](#customizing-the-templates)
- [Markdown 邮件通知](#markdown-mail-notifications)
- [生成消息](#generating-the-message)
- [写消息](#writing-the-message)
- [自定义组件](#customizing-the-components)
- [数据库通知](#database-notifications)
- [先决条件](#database-prerequisites)
- [格式化数据库通知](#formatting-database-notifications)
- [访问通知](#accessing-the-notifications)
- [标记已读通知](#marking-notifications-as-read)
- [广播通知](#broadcast-notifications)
- [先决条件](#broadcast-prerequisites)
- [格式化广播系统](#formatting-broadcast-notifications)
- [监听通知](#listening-for-notifications)
- [短信通知](#sms-notifications)
- [先决条件](#sms-prerequisites)
- [格式化短信通知](#formatting-sms-notifications)
- [自定义 "From" 电话号码](#customizing-the-from-number)
- [短信通知路由](#routing-sms-notifications)
- [Slack 通知](#slack-notifications)
- [先决条件](#slack-prerequisites)
- [格式化 Slack 通知](#formatting-slack-notifications)
- [Slack 附件](#slack-attachments)
- [Slack 通知路由](#routing-slack-notifications)
- [本地化通知](#localizing-notifications)
- [通知事件](#notification-events)
- [自定义频道](#custom-channels)
<a name="introduction"></a>
## 简介
除了支持 [发送邮件](/docs/{{version}}/mail)之外,Laravel 还支持通过多种频道发送通知,包括邮件、短信 (通过 [Nexmo](https://www.nexmo.com/)),以及 [Slack](https://slack.com)。通知还能存储到数据库以便后续在 Web 页面中显示。
通常,通知都是简短、有信息量的消息,用于通知用户应用中发生了什么。举例来说,如果你是在编写一个在线交易的应用,你应该会通过邮件和短信频道类给用户发送一条 「账单支付」 的通知。
<a name="creating-notifications"></a>
## 创建通知
Laravel 中一条通知就是一个类 (通常存放在 `app/Notifications` 文件夹下)。看不到的话不要担心,运行下 `make:notification` 命令就能创建了:
php artisan make:notification InvoicePaid
这条命令会在 `app/Notifications` 目录下生成一个新的通知类。这个类包含 `via` 方法以及一个或多个消息构建的方法 (比如 `toMail` 或者 `toDatabase`) ,它们会针对指定的渠道把通知转换为对应的消息。
<a name="sending-notifications"></a>
## 发送通知
<a name="using-the-notifiable-trait"></a>
### 使用 Notifiable Trait
通知可以通过两种方法发送:`Notifiable` trait 的 `notify` 方法或 `Notification` [facade](/docs/{{version}}/facades)。首先让我们来探讨下使用 trait:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
}
默认的 `App\User` 模型中使用了这个 trait,它包含着一个可以用来发送通知的方法: `notify`。 `notify` 方法需要一个通知实例做参数:
use App\Notifications\InvoicePaid;
$user->notify(new InvoicePaid($invoice));
> {tip} 记住,你可以在任意模型中使用 `Illuminate\Notifications\Notifiable` trait,而不仅仅是在 `User` 模型中。
<a name="using-the-notification-facade"></a>
### 使用 Notification Facade
另外,你可以通过 `Notification` [facade](/docs/{{version}}/facades) 来发送通知。它主要用在当你给多个可接收通知的实体发送的时候,比如给用户集合发送通知。使用 Facade 发送通知的话,要把可以接收通知和通知的实例传递给 `send` 方法:
Notification::send($users, new InvoicePaid($invoice));
<a name="specifying-delivery-channels"></a>
### 发送指定频道
每个通知类都会有个 `via` 方法,它决定了通知会在哪个频道上发送。开箱即用的频道有 `mail`,`database`,`broadcast`,`nexmo` 和 `slack`。
> {tip} 如果你想使用其他的频道,比如 Telegram 或者 Pusher,你可以去看下社区驱动的 [Laravel 通知频道网站](http://laravel-notification-channels.com)。
`via` 方法接收一个 `$notifiable` 实例。这个实例将是通知实际发送到的类的实例。你可以用 `$notifiable` 来决定通知用哪些频道来发送:
/**
* 获取通知发送频道。
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];
}
<a name="queueing-notifications"></a>
### 通知队列
> {注:} 使用通知队列前需要配置队列并 [开启一个队列任务](/docs/{{version}}/queues)。
发送通知可能是耗时的,尤其是通道需要调用额外的 API 来传输通知。为了加速应用的响应时间,可以将通知推送到队列中异步发送,而要实现推送通知到队列,可以让对应通知类实现 `ShouldQueue` 接口并使用 `Queueable` trait 。 如果通知类是通过 `make:notification` 命令生成的,那么该接口和 trait 已经默认导入,你可以快速将它们添加到通知类:
<?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` 接口然后将通知推送到队列:
$user->notify(new InvoicePaid($invoice));
如果你想要延迟通知的发送,可以在通知实例后加上 `delay` 方法:
$when = now()->addMinutes(10);
$user->notify((new InvoicePaid($invoice))->delay($when);
<a name="on-demand-notifications"></a>
### 按需通知
有时候你可能需要发送通知给某个用户,但是该用户不存在于应用的用户系统中,要实现这一目的,我们使用 `Notification::route` 方法在发送通知之前指定特别的通知路由:
Notification::route('mail', 'taylor@example.com')
->route('nexmo', '5555555555')
->notify(new InvoicePaid($invoice));
<a name="mail-notifications"></a>
## 邮件通知
<a name="formatting-mail-messages"></a>
### 格式化邮件消息
如果通知支持以邮件方式发送,你需要在通知类上定义一个 `toMail` 方法。该方法会接收一个 `$notifiable` 实体并返回 `Illuminate\Notifications\Messages\MailMessage` 实例。邮件消息可以包含多行文本以及对动作的调用,让我们来看一个 `toMail` 方法的示例:
/**
* 获取通知对应的邮件。
*
* @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!');
}
> {注:} 注意到我们在 `toMail` 方法中使用了 `$this->invoice->id` ,你可以传递任何通知生成消息所需要的数据到通知的构造器。
在这个例子中,我们注册了一条问候、一行文本、对动作的调用以及另一行文本。 `MailMessage` 对象提供的这些方法让格式化短小的事务邮件变得简单快捷。`mail` 通道会将消息组件转化为美观的、响应式的、带有纯文本副本的 HTML 邮件模板。下面是一个通过 `mail` 通道生成的邮件示例:
<img src="https://laravel.com/assets/img/notification-example.png" width="551" height="596">
> {注:} 发送邮件通知时,确保在配置文件 `config/app.php` 中设置了 `name` 的值,该值将会用在邮件通知消息的头部和尾部。
#### 其他通知格式化选项
除了在通知类中定义多行文本之外,你还可以使用 `view` 方法来指定一个自定义的、用于渲染通知邮件的模板:
/**
* 获取通知邮件。
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)->view(
'emails.name', ['invoice' => $this->invoice]
);
}
此外,你可以从 `toMail` 方法中返回一个 [可邮寄对象](/docs/{{version}}/mail) :
use App\Mail\InvoicePaid as Mailable;
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return Mailable
*/
public function toMail($notifiable)
{
return (new Mailable($this->invoice))->to($this->user->email);
}
<a name="error-messages"></a>
#### 错误消息
一些通知会告知用户错误信息,例如失败的订单支付。你可以在构建消息的时候调用 `error` 方法来指示该邮件消息表示错误信息。在邮件消息中使用 `error` 方法时,动作按钮将会变成红色:
/**
* 获取通知邮件。
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Message
*/
public function toMail($notifiable)
{
return (new MailMessage)
->error()
->subject('Notification Subject')
->line('...');
}
<a name="customizing-the-recipient"></a>
### 自定义接收人
通过 `mail` 通道发送通知时,通知系统会自动在被通知实体上查找 `email` 属性,你可以通过在该实体上定义一个 `routeNotificationForMail` 来自定义使用哪个邮箱地址发送通知:
<?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;
}
}
<a name="customizing-the-subject"></a>
### 自定义主题
默认情况下,邮件的主题就是格式为 「标题风格」 的通知类名,因此,如果通知类被命名为 `InvoicePaid`,邮件的主题就是 `Invoice Paid`,如果你想要为消息指定明确的主题,可以在构建消息的时候调用 `subject` 方法:
/**
* 获取通知的邮件表示。
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Notification Subject')
->line('...');
}
<a name="customizing-the-templates"></a>
### 自定义模板
你可以通过发布通知扩展包的资源来修改邮件通知所使用的 HTML 和纯文本模板。运行完下面这个命令之后,邮件通知模板将会存放到 `resources/views/vendor/notifications` 目录:
php artisan vendor:publish --tag=laravel-notifications
<a name="markdown-mail-notifications"></a>
## Markdown 邮件通知
Markdown 邮件通知允许你利用邮件通知的预置模板,从而让你可以自由编写更长、更具个性化的消息。因为这些消息以 Markdown 格式编写,Laravel 还可以为它们渲染出高颜值、响应式的 HTML 模板,同时自动生成纯文本的副本。
<a name="generating-the-message"></a>
### 生成消息
要生成带有相应 Markdown 模板的通知,可以在使用 Artisan 命令 `make:notification` 时带上 `--markdown` 选项:
php artisan make:notification InvoicePaid --markdown=mail.invoice.paid
和其他邮件通知一样,使用 Markdown 模板的通知类也要定义一个 `toMail` 方法。不过,你可以使用 `markdown` 方法取代构造通知的 `line` 和 `action` 方法来指定要使用的 Markdown 模板名称:
/**
* 获取通知的邮件表示。
*
* @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]);
}
<a name="writing-the-message"></a>
### 编写消息
Markdown 邮件通知联合使用了 Blade 组件和 Markdown 语法,从而让你在不脱离 Laravel 预置组件的情况下轻松构建通知:
@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`,支持的颜色有 `blue`, `green` 和 `red`。你可以添加任意数量的按钮组件到消息中:
@component('mail::button', ['url' => $url, 'color' => 'green'])
View Invoice
@endcomponent
#### 面板组件
面板组件将给定的文字区块渲染到一个面板中,并且有一个淡淡的背景色与周围的消息区分开。适用于需要引起注意的文字区块:
@component('mail::panel')
This is the panel content.
@endcomponent
#### 表格组件
表格组件允许你将一个 Markdown 表格转化为 HTML 表格。该组件接收 Markdown 表格作为其内容。表格列对齐支持使用默认的 Markdown 表格列对齐语法:
@component('mail::table')
| Laravel | Table | Example |
| ------------- |:-------------:| --------:|
| Col 2 is | Centered | $10 |
| Col 3 is | Right-Aligned | $20 |
@endcomponent
<a name="customizing-the-components"></a>
### 自定义组件
你可以导出所有 Markdown 通知组件到应用中进行自定义,要导出组件,使用 Artisan 命令 `vendor:publish` 来发布 `laravel-mail` 资源标签:
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 样式就会自动调整。
> {注:} 如果你想要为 Markdown 组件构建全新的主题,只需在 `html/themes` 目录中编写一个新的 CSS 文件并修改 `mail` 配置文件的 `theme` 选项即可。
<a name="database-notifications"></a>
## 数据库通知
<a name="database-prerequisites"></a>
### 预备知识
`database` 通知通道会在数据表中存储通知信息,该表包含诸如通知类型以及用于描述通知的自定义 JSON 数据之类的信息。
你可以在用户界面中查询这个数据表来展示通知,不过,在此之前,需要创建数据表来保存信息,你可以使用 `notifications:table` 命令来生成迁移文件然后以此生成相应数据表:
php artisan notifications:table
php artisan migrate
<a name="formatting-database-notifications"></a>
### 格式化数据库通知
如果通知支持存入数据库表,就为通知类需要定义 `toDatabase` 或 `toArray` 方法。此方法接受 `$notifiable` 实体作参数并返回原生 PHP 数组。返回的数据将被编码为 JSON 并存储到 `notifications` 表的 `data` 列。来看一个 `toArray` 方法示例:
/**
* 获取通知的数组表示。
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
];
}
#### `toDatabase` Vs. `toArray`
`toArray` 方法还可以使用 `broadcast` 通道来判断哪些数据被广播到 JavaScript 客户端。如果针对 `database` 和 `broadcast` 通道分别有两个不同的数组表示,你需要定义 `toDatabase` 方法代替 `toArray` 方法。
<a name="accessing-the-notifications"></a>
### 访问通知
一旦通知存入数据库,就需要适当的方法自通知实体访问它们。 包含在 Lareval 的默认 `App\User` 模型带有 `Illuminate\Notifications\Notifiable` trait,它的`notifications` Eloquent 关联方法能返回实体通知。要获取通知,可以像其它 Eloquent 关联方法一样访问此方法。默认情况下,通知按照 `created_at` 时间戳排序:
$user = App\User::find(1);
foreach ($user->notifications as $notification) {
echo $notification->type;
}
若要只获取 「未读」通知,可以使用 `unreadNotifications` 关联方法。同样这些通知按照 `created_at` 时间戳排序:
$user = App\User::find(1);
foreach ($user->unreadNotifications as $notification) {
echo $notification->type;
}
> {tip} 若要从 JavaScript 客户端访问通知,需要为应用定义一个通知控制器,它返回可通知实体的通知,比如当前用户。可以从 JavaScript 客户端向该控制器 URI 发送 HTTP 请求。
<a name="marking-notifications-as-read"></a>
### 标记通知已读
通常,在用户阅览一条通知之后,你会想将其标识为「已读」。 `Illuminate\Notifications\Notifiable` trait 提供了 `markAsRead` 方法,它更新数据库中通知记录的 `read_at` 列:
$user = App\User::find(1);
foreach ($user->unreadNotifications as $notification) {
$notification->markAsRead();
}
可以在通知控制集合上直接使用 `markAsRead` 方法代替循环调用通知:
$user->unreadNotifications->markAsRead();
还可以使用指更新将所有的通知标为已读,而不从数据库中读取它们:
$user = App\User::find(1);
$user->unreadNotifications()->update(['read_at' => now()]);
可以使用 `delete` 方法从表中整个删除通知:
$user->notifications()->delete();
<a name="broadcast-notifications"></a>
## 广播通知
<a name="broadcast-prerequisites"></a>
### 预备知识
广播通知前,你需要配置和熟悉 Laravel 的 [事件广播](/docs/{{version}}/broadcasting) 服务。事件广播提供了在 JavaScript 客户端响应服务端触发 Laravel 事件的方法。
<a name="formatting-broadcast-notifications"></a>
### 格式化广播通知
`broadcast` 通道使用 Laravel 的 [event broadcasting](/docs/{{version}}/broadcasting) 服务广播通知,它允许 JavaScript客户端实时捕获通知。如果通知支持广播,你就需要在通知类上定义 `toBroadcast` 方法。此方法接受 `$notifiable` 实体作为参数,并返回 `BroadcastMessage` 实例。返回的数据将被编码为 JSON 并广播给 JavaScript 客户端。我们来看一个 `toBroadcast` 方法示例
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,
]);
}
#### 广播队列配置
所有的广播通知都被放入广播队列。想要配置用于广播操作的队列连接或者队列名称,需要使用 `BroadcastMessage` 的 `onConnection` 和 `onQueue` 方法:
return (new BroadcastMessage($data))
->onConnection('sqs')
->onQueue('broadcasts');
> {tip} 除了指定的数据,广播通知还包含 `type` 域,它包括通知类的类名。
<a name="listening-for-notifications"></a>
### 监听通知
通知将会以格式化为 `{notifiable}.{id}` 的形式在私有频道上广播,因此,如果你要发送通知到 ID 为 `1` 的 `App\User` 实例,那么该通知将会在私有频道 `App.User.1` 上进行广播,如果使用了 [Laravel Echo](/docs/{{version}}/broadcasting),可以使用辅助函数 `notification` 轻松在某个频道上监听通知:
Echo.private('App.User.' + userId)
.notification((notification) => {
console.log(notification.type);
});
#### 自定义通知通道
如果你想要自定义被通知实体在某个通道上接收广播通知,可以在被通知实体上定义一个 `receivesBroadcastNotificationsOn` 方法:
<?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;
}
}
<a name="sms-notifications"></a>
## 短信(SMS)通知
<a name="sms-prerequisites"></a>
### 预备知识
Laravel 基于 [Nexmo](https://www.nexmo.com/) 发送短信通知,在使用Nexmo 发送通知前,需要安装对应 Composer 依赖包 `laravel/nexmo-notification-channel` :
composer require laravel/nexmo-notification-channel
下一步,你需要在配置文件 `config/services.php` 中进行相应配置。你可以参考以下示例配置:
'nexmo' => [
'key' => env('NEXMO_KEY'),
'secret' => env('NEXMO_SECRET'),
'sms_from' => '15556666666',
],
`sms_from` 配置项就是你用于发送短信消息的手机号码,你需要在 Nexmo 控制面板中为应用生成一个手机号码。
<a name="formatting-sms-notifications"></a>
### 格式化短信通知
如果通知支持以短信方式发送,那么你需要在通知类上定义一个 `toNexmo` 方法。该方法接收一个 `$notifiable` 实体并返回 `Illuminate\Notifications\Messages\NexmoMessage` 实例:
/**
* Get the Nexmo / SMS representation of the notification.
*
* @param mixed $notifiable
* @return NexmoMessage
*/
public function toNexmo($notifiable)
{
return (new NexmoMessage)
->content('Your SMS message content');
}
#### Unicode 内容
如果你的短信消息包含 Unicode 字符,需要在构造 `NexmoMessage` 实例时调用 `unicode` 方法:
/**
* Get the Nexmo / SMS representation of the notification.
*
* @param mixed $notifiable
* @return NexmoMessage
*/
public function toNexmo($notifiable)
{
return (new NexmoMessage)
->content('Your unicode message')
->unicode();
}
<a name="customizing-the-from-number"></a>
### 自定义 "发送" 号码
如果你要通过与配置文件 `config/services.php` 中指定的手机号不同的其他号码发送通知,可以使用 `NexmoMessage` 实例上的 `from` 方法:
/**
* Get the Nexmo / SMS representation of the notification.
*
* @param mixed $notifiable
* @return NexmoMessage
*/
public function toNexmo($notifiable)
{
return (new NexmoMessage)
->content('Your SMS message content')
->from('15554443333');
}
<a name="routing-sms-notifications"></a>
### 短信通知路由
使用 `nexmo` 通道发送通知的时候,通知系统会自动在被通知实体上查找 `phone_number` 属性。如果你想要自定义通知被发送到的手机号码,可以在该实体上定义一个 `routeNotificationForNexmo` 方法:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* Route notifications for the Nexmo channel.
*
* @param \Illuminate\Notifications\Notification $notification
* @return string
*/
public function routeNotificationForNexmo($notification)
{
return $this->phone;
}
}
<a name="slack-notifications"></a>
## Slack 通知
<a name="slack-prerequisites"></a>
### 预备知识
在通过 Slack 发送通知前,必须通过 Composer 安装 Slack 通知通道:
composer require laravel/slack-notification-channel
此外,你还要为 Slack 组配置一个 ["Incoming Webhook"](https://api.slack.com/incoming-webhooks) 集成。该集成会在你进行 [Slack 通知路由](#routing-slack-notifications) 的时候提供一个URL。
<a name="formatting-slack-notifications"></a>
### 格式化 Slack 通知
如果通知支持通过 Slack 消息发送,则需要在通知类上定义一个 `toSlack` 方法,该方法接收一个 `$notifiable` 实体并返回 `Illuminate\Notifications\Messages\SlackMessage` 实例,该实例包含文本内容以及格式化额外文本或数组字段的“附件”。让我们来看一个基本的 `toSlack` 使用示例:
/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
return (new SlackMessage)
->content('One of your invoices has been paid!');
}
在这个例子中,我们只发送一行简单的文本到 Slack,最终创建的消息如下:
<img src="https://laravel.com/assets/img/basic-slack-notification.png">
#### Customizing The Sender & Recipient
你可以使用 `from` 和 `to` 方法自定义发送者和接收者, `from` 方法接收一个用户名和 emoji 标识,而 `to` 方法接收通道或用户名:
/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
return (new SlackMessage)
->from('Ghost', ':ghost:')
->to('#other')
->content('This will be sent to #other');
}
还可以使用图片作为 logo 用以取代 emoji:
/**
* Get the Slack representation of the notification.
*
* @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');
}
<a name="slack-attachments"></a>
### Slack 附件
你还可以添加“附件”到 Slack 消息。相对简单文本消息,附件可以提供更加丰富的格式选择。在这个例子中,我们会发送一个在应用程序中出现的异常错误通知,包含查看更多异常细节的链接:
/**
* Get the Slack representation of the notification.
*
* @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 消息:
<img src="https://laravel.com/assets/img/basic-slack-attachment.png">
附件还允许你指定要呈献给用户的数组数据。为了提高可读性,给定的数组会以表格形式展示:
/**
* Get the Slack representation of the notification.
*
* @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 消息:
<img src="https://laravel.com/assets/img/slack-fields-attachment.png">
#### Markdown 附件内容
如果一些附件字段包含 Markdown,可以使用 `markdown` 方法来构建 Slack 用以解析并显示以 Markdown 格式编写的附件字段,该方法支持的值包括 `pretext`、 `text` 或 `fields`。想要了解更多关于 Slack 格式化的信息,查看 [Slack API 文档](https://api.slack.com/docs/message-formatting#message_formatting):
/**
* Get the Slack representation of the notification.
*
* @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']);
});
}
<a name="routing-slack-notifications"></a>
### Slack 通知路由
要路由 Slack 通知到适当的位置,需要在被通知的实体上定义一个 `routeNotificationForSlack` 方法,这将会返回通知被发送到的 Webhook URL。Webhook URL 可通过在 Slack 组上添加一个 "Incoming Webhook" 服务来生成:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* Route notifications for the Slack channel.
*
* @param \Illuminate\Notifications\Notification $notification
* @return string
*/
public function routeNotificationForSlack($notification)
{
return 'https://hooks.slack.com/services/...';
}
}
<a name="localizing-notifications"></a>
## 本地化通知
Laravel 允许您以当前语言环境之外的其他语言发送通知,并且会在通知队列时记住该语言环境。
要实现这一点, `Illuminate\Notifications\Notification` 类提供了一个 `locale` 方法来设置所需的语言。在格式化通知时,应用程序将更改为此语言设置,然后在格式化完成后还原为以前的语言设置:
$user->notify((new InvoicePaid($invoice))->locale('es'));
多重通知的本地化也可通过 `Notification` Facade 实现:
Notification::locale('es')->send($users, new InvoicePaid($invoice));
### 用户首选语言区域设置
有些情况下,应用程序保存了每个用户的首选语言区域设置。通过在模型上实现 `HasLocalePreference` 契约,可以指定 Laravel 在发送通知时使用用户保存的首选语言设置:
use Illuminate\Contracts\Translation\HasLocalePreference;
class User extends Model implements HasLocalePreference
{
/**
* Get the user's preferred locale.
*
* @return string
*/
public function preferredLocale()
{
return $this->locale;
}
}
实现接口后,Laravel 将在向模型发送通知和邮件时自动使用首选区域设置。因此,使用此接口时不需要调用 `locale` 方法:
$user->notify(new InvoicePaid($invoice));
<a name="notification-events"></a>
## 通知事件
当通知被发送后,通知系统会触发 `Illuminate\Notifications\Events\NotificationSent` 事件,该事件实例包含被通知的实体(如用户)和通知实例本身。你可以在 `EventServiceProvider` 中为该事件注册监听器:
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Illuminate\Notifications\Events\NotificationSent' => [
'App\Listeners\LogNotification',
],
];
> {提示} 在 `EventServiceProvider` 中注册监听器之后,使用 Artisan 命令 `event:generate` 可以快速生成监听器类。
在事件监听器中,可以访问事件的 `notifiable`、 `notification` 和 `channel` 属性了解通知接收者和通知本身的更多信息:
/**
* Handle the event.
*
* @param NotificationSent $event
* @return void
*/
public function handle(NotificationSent $event)
{
// $event->channel
// $event->notifiable
// $event->notification
// $event->response
}
<a name="custom-channels"></a>
## 自定义通道
Laravel 为我们提供了多种通知通道,但是尝试编写自定义通道驱动以通过其他通道发送通知,也很简单。首先定义一个包含 `send` 方法的类,该方法接收两个参数: `$notifiable` 和 `$notification`:
<?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);
// Send notification to the $notifiable instance...
}
}
一旦通知通道类被定义后,就可以在应用中通过 `via` 方法返回类名:
<?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)
{
// ...
}
}
- 入门指南
- 安装
- 部署
- 基础功能
- 路由
- 中间件
- CSRF 保护
- 控制器
- 请求
- 响应
- 视图
- URL
- Session
- 表单验证
- 错误
- 日志
- 前端开发
- Blade 模板
- 本地化
- 脚手架
- 编译资源 Mix
- 安全相关
- 用户认证
- API 认证
- 综合话题
- 命令行
- 广播
- 缓存
- 集合
- 事件
- 文件存储
- 辅助函数
- 邮件发送
- 消息通知
- 扩展包开发
- 队列
- 任务调度
- 数据库
- 快速入门
- 查询构造器
- 分页
- 数据库迁移
- 数据填充
- Redis
- Eloquent ORM
- 快速入门
- 速查表
- Artisan
- Auth
- Blade
- Cache
- Collection
- Composer
- Config
- Container
- Cookie
- DB
- Environment
- Event
- File
- Helper
- Input
- Lang
- Log
- Model
- Pagination
- Queue
- Redirect
- Request
- Response
- Route
- SSH
- Schema
- Security
- Session
- Storage
- String
- URL
- UnitTest
- Validation
- View