Buscar..


Introducción

Action Mailer le permite enviar correos electrónicos desde su aplicación usando clases y vistas de correo. Los mailers funcionan de manera muy similar a los controladores. Heredan de ActionMailer :: Base y viven en aplicaciones / correos, y tienen vistas asociadas que aparecen en aplicaciones / vistas.

Observaciones

Es recomendable procesar el envío de correo electrónico de forma asíncrona para no bloquear su servidor web. Esto se puede hacer a través de varios servicios, como delayed_job .

Correo Básico

Este ejemplo utiliza cuatro archivos diferentes:

  • El modelo de usuario
  • El usuario de correo
  • La plantilla html para el correo electrónico.
  • La plantilla de texto plano para el correo electrónico.

En este caso, el modelo de usuario llama al método approved en la aplicación de correo y pasa la post que ha sido aprobada (el método approved en el modelo puede llamarse mediante una devolución de llamada, desde un método de controlador, etc.). Luego, el remitente genera el correo electrónico desde la plantilla html o de texto sin formato utilizando la información de la post aprobada (por ejemplo, el título). De manera predeterminada, la aplicación de correo usa la plantilla con el mismo nombre que el método en la aplicación de correo (por lo que tanto el método de envío como las plantillas tienen el nombre "aprobado").

user_mailer.rb

class UserMailer < ActionMailer::Base
  default from: "[email protected]"

  def approved(post)
      @title = post.title
      @user = post.user
      mail(to: @user.email, subject: "Your Post was Approved!")
  end
end

usuario.rb

def approved(post)
    UserMailer.approved(post)
end

homologado.html.erb

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>Post Approved</title>
    </head>
    <body>
        <h2>Congrats <%= @user.name %>! Your post (#<%= @title %>) has been approved!</h2>
        <p>We look forward to your future posts!</p>
    </body>
</html>

validado.erb

Congrats <%= @user.name %>! Your post (#<%= @title %>) has been approved!
We look forward to your future posts!

Generando un nuevo correo

Para generar un nuevo correo, ingrese el siguiente comando

rails generate mailer PostMailer 

Esto generará un archivo de plantilla en blanco en app/mailers/post_mailer.rb llamado PostMailer

class PostMailer < ApplicationMailer
end

También se generarán dos archivos de diseño para la vista de correo electrónico, uno para el formato html y otro para el formato de texto.

Si prefiere no utilizar el generador, puede crear sus propios correos. Asegúrese de que heredan de ActionMailer::Base

Agregando Adjuntos

ActionMailer también permite adjuntar archivos.

attachments['filename.jpg'] = File.read('/path/to/filename.jpg')

De forma predeterminada, los archivos adjuntos se codificarán con Base64 . Para cambiar esto, puede agregar un hash al método de adjuntos.

attachments['filename.jpg'] = {
  mime_type: 'application/gzip',
  encoding: 'SpecialEncoding',
  content: encoded_content
}

También puede agregar archivos adjuntos en línea

attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')

ActionMailer Callbacks

ActionMailer soporta tres devoluciones de llamada

  • antes_acción
  • after_action
  • alrededor de la acción

Proporcionar estos en su clase de correo

class UserMailer < ApplicationMailer
  after_action :set_delivery_options, :prevent_delivery_to_guests, :set_business_headers

Luego crea estos métodos bajo la palabra clave private

private
  def set_delivery_options
  end

  def prevent_delivery_to_guests
  end

  def set_business_headers
  end
end

Generar un boletín programado

Crear el modelo de boletín :

  rails g model Newsletter name:string email:string

  subl app/models/newsletter.rb

  validates :name, presence: true
  validates :email, presence: true

Crear el controlador del boletín :

  rails g controller Newsletters create
  
  class NewslettersController < ApplicationController
    skip_before_action :authenticate_user!
    before_action :set_newsletter, only: [:destroy]

    def create
      @newsletter = Newsletter.create(newsletter_params)
      if @newsletter.save
        redirect_to blog_index_path
      else
        redirect_to root_path
      end
    end

    private

      def set_newsletter
        @newsletter = Newsletter.find(params[:id])
      end

      def newsletter_params
        params.require(:newsletter).permit(:name, :email)
      end

  end

Después de eso, cambie la vista create.html.erb al nombre nex. Convertiremos este archivo en una vista parcial que se almacenará dentro del Pie de página . El nombre será _form.html.erb .

Cambiar archivo de nombre de: A:
app / views / newsletters / create.html.erb app / views / newsletters / _form.html.erb

Después de eso se establecen las rutas:

  subl app/config/routes.rb
    
  resources :newsletters

Más adelante, necesitamos configurar el formulario que usaremos para guardar cada correo:

  subl app/views/newsletters/_form.html.erb

  <%= form_for (Newsletter.new) do |f| %>
    <div class="col-md-12" style="margin: 0 auto; padding: 0;">
      <div class="col-md-6" style="padding: 0;">
        <%= f.text_field :name, class: 'form-control', placeholder:'Nombre' %>
      </div>
      <div class="col-md-6" style="padding: 0;">
        <%= f.text_field :email, class: 'form-control', placeholder:'Email' %>
      </div>
    </div>
    <div class="col-md-12" style="margin: 0 auto; padding:0;">
      <%= f.submit class:"col-md-12 tran3s s-color-bg hvr-shutter-out-horizontal", style:'border: none; color: white; cursor: pointer; margin: 0.5em auto; padding: 0.75em; width: 100%;' %>
    </div>
  <% end %>

Y después de eso, inserte en el pie de página:

  subl app/views/layouts/_footer.html.erb

  <%= render 'newsletters/form' %>

Ahora, instale - letter_opener - para obtener una vista previa del correo electrónico en el navegador predeterminado en lugar de enviarlo. Esto significa que no necesita configurar la entrega de correo electrónico en su entorno de desarrollo, y ya no tiene que preocuparse por enviar accidentalmente un correo electrónico de prueba a la dirección de otra persona.

Primero agregue la gema a su entorno de desarrollo y ejecute el comando bundle para instalarlo.

  subl your_project/Gemfile

  gem "letter_opener", :group => :development

A continuación, establezca el método de entrega en el entorno de desarrollo:

  subl your_project/app/config/environments/development.rb

  config.action_mailer.delivery_method = :letter_opener

Ahora, cree una estructura de Mailer para administrar todos los correos con los que trabajaremos. En la terminal

  rails generate mailer UserMailer newsletter_mailer

Y dentro del UserMailer , tenemos que crear un método llamado Newsletter Mailer que se creará para contener dentro de la última publicación del blog y se activará con una acción de rake. Asumiremos que antes tenías una estructura de blog creada.

subl your_project/app/mailers/user_mailer.rb

class UserMailer '[email protected]'

  
  def newsletter_mailer
    @newsletter = Newsletter.all
    @post = Post.last(3)
    emails = @newsletter.collect(&:email).join(", ")
    mail(to: emails, subject: "Hi, this is a test mail.")
  end
  
end

Después de eso, crea la plantilla de Mailer :

subl your_project/app/views/user_mailer/newsletter_mailer.html.erb

<p> Dear Followers: </p>
<p> Those are the lastest entries to our blog. We invite you to read and share everything we did on this week. </p>

<br/>
<table>
<% @post.each do |post| %>
  <%#= link_to blog_url(post) do %>
      <tr style="display:flex; float:left; clear:both;">
        <td style="display:flex; float:left; clear:both; height: 80px; width: 100px;">
          <% if post.cover_image.present? %>
            <%= image_tag post.cover_image.fullsize.url, class:"principal-home-image-slider" %>
          <%# else %>
            <%#= image_tag 'http://your_site_project.com' + post.cover_video, class:"principal-home-image-slider" %>
            <%#= raw(video_embed(post.cover_video)) %>
          <% end %>
        </td>
        <td>
          <h3>
            <%= link_to post.title, :controller => "blog", :action => "show", :only_path => false, :id => post.id %>
          </h3>
          <p><%= post.subtitle %></p>
        </td>
        <td style="display:flex; float:left; clear:both;">
           
        </td>
      </tr>
  <%# end %>
<% end %>
</table>

Como queremos enviar el correo electrónico como un proceso separado, creamos una tarea de Rake para activar el correo electrónico. Agregue un nuevo archivo llamado email_tasks.rake al directorio lib / tasks de su aplicación Rails:

touch lib/taks/email_tasks.rake

desc 'weekly newsletter email'
task weekly_newsletter_email: :environment do
  UserMailer.newsletter_mailer.deliver!
end

El entorno send_digest_email:: significa cargar el entorno Rails antes de ejecutar la tarea, para que pueda acceder a las clases de la aplicación (como UserMailer) dentro de la tarea.

Ahora, al ejecutar el comando rake -T se listará la tarea Rake recién creada. Probar todo funciona ejecutando la tarea y verificando si el correo electrónico se envía o no.

Para probar si el método de envío de correo funciona, ejecute el comando rake:

  rake weekly_newsletter_email

En este punto, tenemos una tarea de rastrillo de trabajo que se puede programar usando crontab . Así que instalaremos la gema cuando se use para proporcionar una sintaxis clara para escribir y desplegar trabajos cron.

subl your_project/Gemfile
  
  gem 'whenever', require: false

Después de eso, ejecute el siguiente comando para crear un archivo config / schedule.rb inicial para usted (siempre que la carpeta de configuración ya esté presente en su proyecto).

  wheneverize .

  [add] writing `./config/schedule.rb'
  [done] wheneverized!

Ahora, dentro del archivo de programación, tenemos que crear nuestro TRABAJO CRON y llamar al método de correo dentro de la determinación del TRABAJO CRON para operar algunas tareas sin asistencia y en un intervalo de tiempo seleccionado. Puede usar diferentes tipos de sintaxis como se explica en este enlace .

subl your_project/config/schedule.rb

every 1.day, :at => '4:30 am' do
  rake 'weekly_newsletter_email'
end

Cron Job Basic Sintaxis

Cron trabajos con siempre

Ahora para probar que Cron Job fue creado con éxito, podemos usar el siguiente comando para leer desde la terminal, nuestro trabajo programado en CRON SYNTAX:

your_project your_mac_user$ whenever

30 4 * * * /bin/bash -l -c 'cd /Users/your_mac_user/Desktop/your_project && RAILS_ENV=production bundle exec rake weekly_newsletter_email --silent'

Ahora, para ejecutar la prueba en un entorno de desarrollo, es aconsejable establecer la siguiente línea en el archivo principal application.rb para que la aplicación sepa dónde están los modelos que utilizará.

  subl your_project/config/application.rb

  config.action_mailer.default_url_options = { :host => "http://localhost:3000/" }

Ahora para permitir que Capistrano V3 guarde el nuevo trabajo Cron dentro del servidor y el desencadenante que activará la ejecución de esta tarea, tenemos que agregar el siguiente requisito:

  subl your_project/Capfile

  require 'whenever/capistrano'

E inserte en el archivo de implementación el identificador que CRON JOB usará sobre el entorno y el nombre de la aplicación .

subl your_project/config/deploy.rb

set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:rails_env)}" }

Y listo, después de guardar los cambios en cada archivo, ejecute el comando de implementación de capistrano:

  cap production deploy

Y ahora su TRABAJO se creó y se calendario para ejecutar el Método Mailer, que es lo que quiero y en el intervalo de tiempo que establecemos en estos archivos.

Interceptor ActionMailer

Action Mailer proporciona enlaces a los métodos de interceptor. Estos le permiten registrar clases que se llaman durante el ciclo de vida de la entrega de correo.

Una clase de interceptor debe implementar el método: deliver_email (message) que se llamará antes de que se envíe el correo electrónico, permitiéndole realizar modificaciones en el correo electrónico antes de que llegue a los agentes de entrega. Su clase debe realizar las modificaciones necesarias directamente en la instancia de Mail :: Message.

Puede ser útil para los desarrolladores enviar correos electrónicos a ellos mismos, no a usuarios reales.

Ejemplo de registro de un interceptor actionmailer:

# config/initializers/override_mail_recipient.rb

if Rails.env.development? or Rails.env.test?
  class OverrideMailRecipient
    def self.delivering_email(mail)
      mail.subject = 'This is dummy subject'
      mail.bcc = '[email protected]'
      mail.to = '[email protected]'
    end
  end
  ActionMailer::Base.register_interceptor(OverrideMailRecipient)
end


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow