Bir kayıt formu, sipariş onayı ya da şifre sıfırlama bağlantısı… Modern bir uygulamanın neredeyse her akışında e-posta vardır. Laravel mail altyapısı bu işi gözünüzde büyütmeyecek kadar temiz bir API ile sunar: Mailable sınıfları tek bir e-postayı, Notification sınıfları ise aynı mesajı mail, veritabanı ve Slack gibi birden çok kanala aynı anda ulaştırmayı kolaylaştırır. Bu yazıda ikisinin nerede kullanılacağını, şablonları nasıl tasarlayacağınızı ve gönderimi nasıl güvenilir hale getireceğinizi adım adım göreceğiz.
SMTP yapılandırması ve sürücü seçimi
Her şey config/mail.php ve .env ile başlar. Laravel; SMTP, Amazon SES, Postmark, Mailgun ve log gibi sürücüleri destekler. Geliştirme sırasında log sürücüsü mailleri storage/logs/laravel.log içine yazar; böylece gerçek mail göndermeden çıktıyı görebilirsiniz.
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@example.com
MAIL_PASSWORD=secret
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
Yerel testte Mailpit veya Mailtrap gibi bir araç kullanmak çok işe yarar: gönderilen her mail bir web arayüzünde yakalanır, gerçek kullanıcılara hiçbir şey ulaşmaz.
İlk Mailable sınıfınız
Tek bir e-postayı temsil eden sınıfı Artisan ile oluşturun. --markdown bayrağı hazır bir şablonla birlikte gelir:
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
Laravel 9 ve sonrasında Mailable yapısı üç metoda ayrıldı: envelope() (konu, gönderen), content() (görünüm ve veriler) ve attachments(). Net ve okunması kolay bir yapı:
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public Order $order) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Siparişiniz yola çıktı',
);
}
public function content(): Content
{
return new Content(
markdown: 'mail.orders.shipped',
with: ['order' => $this->order],
);
}
}
Göndermek için Mail facade'ı yeterli:
use Illuminate\Support\Facades\Mail;
Mail::to($order->user)->send(new OrderShipped($order));
Markdown şablonlarıyla tasarım
Markdown mail'leri, Laravel'in hazır bileşenlerini kullanır ve hem HTML hem de düz metin sürümünü otomatik üretir. Şablon, okunaklı ve responsive bir tema ile gelir:
<x-mail::message>
# Merhaba {{ $order->user->name }}
Siparişiniz ({{ $order->number }}) kargoya verildi.
<x-mail::button :url="$url">
Siparişi Görüntüle
</x-mail::button>
Teşekkürler,<br>
{{ config('app.name') }}
</x-mail::message>
Temayı markanıza uyarlamak için php artisan vendor:publish --tag=laravel-mail komutuyla bileşenleri ve resources/css/mail.css dosyasını yayımlayabilirsiniz. Renkleri, logoyu ve alt bilgiyi burada düzenlersiniz.
Notification ile çok kanallı bildirim
Aynı olayı birden fazla kanaldan duyurmak istediğinizde Notification devreye girer. Örneğin bir fatura ödendiğinde hem mail gönderip hem de veritabanına kayıt düşmek isteyebilirsiniz.
php artisan make:notification InvoicePaid
class InvoicePaid extends Notification
{
use Queueable;
public function __construct(public Invoice $invoice) {}
public function via(object $notifiable): array
{
return ['mail', 'database'];
}
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->subject('Faturanız ödendi')
->greeting('Merhaba!')
->line(''.$this->invoice->amount.' tutarındaki faturanız ödendi.')
->action('Faturayı Gör', url('/invoices/'.$this->invoice->id))
->line('Teşekkür ederiz.');
}
public function toArray(object $notifiable): array
{
return ['invoice_id' => $this->invoice->id];
}
}
Modelinizde Notifiable trait'i varsa gönderim tek satır:
$user->notify(new InvoicePaid($invoice));
via() içinde database kanalını kullanıyorsanız php artisan make:notifications-table ile gerekli tabloyu oluşturmayı unutmayın. Slack, SMS (Vonage) ve broadcast gibi resmi kanalların yanında topluluk paketleriyle Telegram veya WhatsApp da eklenebilir.
Kuyruğa alma ve hata yönetimi
E-posta göndermek yavaş bir iştir; kullanıcıyı SMTP yanıtı için bekletmeyin. ShouldQueue arayüzünü uygulamak, mail veya notification'ı otomatik olarak kuyruğa atar:
class OrderShipped extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
// ...
}
Kuyruğun çalışması için bir worker gerekir: php artisan queue:work. Üretimde bunu Supervisor ile sürekli ayakta tutun. Başarısız işler failed_jobs tablosuna düşer ve php artisan queue:retry ile yeniden denenebilir. Geçici SMTP hataları için Mailable üzerinde $tries ve backoff() tanımlayarak otomatik tekrar deneme aralıkları belirleyebilirsiniz.
Test etme
Mail göndermeyi test etmek için gerçek SMTP'ye ihtiyacınız yok. Mail::fake() gönderimi yakalar ve doğrulamanıza olanak tanır:
Mail::fake();
// ... siparişi işle ...
Mail::assertSent(OrderShipped::class, function ($mail) use ($order) {
return $mail->order->id === $order->id;
});
Aynı şekilde Notification::fake() ve Notification::assertSentTo() ile bildirimleri test edebilirsiniz. Bu yaklaşım testlerinizi hızlı ve dış servislerden bağımsız tutar.
Sık Sorulan Sorular
Mailable mı Notification mı kullanmalıyım?
Tek kanaldan (yalnızca e-posta) zengin, özel tasarımlı bir mesaj gönderiyorsanız Mailable yeterlidir. Aynı olayı birden çok kanala (mail + veritabanı + Slack) iletmek ya da kanal seçimini kullanıcıya bırakmak istiyorsanız Notification daha uygundur.
Mailler neden geç gönderiliyor veya hiç gitmiyor?
En sık neden, ShouldQueue kullanıp worker'ı çalıştırmamaktır. queue:work çalışıyor mu kontrol edin, failed_jobs tablosuna ve storage/logs içine bakın. SMTP kimlik bilgileri ve port ayarlarını da doğrulayın.
HTML mail'lerin spam'e düşmesini nasıl önlerim?
Doğrulanmış bir gönderen alan adı, SPF/DKIM/DMARC kayıtları ve düz metin alternatifi içeren mailler en güvenilir sonucu verir. Markdown mail'ler düz metin sürümünü zaten üretir; ayrıca itibarı yüksek bir gönderim sağlayıcısı (SES, Postmark, Mailgun) tercih edin.
E-posta akışınızı baştan kurmak ya da mevcut bildirim sisteminizi düzene sokmak mı istiyorsunuz? Laravel mail ve notification altyapısını ihtiyaçlarınıza göre tasarlayalım. Benimle iletişime geçin.