1 ¿Qué es Action Mailer?
Action Mailer te permite enviar correos electrónicos desde tu aplicación utilizando clases de mailer y vistas.
1.1 Los Mailers son Similares a los Controladores
Heredan de ActionMailer::Base
y residen en app/mailers
. Los mailers también funcionan muy similar a los controladores. Algunos ejemplos de similitudes se enumeran a continuación. Los mailers tienen:
- Acciones, y también, vistas asociadas que aparecen en
app/views
. - Variables de instancia que son accesibles en las vistas.
- La capacidad de utilizar layouts y parciales.
- La capacidad de acceder a un hash de params.
2 Enviando Correos Electrónicos
Esta sección proporcionará una guía paso a paso para crear un mailer y sus vistas.
2.1 Guía para Generar un Mailer
2.1.1 Crear el Mailer
$ bin/rails generate mailer User
create app/mailers/user_mailer.rb
create app/mailers/application_mailer.rb
invoke erb
create app/views/user_mailer
create app/views/layouts/mailer.text.erb
create app/views/layouts/mailer.html.erb
invoke test_unit
create test/mailers/user_mailer_test.rb
create test/mailers/previews/user_mailer_preview.rb
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
layout 'mailer'
end
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
end
Como puedes ver, puedes generar mailers al igual que usas otros generadores con Rails.
Si no quisieras usar un generador, podrías crear tu propio archivo dentro de app/mailers
, solo asegúrate de que hereda de ActionMailer::Base
:
class MyMailer < ActionMailer::Base
end
2.1.2 Editar el Mailer
Los mailers tienen métodos llamados "acciones" y usan vistas para estructurar su contenido. Donde un controlador genera contenido como HTML para enviar de vuelta al cliente, un Mailer crea un mensaje para ser entregado por correo electrónico.
app/mailers/user_mailer.rb
contiene un mailer vacío:
class UserMailer < ApplicationMailer
end
Vamos a añadir un método llamado welcome_email
, que enviará un correo electrónico a la dirección de correo registrada del usuario:
class UserMailer < ApplicationMailer
default from: 'notifications@example.com'
def welcome_email
@user = params[:user]
@url = 'http://example.com/login'
mail(to: @user.email, subject: 'Welcome to My Awesome Site')
end
end
Aquí tienes una explicación rápida de los elementos presentados en el método anterior. Para una lista completa de todas las opciones disponibles, por favor consulta más abajo en la sección Lista Completa de Atributos Configurables de Action Mailer.
- El método
default
establece valores predeterminados para todos los correos electrónicos enviados desde este mailer. En este caso, lo usamos para establecer el valor del encabezado:from
para todos los mensajes en esta clase. Esto se puede anular por correo electrónico. - El método
mail
crea el mensaje de correo electrónico real. Lo usamos para especificar los valores de los encabezados como:to
y:subject
por correo electrónico.
2.1.3 Crear una Vista de Mailer
Crea un archivo llamado welcome_email.html.erb
en app/views/user_mailer/
. Esta será la plantilla utilizada para el correo electrónico, formateada en HTML:
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<h1>Welcome to example.com, <%= @user.name %></h1>
<p>
You have successfully signed up to example.com,
your username is: <%= @user.login %>.<br>
</p>
<p>
To login to the site, just follow this link: <%= @url %>.
</p>
<p>Thanks for joining and have a great day!</p>
</body>
</html>
También hagamos una parte de texto para este correo electrónico. No todos los clientes prefieren correos electrónicos HTML, por lo que enviar ambos es una buena práctica. Para hacer esto, crea un archivo llamado welcome_email.text.erb
en app/views/user_mailer/
:
Welcome to example.com, <%= @user.name %>
===============================================
You have successfully signed up to example.com,
your username is: <%= @user.login %>.
To login to the site, just follow this link: <%= @url %>.
Thanks for joining and have a great day!
Cuando ahora llames al método mail
, Action Mailer detectará las dos plantillas (texto y HTML) y automáticamente generará un correo electrónico multipart/alternative
.
2.1.4 Llamando al Mailer
Los mailers son realmente solo otra forma de renderizar una vista. En lugar de renderizar una vista y enviarla a través del protocolo HTTP, la están enviando a través de los protocolos de correo electrónico. Debido a esto, tiene sentido que tu controlador le diga al Mailer que envíe un correo electrónico cuando un usuario se crea exitosamente.
Configurar esto es simple.
Primero, vamos a crear un scaffold de User
:
$ bin/rails generate scaffold user name email login
$ bin/rails db:migrate
Ahora que tenemos un modelo de usuario para jugar, editaremos el archivo app/controllers/users_controller.rb
, haremos que instruya al UserMailer
para entregar un correo electrónico al usuario recién creado editando la acción create e insertando una llamada a UserMailer.with(user: @user).welcome_email
justo después de que el usuario se guarde exitosamente.
Colocaremos el correo electrónico en cola para ser enviado usando deliver_later
, que está respaldado por Active Job. De esa manera, la acción del controlador puede continuar sin esperar a que se complete el envío.
class UsersController < ApplicationController
# ...
# POST /users or /users.json
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
# Tell the UserMailer to send a welcome email after save
UserMailer.with(user: @user).welcome_email.deliver_later
format.html { redirect_to(@user, notice: 'User was successfully created.') }
format.json { render json: @user, status: :created, location: @user }
else
format.html { render action: 'new' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
# ...
end
NOTA: El comportamiento predeterminado de Active Job es ejecutar trabajos a través del adaptador :async
. Por lo tanto, puedes usar deliver_later
para enviar correos electrónicos de forma asíncrona. El adaptador predeterminado de Active Job ejecuta trabajos con un pool de hilos en proceso. Es adecuado para los entornos de desarrollo/prueba, ya que no requiere ninguna infraestructura externa, pero es una mala opción para producción, ya que elimina los trabajos pendientes al reiniciar. Si necesitas un backend persistente, necesitarás usar un adaptador de Active Job que tenga un backend persistente (Sidekiq, Resque, etc.).
Si deseas enviar correos electrónicos de inmediato (por ejemplo, desde un cronjob) simplemente llama a deliver_now
:
class SendWeeklySummary
def run
User.find_each do |user|
UserMailer.with(user: user).weekly_summary.deliver_now
end
end
end
Cualquier par clave-valor pasado a with
simplemente se convierte en los params
para la acción del mailer. Así que with(user: @user, account: @user.account)
hace que params[:user]
y params[:account]
estén disponibles en la acción del mailer. Al igual que los controladores tienen params.
El método weekly_summary
devuelve un objeto ActionMailer::MessageDelivery
que luego puede ser instruido para deliver_now
o deliver_later
para enviarse a sí mismo. El objeto ActionMailer::MessageDelivery
es un envoltorio alrededor de un Mail::Message
. Si deseas inspeccionar, alterar o hacer cualquier otra cosa con el objeto Mail::Message
, puedes acceder a él con el método message
en el objeto ActionMailer::MessageDelivery
.
2.2 Codificación Automática de Valores de Encabezado
Action Mailer maneja la codificación automática de caracteres multibyte dentro de los encabezados y cuerpos.
Para ejemplos más complejos, como definir conjuntos de caracteres alternativos o auto-codificar texto primero, por favor consulta la biblioteca Mail.
2.3 Lista Completa de Métodos de Action Mailer
Solo hay tres métodos que necesitas para enviar prácticamente cualquier mensaje de correo electrónico:
headers
- Especifica cualquier encabezado en el correo electrónico que desees. Puedes pasar un hash de nombres de campos de encabezado y pares de valores, o puedes llamar aheaders[:field_name] = 'value'
.attachments
- Te permite agregar archivos adjuntos a tu correo electrónico. Por ejemplo,attachments['file-name.jpg'] = File.read('file-name.jpg')
.mail
- Crea el correo electrónico en sí. Puedes pasar encabezados como un hash al métodomail
como un parámetro.mail
creará un correo electrónico, ya sea de texto plano o multipart, dependiendo de las plantillas de correo electrónico que hayas definido.
2.3.1 Agregar Archivos Adjuntos
Action Mailer hace que sea muy fácil agregar archivos adjuntos.
Pasa el nombre del archivo y el contenido, y Action Mailer y la gema Mail adivinarán automáticamente el
mime_type
, establecerán lacodificación
y crearán el archivo adjunto.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
Cuando se active el método mail
, enviará un correo electrónico multipart con un archivo adjunto, adecuadamente anidado con el nivel superior siendo multipart/mixed
y la primera parte siendo un multipart/alternative
que contiene los mensajes de correo electrónico en texto plano y HTML.
NOTA: Mail codificará automáticamente un archivo adjunto en Base64. Si deseas algo diferente, codifica tu contenido y pásalo codificado junto con la codificación en un Hash
al método attachments
.
Pasa el nombre del archivo y especifica encabezados y contenido, y Action Mailer y Mail usarán la configuración que pases.
encoded_content = SpecialEncode(File.read('/path/to/filename.jpg')) attachments['filename.jpg'] = { mime_type: 'application/gzip', encoding: 'SpecialEncoding', content: encoded_content }
NOTA: Si especificas una codificación, Mail asumirá que tu contenido ya está codificado y no intentará codificarlo en Base64.
2.3.2 Hacer Archivos Adjuntos Inline
Action Mailer 3.0 hace que los archivos adjuntos inline, que involucraban mucho hacking en versiones anteriores a 3.0, sean mucho más simples y triviales como deberían ser.
Primero, para decirle a Mail que convierta un archivo adjunto en un archivo adjunto inline, solo llama a
#inline
en el método attachments dentro de tu Mailer:def welcome attachments.inline['image.jpg'] = File.read('/path/to/image.jpg') end
Luego, en tu vista, puedes simplemente referenciar
attachments
como un hash y especificar qué archivo adjunto deseas mostrar, llamando aurl
sobre él y luego pasando el resultado al métodoimage_tag
:<p>Hello there, this is our image</p> <%= image_tag attachments['image.jpg'].url %>
Como esta es una llamada estándar a
image_tag
, puedes pasar un hash de opciones después de la URL del archivo adjunto como podrías para cualquier otra imagen:<p>Hello there, this is our image</p> <%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>
2.3.3 Enviar Correo Electrónico a Múltiples Destinatarios
Es posible enviar correo electrónico a uno o más destinatarios en un solo correo electrónico (por ejemplo, informando a todos los administradores de un nuevo registro) configurando la lista de correos electrónicos en la clave :to
. La lista de correos electrónicos puede ser un array de direcciones de correo electrónico o una sola cadena con las direcciones separadas por comas.
class AdminMailer < ApplicationMailer
default to: -> { Admin.pluck(:email) },
from: 'notification@example.com'
def new_registration(user)
@user = user
mail(subject: "New User Signup: #{@user.email}")
end
end
El mismo formato se puede usar para establecer destinatarios de copia de carbón (Cc:) y copia de carbón oculta (Bcc:), usando las claves :cc
y :bcc
respectivamente.
2.3.4 Enviar Correo Electrónico con Nombre
A veces deseas mostrar el nombre de la persona en lugar de solo su dirección de correo electrónico cuando reciben el correo electrónico. Puedes usar email_address_with_name
para eso:
def welcome_email
@user = params[:user]
mail(
to: email_address_with_name(@user.email, @user.name),
subject: 'Welcome to My Awesome Site'
)
end
La misma técnica funciona para especificar un nombre de remitente:
class UserMailer < ApplicationMailer
default from: email_address_with_name('notification@example.com', 'Example Company Notifications')
end
Si el nombre es una cadena vacía, devuelve solo la dirección.
2.4 Vistas de Mailer
Las vistas de Mailer están ubicadas en el directorio app/views/name_of_mailer_class
. La vista específica del mailer es conocida por la clase porque su nombre es el mismo que el método del mailer. En nuestro ejemplo anterior, nuestra vista de mailer para el método welcome_email
estará en app/views/user_mailer/welcome_email.html.erb
para la versión HTML y welcome_email.text.erb
para la versión en texto plano.
Para cambiar la vista predeterminada del mailer para tu acción, haz algo como esto:
class UserMailer < ApplicationMailer
default from: 'notifications@example.com'
def welcome_email
@user = params[:user]
@url = 'http://example.com/login'
mail(to: @user.email,
subject: 'Welcome to My Awesome Site',
template_path: 'notifications',
template_name: 'another')
end
end
En este caso, buscará plantillas en app/views/notifications
con el nombre another
. También puedes especificar un array de rutas para template_path
, y se buscarán en orden.
Si deseas más flexibilidad, también puedes pasar un bloque y renderizar plantillas específicas o incluso renderizar inline o texto sin usar un archivo de plantilla:
class UserMailer < ApplicationMailer
default from: 'notifications@example.com'
def welcome_email
@user = params[:user]
@url = 'http://example.com/login'
mail(to: @user.email,
subject: 'Welcome to My Awesome Site') do |format|
format.html { render 'another_template' }
format.text { render plain: 'Render text' }
end
end
end
Esto renderizará la plantilla 'another_template.html.erb' para la parte HTML y usará el texto renderizado para la parte de texto. El comando render es el mismo que se usa dentro de Action Controller, por lo que puedes usar todas las mismas opciones, como :text
, :inline
, etc.
Si te gustaría renderizar una plantilla ubicada fuera del directorio predeterminado app/views/mailer_name/
, puedes aplicar prepend_view_path
, así:
class UserMailer < ApplicationMailer
prepend_view_path "custom/path/to/mailer/view"
# This will try to load "custom/path/to/mailer/view/welcome_email" template
def welcome_email
# ...
end
end
También puedes considerar usar el método append_view_path
.
2.4.1 Caché de Vistas de Mailer
Puedes realizar caché de fragmentos en vistas de mailer como en vistas de aplicación usando el método cache
.
<% cache do %>
<%= @company.name %>
<% end %>
Y para usar esta función, necesitas configurar tu aplicación con esto:
config.action_mailer.perform_caching = true
El caché de fragmentos también es compatible en correos electrónicos multipart. Lee más sobre caché en la guía de caché de Rails.
2.5 Layouts de Action Mailer
Al igual que las vistas de controlador, también puedes tener layouts de mailer. El nombre del layout necesita ser el mismo que tu mailer, como user_mailer.html.erb
y user_mailer.text.erb
para ser reconocido automáticamente por tu mailer como un layout.
Para usar un archivo diferente, llama a layout
en tu mailer:
class UserMailer < ApplicationMailer
layout 'awesome' # use awesome.(html|text).erb as the layout
end
Al igual que con las vistas de controlador, usa yield
para renderizar la vista dentro del layout.
También puedes pasar una opción layout: 'layout_name'
a la llamada render dentro del bloque de formato para especificar diferentes layouts para diferentes formatos:
class UserMailer < ApplicationMailer
def welcome_email
mail(to: params[:user].email) do |format|
format.html { render layout: 'my_layout' }
format.text
end
end
end
Renderizará la parte HTML usando el archivo my_layout.html.erb
y la parte de texto con el archivo usual user_mailer.text.erb
si existe.
2.6 Previsualización de Correos Electrónicos
Las previsualizaciones de Action Mailer proporcionan una forma de ver cómo se ven los correos electrónicos visitando una URL especial que los renderiza. En el ejemplo anterior, la clase de previsualización para UserMailer
debería llamarse UserMailerPreview
y ubicarse en test/mailers/previews/user_mailer_preview.rb
. Para ver la previsualización de welcome_email
, implementa un método que tenga el mismo nombre y llama a UserMailer.welcome_email
:
class UserMailerPreview < ActionMailer::Preview
def welcome_email
UserMailer.with(user: User.first).welcome_email
end
end
Luego, la previsualización estará disponible en http://localhost:3000/rails/mailers/user_mailer/welcome_email.
Si cambias algo en app/views/user_mailer/welcome_email.html.erb
o en el propio mailer, se recargará automáticamente y lo renderizará para que puedas ver visualmente el nuevo estilo al instante. Una lista de previsualizaciones también está disponible en http://localhost:3000/rails/mailers.
Por defecto, estas clases de previsualización viven en test/mailers/previews
. Esto se puede configurar usando la opción preview_paths
. Por ejemplo, si deseas agregar lib/mailer_previews
a esto, puedes configurarlo en config/application.rb
:
config.action_mailer.preview_paths << "#{Rails.root}/lib/mailer_previews"
2.7 Generación de URLs en Vistas de Action Mailer
A diferencia de los controladores, la instancia del mailer no tiene ningún contexto sobre la solicitud entrante, por lo que necesitarás proporcionar el parámetro :host
tú mismo.
Como el :host
generalmente es consistente en toda la aplicación, puedes configurarlo globalmente en config/application.rb
:
config.action_mailer.default_url_options = { host: 'example.com' }
Debido a este comportamiento, no puedes usar ninguno de los helpers *_path
dentro de un correo electrónico. En su lugar, necesitarás usar el helper asociado *_url
. Por ejemplo, en lugar de usar
<%= link_to 'welcome', welcome_path %>
Necesitarás usar:
<%= link_to 'welcome', welcome_url %>
Al usar la URL completa, tus enlaces ahora funcionarán en tus correos electrónicos.
2.7.1 Generación de URLs con url_for
url_for
genera una URL completa por defecto en las plantillas.
Si no configuraste la opción :host
globalmente, asegúrate de pasarla a url_for
.
<%= url_for(host: 'example.com',
controller: 'welcome',
action: 'greeting') %>
2.7.2 Generación de URLs con Rutas Nombradas
Los clientes de correo electrónico no tienen contexto web y, por lo tanto, las rutas no tienen una URL base para formar direcciones web completas. Por lo tanto, siempre debes usar la variante *_url
de los helpers de ruta nombrada.
Si no configuraste la opción :host
globalmente, asegúrate de pasarla al helper de URL.
<%= user_url(@user, host: 'example.com') %>
2.8 Agregar Imágenes en Vistas de Action Mailer
A diferencia de los controladores, la instancia del mailer no tiene ningún contexto sobre la solicitud entrante, por lo que necesitarás proporcionar el parámetro :asset_host
tú mismo.
Como el :asset_host
generalmente es consistente en toda la aplicación, puedes configurarlo globalmente en config/application.rb
:
config.action_mailer.asset_host = 'http://example.com'
NOTA: Como no podemos inferir el protocolo de la solicitud, necesitarás especificar un protocolo como http://
o https://
en la configuración de :asset_host
.
Ahora puedes mostrar una imagen dentro de tu correo electrónico.
<%= image_tag 'image.jpg' %>
2.9 Envío de Correos Electrónicos Multipart
Action Mailer enviará automáticamente correos electrónicos multipart si tienes diferentes plantillas para la misma acción. Así que, para nuestro ejemplo de UserMailer
, si tienes welcome_email.text.erb
y welcome_email.html.erb
en app/views/user_mailer
, Action Mailer enviará automáticamente un correo electrónico multipart con las versiones HTML y de texto configuradas como diferentes partes.
El orden de las partes que se insertan está determinado por :parts_order
dentro del método ActionMailer::Base.default
.
2.10 Envío de Correos Electrónicos con Opciones de Entrega Dinámicas
Si deseas anular las opciones de entrega predeterminadas (por ejemplo, credenciales SMTP) mientras envías correos electrónicos, puedes hacerlo usando delivery_method_options
en la acción del mailer.
class UserMailer < ApplicationMailer
def welcome_email
@user = params[:user]
@url = user_url(@user)
delivery_options = { user_name: params[:company].smtp_user,
password: params[:company].smtp_password,
address: params[:company].smtp_host }
mail(to: @user.email,
subject: "Please see the Terms and Conditions attached",
delivery_method_options: delivery_options)
end
end
2.11 Envío de Correos Electrónicos sin Renderizado de Plantilla
Puede haber casos en los que desees omitir el paso de renderizado de plantilla y proporcionar el cuerpo del correo electrónico como una cadena. Puedes lograr esto usando la opción :body
. En tales casos, no olvides agregar la opción :content_type
. Rails predeterminadamente usará text/plain
de lo contrario.
class UserMailer < ApplicationMailer
def welcome_email
mail(to: params[:user].email,
body: params[:email_body],
content_type: "text/html",
subject: "Already rendered!")
end
end
3 Callbacks de Action Mailer
Action Mailer te permite especificar un before_action
, after_action
y around_action
para configurar el mensaje, y before_deliver
, after_deliver
y around_deliver
para controlar la entrega.
Los callbacks pueden especificarse con un bloque o un símbolo a un método en la clase del mailer similar a los controladores.
Podrías usar un
before_action
para establecer variables de instancia, poblar el objeto de correo con valores predeterminados o insertar encabezados y archivos adjuntos predeterminados.
class InvitationsMailer < ApplicationMailer
before_action :set_inviter_and_invitee
before_action { @account = params[:inviter].account }
default to: -> { @invitee.email_address },
from: -> { common_address(@inviter) },
reply_to: -> { @inviter.email_address_with_name }
def account_invitation
mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
end
def project_invitation
@project = params[:project]
@summarizer = ProjectInvitationSummarizer.new(@project.bucket)
mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"
end
private
def set_inviter_and_invitee
@inviter = params[:inviter]
@invitee = params[:invitee]
end
end
Podrías usar un
after_action
para hacer una configuración similar a unbefore_action
pero usando variables de instancia establecidas en tu acción del mailer.Usar un callback
after_action
también te permite anular la configuración del método de entrega actualizandomail.delivery_method.settings
.
class UserMailer < ApplicationMailer
before_action { @business, @user = params[:business], params[:user] }
after_action :set_delivery_options,
:prevent_delivery_to_guests,
:set_business_headers
def feedback_message
end
def campaign_message
end
private
def set_delivery_options
# You have access to the mail instance,
# @business and @user instance variables here
if @business && @business.has_smtp_settings?
mail.delivery_method.settings.merge!(@business.smtp_settings)
end
end
def prevent_delivery_to_guests
if @user && @user.guest?
mail.perform_deliveries = false
end
end
def set_business_headers
if @business
headers["X-SMTPAPI-CATEGORY"] = @business.code
end
end
end
- Podrías usar un
after_deliver
para registrar la entrega del mensaje. También permite comportamientos similares a observadores/interceptores, pero con acceso al contexto completo del mailer.
class UserMailer < ApplicationMailer
after_deliver :mark_delivered
before_deliver :sandbox_staging
after_deliver :observe_delivery
def feedback_message
@feedback = params[:feedback]
end
private
def mark_delivered
params[:feedback].touch(:delivered_at)
end
# An Interceptor alternative.
def sandbox_staging
message.to = ['sandbox@example.com'] if Rails.env.staging?
end
# A callback has more context than the comparable Observer example.
def observe_delivery
EmailDelivery.log(message, self.class, action_name, params)
end
end
- Los callbacks de mailer abortan el procesamiento posterior si el cuerpo se establece en un valor no nulo.
before_deliver
puede abortar conthrow :abort
.
4 Uso de Helpers de Action Mailer
Action Mailer hereda de AbstractController
, por lo que tienes acceso a la mayoría de los mismos helpers que tienes en Action Controller.
También hay algunos métodos helper específicos de Action Mailer disponibles en ActionMailer::MailHelper
. Por ejemplo, estos permiten acceder a la instancia del mailer desde tu vista con mailer
, y acceder al mensaje como message
:
<%= stylesheet_link_tag mailer.name.underscore %>
<h1><%= message.subject %></h1>
5 Configuración de Action Mailer
Las siguientes opciones de configuración son mejores para hacer en uno de los archivos de entorno (environment.rb, production.rb, etc...)
Configuración | Descripción |
---|---|
logger |
Genera información sobre la ejecución del correo si está disponible. Puede establecerse en nil para no registrar nada. Compatible con los loggers de Logger y Log4r de Ruby. |
smtp_settings |
Permite una configuración detallada para el método de entrega :smtp :
|
sendmail_settings |
Te permite anular opciones para el método de entrega :sendmail .
|
raise_delivery_errors |
Si se deben o no generar errores si el correo electrónico no se puede entregar. Esto solo funciona si el servidor de correo externo está configurado para entrega inmediata. Predeterminado es true . |
delivery_method |
Define un método de entrega. Los valores posibles son:
|
perform_deliveries |
Determina si las entregas se realizan realmente cuando se invoca el método deliver en el mensaje de correo. Por defecto, se realizan, pero esto se puede desactivar para ayudar en las pruebas funcionales. Si este valor es false , el array deliveries no se poblará incluso si delivery_method es :test . |
deliveries |
Mantiene un array de todos los correos electrónicos enviados a través de Action Mailer con el método de entrega :test . Más útil para pruebas unitarias y funcionales. |
delivery_job |
La clase de trabajo utilizada con deliver_later . Predeterminado es ActionMailer::MailDeliveryJob . |
deliver_later_queue_name |
El nombre de la cola utilizada con el trabajo de entrega predeterminado. Predeterminado es la cola de Active Job por defecto. |
default_options |
Te permite establecer valores predeterminados para las opciones del método mail (:from , :reply_to , etc.). |
Para una descripción completa de las configuraciones posibles, consulta la Configuración de Action Mailer en nuestra guía de Configuración de Aplicaciones Rails.
5.1 Ejemplo de Configuración de Action Mailer
Un ejemplo sería agregar lo siguiente a tu archivo config/environments/$RAILS_ENV.rb
apropiado:
config.action_mailer.delivery_method = :sendmail
# Defaults to:
# config.action_mailer.sendmail_settings = {
# location: '/usr/sbin/sendmail',
# arguments: %w[ -i ]
# }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_options = { from: 'no-reply@example.com' }
5.2 Configuración de Action Mailer para Gmail
Action Mailer usa la gema Mail y acepta una configuración similar. Agrega esto a tu archivo config/environments/$RAILS_ENV.rb
para enviar a través de Gmail:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'example.com',
user_name: '<username>',
password: '<password>',
authentication: 'plain',
enable_starttls: true,
open_timeout: 5,
read_timeout: 5 }
Si estás usando una versión antigua de la gema Mail (2.6.x o anterior), usa enable_starttls_auto
en lugar de enable_starttls
.
NOTA: Google bloquea los inicios de sesión desde aplicaciones que considera menos seguras. Puedes cambiar la configuración de tu Gmail aquí para permitir los intentos. Si tu cuenta de Gmail tiene habilitada la autenticación de dos factores, entonces necesitarás configurar una contraseña de aplicación y usarla en lugar de tu contraseña regular.
6 Pruebas de Mailer
Puedes encontrar instrucciones detalladas sobre cómo probar tus mailers en la guía de pruebas.
7 Interceptando y Observando Correos Electrónicos
Action Mailer proporciona ganchos en los métodos de observador e interceptor de Mail. Estos te permiten registrar clases que se llaman durante el ciclo de vida de entrega de correo de cada correo electrónico enviado.
7.1 Interceptando Correos Electrónicos
Los interceptores te permiten hacer modificaciones a los correos electrónicos antes de que se entreguen a los agentes de entrega. Una clase de interceptor debe implementar el método ::delivering_email(message)
que se llamará antes de que se envíe el correo electrónico.
class SandboxEmailInterceptor
def self.delivering_email(message)
message.to = ['sandbox@example.com']
end
end
Antes de que el interceptor pueda hacer su trabajo, necesitas registrarlo usando la opción de configuración interceptors
. Puedes hacer esto en un archivo de inicialización como config/initializers/mail_interceptors.rb
:
Rails.application.configure do
if Rails.env.staging?
config.action_mailer.interceptors = %w[SandboxEmailInterceptor]
end
end
NOTA: El ejemplo anterior utiliza un entorno personalizado llamado "staging" para un servidor similar a producción pero para propósitos de prueba. Puedes leer Creando Entornos Rails para más información sobre entornos personalizados de Rails.
7.2 Observando Correos Electrónicos
Los observadores te dan acceso al mensaje de correo electrónico después de que ha sido enviado. Una clase de observador debe implementar el método :delivered_email(message)
, que se llamará después de que se envíe el correo electrónico.
class EmailDeliveryObserver
def self.delivered_email(message)
EmailDelivery.log(message)
end
end
Similar a los interceptores, debes registrar los observadores usando la opción de configuración observers
. Puedes hacer esto en un archivo de inicialización como config/initializers/mail_observers.rb
:
Rails.application.configure do
config.action_mailer.observers = %w[EmailDeliveryObserver]
end
Comentarios
Se te anima a ayudar a mejorar la calidad de esta guía.
Por favor contribuye si ves algún error tipográfico o errores fácticos. Para comenzar, puedes leer nuestra sección de contribuciones a la documentación.
También puedes encontrar contenido incompleto o cosas que no están actualizadas. Por favor agrega cualquier documentación faltante para main. Asegúrate de revisar Guías Edge primero para verificar si los problemas ya están resueltos o no en la rama principal. Revisa las Guías de Ruby on Rails para estilo y convenciones.
Si por alguna razón detectas algo que corregir pero no puedes hacerlo tú mismo, por favor abre un issue.
Y por último, pero no menos importante, cualquier tipo de discusión sobre la documentación de Ruby on Rails es muy bienvenida en el Foro oficial de Ruby on Rails.