diff options
Diffstat (limited to 'app/services/members/invitation_reminder_email_service.rb')
-rw-r--r-- | app/services/members/invitation_reminder_email_service.rb | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/app/services/members/invitation_reminder_email_service.rb b/app/services/members/invitation_reminder_email_service.rb new file mode 100644 index 00000000000..e589cdc2fa3 --- /dev/null +++ b/app/services/members/invitation_reminder_email_service.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Members + class InvitationReminderEmailService + include Gitlab::Utils::StrongMemoize + + attr_reader :invitation + + MAX_INVITATION_LIFESPAN = 14.0 + REMINDER_RATIO = [2, 5, 10].freeze + + def initialize(invitation) + @invitation = invitation + end + + def execute + return unless experiment_enabled? + + reminder_index = days_on_which_to_send_reminders.index(days_after_invitation_sent) + return unless reminder_index + + invitation.send_invitation_reminder(reminder_index) + end + + private + + def experiment_enabled? + Gitlab::Experimentation.enabled_for_attribute?(:invitation_reminders, invitation.invite_email) + end + + def days_after_invitation_sent + (Date.today - invitation.created_at.to_date).to_i + end + + def days_on_which_to_send_reminders + # Don't send any reminders if the invitation has expired or expires today + return [] if invitation.expires_at && invitation.expires_at <= Date.today + + # Calculate the number of days on which to send reminders based on the MAX_INVITATION_LIFESPAN and the REMINDER_RATIO + REMINDER_RATIO.map { |number_of_days| ((number_of_days * invitation_lifespan_in_days) / MAX_INVITATION_LIFESPAN).ceil }.uniq + end + + def invitation_lifespan_in_days + # When the invitation lifespan is more than 14 days or does not expire, send the reminders within 14 days + strong_memoize(:invitation_lifespan_in_days) do + if invitation.expires_at + [(invitation.expires_at - invitation.created_at.to_date).to_i, MAX_INVITATION_LIFESPAN].min + else + MAX_INVITATION_LIFESPAN + end + end + end + end +end |