07. Notifikasi & Event
Mari bawa Chirper ke tingkat selanjutnya dengan mengirimkan notifikasi email saat Chirp baru dibuat.
Selain dukungan untuk mengirim email, Laravel menyediakan dukungan untuk mengirim notifikasi melalui berbagai kanal (channel) pengiriman, termasuk email, SMS, dan Slack. Ditambah lagi, berbagai kanal notifikasi buatan komunitas telah dibuat untuk mengirimkan notifikasi melalui puluhan kanal yang berbeda! Notifikasi juga dapat disimpan dalam database sehingga dapat ditampilkan di antarmuka web Anda.
Membuat notifikasi
Artisan dapat, sekali lagi, melakukan semua pekerjaan berat untuk kita dengan perintah berikut:
php artisan make:notification NewChirp
Ini akan membuat notifikasi baru di app/Notifications/NewChirp.php yang siap untuk kita sesuaikan.
Mari buka kelas NewChirp dan biarkan kelas tersebut menerima Chirp yang baru saja dibuat, lalu sesuaikan pesannya untuk menyertakan nama penulis dan potongan pesan:
<?php namespace App\Notifications; +use App\Models\Chirp; use Illuminate\Bus\Queueable;+use Illuminate\Support\Str; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; class NewChirp extends Notification { use Queueable; /** * Membuat instansi notifikasi baru. */- public function __construct()+ public function __construct(public Chirp $chirp) { // }
/** * Mengembalikan kanal pengiriman notifikasi. * * @return array<int, string> */ public function via(object $notifiable): array { return ['mail']; } /** * Mengembalikan representasi surel dari notifikasi. */ public function toMail(object $notifiable): MailMessage { return (new MailMessage)- ->line('Pendahuluan notifikasi.')- ->action('Aksi Notifikasi', url('/'))+ ->subject("Chirp baru dari {$this->chirp->user->name}")+ ->greeting("Chirp baru dari {$this->chirp->user->name}")+ ->line(Str::limit($this->chirp->message, 50))+ ->action('Buka Chirper', url('/')) ->line('Terima kasih telah menggunakan aplikasi kami!'); }
/** * Mengembalikan representasi array atas notifikasi. * * @return array<string, mixed> */ public function toArray(object $notifiable): array { return [ // ]; } }
Kita bisa mengirim notifikasi langsung dari metode store pada kelas ChirpController kita, tetapi itu menambah lebih banyak beban kerja bagi controller, yang ketika dijalankan dapat memperlambat request, karena kita akan melakukan kueri ke database dan mengirim email.
Sebagai gantinya, mari kita jalankan ("dispatch") sebuah event yang dapat kita dengarkan ("listen") dan proses dalam antrean latar belakang ("background queue") agar aplikasi kita tetap responsif.
Membuat event
Event adalah cara yang bagus untuk memisahkan berbagai aspek aplikasi Anda, karena satu event dapat memiliki beberapa listener yang tidak saling bergantung satu sama lain.
Mari buat event baru kita dengan perintah berikut:
php artisan make:event ChirpCreated
Ini akan membuat kelas event baru di app/Events/ChirpCreated.php.
Karena kita akan menjalankan event untuk setiap Chirp baru yang dibuat, mari perbarui event ChirpCreated kita untuk menerima Chirp yang baru dibuat agar kita dapat meneruskannya ke notifikasi kita:
<?php namespace App\Events; +use App\Models\Chirp; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class ChirpCreated { use Dispatchable, InteractsWithSockets, SerializesModels; /** * Membuat instansi event baru. */- public function __construct()+ public function __construct(public Chirp $chirp) { // }
/** * Mengembalikan kanal yang mana saja yang seharusnya menyiarkan event ini. */ public function broadcastOn(): array { return [ new PrivateChannel('nama-kanal'), ]; } }
Menjalankan event
Sekarang setelah kita memiliki kelas event, kita siap untuk menjalankannya kapan pun Chirp dibuat. Anda dapat menjalankan event di mana pun dalam siklus hidup aplikasi Anda, tetapi karena event kita berkaitan dengan pembuatan model Eloquent, kita dapat mengonfigurasi model Chirp kita untuk menjalankan event tersebut untuk kita.
<?php namespace App\Models; +use App\Events\ChirpCreated; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class Chirp extends Model { use HasFactory; protected $fillable = [ 'message', ]; + protected $dispatchesEvents = [+ 'created' => ChirpCreated::class,+ ]; public function user(): BelongsTo { return $this->belongsTo(User::class); } }
Sekarang setiap kali Chirp baru dibuat, event ChirpCreated akan di-dispatch.
Membuat event listener
Sekarang setelah kita menjalankan event, kita siap untuk "mendengarkan" event tersebut dan mengirimkan notifikasi kita.
Mari buat listener yang akan mendengarkan event ChirpCreated kita:
php artisan make:listener SendChirpCreatedNotifications --event=ChirpCreated
Listener baru akan ditempatkan di app/Listeners/SendChirpCreatedNotifications.php. Mari perbarui listener tersebut untuk mengirimkan notifikasi kita.
<?php namespace App\Listeners; use App\Events\ChirpCreated;+use App\Models\User;+use App\Notifications\NewChirp; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; -class SendChirpCreatedNotifications+class SendChirpCreatedNotifications implements ShouldQueue {
/** * Membuat listener untuk event. */ public function __construct() { // } /** * Menangani _event_ `ChirpCreated`. */ public function handle(ChirpCreated $event): void {- //+ foreach (User::whereNot('id', $event->chirp->user_id)->cursor() as $user) {+ $user->notify(new NewChirp($event->chirp));+ } } }
Kita telah menandai listener kita dengan interface ShouldQueue, yang memberitahu Laravel bahwa listener tersebut harus dijalankan dalam sebuah antrean (queue). Secara default, queue "database" akan digunakan untuk memproses pekerjaan secara asinkron. Untuk mulai memproses pekerjaan yang diantrekan, Anda harus menjalankan perintah Artisan php artisan queue:work di terminal Anda.
Kita juga telah mengonfigurasi listener kita untuk mengirim notifikasi ke setiap pengguna di platform, kecuali penulis Chirp tersebut. Dalam kenyataannya, ini mungkin mengganggu pengguna, jadi Anda mungkin ingin menerapkan fitur "mengikuti" (following) sehingga pengguna hanya menerima notifikasi untuk akun yang mereka ikuti.
Kita telah menggunakan database cursor untuk menghindari pemuatan semua pengguna ke dalam memori sekaligus.
Mote Dalam aplikasi production, Anda harus menambahkan kemampuan bagi pengguna Anda untuk berhenti berlangganan dari notifikasi semacam ini.
Coba sekarang
Anda dapat memanfaatkan alat pengujian email lokal seperti Mailpit dan HELO untuk menangkap email apa pun yang keluar dari aplikasi sehingga Anda dapat melihatnya. Jika Anda mengembangkan melalui Docker dan Laravel Sail, maka Mailpit sudah disertakan untuk Anda.
Sebagai alternatif, Anda dapat mengonfigurasi Laravel untuk menulis email ke file log dengan mengedit file .env di proyek Anda dan mengubah variabel environment MAIL_MAILER menjadi log. Secara default, email akan ditulis ke file log yang terletak di storage/logs/laravel.log.
Kita telah mengonfigurasi notifikasi kita agar tidak dikirim ke penulis Chirp, jadi pastikan untuk mendaftarkan setidaknya dua akun pengguna. Kemudian, silakan posting Chirp baru untuk memicu notifikasi.
Jika Anda menggunakan Mailpit, kunjungi halaman http://localhost:8025/, di mana Anda akan menemukan notifikasi untuk pesan yang baru saja Anda kirim!
Mengirim email di lingkungan production
Untuk mengirim email sungguhan di lingkungan production, Anda akan memerlukan server SMTP, atau penyedia email transaksional, seperti Mailgun, Postmark, atau Amazon SES. Laravel mendukung semua ini secara langsung. Untuk informasi lebih lanjut, silakan lihat dokumentasi Mail.
Lanjutkan untuk mempelajari tentang deployment aplikasi Anda...