FEATURE: Send user activation reminders. (#7280)

FEATURE: Send user activation reminders. (#7280)

diff --git a/app/jobs/scheduled/activation_reminder_emails.rb b/app/jobs/scheduled/activation_reminder_emails.rb
new file mode 100644
index 0000000..8b55100
--- /dev/null
+++ b/app/jobs/scheduled/activation_reminder_emails.rb
@@ -0,0 +1,22 @@
+module Jobs
+  class ActivationReminderEmails < Jobs::Scheduled
+    every 2.hours
+
+    def execute(args)
+      User.joins("LEFT JOIN user_custom_fields ON users.id = user_id AND user_custom_fields.name = 'activation_reminder'")
+        .where(active: false, user_custom_fields: { value: nil })
+        .where('users.created_at < ?', 2.days.ago)
+        .find_each do |user|
+
+        user.custom_fields['activation_reminder'] = true
+        user.save_custom_fields
+
+        email_token = user.email_tokens.create!(email: user.email)
+        Jobs.enqueue(:user_email,
+                     type: :activation_reminder,
+                     user_id: user.id,
+                     email_token: email_token.token)
+      end
+    end
+  end
+end
diff --git a/app/mailers/user_notifications.rb b/app/mailers/user_notifications.rb
index c2f6dd4..523ab0c 100644
--- a/app/mailers/user_notifications.rb
+++ b/app/mailers/user_notifications.rb
@@ -21,6 +21,14 @@ class UserNotifications < ActionMailer::Base
     )
   end
 
+  def activation_reminder(user, opts = {})
+    build_user_email_token_by_template(
+      "user_notifications.activation_reminder",
+      user,
+      opts[:email_token]
+    )
+  end
+
   def signup_after_approval(user, opts = {})
     locale = user_locale(user)
     tips = I18n.t('system_messages.usage_tips.text_body_template',
diff --git a/app/models/email_token.rb b/app/models/email_token.rb
index 0446970..7d592b7 100644
--- a/app/models/email_token.rb
+++ b/app/models/email_token.rb
@@ -66,6 +66,7 @@ class EmailToken < ActiveRecord::Base
         user.send_welcome_message = !user.active?
         user.email = result[:email_token].email
         user.active = true
+        user.custom_fields.delete('activation_reminder')
         user.save!
         user.create_reviewable unless skip_reviewable
         user.set_automatic_groups
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 0fcf19e..2a1b0e5 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -3417,6 +3417,19 @@ en:
 
         If the above link is not clickable, try copying and pasting it into the address bar of your web browser.
 
+    activation_reminder:
+      title: "Activation Reminder"
+      subject_template: "[%{email_prefix}] Reminder to confirm your account"
+      text_body_template: |
+        Welcome to %{site_name}!
+
+        This is a friendly reminder to activate your account.
+
+        Click the following link to confirm and activate your new account:
+        %{base_url}/u/activate-account/%{email_token}
+
+        If the above link is not clickable, try copying and pasting it into the address bar of your web browser.
+
     suspicious_login:
       title: "New Login Alert"
       subject_template: "[%{site_name}] New Login from %{location}"
diff --git a/spec/jobs/activation_reminder_emails_spec.rb b/spec/jobs/activation_reminder_emails_spec.rb
new file mode 100644
index 0000000..d9b639c
--- /dev/null
+++ b/spec/jobs/activation_reminder_emails_spec.rb
@@ -0,0 +1,29 @@
+require 'rails_helper'
+
+describe Jobs::ActivationReminderEmails do
+  before do
+    Jobs.run_immediately!
+  end
+
+  it 'should email inactive users' do
+    user = Fabricate(:user, active: false, created_at: 3.days.ago)
+
+    expect { described_class.new.execute({}) }
+      .to change { ActionMailer::Base.deliveries.size }.by(1)
+      .and change { user.email_tokens.count }.by(1)
+
+    expect(user.custom_fields['activation_reminder']).to eq("t")
+    expect { described_class.new.execute({}) }.to change { ActionMailer::Base.deliveries.size }.by(0)
+
+    user.activate
+    expect(user.reload.custom_fields['activation_reminder']).to eq(nil)
+  end
+
+  it 'should not email active users' do
+    user = Fabricate(:user, active: true, created_at: 3.days.ago)
+
+    expect { described_class.new.execute({}) }
+      .to change { ActionMailer::Base.deliveries.size }.by(0)
+      .and change { user.email_tokens.count }.by(0)
+  end
+end

GitHub sha: 3d545d66

This commit has been mentioned on Discourse Meta. There might be relevant details there: