# -*- coding: utf-8 -*- module JamRuby class EmailBatchProgression < EmailBatchPeriodic BATCH_SIZE = 3 SINCE_WEEKS = 2 SUBTYPES = [:client_notdl, # Registered Musician Has Not Downloaded Client :client_dl_notrun, # Registered Musician Has Downloaded Client But Not Yet Run It :client_run_notgear, # Registered Musician Has Run Client But Not Successfully Qualified Audio Gear :gear_notsess, # Registered Musician Has Successfully Qualified Audio Gear But Has Not Participated in a ‘Real’ Session :sess_notgood, # Registered Musician Has Participated In a "Real" Session But Has Not Had a "Good" Session :reg_notinvite, # Registered Musician Has Not Invited Friends to Join JamKazam :reg_notconnect, # Registered Musician Has Not Connected with any Friends on JamKazam :reg_notlike, # Registered Musician Has Not Liked Jamkazam :sess_notrecord # Registered Musician Has Participated In a "Real" Session But Has Not Made a Recording ] SUBTYPE_METADATA = { :client_notdl => { :subject => "Get the free JamKazam app now and start playing with others!", :title => "Download the Free JamKazam App" }, :client_dl_notrun => { :subject => "Having trouble running the JamKazam application?", :title => "Running the JamKazam App" }, :client_run_notgear => { :subject => "Having trouble setting up your audio gear for JamKazam?", :title => "Setting Up and Qualifying Your Audio Gear on JamKazam" }, :gear_notsess => { :subject => "Having trouble getting into a session with other musicians?", :title => "Tips on Getting into Sessions with Other Musicians" }, :sess_notgood => { :subject => "Have you played in a “good” session on JamKazam yet?", :title => "Having a Good Session on JamKazam" }, :reg_notinvite => { :subject => "Invite your friends to JamKazam, best way to play online!", :title => "Invite Your Friends to Come and Play with You" }, :reg_notconnect => { :subject => "Make friends on JamKazam and play more music!", :title => "Connecting with Friends on JamKazam" }, :reg_notlike => { :subject => "Please give us a LIKE!", :title => "Like/Follow JamKazam" }, :sess_notrecord => { :subject => "Want to make recordings during your JamKazam sessions?", :title => "Making & Sharing Recordings on JamKazam" }, } def self.subject(subtype=nil) SUBTYPE_METADATA[subtype][:subject] if subtype end def self.title(subtype=nil) SUBTYPE_METADATA[subtype][:title] if subtype end def self.subtype_trigger_interval(subtype) [:reg_notlike, :sess_notrecord].include?(subtype) ? [7,14,21] : [2,5,14] end def self.days_past_for_trigger_index(subtype, idx) self.subtype_trigger_interval(subtype)[idx] end def days_past_for_trigger_index(idx) self.class.subtype_trigger_interval(self.sub_type)[idx] end def fetch_recipients(since=nil) since ||= Time.now - SINCE_WEEKS.weeks User.geocoded_users .email_opt_in .where(['created_at < ?', since]) .find_in_batches(batch_size: self::BATCH_SIZE) do |users| new_musicians = users.inject({}) do |hh, uu| if 0 < (nearby = uu.nearest_musicians).count hh[uu] = nearby end hh end yield(new_musicians) if block_given? end end def trigger_date_constraint(trigger_idx, date_column) intervals = self.class.subtype_trigger_interval(self.sub_type) case trigger_idx when 1 return ["#{date_column} >= ? AND #{date_column} < ?", Time.now - intervals[0].days, Time.now - intervals[1].days] else return ["#{date_column} < ?", Time.now - intervals[trigger_idx].days] end end def fetch_client_notdl(trigger_idx=0) fetched = [] rel = User .joins("LEFT JOIN email_batch_sets AS ebs ON ebs.user_id = users.id AND ebs.sub_type = '#{self.sub_type}'") .email_opt_in .musicians .where("ebs.id IS NULL OR (SELECT MAX(trigger_index) FROM email_batch_sets ebs WHERE ebs.sub_type = '#{self.sub_type}' AND ebs.user_id = users.id ) < #{trigger_idx}") .where("first_downloaded_client_at IS NULL") .where(self.trigger_date_constraint(trigger_idx, "users.created_at")) .find_in_batches(batch_size: 100) do |users| block_given? ? yield(users) : fetched.concat(users) end fetched end def deliver_batch_sets! self.opt_in_count = 0 sent = 0 3.times do |trigger_idx| self.send("fetch_#{self.sub_type}", trigger_idx) do |users| users.each do |uu| self.email_batch_sets << (bset = EmailBatchSet.progress_set(self, uu, trigger_idx)) ProgressMailer.send_reminder(bset).deliver sent += 1 end end end self.sent_count = sent self.save self.did_batch_run! end end end