# 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.

- Yayın: 2018-05-06
- Kategori: Web Geliştirme
- Etiketler: Laravel
- Okuma süresi: 3 dk okuma
- Kaynak: https://www.muhammetsafak.com.tr/blog/laravelde-bildirimler-notifications-e-posta-ve-sms/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
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ı](/blog/laravel-ile-e-posta-gonderimi-ve-sablonlari) 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:

```bash
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
<?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
<?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
<?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
<?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
<?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
<?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
<?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.
