Ruby on Rails email scheduling using runner and cron
Posted by admin - 30/10/08 at 11:10:00 amProblem
You want to send emails from a Ruby on Rails application, when there is a specific condition on a database table. If the database table gets modified by another application outside Rails you cannot use an observer model.
Solution
We already assume that:
- You are using a database
- You have a model named voicemail (id, number_id, audio, created_at, updated_at)
- You have a model named number (id, voicemail_email_set, voicemail_email, ….)
- A mail server to use (smtp in our case)
- Another application (voice application) populates the voicemail table but with empty updated_at values
So the steps we have to follow are:
- Change the settings in your config/environment.rb file to use the settings for your mail server, and make sure you restart your application after the changes:
ActionMailer::Base.smtp_settings = { :address => "yourmailserver.com", :port => 25, :domain => "your.domain.com", :authentication => :login, :user_name => "your_smtp_username", :password => "your_smtp_password", :raise_delivery_errors => true} - Create your mailer model (ie voicemail_mailer.rb), in app/models:
class VoicemailMailer "application/wav", :disposition => "attachment; filename=#{file_name}", :transfer_encoding => "base64") do |attachment| attachment.body = tmp_file end end end - Create your email scheduler in file lib/email_scheduler.rb:
#!/usr/bin/env /path_to_your_app/script/runner # get all the voicemails that have not been sent yet voicemails_to_email = VoiceMail.find(:all, :conditions => 'updated_at is null') # For all the voicemails we have, send them and update the field date_sent for vm2email in voicemails_to_email do # Get the number for the voicemail number = Number.find(vm2email.number_id) # check to see if the send to email is set for the number if number.voicemail_email_set # Get number details (email_to,email_from etc) email_to = number.voicemail_email voicemail_to_send = vm2email.audio # Set other details email_from = 'Service@yourdomain.com' email_subject = 'Please find attached your voicemail message' email_body = "Received on: #{Time.now} \n for number: #{number.phone_no}" # Now send the email VoicemailMailer.deliver_sent(email_to,email_from,email_subject,email_body,voicemail_to_send) # And update the record's date_sent field vm2email.updated_at = Time.now vm2email.save end end - Create a task in your crontab that runs the scheduler (every five minutes):
0,5,10,15,20,25,30,35,40,45,50,55 * * * * path_to_your_ror_app/lib/email_scheduler.rb
October 30, 2008 | In linux |
1 Comment »
RSS feed for comments on this post. TrackBack URI
Leave a comment








Very useful. Also note that you can simplify your cron job by specifying “*/5″ instead of “0,5,10,15,20,etc…”.
Comment by codemer — February 9, 2006 #