MailSlurp logo

blog

Laravel Notification Tutorial: Email, SMS, Queues, and Test Automation

Learn how to build Laravel notifications with mail and SMS channels, queue them safely, and test delivery end to end using MailSlurp.

Laravel notifications are easy to start and easy to get wrong at scale. This tutorial focuses on the production details: channel choice, queue behavior, and delivery testing.

What you will build

  • a queued Laravel notification class
  • a mail channel implementation with custom subject/from metadata
  • an optional SMS channel strategy
  • a repeatable test that verifies the notification actually arrives

Channel selection matrix

Channel Best for Common failure mode Guardrail
Mail account verification, receipts, workflow alerts queue delay or provider throttling queue monitoring + deterministic inbox tests
SMS OTP and urgent short-form events provider limits and regional restrictions retry policy + fallback channel
Slack internal incident/event broadcast webhook misconfiguration signed webhook checks + alert routing tests
Database/UI in-app notifications stale read state in clients read-state assertions and pagination tests

Step 1: Create a notification class

php artisan make:notification StatusUpdate

Example notification with queueing:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class StatusUpdate extends Notification implements ShouldQueue
{
    use Queueable;

    public function __construct(
        public string $subjectLine,
        public string $ctaUrl
    ) {}

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

    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
            ->subject($this->subjectLine)
            ->greeting('Hello!')
            ->line('Your account has a new status update.')
            ->action('Open dashboard', $this->ctaUrl)
            ->line('If you did not request this, contact support.');
    }
}

Step 2: Dispatch through the queue

Use queue workers for notification delivery so web requests stay fast.

QUEUE_CONNECTION=redis
php artisan queue:work --tries=3 --backoff=5

In code:

$user->notify(new StatusUpdate(
    subjectLine: 'Your request is approved',
    ctaUrl: route('dashboard')
));

Step 3: Test notification delivery with real inboxes

Unit tests verify class behavior, but integration tests should prove real delivery. MailSlurp can create isolated inboxes for each test run and wait for expected messages.

public function test_status_notification_is_delivered(): void
{
    $recipient = $this->createMailslurpInbox();

    $user = User::factory()->create([
        'email' => $recipient['emailAddress'],
    ]);

    $user->notify(new StatusUpdate(
        subjectLine: 'Your request is approved',
        ctaUrl: url('/dashboard')
    ));

    $email = $this->waitForLatestEmail($recipient['id']);

    $this->assertStringContainsString('approved', $email['subject']);
    $this->assertStringContainsString('/dashboard', $email['body']);
}

Use this pattern for password reset, email verification, billing receipts, and admin workflow notifications.

How to inspect queued notifications

Use these checks during incident triage:

  • queue depth and worker health
  • failed jobs table
  • provider response codes (throttle, reject, timeout)
  • per-notification send latency

If notifications are delayed, fix queue pressure before changing templates or content.

Laravel notification hardening checklist

  • implement ShouldQueue for non-trivial notifications
  • set explicit retry and backoff settings
  • include idempotency strategy for repeatable triggers
  • test delivery end to end in CI, not only in local mail preview
  • track send failure rate and median delivery latency