+4

Laravel: Tìm hiểu về Notifications (Phần 2)

Database Notifications


Prerequisites

Kênh database notification lưu thông tin thông báo vào một bảng cơ sở dữ liệu. Bảng này sẽ chứa thông tin như là kiểu thông báo cũng như kiểu dữ liệu JSON để mô tả thông tin của thông báo.

Bạn có thể query vào bảng để hiển thị thông báo trong giao diện người dùng trong ứng dụng của bạn. Nhưng trước khi bạn làm điều này, bạn cần tạo một bảng để lưu thông báo của bạn. Bạn dùng lệnh notifications:table để tao file migrate chứa các thuộc tính của bảng:

php artisan notifications:table

php artisan migrate

Formatting Database Notifications

Nếu một thông báo hỗ trợ được lưu trong cơ sở dữ liệu, bạn nên định nghĩa một phương thức toDatabase hoặc toArray trong class notification. Phương thức này sẽ nhận về một entity $notifiable và nên trả về một plain PHP array. Mảng trả về này sẽ được encode JSON và lưu tại column data của bảng notifications. Hãy xem ví dụ về phương thức toArray:

/**
 * Get the array representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function toArray($notifiable)
{
    return [
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ];
}

toDatabaseVs. toArray Phương thức toArray cũng được sử dụng bởi kênh broadcast để xác định dữ liệu vào broadcast đến JavaScript client. Nếu bạn muốn có hai mảng representations khác nhau cho kênh databasebroadcast, bạn nên định nghĩa một phương thức toDatabase thay thế phương thức toArray.


Accessing The Notifications

Mỗi thông báo đã được lưu vào database, bạn cần một cách thuận tiện để truy cập chúng từ các thực thể thông báo của bạn. Illuminate\Notifications\Notifiable trait được mặc định thêm vào bởi Laravel trong model App\User, bao gồm một notifications Eloquent relationship nó sẽ trả về thông báo cho entiry (thực thể). Để lấy thông báo, bạn có thể truy cập phương thức này như bất kỳ Eloquent relationship. Mặc định, thông báo sẽ được sắp xếp theo created_at timestamp:

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

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

Nếu bạn chỉ muốn nhận những thông báo "unread", bạn có thể sử dụng unreadNotifications relationship. Một lần nữa, những thông báo đó sẽ được sắp xếp theo created_at timestamp:

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

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

Marking Notifications As Read

Thông thường, bạn sẽ muốn đánh dấu thông báo "read" khi nghười dùng xem nó. Illuminate\Notifications\Notifiable trait cung cấp một phương thức markAsRead, nó sẽ cập nhật column read_at trong record của notification database:

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

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

Tuy nhiên, thay vì dùng vòng lặp qua mỗi thông báo, bạn có thể sử dụng phương thức markAsRead trực tiếp trong một collection của thông báo:

$user->unreadNotifications->markAsRead();

Ngoài ra bạn cũng có thể sử dụng cập nhật hàng loạt để đánh dấu tất cả các thông báo đã đọc mà không cần lấy ra chúng từ database:

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

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

Dĩ nhiên, bạn cũng có thể delete các thông báo từ table entirely:

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

Broadcast Notifications


Prerequisites

Trước khi broadcasting thông báo, bạn nên cấu hình giống với event broadcasting services. Event broadcasting cung cấp một cách để tiếp cận vào server-side bắn ra Laravel từ JavaScript client.


Formatting Broadcast Notifications

Kênh broadcast thông báo broadcasts sử dụng event broadcasting services, cho phép JavaScript client để bắt thông báo realtime. Nếu một thông báo hỗ trợ broadcasting, bạn nên định nghĩa một phương thức toBroadcast trong class notification. Phương thức này sẽ nhận một entiry $notifiable và nên trả về một BroadcastMessage instance. Dữ liệu trả về sẽ được encoded thành JSON và broadcast vào JavaScript client của bạn. Hãy xem ví dụ phương thức BroadcastMessage:

/**
 * Get the broadcastable representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return BroadcastMessage
 */
public function toBroadcast($notifiable)
{
    return new BroadcastMessage([
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ]);
}

Broadcast Queue Configuration Tất cả các broadcast thông báo được xếp hàng đợi để phát sóng. Nếu bạn muốn cấu hình queue connection hoặc queue name được sử dụng cho hàng đợi broadcast operation, bạn có thể sử dụng phương thức onConnectiononQueue của BroadcastMessage:

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

Listening For Notifications

Thông báo sẽ được broadcast trong private chanel được định dạng sử dụng một {notifiable}.{id} convention. Vì vậy, nếu bạn gửi thông báo vào một App\User instance với id là 1, notification sẽ broadcast trong App.User.1 private chanel. Khi sử dụng Laravel Echo, bạn có thể dễ dàng lắng nghe một thông báo trên kênh sử dụng phương thức helper notification:

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

Customizing The Notification Channel Nếu bạn muốn tuỳ chỉnh các chanel thông báo entity nhận được broadcast notifications on, bạn có thể định nghĩa phương thức receiveBroadcastNotificationsOn trên notifiable entity:

<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The channels the user receives notification broadcasts on.
     *
     * @return string
     */
    public function receivesBroadcastNotificationsOn()
    {
        return 'users.'.$this->id;
    }
}

SMS Notifications


Prerequisites

Gửi thông báo SMS trong Laravel được cung cấp bởi Nexmo. Để gửi được thông báo qua Nexmo, bạn cần cài đặt nexmo/client Composer package và thêm một vài cấu hình tùy chọn vào trong file cấu hình ``config/services.php``` của bạn. Bạn có thể copy ví dụ cấu hình sau để bắt đầu:

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

Tùy chọn sms_from là số điện thoại sẽ gửi SMS. Bạn nên tạo một số điện thoại trong Nexmo control panel.


Formatting SMS Notifications

Nếu một thông báo hỗ trợ gửi SMS, bạn nên định nghĩa một phương thức toNexmo trong class notification. Nó sẽ nhận một entity $notifiable và trả về một Illuminate\Notifications\Messages\NexmoMessage instance:

/**
 * 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 Content Nếu tin nhắn SMS của bạn chứa ký tự unicode, bạn nên gọi phương thức unicode khi xây dựng NexmoMessage instance:

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

Customizing The "From" Number

Nếu bạn muốn gửi thông báo từ một số điện thoại khác với số điện thoại từ file cấu hình config/services.php, bạn có thể dùng phương thức from trong NexmoMessage instance:

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

Routing SMS Notifications

Khi gửi thông báo qua kênh nexmo, thông báo hệ thống sẽ tự động tìm thuộc tính phone_number trong notifiable entity. Nếu bạn muốn tùy biến số điện thoại được gửi đến, định nghĩa một phương thức routeNotificationForNexmo trong entity:

<?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.
     *
     * @return string
     */
    public function routeNotificationForNexmo()
    {
        return $this->phone;
    }
}

Slack Notifications


Prerequisites

Trước khi bạn có thể gửi thông báo qua Slack, bạn cần cài thư viện Guzzle HTTP library qua Composer:

composer require guzzlehttp/guzzle

Bạn cũng sẽ cần cấu hình tích hợp "Incoming Webhook" cho Slack team. Integration này sẽ cung cấp cho bạn một URL mà bạn có thể sử dụng khi routing Slack notifications.


Formatting Slack Notifications

Nếu một thông báo hỗ trợ qua thông báo của Slack mesage, bạn nên định nghĩa một phương thức toSlack trong class notification. Phương thức này sẽ nhận một entity $notifiable và trả về một Illuminate\Notifications\Messages\SlackMessage instance. Thông báo Slack có thể chứa nội dung text cũng như "đính kèm". Hãy xem ví dụ đơn giản của phương thức 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!');
}

Trong ví dụ trên chúng ta chỉ gửi một dòng text vào Slack, nó sẽ tạo ra một dòng text và nhìn như bên dưới:


Customizing The Sender & Recipient Bạn có thể sử dụng phương thức````fromtođể tùy chỉnh người gửi và người nhận. Phương thứcfromchấp nhận username và emoji identifier, trong khi phương thứcto``` chấp nhận chanel hoặc username:

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

Bạn cũng có thể sử dụng một hình ảnh làm biểu tượng của mình thay vì một 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 Attachments

Bạn cũng có thể "attachments" vào Slack. Attachments cung cấp nhiều định dạng phong phú hơn là simple text. Trong ví dụ này, chúng ta sẽ gửi một thông báo lỗi về exception xảy ra trong ứng dụng, gồm link để xem chi tiết về exception:

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

Ví dụ trên sẽ sinh ra một thông báo slack nhìn giống như sau: Attachments cũng cho phép bạn chỉ định một mảng được gửi cho người dùng. Mảng này sẽ được hiện theo kiểu bảng rất dễ để đọc:

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

Ví dụ trên sẽ sinh ra một thông báo slack giống như sau:


Markdown Attachment Content Nếu một số attachment fields của bạn có chứa Markdown, bạn có thể sử dụng phương thức markdown để hướng dẫn Slack parse và display các trường đính kèm đã chọn dưới dạng văn bản được định dạng Markdown. Các giá trị được chấp nhận bởi phương thức này là: pretext, text, and / or fields. Để biết thêm thông tin về định dạng tập tin đính kèm Slack, xem Slack API documentation:

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

Routing Slack Notifications

Để route Slack notifications đến vị trí thích hợp, định nghĩa một phương thức routeNotificationForSlack trong notifiable entity. Phương thức này sẽ trả về một webhook URL nơi mà thông báo sẽ được phục vụ. Webhook URLs có thể được sinh bởi "Incoming Webhook" service vào Slack team:

<?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.
     *
     * @return string
     */
    public function routeNotificationForSlack()
    {
        return $this->slack_webhook_url;
    }
}

Tài liệu: https://laravel.com/docs/5.5/notifications


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí