İçeriğe geç
Muhammet Şafak
Web Geliştirme 3 dk okuma

Laravel'de bildirimler (notifications): e-posta ve SMS

Laravel Notification sınıflarıyla aynı bildirim mantığını e-posta, SMS gibi birden çok kanaldan nasıl gönderdiğimi anlatıyorum.


Bir uygulama büyüdükçe bildirim ihtiyacı da çeşitleniyor: sipariş onayı e-posta ile gitsin, kargo bildirimi SMS ile gitsin, yorum bildirimi ise uygulama içi bildirim olsun. Laravel’in notification sistemiyle bu farklı kanalları tek bir sınıf üzerinden yönetmek mümkün. Kanalı çoğaltmak, mevcut bildirimi bozmak zorunda kalmadan yapılıyor — bu yapının asıl değeri bu.

Bildirim sistemi nasıl çalışır?

Laravel’de her bildirim bir sınıftır. Bu sınıf, hangi kanallardan gönderileceğini ve her kanalda nasıl görüneceğini tanımlar. Artisan komutuyla bir iskelet üretebilirsiniz:

php artisan make:notification OrderShipped

Oluşan sınıf app/Notifications/OrderShipped.php yolunda yer alır. İki kritik metot içerir: via ve toMail (ya da toNexmo, toBroadcast gibi kanal metodları).

E-posta bildirimi

via metodu hangi kanalların kullanılacağını döndürür. toMail metodu ise posta mesajını oluşturur:

<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;

class OrderShipped extends Notification
{
    protected $order;

    public function __construct($order)
    {
        $this->order = $order;
    }

    public function via($notifiable)
    {
        return ['mail'];
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->subject('Siparişiniz kargoya verildi')
            ->line('Siparişiniz ' . $this->order->tracking_number . ' takip numarasıyla kargoya verildi.')
            ->action('Siparişi Takip Et', url('/orders/' . $this->order->id))
            ->line('Alışverişiniz için teşekkür ederiz.');
    }
}

Bildirimi bir kullanıcıya göndermek için notify metodu yeterli:

<?php

$user->notify(new OrderShipped($order));

notify metodu, Notifiable trait’ini kullanan her model için otomatik olarak geliyor. User modeli bu trait’i varsayılan olarak içeriyor.

SMS kanalı eklemek

Aynı bildirimi SMS olarak da göndermek istediğinizde via metoduna SMS kanalını eklemeniz yeterli. Laravel, Nexmo (şimdiki adıyla Vonage) entegrasyonuyla birlikte geliyor:

<?php

public function via($notifiable)
{
    return ['mail', 'nexmo'];
}

public function toNexmo($notifiable)
{
    return (new NexmoMessage)
        ->content('Siparişiniz ' . $this->order->tracking_number . ' numarasıyla kargoya verildi.');
}

toMail metodunu değiştirmeden SMS kanalını ekledim. Bildirim mantığı tek yerde, kanallar ayrı metodlarda — bu ayrım sağlam.

Kanalı kullanıcıya göre belirlemek

Gerçek projelerde her kullanıcı her kanalı istemeyebilir. Biri SMS almak istemiyordur, diğeri yalnızca e-posta tercih ediyordur. via metodu $notifiable nesnesini parametre olarak alıyor; kullanıcı tercihlerine göre karar verebilirsiniz:

<?php

public function via($notifiable)
{
    $channels = ['mail'];

    if ($notifiable->sms_notifications_enabled) {
        $channels[] = 'nexmo';
    }

    return $channels;
}

Bu sayede bildirim sınıfı değişmeden, kullanıcı tablosundaki bir sütun kanal listesini belirliyor.

Veritabanı bildirimleri

Uygulamanızın içinde bildirim kutucuğu göstermek istiyorsanız, database kanalı bunu sağlıyor. Bildirimler notifications tablosuna kaydediliyor; okunmamış bildirim sayısını, listesini sorgulamak kolaylaşıyor.

<?php

public function via($notifiable)
{
    return ['mail', 'database'];
}

public function toArray($notifiable)
{
    return [
        'order_id'       => $this->order->id,
        'tracking_number' => $this->order->tracking_number,
    ];
}
<?php

// Okunmamış bildirimleri çekmek
$user->unreadNotifications;

// Tüm bildirimleri okunmuş işaretlemek
$user->unreadNotifications->markAsRead();

database kanalını ilk kullandığımda bir şeyi gözden kaçırdım: notifications tablosunun oluşturulması için migration çalıştırmak gerekiyor. Laravel php artisan notifications:table komutuyla bu migration’ı üretiyor. Bildirimlerin sessizce kaybolduğunu bir süre anlayamadım; tablo yoktu.

Kuyruk ile asenkron gönderim

E-posta ve SMS gönderimi zaman alan işlemler. Bir kullanıcı sipariş verdiğinde yanıtın beklememesi için bildirimleri queue’ya alabileceğinizi belirtmeden geçmeyeyim. Bildirim sınıfınızın ShouldQueue arayüzünü implement etmesi yeterli:

<?php

use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Notification implements ShouldQueue
{
    // ...
}

Kuyruk altyapısı ayrı bir konu; bu yazıda detayına girmeyi planlamıyorum, ama ShouldQueue satırını eklemek gerçek projelerde hemen uygulanabilir ilk adım.

Sonuç

Laravel’in bildirim sistemi, “hangi kanaldan gönderilecek” kararını tek bir sınıfta toplaması bakımından çok temiz bir tasarıma sahip. Yeni bir kanal eklemek mevcut mantığı değiştirmiyor; sadece yeni bir metod geliyor. Proje büyüdükçe, bildirim türleri çoğaldıkça bu ayrımın değeri katlanarak artıyor. Eski yaklaşımda her kanal için ayrı kod yazıyordum ve bir değişiklik her birini ayrı ayrı güncellemeyi gerektiriyordu; artık bildirim mantığı tek yerde.

Bildirim sınıfları büyüdükçe dikkat edilmesi gereken bir şey daha var: via metodu içinde channel kararı sadece kullanıcı tercihinden değil, bildirimin kendisine bağlı koşullardan da etkilenebilir. Örneğin sipariş tutarı belirli bir eşiği aşıyorsa SMS de gönderilsin, altındaysa yalnızca e-posta gitsin gibi bir mantık kurulabilir. Bu karar via içinde kalıyorsa bildirim sınıfı şişebilir; böyle durumlarda farklı bildirim sınıfları oluşturup hangisinin gönderileceği kararını çağıran kodda vermek daha temiz bir ayrım sağlıyor. Bildirim sınıfı “nasıl gönderilir” sorusunu bilmeli; “ne zaman ve hangi koşulda gönderilir” sorusu onu çağıran iş mantığının işi.

Etiketler: #Laravel
Paylaş:

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi