Uma introdução sobre Action Mailer em Rails 7
Tags: rails, actionmailer
Published: 2022-12-12 13:11:27

Nessa introdução, eu vou ensinar a usar action mailer.

## O que é Action Mailer?

O Action Mailer é um recurso de Rails que permite enviar email da sua aplicação.

Uma característica bem interessante do Action Mailer é que ele é bem similar ao Controller, ou seja, tudo que você aprendeu sobre Controller, pode ser aplicado em Mailer.

Vamos ver quais são as semelhanças entre Controller e Mailer:

- Actions e views.
- Variáveis ​​de instância que é acessível no views.
- A capacidade de usar layouts e partials.
- A capacidade de acessar um hash de parâmetros.


Agora que você sabe o que é Mailer, vamos pôr em prática.

## Pondo em prática

Vamos criar uma aplicação simples de autenticação de usuário.

Se quiser acompanhar, basta executar os comandos abaixo.

Primeiro, vamos criar um projeto.

```bash
rails new mailer_introducao
cd mailer_introducao
```

Com projeto criado, vamos usar o scaffold para criar o model e controller de uma vez.

```bash
rails g scaffold Usuario nome email senha
```

Com isso, nós temos um projeto para ação.

Como nós podemos criar o mailer?

Bem, o jeito mais rápido seria usar o generator.

Então vamos usar o generator.

## Criando mailer

Eu quero que a aplicação envie um email de saudação para o usuário que cadastrou na aplicação.

Então vamos criar o mailer.

```bash
rails g mailer Usuario bem_vindo
```

O mailer foi criado com nome `Usuario` e o `bem_vindo` é a action dele.

Vamos ver o arquivo `app/mailers/usuario_mailer.rb` para ver o que o generator gerou.

```ruby
# app/mailers/usuario_mailer.rb
class UsuarioMailer < ApplicationMailer
  def bem_vindo
    @greeting = "Hi"

    mail to: "to@example.org"
  end
end
```

O método `bem_vindo` que é a action que nós colocamos no generator e você pode notar que ele também criou um view para essa action, veja no `app/views/usuario_mailer/`.

O método `mail` cria uma mensagem de email atual. O `to: "to@example.org"` é o email para quem a aplicação vai enviar.

Agora vamos tirar o código gerado do método e colocar o que queremos para que possa enviar o email.

```ruby
# app/mailers/usuario_mailer.rb
class UsuarioMailer < ApplicationMailer
  def bem_vindo
    @usuario = params[:usuario]

    mail(to: @usuario.email, subject: 'Bem vindo ao meu site')
  end
end
```

Podemos percebe que no método `mail`, existe outra argumento além do `to`. O `subject` é o assunto do email.

Agora, Vamos editar a view, pois nós queremos fazer uma mensagem de saudação.

Abra o arquivo `app/views/usuario_mailer/bem_vindo.html.erb`.

```erb
<!-- app/views/usuario_mailer/bem_vindo.html.erb -->
<p><%= @usuario.nome %>, bem vindo ao meu site.</p>

<p>Espero que goste do conteúdo do site.</p>
```

Agora vamos editar o controller, para que envie o email ao criar o usuário.

Abra o arquivo `app/controllers/usuarios_controller.rb`.

```ruby
# app/controllers/usuarios_controller.rb
class UsuariosController < ApplicationController
  ...
  def create
    @usuario = Usuario.new(usuario_params)

    respond_to do |format|
      if @usuario.save
        UsuarioMailer.with(usuario: @usuario).bem_vindo.deliver_later
        format.html { redirect_to usuario_url(@usuario), notice: "Usuario was successfully created." }
        format.json { render :show, status: :created, location: @usuario }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @usuario.errors, status: :unprocessable_entity }
      end
    end
  end
...
end
```

Vamos focar nesse comando `UsuarioMailer.with(usuario: @usuario).bem_vindo.deliver_later`.

O `UsuarioMailer` é classe que nós criamos.

O método `with` é usado para que você possa passar alguma variável para mailer, no nosso caso, nós estamos passando a variável `@usuario` e para acessar no mailer, basta usar o `params[:nome_que_voce_passou_no_metodo]`.

O método `bem_vindo` está, obviamente, chamando o método que nós criamos.

E por último, temos o método `deliver_later`, o que ele faz é  basicamente enviar o email assincronamente, ou seja, a aplicação não vai ficar esperando a execução de envio de email para poder executar os próximos comandos.

E se você não queira enviar o email depois, basta usar o `deliver_now` que ele vai enviar imediatamente.

Agora vamos rodar o servidor, para ver em ação.

Antes de rodar o servidor, migre o banco de dados.

```bash
rails db:migrate
rails server
```

Vá no navegador e acesse no `http://127.0.0.1:3000/usuarios` e crie um novo usuário, saiba que agora, a aplicação não vai enviar o email.

Assim que você criar o usuário, vá no terminal e você vai ver o html do view que nós editamos no `app/views/usuario_mailer/bem_vindo.html.erb`.

Isso significa que até aqui está funcionando.

Mas nós não queremos que aplicação mostre no terminal, queremos que a aplicação envie para Gmail do usuário.

Aqui, eu vou usar o Gmail para enviar, se você quer usar outros serviços, vai ter que pesquisar.

## Enviando email usando Gmail

Vá no `config/environments/development.rb` e adicione o código abaixo.

```ruby
require "active_support/core_ext/integer/time"

Rails.application.configure do
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.gmail.com',
    port:                 587,
    user_name:            'SEU_EMAIL',
    password:             'SUA_SENHA',
    authentication:       'plain',
    enable_starttls_auto: true,
    open_timeout:         5,
    read_timeout:         5
  }
  ...
end
```

> Em 15 de julho de 2014, o Google aumentou suas [medidas de segurança] (https://support.google.com/accounts/answer/6010255) para bloquear tentativas de aplicativos que considera menos seguros. Você pode alterar suas configurações do Gmail [aqui] (https://www.google.com/settings/security/lesssecureapps) para permitir as tentativas. Se sua conta do Gmail tiver autenticação de 2 fatores habilitada, você precisará definir uma [senha de aplicativo] (https://myaccount.google.com/apppasswords) e usá-la em vez de sua senha normal.

Com isso, você vai conseguir enviar o email, então tome cuidado para não enviar para um email de alguém aleatório.

Então é isso, nós acabamos por aqui, claro que tem muitas coisas que não citei, mas eu decidi que não era relevante assim na introdução, pois com isso, já é capaz de fazer muita coisa.

E tchau!