IT & Engineering
Cómo crear un enfoque basado en datos para mantener actualizados los emails de tu base de usuarios
Este blog fue escrito por Roy Young. Roy es especialista en desarrollo de Ruby y está perfeccionando sus skills en Tealeaf Academy.
Ah, la tabla de “usuarios”.
Este blog fue escrito por Roy Young. Roy es especialista en desarrollo de Ruby y está perfeccionando sus skills en Tealeaf Academy.
Ah, la tabla de “usuarios”.
Se podría decir que es uno de los activos más importantes de una startup. Quienes pecan de cinismo no pueden creer que Instagram (¡una app para compartir fotos!) se haya comprado por 715 millones de $ por Facebook o que se rumoreara que Mailbox, un cliente de email móvil para Gmail (y todavía en fase beta en muchos aspectos), fuera comprada por hasta 100 millones de $ por Dropbox.
Esta visión cínica suele ser el resultado de un enfoque miope centrado solo en el producto o la tecnología, lo que facilita que estas valoraciones se descarten por absurdas. Sin embargo, también hay que tener en cuenta el valor de la totalidad de su base de usuarios y su crecimiento. Estas valoraciones astronómicas siempre van de la mano de un producto que cuenta con una base de usuarios grande y de rápido crecimiento. Por lo tanto, es lógico pensar que mantener la tabla de usuarios actualizada con la información de contacto correcta es una buena inversión para tu negocio. Por supuesto, la parte difícil es crear ese crecimiento… así que tendrás que pagar por esa información.
Sin embargo, este consejo sobre la “parte fácil” es gratis. En esta publicación, hablaré sobre una buena metodología para mantener actualizado el email de tu base de usuarios en una época en la que mucha gente tiene múltiples direcciones de email y cuentas desechables para muchos de sus servicios.
Lógica de la aplicación para solicitar la actualización de la dirección de email
Cuando envías un email a una dirección de email que ya no existe, la parte receptora (por ejemplo, Gmail o Yahoo) te devolverá el email con un rebote. Si prestas atención a estos rebotes, tu app puede reaccionar de forma adecuada, lo que crea una gran experiencia de usuario a la vez que mantiene actualizada tu base de datos de clientes. Este blog describe una aplicación de muestra creada en Heroku que utiliza Mailgun para escuchar estos emails devueltos, de modo que quienes tengan direcciones de email no válidas puedan seguir recibiendo sus emails de facturas mensuales. Sin embargo, esta misma lógica podría aplicarse a cualquiera de tus emails, para asegurarte de que tu base de usuarios se mantenga interesada y al día con tu empresa por email.

He creado un sitio de demostración para este artículo y he dejado el código fuente disponible en Github. Esta demostración guía a principiantes por todo el proceso de configuración de esta funcionalidad. Haz clic aquí si quieres saltar directamente a la integración de los webhooks de rebote en tu app.
Envío de emails de facturas mensuales mediante Heroku Scheduler
Para enviar facturas mensuales a tu base de usuarios, tendrás que programar lo siguiente:
- Enviar emails de facturas personalizados a cientos, miles o millones de clientes.
- Programar el envío de estos emails.
Analicemos cada paso uno por uno.
Envío de emails de facturas personalizados
Para los fines de este tutorial, asumiré que ya tienes una cuenta de Mailgun. A partir de ahí, enviarás tu lista de clientes a Mailgun, junto con cualquier variable que quieras que se inserte dinámicamente en los emails mediante un archivo JSON, además del cuerpo en HTML o texto del email. Aquí tienes el código.
class MailgunGateway include Rails.application.routes.url_helpers def send_batch_message(users) RestClient.post(messaging_api_end_point, from: "Mailgun Demo ", to: users.map(&:email).join(", "), subject: "Monthly Billing Info", html: billing_info_text, :"h:Reply-To" => "billing@#{ENV["mailgun_domain_name"]}", :"recipient-variables" => recipient_variables(billing_recipients) ) end private def api_key @api_key ||= ENV["mailgun_api_key"] end def messaging_api_end_point @messaging_api_end_piont ||= "https://api:#{api_key}@api.mailgun.net/v2/#{ENV["mailgun_domain_name"]}/messages" end def billing_recipients @users ||= User.where(locked: false) end def recipient_variables(recipients) vars = recipients.map do |recipient| ""#{recipient.email}": {"name":"#{recipient.fullname}"}" end "{#{vars.join(', ')}}" end def billing_info_text <<-EMAIL Hi %recipient.name%, <p> Your bill for the current month is now available, please click on <br /> #{billing_url} <br /> to see details. </p> <p>Reply to this email directly</p> EMAIL end end
Veamos lo que hemos hecho.
En el método sendbatchmessages, utilizamos variables de destinatario para poder definir variables con las que personalizar cada email. Notarás que insertamos el nombre del usuario en el email. Podrías redactar un email de factura que incluya detalles como el número de cuenta, la cuenta de la factura o cualquier otra cosa que te interese, pero yo voy a simplificarlo.
Envío de emails automáticos de facturación mensual con Heroku Scheduler
Una vez que tengamos nuestro método para crear y enviar emails a través de Mailgun, tenemos que escribir un código que active automáticamente este método. He elegido desplegar esta app en Heroku y estoy utilizando Heroku Scheduler porque cumple su función, es un complemento gratuito y es fácil de integrar.
Heroku Scheduler ejecutará una tarea Rake específica a una hora determinada. Así que aquí tenemos que crear una tarea Rake para enviar emails de facturación mediante Mailgun en lib/tasks/scheduler.rake.
En primer lugar, cuando enviamos facturas a los usuarios, necesitamos encontrar las direcciones de email de los clientes a los que tenemos que facturar.
En el sencillo esquema de base de datos de esta app de muestra, tenemos un atributo :locked que se establece en True cuando un email ha tenido un rebote previamente (hablaremos de esto más adelante). Por tanto, nuestra consulta simplemente extrae todos los perfiles de nuestra base de usuarios en los que este campo es False.
Para enviar de verdad el email, voy a usar Mailgun Envío por lotes. Como el número máximo de destinatarios que se permite por llamada a la API es de 1000, utilizamos findinbatches para enviar a Mailgun los emails de facturación en lotes de 1000 destinatarios.
desc "This task is called by the Heroku scheduler add-on"
task :send_billing_info => :environment do
if DateTime.now.mday == 1
User.where(locked: false).find_in_batches(batch_size: 1000) do |group|
MailgunGateway.new.send_batch_message(group)
end
end
end
Debido a que los ajustes de la “FRECUENCIA” de Heroku Scheduler solo tienen tres selectores (“daily”, “hourly” y “every 10 mins”), debemos comprobar si el día actual es el primer día del mes mediante if DateTime.now.mday == 1. Si es así, se envía el email. Si no, no hay email.
Recepción de notificaciones de emails con rebotes
Cuando un email sufre un rebote, Mailgun enviará un POST a través del webhook de rebote a nuestra app. Tienes que configurar la URL de devolución de llamada en la sección “Bounces” del Panel de control de Mailgun. En esta demostración, mi URL de devolución de llamada es “http://mailgun-demo.herokuapp.com/api/bounced_mails”
Cuando la app recibe la notificación de rebote, buscará la dirección de email en la base de datos de clientes y establecerá el estado del usuario como bloqueado (locked), de modo que la app no le envíe el email de facturación hasta que actualice su dirección de email.
class Api::BouncedMailsController < ApplicationController
skip_before_filter :verify_authenticity_token
def create
if verify(ENV["mailgun_api_key"], params[:token], params[:timestamp], params[:signature])
user = User.find_by_email(params[:recipient])
if user && params[:event] == "bounced"
user.lock!
end
head(200)
end
end
private
def verify(api_key, token, timestamp, signature)
signature == OpenSSL::HMAC.hexdigest(
OpenSSL::Digest::Digest.new('sha256'),
api_key,
'%s%s' % [timestamp, token])
end
end
El user.lock! sirve para establecer el estado del usuario como bloqueado, para que nuestra tarea Rake nunca envíe emails a este usuario. Este método se establece en el modelo User.
class User < ActiveRecord::Base
…
def lock!
self.locked = true
save(validate: false)
end
end
El método verify sirve para comprobar que el webhook procede de Mailgun; de lo contrario, cualquiera podría enviar un POST falso para bloquear a los usuarios en tu app.
Para obtener más detalles sobre la configuración de los webhooks, puedes consultar la documentación de Mailgun: Eventos/Webhooks.
Al final, devolvemos un encabezado 200 para indicarle a Mailgun que esta interacción se ha realizado con éxito; de lo contrario, Mailgun pensará que nuestro servidor está caído y seguirá intentando llamar a nuestro webhook.
Una vez que la app sabe qué usuarios tienen una dirección de email no válida, debemos mostrarles una pantalla flash tras su siguiente inicio de sesión, con un aviso para verificar la información de contacto registrada.
class SessionsController < ApplicationController
def new
redirect_to home_path if current_user
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
if user.locked
flash[:error] = "Your Email Address is invalid, please update it."
redirect_to edit_user_path(current_user)
else
redirect_to home_path
end
else
flash[:error] = "Incorrect email or password. Please try again."
redirect_to sign_in_path
end
end
def destroy
session[:user_id] = nil
redirect_to root_path
end
end
En cuanto hayan actualizado su dirección de email, volveremos a establecer el atributo “locked” en false para que sigan recibiendo emails.
Ya está. Ahora, cuando reboten los emails de tu base de usuarios, puedes pedirles que actualicen su información. Así les brindarás una gran experiencia de usuario, con la ventaja añadida de mantener actualizados los datos de tus clientes.