Ícone do site Mailtrap

Como Enviar Emails no Laravel: Um Guia Completo de SMTP & API

Sending emails in laravel

Neste artigo, vou mostrar como enviar emails no Laravel passo a passo usando Mailtrap, com foco principal na entregabilidade.

Como desenvolvedor Laravel, você pode ter ouvido falar do Mailtrap sendo mencionado exclusivamente como uma solução de teste de email na documentação oficial do Laravel. No entanto, essa plataforma também oferece Email API/SMTP.

Os processos e snippets de código que vou mostrar neste artigo são compatíveis com Laravel 9.x e versões superiores.

Configurando o serviço de email do Laravel antes de enviar emails

O Laravel possui seus próprios serviços de email, que permitem o envio de emails através de serviços locais ou baseados na nuvem.

Por exemplo, a combinação Laravel e Symfony Mailer oferece aos usuários uma variedade de drivers que eles podem usar para enviar emails via SMTP, serviços de envio de email de terceiros e o Sendmail MTA.

Embora tecnicamente você pudesse usar sendmail para enviar emails do seu aplicativo web, é provável que seus emails sejam marcados como spam.

Você também poderia enviar emails no Laravel sem um serviço SMTP ou API externo, usando o log driver, mas isso não enviará realmente seus emails. Em vez disso, escreverá todas as mensagens de email nos arquivos do seu aplicativo.

Outras funcionalidades notáveis dos serviços de email do Laravel incluem:

Gerando e redigindo mailables

No Laravel, o arquivo config.mail.php será a ferramenta principal que usaremos para configurar os serviços de email. Ele possui uma seção mailers, que contém uma entrada de configuração de exemplo para cada driver de email/transportes principais suportados pelo Laravel.

Por padrão, o Laravel escolhe qual serviço usar com base em como configuramos este arquivo. A configuração nos permite escolher diferentes serviços de email para diferentes tipos de emails.

Além disso, o Laravel usa uma classe “mailable” para representar diferentes tipos de email. Estas são armazenadas no diretório app/Mail, mas você não as verá imediatamente em seu projeto. Em vez disso, elas serão geradas quando você criar sua primeira classe mailable.

Para criar uma classe mailable, usei este comando Artisan (incluído no Laravel):

php artisan make:mail MailableName

Depois de criar uma classe mailable, consegui ver o conteúdo e configurar a própria classe. Para isso, usei os métodos da tabela a seguir:

MétodoExplicação
EnvelopeRetorna o objeto Illuminate\Mail\Mailables\Envelope, que define o assunto e os destinatários.
ConteúdoRetorna o objeto Illuminate\Mail\Mailables\Content, que define o modelo Blade usado para gerar o conteúdo da mensagem.
AnexosRetorna uma matriz de anexos.

Configuração do remetente

Agora, precisamos especificar o endereço de email e o nome do remetente ou from. Para isso, podemos:

use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;
 
/**
* Obter o envelope da mensagem.
*
* @return \Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
{
   return new Envelope(
       from: new Address('exemplo@exemplo.com', 'Remetente de Teste'),
       subject: 'Email de Teste',
   );
}
'from' => ['address' => 'exemplo@exemplo.com', 'name' => 'Nome do App']

Dica Pro: você deve usar o endereço global from se planeja usá-lo em todos os emails que seu aplicativo enviar. Achei isso bastante conveniente, pois evitou a necessidade de chamar o método from em cada uma das minhas classes mailable. Além disso, ele serviu como meu endereço from padrão, já que não especifiquei nenhum outro.

Enviar emails no Laravel usando SMTP

Agora que você configurou o serviço de email do Laravel, vou mostrar como configurar o Email API/SMTP do Mailtrap como o provedor de serviço SMTP em seu aplicativo/projeto e, em seguida, como criei classes mailable e executei testes.

Etapa 1. Use as credenciais SMTP do Mailtrap para integração com seu app

A primeira coisa que fiz foi inserir minhas credenciais de servidor SMTP fornecidas pelo Email API/SMTP do Mailtrap no .env do meu aplicativo web.

Para fazer isso, tudo o que você precisa fazer é criar uma conta no Mailtrap, fazer login e navegar até Sending Domains. Lá, você precisa adicionar e verificar seu domínio, o que leva apenas alguns segundos.

Se você aprende melhor de forma visual, o Mailtrap tem um vídeo fácil de seguir.

Depois de verificar seu domínio, o Mailtrap o levará para a página de onde você pode copiar as credenciais SMTP e colá-las facilmente em seu projeto, app ou serviço de envio de email.

Nota: usaremos o Transactional Stream para este capítulo, e mostrarei como você pode usar o Bulk Stream mais adiante no artigo.

E aqui está como suas credenciais de email SMTP devem ficar depois de integrá-las ao seu código Laravel:

// .env file

MAIL_MAILER=smtp
MAIL_HOST=live.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=//seu nome de usuário
MAIL_PASSWORD=//sua senha
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=from@exemplo.com
MAIL_FROM_NAME=//nome do seu aplicativo

Etapa 2. Verifique sua configuração SMTP

Depois de inserir as credenciais e enviar um email de teste do meu projeto Laravel, o Mailtrap verificou minha configuração SMTP.

Aqui está o que você deve receber como resposta se o seu email de teste for enviado com sucesso:

Então, basta clicar em “Verify Setup”, que iniciará o processo de verificação.

Etapa 3. Ativar as configurações de rastreamento do Mailtrap (opcional)

Agora, esta etapa é opcional, mas recomendo fortemente, pois me permite monitorar o desempenho dos meus emails.

Especificamente, o Mailtrap fornece análises detalhadas que permitem monitorar aberturas, cliques, bounces e mais.

Isso é o que vejo quando abro minhas estatísticas:

Etapa 4. Criar classes mailable

Lembra das classes mailable que mencionei anteriormente? É hora de criá-las com o seguinte comando:

php artisan make:mail MyTestEmail

Depois de executar esse comando, você deverá ver a classe MyTestEmail em “app/mailMyTestEmail.php“.

Aqui está o código da classe para sua conveniência:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Cria uma nova instância de mensagem.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Obter o envelope da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */

    public function envelope()
    {
        return new Envelope(
            subject: 'Meu Email de Teste',
        );
    }
 /**
     * Obter a definição do conteúdo da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */

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

    /**
     * Obter os anexos para a mensagem.
     *
     * @return array
     */
    public function attachments()
    {
        return [];
    }
}

Viu algo interessante? Isso mesmo, o método content() retorna uma visualização. Então, vamos para resources/views e criar uma nova pasta com um arquivo blade.php.

Pronto para finalmente escrever algum texto? Você pode fazer isso no arquivo blade.php, assim:

Agora, vamos voltar ao método content() e substituir o nome da visualização retornada pelo nome da nossa recém-criada.

Você também pode tornar as coisas um pouco mais dinâmicas, fazendo com que seu arquivo template/blade.php de email inclua o nome do destinatário usando o atributo with para passar o nome.

Veja:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Cria uma nova instância de mensagem.
     *
     * @return void
     */
    public function __construct(private $name)
    {
        //
    }

    /**
     * Obter o envelope da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'Meu Email de Teste',
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }
}

Para que isso funcione, tive que fazer uma pequena alteração no arquivo test-email.blade.php da visualização também. Isso permite que ele aceite a variável $name.

// resources/views/mail/test-email.blade.php

Oi {{$name}}, 
Seu app Laravel já consegue enviar emails? 😉 
Mailtrap

E, por fim, vamos criar uma rota no arquivo routes/web.php com este código:

<?php

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;
use Illuminate\Support\Facades\Mail;

Route::get('/testroute', function() {
    $name = "Funny Coder";

    // O envio de emails é feito usando o método "to" na facade Mail
    Mail::to('destinatarioteste@gmail.com'')->send(new MyTestEmail($name));
});

E assim deve ficar o arquivo:

E, o momento da verdade chegou. Testei as coisas executando o comando php artisan serve e fui ao meu navegador, onde colei a rota que criei. No meu caso, foi localhost:8000/testroute.

Se tudo funcionar, seu email deve chegar à caixa de entrada do endereço “to” (para) especificado.

Envio de emails em HTML

Para configurações avançadas de personalização de email HTML no Laravel, confira nosso artigo dedicado.

Enviar emails que chamam a atenção no Laravel é bastante simples. Tudo o que você precisa fazer é adicionar código HTML ao seu arquivo de visualização Blade. Se você se lembrar, usamos test-email.blade.php neste guia.

Aqui está um snippet de código que você pode usar para enviar uma mensagem HTML básica:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <style>
        p {
            font-size: 12px;
        }

        .signature {
            font-style: italic;
        }
    </style>
</head>
<body>
<div>
    <p>Oi {{ $name }},</p>
    <p>Seu app Laravel já consegue enviar emails? 😉 </p>
    <p class="signature">Mailtrap</p>
</div>
</body>
</html>

Envio de emails para vários destinatários

Para enviar emails para várias pessoas no Laravel, usei o seguinte código:

foreach (['First Coder' => 'primeiro-destinatario@gmail.com', 'Second Coder' => 'segundo-destinatario@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

O que esse código faz é iterar sobre uma matriz de destinatários. Ele também recria a instância mailable a cada vez, o que é super útil, pois evita o envio de outro email para cada destinatário anterior a cada iteração no loop. Apenas imagine a dor de cabeça. 🤕

“Mas como envio emails para apenas um destinatário enquanto também adiciono cc e bcc para alguns outros?”, você deve estar se perguntando. Basta seguir este exemplo na classe MyTestEmail:

return new Envelope(
    subject: 'Meu Email de Teste',
    cc: ['destinatarioteste-cc@gmail.com'],
    bcc: ['destinatarioteste-bcc@gmail.com']
);

Envio de emails com anexos

Para adicionar anexos aos meus emails no Laravel, simplesmente modifiquei o método attachments no exemplo de código para envio de emails que mostrei anteriormente.

Primeiro, fiz isso na classe MyTestEmail:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Contracts\Queue\ShouldQueue;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Cria uma nova instância de mensagem.
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * Obter o envelope de mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'Meu Email de Teste',
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obter os anexos da mensagem.
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

Depois, fiz algumas alterações no código testroute em routes/web.php:

<?php

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;

Route::get('/testroute', function () {

    $filePath = public_path('favicon.ico');

    $name = "Funny Coder";

    Mail::to('destinatarioteste@gmail.com'')->send(new MyTestEmail($name, $filePath));
});

E é basicamente isso! Se você usou esse código, seu email agora deve vir com um anexo ICO chamado favicon.ico, como você pode ver no snippet acima.

Envio de emails com imagens incorporadas

Para enviar um email com uma imagem incorporada no Laravel, usei o método embed no template Blade. O método embed permite que você anexe imagens diretamente ao conteúdo do seu email, que serão exibidas inline.

Primeiro, certifique-se de que sua classe mailable (MyTestEmail neste exemplo) passe os dados necessários para a visualização. Você não precisa mudar nada na classe especificamente para a imagem.

No seu template Blade de email, use o método embed para incluir a imagem. Suponha que você tenha uma imagem em, digamos, public/images/logo.png.

// resources/views/mail/test-email.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>
        <p>Oi {{$name}},</p>
        <p>Seu app Laravel já consegue enviar emails? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">
    </div>
</body>
</html>

Como você pode ver, adicionei essencialmente esta linha de código:

<img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">

Isso incorpora a imagem localizada em public/images/logo.png no email, e o método embed retorna uma URL que aponta para a imagem incorporada. A imagem retornada é então usada como o atributo src da tag \, exibindo a imagem inline no email.

Enfileiramento de emails para envio assíncrono

Para envio de emails assíncrono, usei o sistema de filas do Laravel ShouldQueue.

Então, primeiro certifique-se de que sua classe mailable implemente a interface ShouldQueue e use o trait Queueable:

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class MyTestEmail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;
    // Resto da sua classe...
}

Em seguida, configure seu driver de fila no arquivo .env definindo QUEUE_CONNECTION para um driver de fila (por exemplo, database, redis, sqs, etc.).

Por fim, quando você enviar um email com o comando a seguir, o Laravel o colocará automaticamente na fila se a classe mailable implementar ShouldQueue:

Mail::to('destinatarioteste@exemplo.com')->send(new MyTestEmail($name));

Nota: para iniciar seu worker de fila para processar os jobs enfileirados, você pode executar o comando php artisan queue:work no seu terminal.

Envio de emails em massa no Laravel

Lembra das credenciais SMTP Bulk Stream do Mailtrap que mencionei anteriormente? Bem, vamos usá-las para enviar, como você deve ter adivinhado, emails em massa.

Primeiro, faça login na sua conta Mailtrap e navegue até a guia ‘SMTP/API Settings’. Lá, você encontrará as credenciais do Bulk Stream à direita.

Depois, abra seu .env e insira essas credenciais. O arquivo de configuração deve ficar assim:

MAIL_MAILER=smtp
MAIL_HOST=bulk.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=seu_nome_de_usuario_bulk_do_mailtrap
MAIL_PASSWORD=sua_senha_bulk_do_mailtrap
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=from@exemplo.com
MAIL_FROM_NAME="Nome do Seu Aplicativo"
Substitua seu_nome_de_usuario_bulk_do_mailtrap e sua_senha_bulk_do_mailtrap pelas suas credenciais SMTP reais do Mailtrap para o fluxo em massa.

Agora, se você ainda não fez isso, precisa gerar uma classe Mailable que usará para enviar emails. Você pode personalizá-la para adequar os emails que está planejando enviar em massa, e é assim que deve parecer:

php artisan make:mail BulkEmail

Depois de gerar sua classe mailable BulkEmail, defina as propriedades e métodos que configuram o conteúdo do email.

Você pode passar dados para sua classe Mailable através de seu construtor e usar esses dados nas visualizações do seu email.

Por fim, percorri meus destinatários e enviei emails individualmente com a conexão SMTP configurada para uso em massa.

Aqui está um exemplo:

use App\Mail\BulkEmail;
use Illuminate\Support\Facades\Mail;

$users = User::all(); // Exemplo: Obtendo todos os usuários a quem deseja enviar emails

foreach ($users as $user) {
    Mail::to($user->email)->send(new BulkEmail($data));
}

No entanto, há algumas coisas a ter em mente para melhorar sua escalabilidade e desempenho:

User::chunk(200, function ($users) use ($data) {
    foreach ($users as $user) {
        Mail::to($user->email)->queue(new BulkEmail($data));
    }
});
class SendBulkEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;
    protected $data;

    public function __construct($user, $data)
    {
        $this->user = $user;
        $this->data = $data;
    }

    public function handle()
    {
        Mail::to($this->user->email)->send(new BulkEmail($this->data));
    }
}

// Expedindo o job para cada usuário
foreach ($users as $user) {
    SendBulkEmailJob::dispatch($user, $data)->onQueue('emails');
}

Por fim, fique de olho nos logs do seu aplicativo e nos painéis do Mailtrap, pois isso pode ajudar a garantir que seus emails estejam sendo processados e enviados conforme o esperado.

Enviar emails no Laravel usando API

Se você deseja automatizar seu processo de envio, o Email API/SMTP do Mailtrap API é a solução que você está procurando.

Integrar a API de email do Mailtrap ao seu aplicativo Laravel é super fácil, pois você pode usar o SDK oficial em PHP e a documentação para o framework Laravel. Com isso, você não precisará escrever manualmente o código de integração para o seu projeto, tornando a integração muito mais fácil e eficiente. Além disso, a biblioteca do Mailtrap é totalmente compatível com Laravel 9.x e versões superiores.

Para começar, siga estas etapas:

composer require railsware/mailtrap-php symfony/http-client nyholm/psr7
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configurações Mailer
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // início do transporte do mailtrap
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // fim do transporte do mailtrap
    
    ]
];
MAIL_MAILER="mailtrap"
MAILTRAP_HOST="send.api.mailtrap.io"
MAILTRAP_API_KEY="SUA_CHAVE_API_AQUI"
MAIL_FROM_ADDRESS=”nome@dominio_registrado.com”
php artisan make:mail WelcomeMail
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Attachment;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Headers;
use Illuminate\Queue\SerializesModels;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    private string $name;

    /**
     * Cria uma nova instância de mensagem.
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Obter o envelope da mensagem.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('jeffrey@exemplo.com', 'Jeffrey Way'),
            replyTo: [
                      new Address('taylor@exemplo.com', 'Taylor Otwell'),
                  ],
            subject: 'Email de Boas-Vindas',
            using: [
                      function (Email $email) {
                          // Cabeçalhos
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'exemplo.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

                          // Variáveis Customizadas
                          $email->getHeaders()
                              ->add(new CustomVariableHeader('user_id', '45982'))
                              ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
                          ;

                          // Categoria (deve ser apenas uma)
                          $email->getHeaders()
                              ->add(new CategoryHeader('Teste de Integração'))
                          ;
                      },
                  ]
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem.
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obter os anexos para a mensagem.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [
           Attachment::fromPath('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg')
                ->as('logo.svg')
                ->withMime('image/svg+xml'),
        ];
    }

    /**
     * Obter os cabeçalhos da mensagem.
     */
    public function headers(): Headers
    {
        return new Headers(
            'id-da-mensagem-personalizada@exemplo.com',
            ['mensagem-anterior@exemplo.com'],
            [
                'X-Custom-Header' => 'Custom Value',
            ],
        );
    }
}
Oi, {{$name}} e bem-vindo 😉

<br>
Funny Coder
<?php

use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Mail;

/*
|--------------------------------------------------------------------------
| Rotas de Console
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('destinatarioteste@gmail.com')->send(new WelcomeMail("Jon"));
    // Além disso, você pode usar um mailer específico se o seu mailer padrão não for "mailtrap", mas você quiser usá-lo para emails de boas-vindas
    // Mail::mailer('mailtrap')->to('destinatarioteste@gmail.com')->send(new WelcomeMail("Jon"));
})->purpose('Enviar email de boas-vindas');
php artisan send-welcome-mail

Depois de completar essas etapas, você deve ser capaz de usar a API de email do Mailtrap para enviar emails transacionais sem obter nenhum erro.

Além disso, lembra das configurações de rastreamento que mencionei anteriormente? Você pode ativá-las se usar a API de email também.

Envio de emails em HTML

Para enviar emails em HTML no Laravel, tudo o que você precisa fazer é adicionar código HTML ao seu arquivo de visualização Blade, que, no caso deste tutorial, é test-email.blade.php.

E aqui está como o email em texto simples fica em formato HTML:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <style>
        p {
            font-size: 12px;
        }

        .signature {
            font-style: italic;
        }
    </style>
</head>
<body>
<div>
    <p>Oi {{ $name }},</p>
    <p>Seu app Laravel já consegue enviar emails? 😉 </p>
    <p class="signature">Mailtrap</p>
</div>
</body>
</html>

Envio de emails para vários destinatários

De acordo com a documentação do Laravel, você pode enviar um email para vários destinatários com o seguinte código:

foreach (['First Coder' => 'primeiro-destinatario@gmail.com', 'Second Coder' => 'segundo-destinatario@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

Você também pode enviar seu email para apenas um destinatário e “cc” e “bcc” para alguns outros com o seguinte código na classe MyTestEmail:

return new Envelope(
    subject: 'Meu Email de Teste',
    cc: ['destinatarioteste-cc@gmail.com'],
    bcc: ['destinatarioteste-bcc@gmail.com']
);

Envio de emails com anexos

Da mesma forma, como com SMTP, modifiquei o método attachments para adicionar anexos aos meus emails.

Primeiro, fiz isso na classe MyTestEmail:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Contracts\Queue\ShouldQueue;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Cria uma nova instância de mensagem.
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * Obter o envelope da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'Meu Email de Teste',
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem.
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obter os anexos para a mensagem.
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

Depois, fiz algumas alterações no código testroute em routes/web.php:

<?php

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;

Route::get('/testroute', function () {

    $filePath = public_path('favicon.ico');

    $name = "Funny Coder";

    Mail::to('destinatarioteste@gmail.com'')->send(new MyTestEmail($name, $filePath));
});

E, como com SMTP, seu email agora deve vir com um anexo ICO chamado favicon.ico.

Envio de emails com imagens incorporadas

Para enviar um email com uma imagem incorporada, use o método embed no template Blade para incluir a imagem. Por exemplo, vamos imaginar que você tenha uma imagem em public/images/logo.php.

Aqui está como seu código ficaria então:

// resources/views/mail/test-email.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>
        <p>Oi {{$name}},</p>
        <p>Seu app Laravel já consegue enviar emails? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">
    </div>
</body>
</html>

Enfileiramento de emails para envio assíncrono

Da mesma forma que com SMTP, você pode usar o ShouldQueue do Laravel para envio assíncrono.

Para fazer isso funcionar, sua classe mailable deve implementar a interface ShouldQueue e usar o trait Queueable:

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class MyTestEmail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;
    // Resto da sua classe...
}

Você pode configurar seu driver de fila no arquivo .env definindo QUEUE_CONNECTION para um driver de fila como database, redis, sqs, etc.

E para enviar um email, você pode usar o seguinte comando:

Mail::to('destinatarioteste@exemplo.com')->send(new MyTestEmail($name));

Lembre-se de que você pode executar o comando php artisan queue:work no seu terminal para iniciar seu worker de fila para processar o job enfileirado.

Envio de emails em massa

Para começar a enviar emails em massa, primeiro você precisa inserir as credenciais Bulk Stream, que pode encontrar na guia ‘SMTP/API Settings’ quando fizer login na sua conta Mailtrap.

Depois de encontrar as credenciais, adicione-as ao seu arquivo .env do Laravel (certifique-se de selecionar o Bulk Stream).

Aqui está como deve ficar o seu arquivo .env quando você inserir suas credenciais Bulk Stream:

MAIL_MAILER="mailtrap"
MAILTRAP_HOST="bulk.smtp.mailtrap.io"
MAILTRAP_API_KEY="SUA_CHAVE_API_DO_BULK_STREAM_AQUI"

Depois de substituir suas credenciais, você precisa gerar uma classe Mailable para enviar emails:

php artisan make:mail BulkEmail

A partir daqui, você tem três opções para enviar email em massa, a saber:

Se você estiver enviando uma pequena quantidade de emails em massa, pode percorrer seus destinatários e enviar emails individualmente. Assim:

use App\Mail\BulkEmail;
use Illuminate\Support\Facades\Mail;

$users = User::all(); // Exemplo: Obtendo todos os usuários a quem deseja enviar emails

foreach ($users as $user) {
    Mail::to($user->email)->send(new BulkEmail($data));
}

Se você planeja enviar uma grande quantidade de emails em massa, o método de fragmentação pode ajudá-lo a processar os usuários em pequenos lotes.

Veja:

User::chunk(200, function ($users) use ($data) {
    foreach ($users as $user) {
        Mail::to($user->email)->queue(new BulkEmail($data));
    }
});

Se você planeja enviar uma grande quantidade de emails em massa e liberar seu aplicativo para lidar com outras solicitações, pode despachar um job para cada email:

class SendBulkEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;
    protected $data;

    public function __construct($user, $data)
    {
        $this->user = $user;
        $this->data = $data;
    }

    public function handle()
    {
        Mail::to($this->user->email)->send(new BulkEmail($this->data));
    }
}

// Expedindo o job para cada usuário
foreach ($users as $user) {
    SendBulkEmailJob::dispatch($user, $data)->onQueue('emails');
}

Independentemente do método de envio em massa que você escolher, você deve sempre ficar de olho nos Logs do seu aplicativo e no painel do Mailtrap para garantir que seus emails estejam sendo processados e enviados.

Além disso, considere limitar as taxas ou implementar atrasos entre os emails se você estiver enviando para um grande número de destinatários.

Teste e envio de emails: porquê e como

Com todo esse código escrito, você não gostaria de ter seus emails enviados de um domínio na lista de bloqueio, marcados como spam ou com seu template HTML mal renderizado por alguns navegadores. Por isso, você deve testar seus emails no Laravel antes de enviá-los.

Tecnicamente, você poderia fazer isso com sua caixa de entrada pessoal ou driver de log, mas por que afetar a reputação do seu domínio e inundar sua caixa de entrada com lixo, quando você pode usar Email Testing do Mailtrap?

O Mailtrap também é suportado pelo Laravel na documentação oficial.

Essa plataforma de envio de email também possui muitos recursos que podem ajudá-lo a resolver inúmeros problemas de teste, enquanto mantém o processo de teste de email seguro.

Com o Email Testing do Mailtrap, você pode capturar emails de teste e visualizá-los em um ambiente sandbox seguro. Você também pode verificar a pontuação de spam dos seus emails, analisar seu HTML/CSS e mais, tudo antes de enviá-los.

Basicamente, o que o Email Testing do Mailtrap faz é garantir que seus emails cheguem onde e quando deveriam, em vez de ir para as pastas de spam.

O Email Testing do Mailtrap também permite que você compartilhe facilmente o processo de teste com os membros da sua equipe, crie novos projetos e adicione vários objetos dentro.

Você também pode encaminhar os emails para os endereços reais manual ou automaticamente, uma vez que esteja satisfeito com os resultados que está obtendo.

Essencialmente, testar emails com o Mailtrap é muito fácil.

SMTP

Para testar seus emails com o Mailtrap, tudo o que você precisa fazer é criar uma conta gratuita no Mailtrap, que lhe dará acesso a toda a Plataforma de Email Delivery do Mailtrap. Isso significa que você poderá usar tanto o Email Testing quanto o Email API/SMTP.

Depois de criar sua conta e fazer login, siga estas etapas:

MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=07f4dbf61b8122
MAIL_PASSWORD=d7fc5d57bc6eac
MAIL_ENCRYPTION=tls

Depois de terminar, você poderá enviar o primeiro email de teste com o seguinte código:

<?php
use App\Mail\JustTesting;
use Illuminate\Support\Facades\Mail;
Route::get('/send-mail', function () {
    Mail::to('novousuario@exemplo.com')->send(new JustTesting());
    return 'Uma mensagem foi enviada para o Mailtrap!';
});

Dica Pro: certifique-se de estar usando Laravel 5.8 ou uma versão mais recente e que você especificou a rota no arquivo routes/web.php.

Para enviar o email de teste, inicie o aplicativo e acesse o caminho /send-mail em seu navegador. Você logo poderá ver o email em Email TestingInboxes.

API

Alternativamente, você pode integrar o Email Testing ao seu app e usar a Testing API para teste, automação e teste de sequências automatizadas.

Dependendo de qual cliente HTTP você usar, execute um dos seguintes comandos:

# Com o cliente symfony http (recomendado)
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7

# Ou com o cliente guzzle http
composer require railsware/mailtrap-php guzzlehttp/guzzle php-http/guzzle7-adapter

Adicione o transporte do Mailtrap ao seu arquivo config.mail.php:

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configurações Mailer
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // início do transporte do mailtrap
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // fim do transporte do mailtrap
    
    ]
]

Em seguida, você precisa definir a chave de API na variável MAILTRAP_API_KEY e definir o ID da sua caixa de entrada no MAILTRAP_INBOX_ID, assim:

MAIL_MAILER="mailtrap"

MAILTRAP_HOST="sandbox.api.mailtrap.io"
MAILTRAP_API_KEY="SUA_CHAVE_API_AQUI"
MAILTRAP_INBOX_ID=1000001

Notas

php artisan config:clear

E para testar seu primeiro email, você precisa gerar uma classe Mailable, assim como no envio:

php artisan make:mail WelcomeMail

Depois de criar sua classe Mailable, você pode configurar seu email. Aqui está um exemplo:

# app/Mail/WelcomeMail.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Attachment;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Headers;
use Illuminate\Queue\SerializesModels;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    private string $name;

    /**
     * Cria uma nova instância de mensagem.
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * Obter o envelope de mensagem.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('jeffrey@exemplo.com', 'Jeffrey Way'),
            replyTo: [
                      new Address('taylor@exemplo.com', 'Taylor Otwell'),
                  ],
            subject: 'Email de Boas-Vindas',
            using: [
                      function (Email $email) {
                          // Cabeçalhos
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'exemplo.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

                          // Variáveis Personalizadas
                          $email->getHeaders()
                              ->add(new CustomVariableHeader('user_id', '45982'))
                              ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
                          ;

                          // Categoria (deverá ser apenas uma)
                          $email->getHeaders()
                              ->add(new CategoryHeader('Teste de Integração'))
                          ;
                      },
                  ]
        );
    }

    /**
     * Obter a definição do conteúdo da mensagem.
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * Obter os anexos para a mensagem.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [
            Attachment::fromPath('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg')
                ->as('logo.svg')
                ->withMime('image/svg+xml'),
        ];
    }

    /**
     * Obter os cabeçalhos da mensagem.
     */
    public function headers(): Headers
    {
        return new Headers(
            'id–da-mensagem-personalizada@exemplo.com',
            ['mensagem-anterior@exemplo.com'],
            [
                'X-Custom-Header' => 'Custom Value',
            ],
        );
    }
}

Além disso, você pode usar um template de email:

# resources/views/mail/welcome-email.blade.php

Oi, {{$name}} e bem-vindo 😉

<br>
Funny Coder

E adicione o roteador CLI:

# app/routes/console.php
<?php

use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Mail;

/*
|--------------------------------------------------------------------------
| Rotas de Console
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('destinatarioteste@gmail.com')->send(new WelcomeMail("Jon"));
    // Além disso, você pode usar um mailer específico se o seu mailer padrão não for "mailtrap", mas você quiser usá-lo para emails de boas-vindas
    // Mail::mailer('mailtrap')->to('destinatarioteste@gmail.com')->send(new WelcomeMail("Jon"));
})->purpose('Enviar email de boas-vindas');

E para enviar seu email, basta chamar este comando CLI:

php artisan send-welcome-mail

Para informações adicionais, dê uma olhada na documentação oficial para a API do Mailtrap.

Concluindo

E com isso, terminamos nosso guia de envio de email do Laravel.

Cobrimos muitos tópicos, desde configurar o Laravel para enviar email com SMTP até enviar email via API. Independentemente da opção que você escolher, você sempre pode consultar este artigo para obter instruções passo a passo.

Para saber mais sobre o Laravel, confira a documentação oficial. E se você está procurando mais conteúdo sobre envio de email com Laravel, não deixe de visitar o blog do Mailtrap, onde você pode encontrar mais artigos úteis, como:

Sair da versão mobile