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