Blog EspecializaTi
Carlos Ferreira Por: Carlos Ferreira Comentar

Envio de E-mails no Laravel

Envio de E-mails no Laravel

Sem dúvidas algo que praticamente toda aplicação precisa fazer hora ou outra é enviar e-mails, esse é um recurso fundamental para a maioria das aplicações.
O Laravel fornece uma simples implementação de envios de e-mails, graças a biblioteca SwiftMailer, que provê diversos tipos de drivers como: SMTP, Mailgun, SparkPost, Amazon SES, PHP’s mail e sendmail.

 
 

Configurações

O arquivo de configuração de e-mails no Laravel fica em config/mail.php

Nesse arquivo mail.php tem algumas configurações como: driver, host, port, from, encryption, username, password, sendmail, markdown

  • driver: Driver de envio de e-mails, por default é SMTP (Drivers suportados pelo Laravel: "smtp", "sendmail", "mailgun", "mandrill", "ses", "sparkpost", "log", "array")
  • host: Endereço do host de autenticação do e-mail
  • port: Porta de envio do e-mail
  • from: Dados default (padrão) do nome e e-mail do remetente dos e-mails
  • encryption: Tipo de criptografia dos e-mails, normalmente tls ou ssl
  • username: Usuário de autenticação do e-mail
  • password: Senha de autenticação do e-mail
  • sendmail: Se estiver usando o driver de e-mail sendmail precisa especificar o path (caminho) Sendmail no servidor
  • markdown: Configurações para e-mails Markdown

 
 

Envio de E-mails em Ambiente de Testes

Para o envio de e-mails local, recomendo muito o serviço do Mailtrap.io, com essa ferramenta é possível analisar o conteúdo do e-mail, desde o remetente, assunto, qualidade do e-mail (chances de cair no SPAM) entre outras aspectos relacionados ao e-mail.

 
 

Classe de E-mails

As classes para envio de e-mails no Laravel ficam armazenadas em app/Mail/

E para criar uma nova classe de envio de e-mails deve rodar esse comando do artisan:

php artisan make:mail SendMailUser

SendMailUser é o novo arquivo de classe para definição e envio do e-mail.

As classes de envios de e-mails por default possuem dois métodos: __construct() e build()

No método construtor pode definir alguns comportamentos iniciais na classe, como por exemplo injetar dependências.

O método build() é onde fica a implementação do envio do e-mail:

public function build()
{
    return $this->from('[email protected]')
                ->view('emails.test');
}

Algumas opções possíveis são:

  • from: Quem vai receber o e-mail.
  • view: A view blade com o layout e conteúdo do e-mail.
  • subject: Assunto do e-mail (Caso não seja especificado por default pega o nome da própria classe).
  • attach: Para enviar anexos por e-mail.
  • with: Para enviar valores (variáveis) para a view blade.

 
 

Enviando E-mails

Uma vez que criou a classe de envio de e-mail’s o próximo passo é realmente fazer um novo envio de e-mail a partir da classe. A implementação de ser mais ou

menos assim:

// Precisa importar a classe Mail:
// use Illuminate\Support\Facades\Mail;
Mail::to($to)->send(new SendMailUser());

Na classe Mail podemos encadear a chamada de vários outros métodos, como:

  • cc: Recepiente com cópia para
  • bcc: Cópia oculta
  • to: E-mail remetente (Por default pega as configurações do arquivo config/mail.php em from => address)

Exemplo:

Mail::to('[email protected]')
        ->cc('[email protected]')
        ->send(new SendMailUser());

Algo muito comum é passar informações para a classe de e-mail SendMailUser. Podemos fazer isso passando informações através do construtor, nesse caso precisamos alterar a classe de e-mail e fazer as seguintes modificações no método construtor:

public $user;

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

PS. Não pode esquecer de importar o model User: use App\User;

Dessa forma estamos especificando que a classe de e-mail SendMailUser precisa receber no construtor um objeto de User.
Agora voltamos a implementação do envio do e-mail e atualizamos dessa forma:

#controller
$id = 1;
$user = User::where('id', $id)->first();

Mail::to($user->email)->send(new SendMailUser($user));

Agora vamos voltar a atenção a classe de e-mail SendMailUser, e conferir o método build(), nele usa uma view emails.test
Ou seja, precisamos implementar a view com o conteúdo do e-mail, essa view deve ficar em resources/views/emails/test.blade.php

Mas, antes de implementar essa view podemos passar uma ou mais variáveis para a view, nesse formato temos duas opções, deixar os atributos da classe SendMailUser como públicos, ou usar o método with() pra fazer isso.

Como já definimos o atributo $user como public (publico) podemos acessar essa variável diretamente na view definida no método build(), caso contrário precisamos passar através do método with(), assim:

public function build()
{
    return $this->from('[email protected]')
                ->view('emails.test')
                ->with([
                    'user' => $this->user,
                ]);
}

 

Implementando a view de e-mail:

Após criar um novo arquivo de view em resources/views/emails/test.blade.php podemos definir a parte visual ao nosso gosto. Veja como pode ficar:

<html>
    <body>
        <p>Olá {{ $user->name }}!</p>
        <p></p>
        <p>Esse é apenas um e-mail de teste, para exemplificar o funcionamento do envio de e-mails no Laravel.</p>
        <p></p>
        <p>Att, <br>
        Carlos Ferreira!</p>
    </body>
</html>

Rode o exemplo e faça o teste!

 
 

Envios de e-mails com anexo:

Provavelmente em algum momento pode ser necessário enviar um e-mail, e junto anexar algum arquivo. O Laravel disponibiliza essa opção também, basta simplesmente passar a opção com o path (caminho) do arquivo que deseja anexar.

Vamos supor que temos um arquivo em storage/app/image.jpg

Podemos anexar essa imagem da seguinte forma:

public function build()
{
    return $this->from('[email protected]')
                ->view('emails.test')
                ->attach(storage_path('app/image.jpg'))
                ->with([
                    'user' => $this->user,
                ]);
}

 

Anexos inline:

Outra opção muito útil quando o assunto é e-mails, é anexar uma imagem no corpo do e-mail, como por exemplo a logo da empresa. Nesse exemplos vamos ter a logo da empresa em public/imgs/especializati.png

E para anexar essa imagem no corpo do e-mail vamos na view resources/views/emails/test.blade.php

<html>
    <body>
        <img src="{{ $message->embed($pathToFile) }}" alt="Logo Aqui">
        <p>Olá {{ $user->name }}!</p>
        <p></p>
        <p>Esse é apenas um e-mail de teste, para exemplificar o funcionamento do envio de e-mails no Laravel.</p>
        <p></p>
        <p>Att, <br>
        Carlos Ferreira!</p>
    </body>
</html>

Essa varável $message é disponível nas views de envio de e-mails, exceto quando usamos Markdown (que falarei mais adiante.)

A variável $pathToFile pode ser enviada através da classe SendMailUser, ou poderíamos passar o path diretamente na view, sem a necessidade de criar essa variável. O conteúdo dela deve ser:

$pathToFile = public_path('imgs/especializati.png');

 
 

E-mail com Markdown no Laravel

A partir da versão 5.5 passou a dá suporte ao Markdown. Esse recurso permite que você desfrute de modelos e components de layouts prontos, para envio dos seus e-mails. Em outras palavras, é possível construir e-mails visualmente mais atrativos em pouquíssimo tempo. (Saiba mais sobre o Markdown).

Se quiser gerar um e-mail com o padrão Markdown, basta passar a opção –markdown, veja o exemplo:

php artisan make:mail SendMailUser --markdown=emails.test-markdown

Agora na classe SendMailUser precisamos alterar o método build() e usar o arquivo de view markdown que foi criado:

public function build()
{
    return $this->from('[email protected]')
                ->markdown('emails.test-markdown')
                ->with([
                    'user'     => $this->user,
                    'url'     => route('home'),
                ]);
}

Observe que acrescetamos no método with() a “url“, que é exatamente o link da rota cujo o nome é home. No arquivo de rotas routes/web.php precisa ter essa rota:

Route::get('/', '[email protected]')->name('home');

Por último basta alterar o conteúdo da nossa view resources/views/emails/test-markdown.blade.php, usando os recursos do Markdown, veja o exemplo:

@component('mail::message')
# Olá {{ $user->name }}!

<p>Esse é um e-mail de teste! =D</p>

@component('mail::button', ['url' => $url])
Visite o nosso site
@endcomponent

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

O component button pode ser personalizado, alterando a cor através da opção color que aceita: blue, green e red. Exemplo:

@component('mail::button', ['url' => $url, 'color' => 'green'])
Visite o nosso site
@endcomponent

Como estamos usando Markdown obviamente também podemos criar os blocos (painéis) no e-mail, veja como:

@component('mail::panel')
Painel
@endcomponent

Para trabalhar com tabelas, precisa seguir essa estrutura, observe atentamente os detalhes :—:

@component('mail::table')
| id               | Nome                 | Telefone                 | E-mail                          |
| ------------- |:-----------------:|:---------------------:| -----------------------------:|
| 1              | Carlos Ferreira   | (64) 98170-1406          | [email protected]   |
| 2              | Other Name         | (64) 98170-1406         | [email protected]    |
@endcomponent

Mais detalhes sobre opções de layout Markdow nesse link (http://devdocs.io/markdown/)

O Laravel é muito flexível quanto a customizações de components de view, caso queria alterar alguma formtação default você pode rodar esse comando que ele vai publicar as views para que possam ser customizadas a gosto:

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

Ao fazer isso vai publicar os arquivos de views de e-mails em resources/views/vendor/mail/

Nesse diretório publica duas pastas, html e

  • html: diretório é usado para os e-mails padrões
  • markdown: arquivos de views do padrão markdown

Caso queira customizar o layout, cores e etc, os arquivos de css ficam em

resources/views/vendor/mail/html/themes/

O arquivo default.css contém a formatação padrão dos e-mails, altere a gosto e veja as mudanças no visual dos seus próximos e-mails.

 
 

Pré-visualizar os E-mails no Browser:

Já que acabamos de trabalhar com o layout do e-mail, nada melhor que testar de uma forma mais rápida. Não é mesmo?!

O Laravel também permite que você renderize o layout do seu e-mail diretamente no Browser, e isso facilita muito pois a pré-visualização é mais rápida e consequentemente a adaptação fica mais simples.

Veja o exemplo de como visualizar o nosso e-mail:

Route::get('/mailable', function () {
    $user = App\User::find(1);

    return new App\Mail\SendMailUser($user);
});

Abra essa rota no Browser e veja o resultado!

 
 

Envio de E-mails com Filas

Um ponto que deve ser avaliado no momento de enviar e-mails é a questão do tempo, envio de e-mails é uma tarefa pesada, que tem um tempo de resposta razoavelmente grande, por esse motivo usar Queues (filas) é uma boa alternativa. Caso não conheça sobre filas, recomendo a leitura desse tutorial sobre filas no Laravel.

O Laravel dispõe de algumas formas de uso de Queues no momento de enviar e-mails, vamos a elas!

 

Queue por E-mail

Podemos definir que o e-mail será enviado e processado pelo sistema de Queues (filas) do Laravel, basta no momento de fazer o envio trocar o método send() por queue(), veja:

Mail::to($to)->queue(new SendMailUser());

 

Enviar E-mail com Atraso:

Caso queira por exemplo enviar um e-mails só depois de X minutos pode fazer isso usando o método later() e passar o tempo after (depois) que é para disparar o e-mail, veja:

$when = now()->addMinutes(10);
Mail::to($to)
        ->later($when, new SendMailUser());

Nesse exemplo só vai disparar o e-mail (processar a fila) após 10 minutos.

 

Queue por Padrão

Na maioria dos casos não é muito usual ficar definindo Queue no momento de enviar o e-mail, mas sim, deixar por default o envio de e-mails por Queue. E para conseguir esse feito basta fazer a classe de e-mail implementar a Interface ShouldQueue. Veja:

[...]
use Illuminate\Contracts\Queue\ShouldQueue;

class SendMailUser extends Mailable implements ShouldQueue
{
    // [...]
}

 

Vamos ficando por aqui, espero que tenha gostado, e já sabe, qualquer dúvida só deixar aquele comentário. 🙂

 

Abraços []’s

 

Carlos Ferreira

Sobre o Autor:

Carlos Ferreira

Carlos Ferreira é Analista de Sistemas Experiente, Empreendedor, Fundador da empresa EspecializaTi. Certificações: Comptia Linux +, LPI, Novell Certification.

Todos os direitos reservados © 2018 - EspecializaTi. É proibida a reprodução total ou parcial deste conteúdo.