2010-04-16 14 views
15

Me gustaría poder enviar una cadena de correos electrónicos en un intervalo determinado a diferentes destinatarios.Enviando correos electrónicos basados ​​en intervalos usando Ruby on Rails

Asigno a cada contacto esta serie de correos electrónicos llamada Campaña, donde Campaña tiene Correo electrónico1, Correo electrónico2, etc. Cada contacto tiene una fecha de contacto.start_date. Cada correo electrónico tiene email.days que almacena el número de días desde la fecha de inicio de un contacto para enviar el correo electrónico.

Por ejemplo: Email1.days = 5, Email2.days = 7, Email3.days = 11.

Contact1.start_date = 4/10/2010; contact2.start_date = 4/08/2010

SI hoy es 4/15, Contact1 recibe el correo electrónico 1 (4/15-4/10 = 5 días) SI hoy es 4/15, Contact2 recibió el correo electrónico 2 (4/15 - 4/8 = 7 días).

¿Cuál es una buena acción para ejecutar todos los días usando un trabajo cron que luego siga estas reglas para enviar correos electrónicos utilizando ActionMailer?

NOTA: La pregunta no se trata de usar ActionMailer. Se trata de hacer las "matemáticas" y la ejecución. ¿Qué correo electrónico enviar a quién? Supongo que tiene que ver con alguna versión de Date - Contact [x] .start_date y luego compararla con el correo electrónico [x] .days, pero no estoy exactamente claro cómo. Gracias.

Me gustaría obtener una guía sobre si usar date.today versus time.now también.

Nota: la intención es que una persona individual pueda necesitar programar un seguimiento individual de manera consistente. En lugar de tener que recordar cuándo seguir el correo electrónico con quién, simplemente seguiría una campaña predeterminada y enviaría a esa persona.

Por lo tanto, no es un "correo masivo": en realidad está automatizando el seguimiento de la correspondencia individual.

+0

@Angela, ¿quiere enviar estos correos electrónicos a cada contacto _every_ 'Email # {n} .days', o simplemente a _un_ contacto, una vez que' Email # {n} .days' haya pasado? Debido a que la solución de la que hemos estado hablando (la de @Jens) hasta el momento solo lo hace el _once_. –

+0

Sí, solo una vez por contacto. Entonces, una campaña consiste en Email1, Email2, Email3, cada uno con su propio correo electrónico.días – Angela

Respuesta

14

me gustaría utilizar DelayedJob para esto (suponiendo que no está enviando gran número de correos electrónicos correos electrónicos al día, es decir, 100 de los miles por día, etc.)

class Email < ActiveRecord::Base 
    belongs_to :campaign 
    after_create :schedule_email_dispatch 

    def schedule_email_dispatch 
    send_at(campaign.created_at + self.days.days, :send_email) 
    end 

    def send_email 
    end 
end 

Run los trabajadores mediante la tarea rake:

rake jobs:work 

Cada vez que se crea un nuevo objeto de correo electrónico, se agrega un elemento de trabajo retrasado a la cola. En el intervalo correcto, el correo electrónico será enviado por el trabajador.

@campaign = Compaign.new(...) 
@campaign.emails.build(:days => 1) 
@campaign.emails.build(:days => 2) 
@campaign.save # now the delay 

En el ejemplo anterior, se crearán dos entradas de trabajo diferidas después de guardar la campaña. Se ejecutan 1 y 2 días después de la fecha de creación de la campaña.

Esta solución garantiza que los correos electrónicos se envíen aproximadamente en el horario previsto. En una solución basada en cron job, la desaparición ocurre en los intervalos de cron. Puede haber varias horas de retraso entre el tiempo de envío previsto y el tiempo de envío real.

Si desea utilizar el enfoque cron haga lo siguiente:

class Email < ActiveRecord::Base 
    def self.dispatch_emails 
    # find the emails due for dispatch 
    Email.all(:conditions => ["created_at <= DATE_SUB(?, INTERVAL days DAY)", 
      Time.now]).each do |email| 
     email.send_email 
    end 
    end 
end 

En esta solución, la mayor parte del procesamiento es realizado por el PP.

Añadir email.rake archivo en lib/tasks directorio:

task :dispatch_emails => :environment do 
    Email.dispatch_emails 
end 

Configurar el cron para ejecutar rake dispatch_emails a intervalos regulares (en su caso < 24 horas)

+1

Esta es una manera genial de manejar el problema. La programación en el momento de la creación significa que no tiene que preocuparse por hacer los cálculos al tratar de determinar qué se debe ejecutar. Si el interlocutor no quiere usar DJ (para evitar la complejidad), aún podría hacer el mismo truco almacenando las fechas en que los correos deberían salir. Sin embargo, dado que ya se necesita la capacidad, apuesto a que el interlocutor la necesitará nuevamente en el futuro, por lo que también puede pagar el precio ahora. No olvides pasar un "designador de tipo" o algo similar a Email # build para que sepas qué correo electrónico deseas enviar. Desearía poder hacer múltiples votos al alza. – Sixty4Bit

+0

Interesante ... por lo tanto, cuando se crea un nuevo contacto (cada contacto se agregará en el futuro con una fecha de fecha de entrada diferente) ... ¿cómo me aseguro de que cada contacto reciba el correo electrónico en el intervalo apropiado? No solo son los correos electrónicos los que tienen intervalos variables, sino también los Contactos (destinatarios). – Angela

+0

Sí, echando un vistazo a esto, parece que hace referencia a las fechas de la campaña, pero no a las fechas de contacto individuales ... los contactos serían de miles ... cada uno con su propia fecha (muchos de ellos coincidentes), pero muchos no. – Angela

1

Creo que sería mucho más fácil y más seguro (no tiene que preocuparse por la autenticación, etc.) para crear una tarea de rake para enviar los correos electrónicos. Además, no tiene que preocuparse por una solicitud de ejecución posiblemente muy larga. Basta con crear un archivo RAILS_ROOT/lib/tareas/email.rake

namespace :email do 
    desc "Sends scheduled emails" 
    task :send_scheduled => :enviroment do 
    Email.send_scheduled_emails 
    end 
end 

y en RAILS_ROOT/app/email.rb

class Email < ActiveRecord::Base  
    # ... 

    def self.send_scheduled_emails 
    #send your emails ... 
    end 
end 

A continuación, crear una tarea programada

0 0 * * * user cd /your/rails/app/ && RAILS_ENV=production rake emais:send_scheduled 

para enviar los correos electrónicos todas las noches a las 12:00.

+0

Votado abajo porque no muestra cómo determinar cuándo enviar cada tipo de correo electrónico. – Sixty4Bit

+0

Derecha: necesito saber qué correo electrónico y cuándo enviarlo ... diferentes contactos tienen diferentes fechas de inicio. Puedo calcular un intervalo y proponer una situación en la que el intervalo = 0 ... pero tendría que recorrer cada contacto y todos los eventos de la campaña. – Angela

6

me gustaría crear una tarea rake en RAILS_ROOT/lib/tareas/email.rake

namespace :email do 
    desc "send emails to contacts" 
    task :send do 
    Email.all.each do |email| 
     # if start_date is a datetime or timestamp column 
     contacts = Contact.all(:conditions => ["DATE(start_date) = ?", email.days.days.ago.to_date]) 
     # if start_date is a date column 
     contacts = Contact.all(:conditions => { :start_date => email.days.days.ago.to_date }) 
     contacts.each do |contact| 
     #code to send the email 
     end 
    end 
    end 
end 

Entonces me gustaría utilizar una tarea programada para llamar a esta tarea rake cada día una t 3 a.m .:

0 3 * * * app_user cd RAILS_APP_FOLDER && RAILS_ENV=production rake email:send 
+0

@Angela, este tiene el cálculo de comparación de fecha que usted quería. 'email.days' => decir, 5,' 5.days.ago.to_date' => cualquier fecha es hace cinco días. –

+0

@Jens Fahnenbruck: ': start_date, email.days.days.ago.to_date' debe ser': start_date => email.days.days.ago.to_date' –

+0

@Tim Snowhite .... ah, está bien, lo necesito para digerir email.days.days.ago.to_date ... ¿dónde puedo ir a analizar eso? Me perdí después de email.days .... – Angela

1

estoy usando rufus-planificador para el correo electrónico programado y Twitter actualizaciones. Deberías verificarlo.

Cuestiones relacionadas