Skip to content

Mail

Giới thiệu (Introduction)

Laravel cung cấp API sạch sẽ, đơn giản dựa trên Symfony Mailer. Hỗ trợ gửi email qua SMTP, Mailgun, Postmark, Resend, Amazon SES, và nhiều drivers khác.

Cấu hình (Configuration)

File cấu hình tại config/mail.php. Mỗi mailer có transport (phương thức gửi) riêng:

php
// .env
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

Driver Prerequisites

Mailgun

bash
composer require symfony/mailgun-mailer symfony/http-client

Postmark

bash
composer require symfony/postmark-mailer symfony/http-client

Amazon SES

bash
composer require aws/aws-sdk-php

Failover Configuration

Cấu hình mailer dự phòng:

php
'failover' => [
    'transport' => 'failover',
    'mailers' => ['postmark', 'mailgun', 'sendmail'],
],

Tạo Mailables (Generating Mailables)

bash
php artisan make:mail OrderShipped

Viết Mailables (Writing Mailables)

php
<?php

namespace App\Mail;

use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(
        public Order $order,
    ) {}

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Đơn hàng đã giao',
        );
    }

    public function content(): Content
    {
        return new Content(
            view: 'mail.orders.shipped',
        );
    }

    public function attachments(): array
    {
        return [];
    }
}

View Data

Public properties tự động có sẵn trong view:

blade
{{-- mail/orders/shipped.blade.php --}}
<div>
    <p>Giá: {{ $order->price }}</p>
</div>

Hoặc truyền data qua with:

php
public function content(): Content
{
    return new Content(
        view: 'mail.orders.shipped',
        with: [
            'orderName' => $this->order->name,
            'orderPrice' => $this->order->price,
        ],
    );
}

Attachments (Đính kèm)

php
use Illuminate\Mail\Mailables\Attachment;

public function attachments(): array
{
    return [
        Attachment::fromPath('/path/to/file'),
        Attachment::fromStorage('/path/to/file'),
        Attachment::fromStorageDisk('s3', '/path/to/file')
            ->as('name.pdf')
            ->withMime('application/pdf'),
    ];
}

Headers

php
use Illuminate\Mail\Mailables\Headers;

public function headers(): Headers
{
    return new Headers(
        messageId: 'custom-message-id@example.com',
        references: ['previous-message@example.com'],
        text: ['X-Custom-Header' => 'Custom Value'],
    );
}

Markdown Mailables

bash
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
php
public function content(): Content
{
    return new Content(
        markdown: 'mail.orders.shipped',
    );
}

Markdown template:

blade
<x-mail::message>
# Đơn Hàng Đã Giao

Đơn hàng của bạn đã được giao thành công.

<x-mail::button :url="$url">
    Xem Đơn Hàng
</x-mail::button>

Cảm ơn,<br>
{{ config('app.name') }}
</x-mail::message>

Gửi Mail (Sending Mail)

php
use App\Mail\OrderShipped;
use Illuminate\Support\Facades\Mail;

Mail::to($request->user())->send(new OrderShipped($order));

// Chỉ định CC, BCC
Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($managers)
    ->send(new OrderShipped($order));

Queueing Mail

php
Mail::to($request->user())
    ->queue(new OrderShipped($order));

// Queue cụ thể
Mail::to($request->user())
    ->queue(new OrderShipped($order), 'emails');

// Delay
Mail::to($request->user())
    ->later(now()->addMinutes(10), new OrderShipped($order));

Hoặc implement ShouldQueue trên Mailable:

php
class OrderShipped extends Mailable implements ShouldQueue
{
    // Tự động queue khi gọi send()
}

Rendering Mailables

Preview mailable trong browser:

php
Route::get('/mailable', function () {
    $order = App\Models\Order::find(1);
    return new App\Mail\OrderShipped($order);
});

Localize Mailables

php
Mail::to($request->user())
    ->locale('vi')
    ->send(new OrderShipped($order));

Testing

php
use App\Mail\OrderShipped;
use Illuminate\Support\Facades\Mail;

Mail::fake();

// Action...

Mail::assertSent(OrderShipped::class);
Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) {
    return $mail->order->id === 1;
});
Mail::assertNotSent(AnotherMailable::class);
Mail::assertSentCount(1);
Mail::assertNothingSent();
Mail::assertQueued(OrderShipped::class);

Local Development

Trong development, dùng log driver hoặc tools như Mailpit, HELO:

env
MAIL_MAILER=log