diff --git a/app/models/user.rb b/app/models/user.rb
index 9459db7fe4..892a07bba0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -170,6 +170,10 @@ class User < ApplicationRecord
settings.default_privacy || (account.locked? ? 'private' : 'public')
end
+ def allows_digest_emails?
+ settings.notification_emails['digest']
+ end
+
def token_for_app(a)
return nil if a.nil? || a.owner != self
Doorkeeper::AccessToken
diff --git a/app/workers/digest_mailer_worker.rb b/app/workers/digest_mailer_worker.rb
index 028db89a9a..21f1c357a0 100644
--- a/app/workers/digest_mailer_worker.rb
+++ b/app/workers/digest_mailer_worker.rb
@@ -9,7 +9,7 @@ class DigestMailerWorker
def perform(user_id)
@user = User.find(user_id)
- deliver_digest if user_receives_digest?
+ deliver_digest if @user.allows_digest_emails?
end
private
@@ -18,8 +18,4 @@ class DigestMailerWorker
NotificationMailer.digest(user.account).deliver_now!
user.touch(:last_emailed_at)
end
-
- def user_receives_digest?
- user.settings.notification_emails['digest']
- end
end
diff --git a/app/workers/scheduler/email_scheduler.rb b/app/workers/scheduler/email_scheduler.rb
new file mode 100644
index 0000000000..24d0c0ebef
--- /dev/null
+++ b/app/workers/scheduler/email_scheduler.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+require 'sidekiq-scheduler'
+
+class Scheduler::EmailScheduler
+ include Sidekiq::Worker
+
+ def perform
+ eligible_users.find_each do |user|
+ next unless user.allows_digest_emails?
+ DigestMailerWorker.perform_async(user.id)
+ end
+ end
+
+ private
+
+ def eligible_users
+ User.confirmed
+ .joins(:account)
+ .where(accounts: { silenced: false, suspended: false })
+ .where(disabled: false)
+ .where('current_sign_in_at < ?', 20.days.ago)
+ .where('last_emailed_at IS NULL OR last_emailed_at < ?', 20.days.ago)
+ end
+end
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index ff1a40ccd0..143daaa298 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -4,7 +4,7 @@ en:
hints:
defaults:
avatar: PNG, GIF or JPG. At most 2MB. Will be downscaled to 120x120px
- digest: Sent after a long period of inactivity with a summary of mentions you've received in your absence
+ digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence
display_name:
one: 1 character left
other: %{count} characters left
diff --git a/config/sidekiq.yml b/config/sidekiq.yml
index 4c35dcd43a..bfe29b8f81 100644
--- a/config/sidekiq.yml
+++ b/config/sidekiq.yml
@@ -27,3 +27,6 @@
ip_cleanup_scheduler:
cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *'
class: Scheduler::IpCleanupScheduler
+ email_scheduler:
+ cron: '0 10 * * 2'
+ class: Scheduler::EmailScheduler
diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake
index 33969d470c..38dbed982a 100644
--- a/lib/tasks/mastodon.rake
+++ b/lib/tasks/mastodon.rake
@@ -171,11 +171,10 @@ namespace :mastodon do
end
namespace :emails do
- desc 'Send out digest e-mails'
+ desc 'Send out digest e-mails (deprecated)'
task digest: :environment do
- User.confirmed.joins(:account).where(accounts: { silenced: false, suspended: false }).where('current_sign_in_at < ?', 20.days.ago).find_each do |user|
- DigestMailerWorker.perform_async(user.id)
- end
+ # No-op
+ # This task is now executed via sidekiq-scheduler
end
end