訊息通知


#

訊息通知

簡介

除了支援發送郵件之外,Laravel 還支援透過多種頻道發送通知,包括郵件、簡訊(透過Nexmo),以及Slack。通知還能儲存到資料庫以便後續在 Web 頁面中顯示。

通常,通知都是簡短、有資訊量的訊息,用於通知用戶應用程式中發生了什麼。舉例來說,如果你是在編寫一個線上交易的應用,你應該會透過郵件和簡訊頻道類別給用戶發送一條 「帳單支付」 的通知。

建立通知

Laravel 中一條通知就是一個類別(通常存放在app/Notifications 資料夾下) 。看不到的話別擔心,執行下make:notification 指令就能創建了:

php artisan make:notification InvoicePaid

這條指令會在app/Notifications 目錄下產生一個新的通知類。這個類別包含via 方法以及一個或多個訊息建構的方法(例如toMail 或 toDatabase) ,它們會針對指定的管道把通知轉換為對應的消息。

傳送通知

#使用Notifiable Trait

通知可以透過兩種方法發送:Notifiable trait 的notify 方法或Notification facade。首先讓我們來探討下使用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 模型中。

使用 Notification Facade

另外,你可以透過 Notification facade 來發送通知。它主要用在當你給多個可接收通知的實體發送的時候,例如給用戶集合發送通知。使用Facade 傳送通知的話,要把可以接收通知和通知的實例傳遞給send 方法:

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

##發送指定頻道

每個通知類別都會有一個

via 方法,它決定了通知會在哪個頻道上傳送。開箱即用的頻道有 maildatabasebroadcastnexmoslack

{tip} 如果你想使用其他的頻道,例如 Telegram 或 Pusher,你可以去看下社群驅動的 Laravel 通知頻道網站。

via 方法接收一個 $notifiable 實例。這個實例將是通知實際發送到的類別的實例。你可以用$notifiable 來決定通知用哪些頻道來傳送:

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

##通知佇列

{註:} 使用通知佇列前需要設定佇列並開啟一個佇列任務。

發送通知可能是耗時的,尤其是通道需要呼叫額外的 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);

按需通知

有時候你可能需要發送通知給某個用戶,但是該用戶不存在於應用的用戶系統中,要實現這一目的,我們使用 Notification::route 方法在發送通知之前指定特別的通知路由:

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

郵件通知

#格式化郵件訊息

如果通知支援以郵件方式傳送,你需要在通知類別上定義一個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 通道產生的郵件範例:

1.png


{註:} 發送郵件通知時,請確保在設定檔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 方法中傳回一個可郵寄物件:

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

錯誤訊息

有些通知會告知使用者錯誤訊息,例如失敗的訂單付款。你可以在建構訊息的時候呼叫 error 方法來指示該郵件訊息表示錯誤訊息。在郵件訊息中使用error 方法時,動作按鈕將會變成紅色:

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

自訂接收人

透過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;   
      }
  }

自訂主題

預設情況下,郵件的主題是格式為「標題風格」 的通知類別名,因此,如果通知類別被命名為InvoicePaid,郵件的主題就是Invoice Paid,如果你想要為訊息指定明確的主題,可以在建置訊息的時候呼叫subject 方法:

/**
 * 获取通知的邮件表示。
 *
 * @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 artisan vendor:publish --tag=laravel-notifications

Markdown 郵件通知

Markdown 郵件通知可讓你利用郵件通知的預置模板,讓你可以自由撰寫更長、更個人化的訊息。因為這些訊息以 Markdown 格式編寫,Laravel 還可以為它們渲染出高顏值、響應式的 HTML 模板,同時自動產生純文字的副本。

產生訊息

要產生具有對應Markdown 範本的通知,可以在使用Artisan 指令make:notification#時帶上--markdown 選項:

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

和其他郵件通知一樣,使用Markdown 範本的通知類別也要定義一個toMail 方法。不過,你可以使用markdown 方法取代建構通知的lineaction 方法來指定要使用的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]);
   }

#

寫訊息

Markdown 郵件通知聯合使用了Blade 元件和Markdown 語法,讓你在不脫離Laravel 預置元件的情況下輕鬆建立通知:

@component('mail::message')
# Invoice PaidYour invoice has been paid!
@component('mail::button', ['url' => $url])
View Invoice
@endcomponent
Thanks,<br>
{{ config('app.name') }}
@endcomponent

#按鈕元件

按鈕元件渲染一個居中的按鈕連結。此元件接收兩個參數, url 和可選的color,支援的顏色有bluegreen 和 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      |       |
| Col 3 is      | Right-Aligned |       |
@endcomponent

#自訂元件

你可以匯出所有Markdown 通知元件到應用中進行自訂,要匯出元件,使用Artisan 指令vendor:publish 來發佈 laravel-mail 資源標籤:

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

該指令會發佈Markdown 郵件通知元件到resources/views/vendor/mail 目錄。 mail 目錄包含 htmlmarkdown 目錄,每個子目錄中都包含各自的所有有效元件。你可以按照自己的喜好自由編輯這些元件。

自訂CSS

匯出元件之後, resources/views/vendor/mail/html/themes 目錄將會包含一個預設的default.css 文件,你可以在這個文件中自訂CSS,這樣Markdown 通知的HTML 樣式就會自動調整。

{註:} 如果你想要為Markdown 元件建立全新的主題,只需在html/themes 目錄中寫一個新的CSS 檔案並修改  mail 設定檔的 theme 選項即可。

資料庫通知

#預備知識

#database

通知通道會在資料表中儲存通知訊息,該表包含諸如通知類型以及用於描述通知的自訂JSON 資料之類的資訊。 你可以在使用者介面中查詢這個資料表來展示通知,不過,在此之前,需要建立資料表來儲存訊息,你可以使用 

notifications:table

指令來產生遷移檔案接著以此產生對應資料表:

php artisan notifications:table
php artisan migrate

######

格式化資料庫通知

如果通知支援存入資料庫表,就為通知類別需要定義 toDatabasetoArray 方法。此方法接受 $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 用戶端。如果針對 databasebroadcast 通道分別有兩個不同的陣列表示,你需要定義 toDatabase 方法來取代 toArray 方法。

存取通知

一旦通知存入資料庫,就需要適當的方法自通知實體存取它們。包含在 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 請求。

標記通知已讀

#通常,在使用者閱覽一則通知之後,你會想將其標識為「已讀」。 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();

##廣播通知

############# ##########預備知識######廣播通知前,你需要設定和熟悉Laravel 的事件廣播服務。事件廣播提供了在 JavaScript 用戶端回應服務端觸發 Laravel 事件的方法。 ################

格式化廣播通知

broadcast 通道使用 Laravel 的 event 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,   
      ]);
   }

廣播佇列設定

所有的廣播通知都會被放入廣播佇列。想要設定用於廣播作業的佇列連線或佇列名稱,需要使用BroadcastMessageonConnectiononQueue 方法:

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

{tip} 除了指定的數據,廣播通知還包含type 域,它包括通知類別的類別名稱。

監聽通知

通知將會以格式化為{notifiable}.{id} 的形式在私人頻道上廣播,因此,如果你要發送通知到ID 為 1 的 App\User 實例,那麼該通知將會在私有頻道App.User .1 上進行廣播,如果使用了Laravel Echo,可以使用輔助函數 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;   
      }
   }

#簡訊(SMS)通知

預備知識

Laravel 基於Nexmo 發送簡訊通知,在使用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 控制面板中為應用程式產生一個手機號碼。

格式化簡訊通知

如果通知支援以簡訊方式發送,那麼你需要在通知類別上定義一個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();
    }

自訂"發送" 號碼

如果你要透過與設定檔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');
   }

簡訊通知路由

使用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;   
        }
    }

Slack通知

預備知識

在透過Slack 發送通知前,必須透過Composer 安裝Slack 通知通道:

composer require laravel/slack-notification-channel

此外,你也要為Slack 群組配置一個"Incoming Webhook" 整合。這個整合會在你進行 Slack 通知路由 的時候提供一個 URL。

格式化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,最終建立的訊息如下:

2.png

#Customizing The Sender & Recipient

你可以使用fromto 方法自訂發送者和接收者,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');
   }

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 訊息:

3.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' => ',234',                                    
                        'Via' => 'American Express',                                    
                        'Was Overdue' => ':-1:',                                
                        ]);              
          });
     }

上述程式碼會產生如下 Slack 訊息:

4.png

Markdown 附件內容

如果一些附件字段包含Markdown,可以使用markdown 方法來建構Slack 用來解析並顯示以Markdown 格式編寫的附件字段,則該方法支援的值包括 pretexttextfields。想要了解更多關於Slack 格式化的信息,請查看Slack API 文件

/**
 * 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']);            
              });
       }

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/...';  
        }
     }

本地化通知

#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));

#通知事件

當通知被傳送後,通知系統會觸發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
  }

自訂通道

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)  
     {     
        // ...  
      }
   }
本文章首發在LearnKu.com網站上。