-
-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Send recap emails for new feedback (#440)
- Loading branch information
Showing
19 changed files
with
426 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
class SendRecapEmails < ActiveJob::Base | ||
queue_as :default | ||
|
||
def perform(*args) | ||
# Fix times to 15:00 UTC | ||
time_now = Time.now.utc.change(hour: args[0], min: 0, sec: 0) | ||
one_day_ago = 1.day.ago.utc.change(hour: args[0], min: 0, sec: 0) | ||
one_week_ago = 1.week.ago.utc.change(hour: args[0], min: 0, sec: 0) | ||
one_month_ago = 1.month.ago.utc.change(hour: args[0], min: 0, sec: 0) | ||
|
||
# Get tenants with active subscriptions | ||
tbs = TenantBilling.unscoped.all | ||
tbs = tbs.select { |tb| tb.has_active_subscription? } | ||
tenants = Tenant.where(id: tbs.map(&:tenant_id)) | ||
|
||
# Based on the current date, determine which recap notifications to send | ||
frequencies_to_notify = ['daily'] | ||
frequencies_to_notify.push('weekly') if Date.today.monday? # Send weekly recap on Mondays | ||
frequencies_to_notify.push('monthly') if Date.today.day == 1 # Send monthly recap on the 1st of the month | ||
|
||
tenants.each do |tenant| | ||
Current.tenant = tenant | ||
I18n.locale = tenant.locale | ||
|
||
# Get users with recap notifications enabled | ||
users = tenant.users.where( | ||
role: ['owner', 'admin', 'moderator'], | ||
notifications_enabled: true, | ||
recap_notification_frequency: frequencies_to_notify, | ||
) | ||
|
||
# Get the different recap notification frequencies for users | ||
users_recap_notification_frequencies = users.map(&:recap_notification_frequency).flatten.uniq | ||
|
||
# Get only needed posts | ||
if users_recap_notification_frequencies.include?('daily') | ||
published_posts_daily = Post.where(approval_status: 'approved', created_at: one_day_ago..time_now).to_a | ||
pending_posts_daily = Post.where(approval_status: 'pending', created_at: one_day_ago..time_now).to_a | ||
end | ||
if frequencies_to_notify.include?('weekly') && users_recap_notification_frequencies.include?('weekly') | ||
published_posts_weekly = Post.where(approval_status: 'approved', created_at: one_week_ago..time_now).to_a | ||
pending_posts_weekly = Post.where(approval_status: 'pending', created_at: one_week_ago..time_now).to_a | ||
end | ||
if frequencies_to_notify.include?('monthly') && users_recap_notification_frequencies.include?('monthly') | ||
published_posts_monthly = Post.where(approval_status: 'approved', created_at: one_month_ago..time_now).to_a | ||
pending_posts_monthly = Post.where(approval_status: 'pending', created_at: one_month_ago..time_now).to_a | ||
end | ||
|
||
# Notify each user based on their recap notification frequency | ||
users.each do |user| | ||
# Remove from published_posts the posts published by the user | ||
published_posts_daily_user = published_posts_daily&.select { |post| post.user_id != user.id } | ||
should_send_daily_recap = published_posts_daily_user&.any? || pending_posts_daily&.any? | ||
|
||
published_posts_weekly_user = published_posts_weekly&.select { |post| post.user_id != user.id } | ||
should_send_weekly_recap = published_posts_weekly_user&.any? || pending_posts_weekly&.any? | ||
|
||
published_posts_monthly_user = published_posts_monthly&.select { |post| post.user_id != user.id } | ||
should_send_monthly_recap = published_posts_monthly_user&.any? || pending_posts_monthly&.any? | ||
|
||
# Send recap email | ||
if user.recap_notification_frequency == 'daily' && should_send_daily_recap | ||
UserMailer.recap( | ||
frequency: I18n.t('common.forms.auth.recap_notification_frequency_daily'), | ||
user: user, | ||
published_posts_count: published_posts_daily_user&.count, | ||
pending_posts_count: pending_posts_daily&.count, | ||
).deliver_later | ||
elsif user.recap_notification_frequency == 'weekly' && should_send_weekly_recap | ||
UserMailer.recap( | ||
frequency: I18n.t('common.forms.auth.recap_notification_frequency_weekly'), | ||
user: user, | ||
published_posts_count: published_posts_weekly_user&.count, | ||
pending_posts_count: pending_posts_weekly&.count, | ||
).deliver_later | ||
elsif user.recap_notification_frequency == 'monthly' && should_send_monthly_recap | ||
UserMailer.recap( | ||
frequency: I18n.t('common.forms.auth.recap_notification_frequency_monthly'), | ||
user: user, | ||
published_posts_count: published_posts_monthly_user&.count, | ||
pending_posts_count: pending_posts_monthly&.count, | ||
).deliver_later | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<%= render 'user_mailer/opening', user_name: @user.full_name_or_email %> | ||
|
||
<p> | ||
<%= t('mailers.user.recap.body_html', frequency: @frequency.downcase) %>: | ||
</p> | ||
|
||
<ul> | ||
<li><%= t('mailers.user.recap.published_posts_count_html', count: @published_posts_count) %></li> | ||
<li><%= t('mailers.user.recap.pending_posts_count_html', count: @pending_posts_count) %></li> | ||
</ul> | ||
|
||
<p> | ||
<%= link_to t('mailers.user.learn_more'), get_url_for(method(:root_url)) %> | ||
</p> | ||
|
||
<%= render 'user_mailer/closing' %> | ||
|
||
<%= render 'user_mailer/unsubscribe_from_site' %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Sidekiq::Cron.configure do |config| | ||
config.cron_schedule_file = 'config/sidekiq_cron_schedule.yml' | ||
|
||
config.cron_poll_interval = 30 | ||
config.cron_history_size = 50 | ||
config.default_namespace = 'default' | ||
config.natural_cron_parsing_mode = :strict | ||
|
||
# Handles the case when the Sidekiq process was down for a while and the cron job should have run (set to 10 minutes, i.e. 600 seconds) | ||
# This could happen during the deployment of a new version of the application | ||
config.reschedule_grace_period = 600 | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# For crontab syntax, see https://crontab.guru/ | ||
|
||
send_recap_emails: | ||
cron: "0 15 * * *" # At 15:00 every day | ||
# cron: "*/30 * * * * *" # Execute every 30 seconds (for testing purposes) | ||
class: "SendRecapEmails" | ||
queue: default | ||
args: | ||
hour: 15 # This should be in sync with the "cron" time |
5 changes: 5 additions & 0 deletions
5
db/migrate/20241118082824_add_recap_notification_frequency_to_users.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
class AddRecapNotificationFrequencyToUsers < ActiveRecord::Migration[6.1] | ||
def change | ||
add_column :users, :recap_notification_frequency, :integer, default: 0, null: false | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.