Ruby on Rails desde Cero: Enviar emails (ActionMailer)

Publicado el 01 noviembre 2013 por Codehero @codeheroblog

Configuración del remitente

Lo primero que debemos hacer, una vez tengamos nuestro proyecto en Rails creado, es configurar los datos del servidor de correo que estemos utilizando para enviar emails. Para este caso agregaremos la configuración al final del archivo development.rb, ubicado en la ruta dentro del proyecto /config/environments resultando algo como esto:

/config/environments/development.rb

config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'gmail.com', user_name: 'ejemplo@gmail.com', password: 'secret', authentication: 'plain', enable_starttls_auto: true }

123456789 configaction_mailerdelivery_method=:smtpconfigaction_mailersmtp_settings={  address:  'smtp.gmail.com',  port:   587,  domain:   'gmail.com',  user_name:  'ejemplo@gmail.com',  password:   'secret',  authentication:   'plain',  enable_starttls_auto:true  }

Esta configuración esta diseñada para enviar correos desde gmail como prueba para verificar que funcione. Recuerde agregar su domain, user_name y su password para que funcione el ejemplo.


Generando nuestra clase de correos (Mailer)

Una vez configurado nuestro servidor de correos en el proyecto, procedemos a crear nuestra clase encargada de la gestión de los emails. Esta clase se comporta casi como una clase del controlador, donde preparamos todos los datos del correo e incluso agregamos vistas que serán manipuladas por nuestra clase(mailer) igual que los controladores. Estas vistas alojan el contenido del correo electrónico. Veamos como crear esta clase con una simple línea de comando.

Nos ubicamos con la consola o terminal en el directorio de nuestro proyecto y escribimos la siguiente línea:

rails generate mailer ActionCorreo

1 rails generate mailer ActionCorreo

Este comando nos crea una lista de archivos y carpetas que vamos a utilizar para poder enviar correos. La lista de estos archivos la verán cuando ejecuten el comando y debería ser algo como esto:

create app/mailers/action_correo.rb invoke erb create app/views/action_correo invoke test_unit create test/mailers/action_correo_test.rb

12345 create  app/mailers/action_correorbinvoke  erbcreate  app/views/action_correoinvoke  test_unitcreate  test/mailers/action_correo_testrb

Como ven, nos crea dentro de nuestra aplicación una carpeta mailers y dentro de ella nuestro archivo Ruby (action_correo.rb) que se puede ver como un controlador para enviar correos. Este archivo debe contener algo parecido a este código:

app/mailers/action_correo.rb

class UserMailer < ActionMailer::Base default from: 'from@example.com' end

123 classUserMailer&lt;ActionMailer::Base  defaultfrom:'from@example.com'end

También vemos que el comando nos crea una carpeta dentro de las vista donde alojaremos los archivos con el contenido de los correos electrónicos (Esto lo veremos un poco más avanzado el tutorial).

Correo electrónico simple

Una vez creado nuestro Mailer, le vamos a agregar un método, el cual será el encargado de enviar nuestro primer correo electrónico desde Ruby on Rails. Este será un correo simple sin adjuntos, sólo texto html y un único destinatario. Primero, creamos un método dentro de nuestro Mailer de la siguiente manera:

def bienvenido_email(user) @user = user @url = 'http://codeHero.co' mail(to: @user.email, subject: 'Aprende a programar con nuestros cursos gratis') end

12345 def bienvenido_email(user)   @user=user   @url  ='http://codeHero.co'   mail(to:@useremail,subject:'Aprende a programar con nuestros cursos gratis')end

Como ven, el método recibe una variable que en nuestro caso es un objeto usuario, luego definimos las variables que utilizaremos para armar el contenido del mensaje y por último ejecutamos la función de envío de correos, agregándoles el correo destinatario y el título de nuestro email.

Una vez creado el método agregamos un archivo a la carpeta de las vistas que se creo en el paso anterior, donde vamos a desarrollar el contenido del correo electrónico. Este archivo lo llamaremos igual que el método del Mailer bienvenido_email.html.erb (como se dieron cuenta, aplica la misma teoría que un controlador normal). La ruta y el contenido del correo electrónico es el siguiente.

/views/action_correo/bienvenido_email.html.erb

¡Listo! Ya tenemos configurado nuestra clase para enviar un correo electrónico, sólo nos queda implementarlo en nuestro controlador normal del proyecto. Pudiera ser de la siguiente manera: Creando un método dentro de un controlador, que cree, envíe por correo electrónico y muestre en formato JSON el usuario

def enviarCorreo #Creamos el usuario @persona1 = Persona.create({ nombre: 'Ricardo Sampayo', email: 'me@ricardoSampayo.com',email_confirmation: 'me@ricardoSampayo.com"', identificador: "123456789", sexo: 'm', telefono: '123456789123' }) # Llamamos al ActionMailer que creamos ActionCorreo.bienvenido_email(@persona1).deliver # mostramos el usuario en formato JSON render json: @persona1 end

12345678910 def enviarCorreo  #Creamos el usuario     @persona1=Personacreate({nombre:'Ricardo Sampayo',email:'me@ricardoSampayo.com',email_confirmation:'me@ricardoSampayo.com"',identificador:"123456789",sexo:'m',telefono:'123456789123'})    # Llamamos al   ActionMailer que creamos  ActionCorreobienvenido_email(@persona1)deliver    # mostramos el usuario en formato JSON  render json:@persona1  end

Al ejecutar este método nos debe llegar un correo electrónico como este:

Correo electrónico con archivo adjunto y múltiples usuarios

También es bastante fácil enviar correos con archivos adjuntos en Ruby on Rails, lo único que debemos hacer es agregarle en el Mailer los archivos adjuntos de la siguiente forma:

attachments["codehero.png"] = File.read("#{Rails.root}/public/codehero.png")

1 attachments["codehero.png"]=Fileread("#{Rails.root}/public/codehero.png")

Como ven es bastante fácil añadir un adjunto, tan sólo hay que añadir una nueva llamada a attachments, poniendo como clave el nombre del adjunto y pasando el archivo correspondiente.

Por otro lado agregar múltiples destinatarios es igual de sencillo que todos los procedimientos que hemos visto en el framework, simplemente, los tenemos que agregar de la siguiente forma:

email_with_name = "#{@user.nombre} <#{@user.email}>" email_with_name2 = "Ricardo < test@ricardosampayo.com>" email_with_name3 = "Ricardo < test2@ricardosampayo.com>" email_with_name4 = "Ricardo < test3@ricardosampayo.com>" mail(to: [email_with_name, email_with_name3], bcc: email_with_name2, cc: email_with_name4, subject: 'Aprende a programar con nuestros cursos gratis')

123456789 email_with_name="#{@user.nombre} <#{@user.email}>"  email_with_name2="Ricardo < test@ricardosampayo.com>"  email_with_name3="Ricardo < test2@ricardosampayo.com>"  email_with_name4="Ricardo < test3@ricardosampayo.com>"   mail(to:[email_with_name,email_with_name3],  bcc:email_with_name2,  cc:email_with_name4,  subject:'Aprende a programar con nuestros cursos gratis')

En el ejemplo, vemos como estamos enviando el correo directamente a dos usuarios, por otro lado, también agregamos dos usuarios más con copia y con copia oculta respectivamente.


Interceptar Correos

Hay situaciones en las que se necesita interceptar un correo antes de ser enviado para hacerle algunos ajustes, como por ejemplo: cambiarle el asunto o agregarle algún nuevo destinatario. Afortunadamente, AcciónMailer proporciona una herramienta para interceptar cada correo electrónico. Veamos cómo hacemos esto:

Lo primero que debemos hacer es crear la clase interceptadora. Esta clase podría ir en el directorio /lib, y le pondremos el nombre development_mail_interceptor.rb.

class DevelopmentMailInterceptor def self.delivering_email(message) message.to = "test99@ricardosampayo.com" end end

12345 classDevelopmentMailInterceptor    def selfdelivering_email(message)    messageto="test99@ricardosampayo.com"    end  end  

El método de clase delivering_email recibe el mensaje de correo que está a punto de ser enviado y cambia la persona a la que iba dirigido el correo.

Antes de que el interceptor pueda hacer su trabajo, es necesario registrar el interceptor, esto se puede hacer en un archivo de inicialización en config/initializers/ el cual llamaremos setup_mail.rb

Mail.register_interceptor(DevelopmentMailInterceptor) if Rails.env.development?

1 Mailregister_interceptor(DevelopmentMailInterceptor)ifRailsenvdevelopment?  

Esto invocará al método delivering_email en nuestro interceptador, si nuestra aplicación está en modo de desarrollo. Usted puede leer sobre la creación de entornos Rails para obtener más información sobre los entornos personalizados.


Conclusión

En esta lección hemos estudiado cómo se envían correos electrónicos desde nuestras aplicaciones en Ruby on Rails, como siempre demostrado en ejemplos, para agilizar su proceso de aprendizaje probándolo usted mismo.

Una vez más te recomiendo echarle un vistazo a la serie completa de Ruby on Rails desde cero, así como a las otras series de CodeHero, agradeciendo de antemano todas sus dudas y comentarios en la sección de comentarios.

¡Hasta el próximo capítulo!