2010-04-16 2 views
15

J'aimerais pouvoir envoyer une série de courriels à intervalles déterminés à différents destinataires.Envoi de courriels basés sur des intervalles à l'aide de Ruby on Rails

J'attribue à chaque contact cette série de courriels appelée Campagne, où Campagne a Email1, Email2, etc. Chaque contact a un Contact.start_date. Chaque email a email.days qui stocke le nombre de jours depuis la date de début d'un contact pour envoyer l'email.

Par exemple: Email1.days = 5, Email2.days = 7, Email3.days = 11.

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

SI aujourd'hui c'est 4/15, puis Contact1 reçoit Email 1 (4/15-4/10 = 5 jours) SI aujourd'hui c'est 4/15, puis Contact2 reçu Email 2 (4/15 - 4/8 = 7 jours).

Quelle est une bonne action à exécuter tous les jours à l'aide d'un travail cron qui suivrait ces règles pour envoyer des courriels à l'aide d'ActionMailer?

REMARQUE: La question ne concerne pas l'utilisation d'ActionMailer. Il s'agit de faire le "math" ainsi que l'exécution. Quel email envoyer à qui? Je devine que cela a à voir avec une version de Date - Contact [x] .start_date, puis comparez avec l'email [x] .days mais je ne comprends pas exactement comment. Merci.

Je voudrais savoir si utiliser date.today par rapport à time.now maintenant.

Note: l'intention est qu'une personne individuelle peut avoir besoin de planifier un suivi individuel sur une base cohérente. Plutôt que de devoir se rappeler quand faire un suivi avec qui, il suivrait simplement une campagne prédéterminée et l'enverrait pour cette personne.

Il ne s'agit donc pas d'un «courrier en nombre» - il automatise vraiment le suivi de la correspondance individuelle.

+0

@ Angela, voulez-vous envoyer ces courriels à chaque contact _every_ 'Email # {n} .days', ou juste _once_ par contact, après que' Email # {n} .days' soit passé? Parce que la solution dont nous avons déjà parlé (@Jens) ne fait que le _once_. –

+0

Oui, une seule fois par contact. Ainsi, une campagne se compose de Email1, Email2, Email3, chacun avec leur propre Emailn.days – Angela

Répondre

14

J'utiliser DelayedJob pour cela (en supposant que vous n'êtes pas d'envoyer un grand nombre d'e-mails e-mails par jour, soit 100 de milliers par jour, 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 

Exécutez les travailleurs en utilisant la tâche rake:

rake jobs:work 

Chaque fois qu'un nouvel objet E-mail est créé, un élément de travail retardé est ajouté à la file d'attente. À l'intervalle correct, le courrier électronique sera envoyé par le travailleur.

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

Dans l'exemple ci-dessus, deux tâches retardées seront créées après l'enregistrement de la campagne. Ils sont exécutés 1 et 2 jours après la date de création de la campagne.

Cette solution garantit que les courriels sont envoyés environ aux heures prévues. Dans une solution cron basée sur le travail, le détachement se produit aux intervalles cron. Il peut s'écouler plusieurs heures entre l'heure d'expédition prévue et l'heure d'expédition réelle.

Si vous voulez utiliser l'approche Cron procédez comme suit:

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 

Dans cette solution, la plupart du traitement se fait par la DB.

Ajouter email.rake fichier lib/tasks répertoire:

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

Configurer le cron pour exécuter rake dispatch_emails à intervalles réguliers (dans votre cas < 24 heures)

+1

C'est une façon cool de gérer le problème. La planification au moment de la création signifie que vous n'avez pas à vous soucier de faire le calcul en essayant de déterminer ce qui doit être exécuté. Si le questionneur ne veut pas utiliser DJ (pour éviter la complexité), il pourrait toujours faire le même tour en stockant les dates auxquelles les emails devraient sortir. Cependant, puisque vous avez déjà besoin de la capacité, je parie que le questionneur en aura besoin à l'avenir, donc peut aussi bien payer le prix maintenant. N'oubliez pas de transmettre un "identificateur de type" ou quelque chose à l'adresse email # build afin que vous sachiez quel email envoyer. J'aimerais pouvoir faire plusieurs votes. – Sixty4Bit

+0

Intéressant .... alors quand un nouveau contact est créé (chaque contact sera ajouté dans le futur avec une date date_entrée différente) ... comment puis-je m'assurer que chaque contact reçoit l'email à l'intervalle approprié. Ce ne sont pas seulement les emails qui ont des intervalles variables, mais aussi les contacts (destinataires). – Angela

+0

Oui, écrémé cela, il semble que ce soit le référencement des dates de la campagne, mais pas les dates de contact individuel ... les contacts seraient dans les milliers .... chacun avec leur propre date (beaucoup d'entre eux coïncident), mais beaucoup ne pas. – Angela

1

Je pense que ce serait beaucoup plus facile et plus sûr (vous n'avez pas à vous soucier de l'authentification, etc.) pour créer une tâche de rake pour envoyer les emails. De plus, vous n'avez pas à vous soucier d'une éventuelle demande de fonctionnement très longue. Il suffit de créer un fichier RAILS_ROOT/lib/tâches/email.rake

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

et RAILS_ROOT/app/email.rb

class Email < ActiveRecord::Base  
    # ... 

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

Ensuite, créez une tâche cron

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

envoyer les emails tous les soirs à 12:00.

+0

Abandonné parce qu'il ne montre pas comment déterminer quand envoyer chaque type d'Email. – Sixty4Bit

+0

Droite: J'ai besoin de savoir quel e-mail et quand l'envoyer ... différents contacts ont des dates de début différentes. Je peux calculer un intervalle et arriver à une situation où l'intervalle = 0 ... mais je devrais traverser chaque contact et à travers tous les événements de la campagne. – Angela

6

Je voudrais créer une tâche de râteau dans RAILS_ROOT/lib/tasks/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 

Ensuite, je voudrais utiliser un cronjob pour appeler cette tâche de rake tous les jours un t 3 a.m .:

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

@Angela, Cela a le calcul de comparaison de la date que vous vouliez. 'email.days' => say, 5,' 5.days.ago.to_date' => quelle que soit la date il y a cinq jours. –

+0

@Jens Fahnenbruck: ': start_date, email.days.days.ago.to_date' devrait être': start_date => email.days.days.ago.to_date' –

+0

@Tim Snowhite .... ah, d'accord, j'ai besoin digérer email.days.days.ago.to_date ... où puis-je aller pour analyser cela? Je me suis perdu après email.days .... – Angela

1

J'utilise rufus-programmateur pour le courrier électronique prévu et Twitter mises à jour. Vous devriez le vérifier.