Вступление

Laravel предоставляет чистый и простой API поверх популярной библиотеки SwiftMailer с драйверами для SMTP, Mailgun, Postmark, SparkPost, Amazon SES и sendmail позволяет быстро начать отправку почты через локальную или облачную службу по вашему выбору.

Необходимые условия для водителя

Драйверы на основе API, такие как Mailgun, SparkPost и Postmark, часто проще и быстрее, чем SMTP-серверы. Если возможно, вы должны использовать один из этих драйверов. Для всех драйверов API требуется библиотека Guzzle HTTP, которую можно установить через менеджер пакетов Composer:

composer require guzzlehttp/guzzle

Mailgun Driver

Чтобы использовать драйвер Mailgun, сначала установите Guzzle, затем установите driverопцию в вашем файле конфигурации на . Затем убедитесь, что ваш файл конфигурации содержит следующие параметры:config/mail.phpmailgunconfig/services.php

'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-key',
],

Если вы не используете регион почтовой пушки США , вы можете определить конечную точку своего региона в servicesфайле конфигурации:

'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-key',
    'endpoint' => 'api.eu.mailgun.net',
],

Почтовый штемпель

Чтобы использовать драйвер Postmark, установите транспорт Postmark SwiftMailer через Composer:

composer require wildbit/swiftmailer-postmark

Далее установите Guzzle и установите driverопцию в вашем файле конфигурации на . Наконец, убедитесь, что ваш файл конфигурации содержит следующие параметры:config/mail.phppostmarkconfig/services.php

'postmark' => [
    'token' => 'your-postmark-token',
],

SparkPost Драйвер

Чтобы использовать драйвер SparkPost, сначала установите Guzzle, а затем установите driverпараметр в файле конфигурации на . Затем убедитесь, что ваш файл конфигурации содержит следующие параметры:config/mail.phpsparkpostconfig/services.php

'sparkpost' => [
    'secret' => 'your-sparkpost-key',
],

При необходимости вы также можете указать, какую конечную точку API следует использовать:

'sparkpost' => [
    'secret' => 'your-sparkpost-key',
    'options' => [
        'endpoint' => 'https://api.eu.sparkpost.com/api/v1/transmissions',
    ],
],

SES Driver

Чтобы использовать драйвер Amazon SES, сначала необходимо установить Amazon AWS SDK для PHP. Вы можете установить эту библиотеку, добавив следующую строку в раздел вашего файла и выполнив команду:composer.jsonrequirecomposer update

"aws/aws-sdk-php": "~3.0"

Затем установите driverпараметр в вашем файле конфигурации и убедитесь, что ваш файл конфигурации содержит следующие параметры:config/mail.phpsesconfig/services.php

'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'ses-region',  // e.g. us-east-1
],

Если вам нужно включить дополнительные параметры при выполнении SendRawEmailзапроса SES , вы можете определить optionsмассив в вашей sesконфигурации:

'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'ses-region',  // e.g. us-east-1
    'options' => [
        'ConfigurationSetName' => 'MyConfigurationSet',
        'Tags' => [
            [
                'Name' => 'foo',
                'Value' => 'bar',
            ],
        ],
    ],
],

 

Создание почтовых сообщений

В Laravel каждый тип электронной почты, отправляемой вашим приложением, представлен как «почтовый» класс. Эти классы хранятся в каталоге. Не беспокойтесь, если вы не увидите этот каталог в своем приложении, так как он будет сгенерирован для вас, когда вы создадите свой первый почтовый класс с помощью команды:app/Mailmake:mail

php artisan make:mail OrderShipped

 

Написание почтовых сообщений

Вся конфигурация почтового класса выполняется в buildметоде. В рамках этого метода, вы можете вызвать различные методы , такие как fromsubjectviewи attachдля настройки представления и доставки сообщения электронной почты.

Настройка отправителя

Используя fromметод

Сначала рассмотрим настройку отправителя электронного письма. Или, другими словами, кто электронная почта будет "от". Есть два способа настроить отправителя. Во-первых, вы можете использовать fromметод внутри метода вашего почтового класса build:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com')
                ->view('emails.orders.shipped');
}

Использование глобального fromадреса

Однако, если ваше приложение использует один и тот же адрес «от» для всех своих электронных писем, вызывать fromметод в каждом создаваемом вами почтовом классе может быть затруднительно . Вместо этого вы можете указать глобальный адрес «из» в вашем файле конфигурации. Этот адрес будет использоваться, если в почтовом классе не указан другой адрес «от»:config/mail.php

'from' => ['address' => 'example@example.com', 'name' => 'App Name'],

Кроме того, вы можете определить глобальный адрес «reply_to» в вашем файле конфигурации:config/mail.php

'reply_to' => ['address' => 'example@example.com', 'name' => 'App Name'],

 

Конфигурирование View

В методе почтового класса buildвы можете использовать viewметод, чтобы указать, какой шаблон следует использовать при визуализации содержимого электронного письма. Поскольку каждое электронное письмо обычно использует шаблон Blade для рендеринга своего содержимого, у вас есть все возможности и удобство шаблонизатора Blade при создании HTML-кода вашей электронной почты:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped');
}

Вы можете создать каталог для размещения всех ваших шаблонов электронной почты; однако вы можете свободно размещать их в своем каталоге.resources/views/emailsresources/views

Обычные текстовые электронные письма

Если вы хотите определить текстовую версию своего электронного письма, вы можете использовать этот textметод. Как и viewметод, textметод принимает имя шаблона, которое будет использоваться для визуализации содержимого электронного письма. Вы можете определить как HTML, так и текстовую версию вашего сообщения:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->text('emails.orders.shipped_plain');
}

 

Просмотр данных

Через общественные свойства

Как правило, вы захотите передать некоторые данные вашему представлению, которые вы можете использовать при рендеринге HTML письма. Есть два способа сделать данные доступными для просмотра. Во-первых, любое общедоступное свойство, определенное в вашем почтовом классе, будет автоматически доступно для просмотра. Так, например, вы можете передать данные в конструктор вашего почтового класса и установить эти данные для открытых свойств, определенных в классе:

<?php

namespace App\Mail;

use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * The order instance.
     *
     * @var Order
     */
    public $order;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
}

Как только данные будут установлены в публичное свойство, они будут автоматически доступны в вашем представлении, поэтому вы можете получить к ним доступ так же, как и к любым другим данным в ваших шаблонах Blade:

<div>
    Price: {{ $order->price }}
</div>

С помощью withметода:

Если вы хотите настроить формат данных вашего электронного письма перед его отправкой в ​​шаблон, вы можете вручную передать свои данные в представление с помощью withметода. Как правило, вы все равно будете передавать данные через конструктор почтового класса; однако вы должны установить эти данные protectedили privateсвойства, чтобы данные не делались автоматически доступными для шаблона. Затем при вызове withметода передайте массив данных, которые вы хотите сделать доступными для шаблона:

<?php

namespace App\Mail;

use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * The order instance.
     *
     * @var Order
     */
    protected $order;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->with([
                        'orderName' => $this->order->name,
                        'orderPrice' => $this->order->price,
                    ]);
    }
}

Как только данные будут переданы withметоду, они будут автоматически доступны в вашем представлении, поэтому вы можете получить к ним доступ так же, как и к любым другим данным в ваших шаблонах Blade:

<div>
    Price: {{ $orderPrice }}
</div>

 

Вложения

Чтобы добавить вложения в электронное письмо, используйте attachметод в методе класса mailable buildattachМетод принимает полный путь к файлу в качестве первого аргумента:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->attach('/path/to/file');
}

Прикрепляя файлы к сообщению, вы также можете указать отображаемое имя и / или тип MIME, передав arrayв attachметоде второй аргумент :

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->attach('/path/to/file', [
                    'as' => 'name.pdf',
                    'mime' => 'application/pdf',
                ]);
}

Вложение файлов с диска

Если вы сохранили файл на одном из дисков вашей файловой системы , вы можете прикрепить его к электронному письму, используя attachFromStorageметод:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
   return $this->view('email.orders.shipped')
               ->attachFromStorage('/path/to/file');
}

При необходимости вы можете указать имя вложения файла и дополнительные параметры, используя второй и третий аргументы attachFromStorageметода:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
   return $this->view('email.orders.shipped')
               ->attachFromStorage('/path/to/file', 'name.pdf', [
                   'mime' => 'application/pdf'
               ]);
}

Этот attachFromStorageDiskметод можно использовать, если вам нужно указать диск хранения, отличный от диска по умолчанию:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
   return $this->view('email.orders.shipped')
               ->attachFromStorageDisk('s3', '/path/to/file');
}

Вложения необработанных данных

Этот attachDataметод может использоваться для присоединения необработанной строки байтов в качестве вложения. Например, вы можете использовать этот метод, если вы создали PDF-файл в памяти и хотите прикрепить его к электронному письму, не записывая его на диск. attachDataМетод принимает исходные байты данных в качестве первого аргумента, имя файла в качестве второго аргумента, и массив значений в качестве третьего аргумента:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->attachData($this->pdf, 'name.pdf', [
                    'mime' => 'application/pdf',
                ]);
}

 

Встроенные вложения

Встраивание встроенных изображений в ваши электронные письма обычно обременительно; тем не менее, Laravel предоставляет удобный способ прикреплять изображения к вашим электронным письмам и получать соответствующий CID. Чтобы встроить встроенное изображение, используйте embedметод для $messageпеременной в шаблоне электронной почты. Laravel автоматически делает $messageпеременную доступной для всех ваших шаблонов электронной почты, поэтому вам не нужно беспокоиться о передаче ее вручную:

<body>
    Here is an image:

    <img src="{{ $message->embed($pathToImage) }}">
</body>

$message переменная недоступна в текстовых сообщениях, так как текстовые сообщения не используют встроенные вложения.

Вложение необработанных вложений данных

Если у вас уже есть строка необработанных данных, которую вы хотите встроить в шаблон электронной почты, вы можете использовать embedDataметод для $messageпеременной:

<body>
    Here is an image from raw data:

    <img src="{{ $message->embedData($data, $name) }}">
</body>

 

Настройка сообщения SwiftMailer

withSwiftMessageМетод Mailableбазового класса позволяет зарегистрировать функцию обратного вызова , которая будет вызываться с экземпляром сообщения сырого SwiftMailer перед отправкой сообщения. Это дает вам возможность настроить сообщение до его доставки:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    $this->view('emails.orders.shipped');

    $this->withSwiftMessage(function ($message) {
        $message->getHeaders()
                ->addTextHeader('Custom-Header', 'HeaderValue');
    });
}

 

Markdown Mailables

Почтовые сообщения с разметкой позволяют использовать предварительно созданные шаблоны и компоненты почтовых уведомлений в ваших почтовых сообщениях. Поскольку сообщения написаны в Markdown, Laravel может создавать красивые, отзывчивые HTML-шаблоны для сообщений, а также автоматически генерировать простой текстовый аналог.

Создание почтовых рассылок уценки

Чтобы создать почтовое сообщение с соответствующим шаблоном Markdown, вы можете использовать --markdownопцию команды Artisan:make:mail

php artisan make:mail OrderShipped --markdown=emails.orders.shipped

Затем при настройке почтового сообщения в его buildметоде вызовите markdownметод вместо viewметода. В markdownметоды принимает имя шаблона Markdown и дополнительный массив данных , чтобы сделать доступными в шаблоне:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com')
                ->markdown('emails.orders.shipped');
}

 

Написание уценочных сообщений

В почтовых сообщениях Markdown используется комбинация компонентов Blade и синтаксиса Markdown, которые позволяют легко создавать почтовые сообщения, используя заранее созданные компоненты Laravel:

@component('mail::message')
# Order Shipped

Your order has been shipped!

@component('mail::button', ['url' => $url])
View Order
@endcomponent

Thanks,<br>
{{ config('app.name') }}
@endcomponent

Не используйте лишние отступы при написании писем Markdown. Анализаторы Markdown будут отображать содержимое с отступом в виде блоков кода.

Компонент кнопки

Компонент кнопки отображает ссылку по центру кнопки. Компонент принимает два аргумента, a urlи необязательный color. Поддерживаемые цвета primarysuccessи error. Вы можете добавить в сообщение столько компонентов кнопок, сколько пожелаете:

@component('mail::button', ['url' => $url, 'color' => 'success'])
View Order
@endcomponent

Компонент панели

Компонент панели отображает данный блок текста на панели, цвет фона которой немного отличается от остальной части сообщения. Это позволяет вам обратить внимание на данный блок текста:

@component('mail::panel')
This is the panel content.
@endcomponent

Компонент таблицы

Компонент table позволяет вам преобразовывать таблицу Markdown в таблицу HTML. Компонент принимает таблицу Markdown в качестве своего содержимого. Выравнивание столбцов таблицы поддерживается с использованием синтаксиса выравнивания таблицы Markdown по умолчанию:

@component('mail::table')
| Laravel       | Table         | Example  |
| ------------- |:-------------:| --------:|
| Col 2 is      | Centered      | $10      |
| Col 3 is      | Right-Aligned | $20      |
@endcomponent

 

Настройка компонентов

Вы можете экспортировать все почтовые компоненты Markdown в собственное приложение для настройки. Чтобы экспортировать компоненты, используйте команду Artisan для публикации тега ресурса:vendor:publishlaravel-mail

php artisan vendor:publish --tag=laravel-mail

Эта команда опубликует почтовые компоненты Markdown в каталоге. Каталог будет содержать и в каталог, каждый из которых содержит свои соответствующие представления каждого доступного компонента. Вы можете настроить эти компоненты по своему усмотрению.resources/views/vendor/mailmailhtmltext

Настройка CSS

После экспорта компонентов каталог будет содержать файл. Вы можете настроить CSS в этом файле, и ваши стили будут автоматически встроены в представления HTML ваших почтовых сообщений Markdown.resources/views/vendor/mail/html/themesdefault.css

Если вы хотите создать совершенно новую тему для компонентов Markdown, напишите новый CSS-файл в каталоге и измените опцию вашего файла конфигурации.html/themesthememail

 

Отправка почты

Чтобы отправить сообщение, используйте toметод на Mail фасаде . toМетод принимает адрес электронной почты, пользовательский экземпляр, или набор пользователей. Если вы передадите объект или коллекцию объектов, почтовая программа автоматически использует их emailи nameсвойства при настройке получателей электронной почты, поэтому убедитесь, что эти атрибуты доступны для ваших объектов. После того как вы определили своих получателей, вы можете передать экземпляр вашего почтового класса sendметоду:

<?php

namespace App\Http\Controllers;

use App\Order;
use App\Mail\OrderShipped;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\Controller;

class OrderController extends Controller
{
    /**
     * Ship the given order.
     *
     * @param  Request  $request
     * @param  int  $orderId
     * @return Response
     */
    public function ship(Request $request, $orderId)
    {
        $order = Order::findOrFail($orderId);

        // Ship order...

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

Вы не ограничены указанием только «получателей» при отправке сообщения. Вы можете установить получателей «to», «cc» и «bcc» в одном цепочечном вызове метода:

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->send(new OrderShipped($order));

 

Рендеринг почтовых отправлений

Иногда вы можете захотеть перехватить содержимое HTML сообщения, не отправляя его. Для этого вы можете вызвать renderметод mailable. Этот метод вернет оцененное содержимое отправляемого сообщения в виде строки:

$invoice = App\Invoice::find(1);

return (new App\Mail\InvoicePaid($invoice))->render();

 

Предварительный просмотр почтовых сообщений в браузере

При разработке шаблона почтового сообщения удобно быстро просмотреть отображаемое почтовое сообщение в вашем браузере, как обычный шаблон Blade. По этой причине Laravel позволяет вам возвращать любую отправляемую почту непосредственно из закрытия маршрута или контроллера. Когда почтовое сообщение возвращается, оно будет отображено и отображено в браузере, что позволяет быстро просмотреть его дизайн, не отправляя его на фактический адрес электронной почты:

Route::get('mailable', function () {
    $invoice = App\Invoice::find(1);

    return new App\Mail\InvoicePaid($invoice);
});

 

Очередь почты

Очередь почтового сообщения

Поскольку отправка сообщений электронной почты может значительно увеличить время отклика вашего приложения, многие разработчики предпочитают помещать сообщения электронной почты в очередь для фоновой отправки. Laravel облегчает это, используя встроенный API единой очереди . Чтобы поставить в очередь почтовое сообщение, используйте queueметод на Mailфасаде после указания получателей сообщения:

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue(new OrderShipped($order));

Этот метод автоматически позаботится о переносе задания в очередь, чтобы сообщение отправлялось в фоновом режиме. Вам нужно будет настроить свои очереди перед использованием этой функции.

Отложенная очередь сообщений

Если вы хотите отложить доставку сообщения электронной почты в очереди, вы можете использовать этот laterметод. В качестве первого аргумента laterметод принимает DateTimeэкземпляр, указывающий, когда сообщение должно быть отправлено:

$when = now()->addMinutes(10);

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->later($when, new OrderShipped($order));

Нажатие на определенные очереди

Так как все классы , порожденные разрешенные к пересылке по почте с помощью команды делают использование признака, вы можете вызвать и методу любого экземпляра класса разрешенного к пересылке по почте, что позволяешь указать соединение и имя очереди для сообщения:make:mailIlluminate\Bus\QueueableonQueueonConnection

$message = (new OrderShipped($order))
                ->onConnection('sqs')
                ->onQueue('emails');

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue($message);

Очередь по умолчанию

Если у вас есть почтовые классы, которые вы хотите всегда ставить в очередь, вы можете реализовать ShouldQueueконтракт для этого класса. Теперь, даже если вы вызываете sendметод при отправке по почте, почтовое сообщение все равно будет поставлено в очередь, так как оно реализует контракт:

use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Mailable implements ShouldQueue
{
    //
}

 

Локализация почтовых отправлений

Laravel позволяет отправлять почтовые сообщения в локали, отличной от текущего языка, и даже запомнит эту локаль, если почта поставлена ​​в очередь.

Для этого Mailфасад предлагает localeметод для установки желаемого языка. Приложение изменится на эту локаль при форматировании почтового сообщения, а затем вернется к предыдущей локали после завершения форматирования:

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

Предпочтительные для пользователя локали

Иногда приложения хранят предпочтительный язык каждого пользователя. Заключив HasLocalePreferenceдоговор на одну или несколько ваших моделей, вы можете поручить Laravel использовать эту сохраненную локаль при отправке почты:

use Illuminate\Contracts\Translation\HasLocalePreference;

class User extends Model implements HasLocalePreference
{
    /**
     * Get the user's preferred locale.
     *
     * @return string
     */
    public function preferredLocale()
    {
        return $this->locale;
    }
}

После того, как вы реализовали интерфейс, Laravel будет автоматически использовать предпочтительный языковой стандарт при отправке почтовых отправлений и уведомлений модели. Поэтому нет необходимости вызывать localeметод при использовании этого интерфейса:

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

 

Почта и местное развитие

При разработке приложения, которое отправляет электронную почту, вы, вероятно, не хотите на самом деле отправлять электронные письма на действующие адреса электронной почты. Laravel предоставляет несколько способов «отключить» фактическую отправку электронных писем во время локальной разработки.

Драйвер журнала

Вместо того, чтобы отправлять ваши электронные письма, logпочтовый драйвер запишет все электронные письма в ваши файлы журнала для проверки. Для получения дополнительной информации о настройке приложения для каждой среды ознакомьтесь с документацией по конфигурации .

Универсальный К

Еще одно решение, предоставляемое Laravel, - установить универсального получателя всех электронных писем, отправляемых платформой. Таким образом, все электронные письма, сгенерированные вашим приложением, будут отправляться на определенный адрес, а не на адрес, фактически указанный при отправке сообщения. Это можно сделать с помощью toопции в вашем файле конфигурации:config/mail.php

'to' => [
    'address' => 'example@example.com',
    'name' => 'Example'
],

Mailtrap

Наконец, вы можете использовать такую ​​службу, как Mailtrap и smtpдрайвер, чтобы отправлять ваши электронные письма в «фиктивный» почтовый ящик, где вы можете просматривать их в настоящем почтовом клиенте. Преимущество этого подхода заключается в том, что вы можете просматривать последние письма в средстве просмотра сообщений Mailtrap.

 

События

Laravel запускает два события в процессе отправки почтовых сообщений. MessageSendingСобытие вызывается перед сообщением отправляется, в то время как MessageSentсобытие вызывается после того, как сообщение было отправлено. Помните, что эти события запускаются при отправке почты , а не когда она ставится в очередь. Вы можете зарегистрировать прослушиватель событий для этого события в вашем EventServiceProvider:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Mail\Events\MessageSending' => [
        'App\Listeners\LogSendingMessage',
    ],
    'Illuminate\Mail\Events\MessageSent' => [
        'App\Listeners\LogSentMessage',
    ],
];