Send automatic email reminders

Closes #4
This commit is contained in:
ricola 2026-03-23 18:26:32 -06:00
parent ecb4f16ec5
commit d5f77d338b
7 changed files with 50 additions and 2 deletions

View file

@ -25,3 +25,8 @@ desc "Close votes that have expired"
task :close_expired_votes do
close_expired_votes
end
desc "Send email reminders"
task :send_reminders do
send_reminders
end

View file

@ -6,3 +6,5 @@ set :values, [ { :id => 1, :label => _("Awful"), :color => '#ff4500' },
{ :id => 5, :label => _("Good"), :color => '#228b22' },
{ :id => 6, :label => _("Very good"), :color => '#006400' } ]
set :expire_after, 7 * 24 * 60 * 60 # 7 days
set :reminders, [ { :timeout => 48 * 60 * 60 },
{ :timeout => 24 * 60 * 60 } ]

View file

@ -6,4 +6,5 @@ set :environment_variable, 'RACK_ENV'
every 5.minutes do
rake "close_expired_votes"
rake "send_email_reminders"
end

View file

@ -0,0 +1,5 @@
class AddRemindersToVotes < ActiveRecord::Migration[7.2]
def change
add_column :votes, :reminders, :integer
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2025_06_08_223006) do
ActiveRecord::Schema[7.2].define(version: 2026_03_23_215246) do
create_table "candidates", force: :cascade do |t|
t.integer "vote_id"
t.string "name"
@ -56,6 +56,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_06_08_223006) do
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "state"
t.integer "reminders"
end
add_foreign_key "ratings", "votes"

View file

@ -268,6 +268,7 @@ post '/admin/votes/:id' do
if (@vote.state == 'open' or @vote.state == 'closed') and new_expiry > Time.now
puts "change"
@vote.expire_on = new_expiry
@vote.reminders = 0
@vote.state = 'open'
@vote.save
end
@ -589,7 +590,7 @@ def close_expired_votes
mail = Mail.new
mail.from = settings.admin_email
mail.to = user.email
mail.subject = _("Results of the vote: %{t}") % { t: vote.title }
mail.subject = _("Results of the vote '%{t}'") % { t: vote.title }
template = ERB.new(File.read("views/votes_close_email.erb"))
mail.body = template.result(binding)
mail.deliver
@ -597,6 +598,34 @@ def close_expired_votes
end
end
def send_reminders
Vote.where(state: 'open').each do |vote|
settings.reminders.slice(vote.reminders..settings.reminders.length-1).each do |reminder|
minutes_to_expiry = ( vote.expire_on - Time.now.utc ) / 60
if minutes_to_expiry < reminder[:timeout] / 60
User.all.each do |user|
if not vote.ratings.collect { |rating| rating.user }.include?(user)
puts "#{Time.now.utc} Sending reminder #{reminder[:template]} for '#{vote.title}' to #{user.email}..."
mail = Mail.new
mail.from = settings.admin_email
mail.to = user.email
if minutes_to_expiry < 60
mail.subject = _("%{m} minutes left to vote on '%{t}'") % { m: minutes_to_expiry.round, t: vote.title }
else
mail.subject = _("%{h} hours left to vote on '%{t}'") % { h: (minutes_to_expiry / 60).round, t: vote.title }
end
template = ERB.new(File.read("views/votes_reminder_email.erb"))
mail.body = template.result(binding)
mail.deliver
end
end
vote.reminders = vote.reminders + 1
vote.save
end
end
end
end
helpers do
def current_user
if session[:user_id]

View file

@ -0,0 +1,5 @@
<%= _("You haven't voted yet!") %>
<%= _("Visit this link to vote:") %>
<%= "#{settings.base_url}votes/#{vote.secure_id}" %>