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

On abril 24, 2024
21min read
Aleksandr Varnin Full Stack Developer @ Railsware
Ivan Djuric, an author at Mailtrap
Ivan Djuric Technical Content Writer @Mailtrap
Sending emails in laravel

Neste artigo, mostrarei a você como enviar emails no Laravel usando o Mailtrap, passo a passo, com foco principal na capacidade de entrega.

Como desenvolvedor Laravel, você deve ter ouvido falar que o Mailtrap é mencionado exclusivamente como uma solução de teste de email na documentação oficial do Laravel. No entanto, essa plataforma também oferece Email Sending (envio de emails).

Os processos e os code snippets que mostrarei neste artigo são compatíveis com o Laravel 9.x. e superior. 

Configure o serviço de email Laravel antes de enviar emails

O Laravel tem seus próprios serviços de email que permitem o envio de emails por meio de serviços locais ou baseados na nuvem.

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

Embora tecnicamente seja possível usar o sendmail para enviar emails do seu aplicativo web, é provável que seus emails sejam marcados como spam. 

Na verdade, você também pode enviar emails no Laravel sem um serviço externo de SMTP ou API usando o driver de logs, mas ele não enviará de fato seus emails. Em vez disso, ele gravará todas as mensagens de email nos arquivos do seu aplicativo.

Outras funcionalidades a destacar sobre os serviços de email do Laravel incluem:

  • Colocar os emails em fila de espera.
  • Criar mensagens de email regulares em texto simples e em HTML.
  • Anexar arquivos em diferentes formatos e tipos de MIME, bem como dados raw.
  • Incluir anexos inline (no corpo do email) e incorporar dados raw em modelos de email. 
  • Pré-visualizar mensagens dentro do navegador.
  • Suporte de Markdown (em várias frameworks) – crie modelos bonitos e inclua facilmente botões, tabelas ou painéis.
  • Sistema de templates – usar vários modelos e configurar as views. 
  • Métodos de localização – definir o idioma desejado para um usuário específico.
  • Desenvolvimento local de emails – evitar o envio de emails de teste para caixas de entrada reais.

Criar e redigir mailables

No Laravel, o ficheiro config.mail.php será a principal ferramenta que usaremos para configurar os serviços de email. Ele tem uma seção de mailers, que tem um acesso de amostra para configuração de cada um dos principais drivers/transportes de email suportados pelo Laravel.

Por padrão, o Laravel escolhe o serviço a ser usado com base em como configuramos esse 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. Estes são armazenados no diretório app/Mail, mas você não os verá imediatamente em seu projeto. Em vez disso, o tipo de email será gerado quando você criar a sua primeira classe mailable.

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

php artisan make:mail MailableName

Depois de criar uma classe mailable, pude 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 série de anexos.

Configuração do remetente

Agora, precisamos especificar o remetente ou o endereço de email e nome do from. Para isso, podemos realizar uma das seguintes opções:

  • Especificar o remetente no objeto Envelope da mensagem, da seguinte forma:
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('example@example.com', 'Test Sender'),
       subject: 'Test Email',
   );
}
  • Especificar o remetente em config/mail.php com um endereço de email global from, da seguinte forma:
'from' => ['address' => 'example@example.com', 'name' => 'App Name']

Pro Tip: 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 que eu tivesse 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, pois não especifiquei nenhum outro.

Envie emails no Laravel usando SMTP

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

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

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

Para fazer isso, basta criar uma conta no Mailtrap, fazer login e navegar até ao menu Sending Domains em Email Sending. 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á à página na qual você poderá copiar as credenciais SMTP e colá-las facilmente em seu projeto, aplicativo ou serviço de envio de email.

Nota: neste capítulo, usaremos o Transactional Stream, e mostrarei como usar o Bulk Stream mais adiante neste artigo.

E aqui está como as suas credenciais de email SMTP deverão aparentar 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=//o seu username
MAIL_PASSWORD=//a sua password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=from@example.com
MAIL_FROM_NAME=//o nome do seu aplicativo

Etapa 2. Verifique sua configuração de SMTP

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

Veja o que você deve receber como resposta se o email de teste tiver sido enviado com êxito:

  • “250 2.0.0 Ok: queued as …”

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

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

Essa etapa é opcional, mas eu a recomendo muito, pois ela me permite monitorar o desempenho dos meus emails.

Ou seja, o Mailtrap fornece análises detalhadas por meio das quais você pode ficar de olho em suas aberturas, cliques, bounces e muito mais.

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

E aqui está a visão geral das estatísticas:

Etapa 4. Crie classes mailable

Lembra-se das classes mailabale 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“.

Mytestemail class under 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;

    /**
     * Criar 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: 'My Test Email',
        );
    }
 /**
     * 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 [];
    }
}

Está vendo algo interessante? É isso mesmo, o método content() retorna uma view. Portanto, vamos acessar resources/views e criar uma nova pasta com um ficheiro blade.php nela.

Pronto para finalmente escrever algum texto? Você pode fazer isso no ficheiro blade.php, da mesma forma:

Agora, vamos retornar ao método content() e substituir o nome da view retornada com o nome da recém-criada.

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

Dê uma olhada.

<?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;

    /**
     * Criar 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: 'My Test Email',
        );
    }

    /**
     * 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 funcionasse, tive que fazer uma pequena alteração no ficheiro view test-email.blade.php também. O que isso faz é permitir que ele aceite a variável $name.

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

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

E, por fim, vamos criar uma rota no ficheiro 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 fachada Mail
    Mail::to('testreceiver@gmail.com'')->send(new MyTestEmail($name));
});

O ficheiro deve ficar assim:

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

Se tudo funcionar, seu email deverá chegar à caixa de entrada do endereço “to” (para) que você especificou.

Enviar emails em HTML

Para definições avançadas de personalização HTML dos emails no Laravel, veja o nosso artigo sobre isso.

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

Aqui está um code snippet 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 aplicativo Laravel já consegue enviar emails? 😉 </p>
    <p class="signature">Mailtrap</p>
</div>
</body>
</html>

Enviar emails para vários destinatários

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

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

O que esse código faz é iterar sobre uma série de destinatários. Ele também recria a instância mailable a cada vez, o que é muito útil, pois evita o envio de outro email para cada destinatário anterior, a cada iteração ao longo do loop. Imagine só a dor de cabeça. 🤕

“Mas como faço para enviar emails para apenas um destinatário e, ao mesmo tempo, incluir alguns outros como cc e bcc?”, você deve estar se perguntando. Basta seguir este exemplo na classe MyTestEmail:

return new Envelope(
    subject: 'My Test Email',
    cc: ['testreceiver-cc@gmail.com'],
    bcc: ['testreceiver-bcc@gmail.com']
);

Enviar emails com anexos

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

Eu os criei pela primeira vez 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;

    /**
     * Criar 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: 'My Test Email',
        );
    }

    /**
     * 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),
        ];

    }
}

Em seguida, fiz algumas alterações no código do 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('testreceiver@gmail.com'')->send(new MyTestEmail($name, $filePath));
});

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

Enviar emails com imagens incorporadas

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

Primeiro, certifique-se de que sua classe mailable (MyTestEmail neste exemplo) passe os dados necessários para a view. Não é necessário alterar especificamente nada na classe para a imagem.

Em seu modelo de email Blade, 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 aplicativo Laravel já consegue enviar emails? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">
    </div>
</body>
</html>

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

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

Ela incorpora a imagem localizada em public/images/logo.png no email, e o método embed retorna um URL que aponta para a imagem incorporada. A imagem retornada é então usada como o atributo src da tag <img>, exibindo a imagem no corpo do email.

Colocar emails em fila de espera para envio assíncrono

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

Portanto, primeiro certifique-se de que sua classe mailable implementa a interface ShouldQueue e usa a característica 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 ficheiro .env definindo QUEUE_CONNECTION como um driver de fila (ex: database, redis, sqs, etc.).

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

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

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

Enviar emails em massa no Laravel

Lembra-se das credenciais de 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 do Mailtrap e navegue até à guia SMTP/API Settings no menu. Lá, você encontrará as credenciais do Bulk Stream à direita.

Em seguida, abra seu ficheiro .env e insira essas credenciais. O ficheiro de configuração deve ser semelhante a este:

MAIL_MAILER=smtp
MAIL_HOST=bulk.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=seu_username_do_mailtrap_bulk
MAIL_PASSWORD=sua_password_do_mailtrap_bulk
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=from@example.com
MAIL_FROM_NAME="Nome do seu aplicativo"
Substitua seu_username_do_mailtrap_bulk e sua_password_do_mailtrap_bulk com suas reais credenciais SMTP do Mailtrap para o bulk stream.

Agora, se ainda não o fez, você precisa gerar uma classe Mailable que usará para enviar emails. Você pode personalizá-la para se adequar aos emails que planeja enviar em massa, e aqui está como ela deve ficar:

php artisan make:mail BulkEmail

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

Você pode passar dados para sua classe Mailable por meio de seu construtor e usar esses dados em suas views de 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á alguns aspectos que devem ser levados em conta para melhorar sua escalabilidade e desempenho:

  • Limitação de taxa e atrasos – Considere limitar as taxas ou implementar atrasos entre os emails se estiver enviando para um grande número de destinatários.
  • Chunking – Para listas muito grandes, o método chunk do Laravel pode ajudá-lo a processar os usuários em grupos menores.
    • Por exemplo:
User::chunk(200, function ($users) use ($data) {
    foreach ($users as $user) {
        Mail::to($user->email)->queue(new BulkEmail($data));
    }
});
  • Job queues – Ao expedir um job para cada email, o Laravel pode enfileirar os emails e enviá-los em segundo plano, liberando seu aplicativo para lidar com outros pedidos.
    • Por exemplo:
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));
    }
}

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

Finalmente, fique atento aos logs do seu aplicativo e aos painéis do Mailtrap, pois isso pode ajudá-lo a garantir que seus emails estejam sendo processados e enviados conforme o esperado.

Envie emails no Laravel usando a API

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

Integrar a API de email Mailtrap em seu aplicativo Laravel é muito fácil, pois você pode usar o SDK oficial do PHP e a documentação para a bridge da framework do Laravel. Com eles, 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 Mailtrap é totalmente compatível com o Laravel 9.x e superior.

Para começar, basta seguir estes passos:

  • Crie uma conta do Mailtrap e faça login.
  • Adicione e verifique seu domínio.
  • Instale o cliente PHP Mailtrap e as dependências usando o Composer.
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7
  • Adicione o transporte do Mailtrap em seu ficheiro config.mail.php.
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configurações Mailer
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // iniciar o transporte mailtrap
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // terminar o transporte mailtrap
    
    ]
];
  • Adicione suas credenciais do Mailtrap ao ficheiro .envdo Laravel (certifique-se de que seleciona o Transactional Stream; usaremos o Bulk Stream mais tarde).
MAIL_MAILER="mailtrap"
MAILTRAP_HOST="send.api.mailtrap.io"
MAILTRAP_API_KEY="SUA_CHAVE_API_AQUI"
MAIL_FROM_ADDRESS=”name@registered_domain.com”
  • Crie uma classe mailable para enviar emails.
php artisan make:mail WelcomeMail
  • Configure a classe app/Mail/WelcomeMail.php de acordo com este exemplo.
<?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;

    /**
     * Criar 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@example.com', 'Jeffrey Way'),
            replyTo: [
                      new Address('taylor@example.com', 'Taylor Otwell'),
                  ],
            subject: 'Welcome Mail',
            using: [
                      function (Email $email) {
                          // Headers
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'example.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

                          // Custom Variables
                          $email->getHeaders()
                              ->add(new CustomVariableHeader('user_id', '45982'))
                              ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
                          ;

                          // Category (deve ser apenas uma)
                          $email->getHeaders()
                              ->add(new CategoryHeader('Integration Test'))
                          ;
                      },
                  ]
        );
    }

    /**
     * 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(
            'custom-message-id@example.com',
            ['previous-message@example.com'],
            [
                'X-Custom-Header' => 'Custom Value',
            ],
        );
    }
}
  • Crie um modelo de email em resources/views/mail/welcome-email.blade.php.
Oi, {{$name}} e bem-vindo 😉

<br>
Funny Coder
  • Adicione o router CLI ao ficheiro app/routes/console.php.
<?php

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

/*
|--------------------------------------------------------------------------
| Console Routes
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('testreceiver@gmail.com')->send(new WelcomeMail("Jon"));
    // Você também pode usar um mailer específico se o seu mailer padrão não for "mailtrap" mas quer usá-lo para emails de boas-vindas
    // Mail::mailer('mailtrap')->to('testreceiver@gmail.com')->send(new WelcomeMail("Jon"));
})->purpose('Send welcome mail');
  • Chame o comando CLI para enviar seu email.
php artisan send-welcome-mail

Depois de concluir essas etapas, você poderá usar a API de email do Mailtrap para enviar emails transacionais, sem receber nenhum erro.

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

Enviar emails em HTML

Para enviar um email em HTML no Laravel, tudo o que você precisa fazer é adicionar o código HTML ao ficheiro view do Blade, que, no caso deste tutorial, é test-email.blade.php.

E aqui está o email em texto simples 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 aplicativo Laravel já consegue enviar emails? 😉 </p>
    <p class="signature">Mailtrap</p>
</div>
</body>
</html>

Enviar 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' => 'first-recipient@gmail.com', 'Second Coder' => 'second-recipient@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 colocar mais uns quantos em “cc” e “bcc” com o seguinte código na classe MyTestEmail:

return new Envelope(
    subject: 'My Test Email',
    cc: ['testreceiver-cc@gmail.com'],
    bcc: ['testreceiver-bcc@gmail.com']
);

Enviar emails com anexos

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

Primeiro, eu os criei 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;

    /**
     * Criar 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: 'My Test Email',
        );
    }

    /**
     * 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),
        ];

    }
}

Em seguida, alterei o código do 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('testreceiver@gmail.com'')->send(new MyTestEmail($name, $filePath));
});

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

Enviar emails com imagens incorporadas

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

Veja 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 aplicativo Laravel já consegue enviar emails? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="Logo">
    </div>
</body>
</html>

Colocar emails em fila de espera para envio assíncrono

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

Para que isso funcione, sua classe mailable deve implementar a interface ShouldQueue e usar a característica 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 ficheiro .env definindo QUEUE_CONNECTION como um driver de fila (ex: database, redis, sqs, etc.)

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

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

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

Enviar emails em massa

Para começar a enviar emails em massa, primeiro você precisa inserir as credenciais do Bulk Stream, que podem ser encontradas no separador SMTP/API Settings (Configurações de SMTP/API) após o login na sua conta do Mailtrap.

Depois de encontrar as credenciais, adicione-as ao ficheiro .env do Laravel (certifique-se de que seleciona o Bulk Stream).

Veja como o ficheiro .env deve ficar quando você insere as credenciais do Bulk Stream:

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

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

php artisan make:mail BulkEmail

A partir daí, você tem três opções para enviar emails em massa, nomeadamente:

  • Percorrer o loop

Se você estiver enviando uma pequena quantidade de emails em massa, poderá fazer o loop pelos 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));
}
  • Chunking

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

Dê uma olhada:

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

Se você planeja enviar uma grande quantidade de emails em massa e liberar seu aplicativo para lidar com outros pedidos, poderá expedir 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 escolhido, você deve estar sempre atento aos logs do aplicativo e ao 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 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 deverá querer que seus emails sejam enviados de um domínio nas listas de bloqueio, marcados como spam, ou que seu modelo HTML seja mal renderizado por alguns browsers. É por isso que você deve testar seus emails no Laravel antes de enviá-los.

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

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

Essa plataforma de envio de emails também tem muitos recursos que podem ajudá-lo a resolver vários problemas de teste e, ao mesmo tempo, manter seu processo de teste de emails seguro.

Com o Mailtrap Email Testing, você pode capturar emails de teste e visualizá-los em um ambiente seguro de sandbox. Você também pode verificar o spam score dos seus emails, analisar o HTML/CSS e muito mais. Tudo isso antes de enviá-los.

Basicamente, o que o Mailtrap Email Testing faz é garantir que seus emails chegam onde e quando devem chegar, em vez de irem para as pastas de spam. 

O Mailtrap Email Testing 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 lá dentro.

Você também pode encaminhar os emails para os endereços reais manual ou automaticamente, quando estiver satisfeito com os resultados obtidos.

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

SMTP

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

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

  • Navegue até Email TestingInboxesSMTP Settings
  • Selecione a versão desejada do Laravel na lista de integrações (recomendo a versão 9+)
  • Copie o code snippet gerado no ficheiro .env localizado no diretório raiz do seu projeto. Ele deve ser assim:
MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=07f4dbf61b8122
MAIL_PASSWORD=d7fc5d57bc6eac
MAIL_ENCRYPTION=tls

Quando 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('newuser@example.com')->send(new JustTesting());
    return 'A message has been sent to Mailtrap!';
});

Pro Tip: certifique-se de que está usando o Laravel 5.8 ou uma versão mais recente e que tenha especificado a rota no ficheiro routes/web.php.

Para enviar o email de teste, inicie o aplicativo e o trajeto access/send-mail em seu navegador. Em breve, você poderá ver o email em Email TestingInboxes.

API

Como alternativa, você pode integrar o Email Testing ao seu aplicativo e usar a Testing API, para testar, para automatizar e para testar sequências automatizadas.

Dependendo do cliente HTTP que você usa, 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 em seu ficheiro config.mail.php:

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Configurações Mailer
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // iniciar o transporte mailtrap
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // terminar o transporte mailtrap
    
    ]
]

Em seguida, você precisa definir a chave da API para a variável MAILTRAP_API_KEY e definir o ID da caixa de entrada para MAILTRAP_INBOX_ID, da seguinte forma:

MAIL_MAILER="mailtrap"

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

Notas

  • Você pode encontrar sua chave/token de API acessando sua conta do Mailtrap e navegando até Sending DomainsSMTP/API Settings
  • Certifique-se de executar o comando clear configuration cache (limpar cache de configuração) para definir novas variáveis com:
php artisan config:clear

E para testar seu primeiro email, você precisa gerar uma classe Mailable, como acontece 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;

    /**
     * Criar 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@example.com', 'Jeffrey Way'),
            replyTo: [
                      new Address('taylor@example.com', 'Taylor Otwell'),
                  ],
            subject: 'Welcome Mail',
            using: [
                      function (Email $email) {
                          // Headers
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'example.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

                          // Custom Variables
                          $email->getHeaders()
                              ->add(new CustomVariableHeader('user_id', '45982'))
                              ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
                          ;

                          // Category (deverá ser apenas uma)
                          $email->getHeaders()
                              ->add(new CategoryHeader('Integration Test'))
                          ;
                      },
                  ]
        );
    }

    /**
     * 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(
            'custom-message-id@example.com',
            ['previous-message@example.com'],
            [
                'X-Custom-Header' => 'Custom Value',
            ],
        );
    }
}

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

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

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

<br>
Funny Coder

E adicione o router CLI:

# app/routes/console.php
<?php

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

/*
|--------------------------------------------------------------------------
| Console Routes
|--------------------------------------------------------------------------
|
*/

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

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

php artisan send-welcome-mail

Para obter mais informações, dê uma olhada na documentação oficial da API do Mailtrap.

Concluíndo

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

Abordamos muitos assuntos, desde a configuração do Laravel até o envio de email com SMTP e o envio de email via API. Independentemente da opção escolhida, você sempre pode recorrer a este artigo para obter instruções passo-a-passo.

Para saber mais sobre o Laravel, consulte a documentação oficial. E se estiver procurando mais conteúdo sobre o envio de emails especificamente com o Laravel, visite o blog do Mailtrap, onde poderá encontrar mais artigos úteis, como:

Article by Aleksandr Varnin Full Stack Developer @ Railsware
Ivan Djuric, an author at Mailtrap
Article by Ivan Djuric Technical Content Writer @Mailtrap

I’m a Technical Content Writer with 5 years of background covering email-related topics in tight collaboration with software engineers and email marketers. I just love to research and share actionable insights with you about email sending, testing, deliverability improvements, and more. Happy to be your guide in the world of emails!