From 71716b2240aa276e3a8ae7b0edab0bf4cc50a564 Mon Sep 17 00:00:00 2001 From: Nuwan Chaturanga Date: Sat, 5 Apr 2025 20:18:38 +0000 Subject: [PATCH] Merged in 5534-profile-reminder-emails (pull request #54) Profile prompts & reminders * Profile prompts & reminders 3 email reminders to for new users who have not completed their jamkazam profile * PR change requests. moved email sernding job to hourly job tasks. and add database table index Approved-by: Seth Call --- ...1_add_profile_complete_columns_to_users.rb | 18 +++++ ruby/lib/jam_ruby/app/mailers/user_mailer.rb | 36 +++++++++ .../profile_complete_reminder1.html.erb | 73 +++++++++++++++++++ .../profile_complete_reminder1.text.erb | 17 +++++ .../profile_complete_reminder2.html.erb | 34 +++++++++ .../profile_complete_reminder2.text.erb | 11 +++ .../profile_complete_reminder3.html.erb | 29 ++++++++ .../profile_complete_reminder3.text.erb | 9 +++ .../jam_ruby/lib/email_profile_reminder.rb | 43 +++++++++++ .../jam_ruby/resque/scheduled/hourly_job.rb | 1 + .../scheduled/profile_reminder_emailer.rb | 15 ++++ web/config/locales/en.yml | 29 ++++++++ 12 files changed, 315 insertions(+) create mode 100644 ruby/db/migrate/20250227125441_add_profile_complete_columns_to_users.rb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder1.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder1.text.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder2.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder2.text.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder3.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder3.text.erb create mode 100644 ruby/lib/jam_ruby/lib/email_profile_reminder.rb create mode 100644 ruby/lib/jam_ruby/resque/scheduled/profile_reminder_emailer.rb diff --git a/ruby/db/migrate/20250227125441_add_profile_complete_columns_to_users.rb b/ruby/db/migrate/20250227125441_add_profile_complete_columns_to_users.rb new file mode 100644 index 000000000..cef65f792 --- /dev/null +++ b/ruby/db/migrate/20250227125441_add_profile_complete_columns_to_users.rb @@ -0,0 +1,18 @@ + class AddProfileCompleteColumnsToUsers < ActiveRecord::Migration + def self.up + execute "ALTER TABLE users ADD COLUMN profile_completed_at TIMESTAMP" + #add index on profile_completed_at + execute "CREATE INDEX index_users_on_profile_completed_at ON users USING btree (profile_completed_at)" + execute "ALTER TABLE users ADD COLUMN profile_complete_reminder1_sent_at TIMESTAMP" + execute "ALTER TABLE users ADD COLUMN profile_complete_reminder2_sent_at TIMESTAMP" + execute "ALTER TABLE users ADD COLUMN profile_complete_reminder3_sent_at TIMESTAMP" + + User.where('users.id IN (SELECT player_id FROM musicians_instruments) OR users.id IN (SELECT player_id FROM genre_players)').update_all(profile_completed_at: Time.now) + end + def self.down + execute "ALTER TABLE users DROP COLUMN profile_completed_at" + execute "ALTER TABLE users DROP COLUMN profile_complete_reminder1_sent_at" + execute "ALTER TABLE users DROP COLUMN profile_complete_reminder2_sent_at" + execute "ALTER TABLE users DROP COLUMN profile_complete_reminder3_sent_at" + end + end diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index 6cf4e7940..193402404 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -418,6 +418,42 @@ module JamRuby end end + def profile_complete_reminder1(user) + @user = user + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + sendgrid_unique_args :type => "profile_complete_reminder1" + + mail(:to => user.email, :subject => I18n.t('user_mailer.profile_complete_reminder1.subject')) do |format| + format.text + format.html { render layout: "user_mailer_beta" } + end + end + + def profile_complete_reminder2(user) + @user = user + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + sendgrid_unique_args :type => "profile_complete_reminder2" + + mail(:to => user.email, :subject => "Take 2 minutes to fill out your JamKazam profile now") do |format| + format.text + format.html { render layout: "user_mailer_beta" } + end + end + + def profile_complete_reminder3(user) + @user = user + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + sendgrid_unique_args :type => "profile_complete_reminder3" + + mail(:to => user.email, :subject => "Last reminder to update your JamKazam profile") do |format| + format.text + format.html { render layout: "user_mailer_beta" } + end + end + #################################### NOTIFICATION EMAILS #################################### def friend_request(user, msg, friend_request_id) return if !user.subscribe_email diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder1.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder1.html.erb new file mode 100644 index 000000000..ec48a3778 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder1.html.erb @@ -0,0 +1,73 @@ +

<%=I18n.t('user_mailer.profile_complete_reminder1.greeting') -%> <%= @user.first_name -%> -

+ +

+ <%=I18n.t('user_mailer.profile_complete_reminder1.paragraph1') -%> +

+ +

+ + <%=I18n.t('user_mailer.profile_complete_reminder1.update_profile') -%> + +

+ +

+<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph2') -%> +

+ +

+ <%=I18n.t('user_mailer.profile_complete_reminder1.paragraph3') -%> +

+ +

+ + <%=I18n.t('user_mailer.profile_complete_reminder1.download_app') -%> + + + <%=I18n.t('user_mailer.profile_complete_reminder1.download_legacy_app') -%> + +

+

+ <%=I18n.t('user_mailer.profile_complete_reminder1.paragraph4') -%> +

+ +
+

+ <%=I18n.t('user_mailer.profile_complete_reminder1.regards') -%> +
+ <%=I18n.t('user_mailer.profile_complete_reminder1.signature') -%> +

+
\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder1.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder1.text.erb new file mode 100644 index 000000000..026906af5 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder1.text.erb @@ -0,0 +1,17 @@ +<%=I18n.t('user_mailer.profile_complete_reminder1.greeting') -%> <%= @user.first_name -%> - + +<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph1') -%> + +<%= APP_CONFIG.spa_origin_url %>/profile + +<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph2') -%> + +<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph3') -%> + +<%= APP_CONFIG.external_root_url %>/downloads + +<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph4') -%> + +<%=I18n.t('user_mailer.profile_complete_reminder1.regards') -%> +<%=I18n.t('user_mailer.profile_complete_reminder1.signature') -%> + diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder2.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder2.html.erb new file mode 100644 index 000000000..95a83fe17 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder2.html.erb @@ -0,0 +1,34 @@ +

<%=I18n.t('user_mailer.profile_complete_reminder2.greeting') -%> <%= @user.first_name -%> -

+ +

+ <%=I18n.t('user_mailer.profile_complete_reminder2.paragraph1') -%> +

+ +

+ + <%=I18n.t('user_mailer.profile_complete_reminder2.update_profile') -%> + +

+ +

+ <%=I18n.t('user_mailer.profile_complete_reminder2.paragraph2') -%> +

+ +
+

+ <%=I18n.t('user_mailer.profile_complete_reminder2.regards') -%> +
+ <%=I18n.t('user_mailer.profile_complete_reminder2.signature') -%> +

+
\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder2.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder2.text.erb new file mode 100644 index 000000000..0cda26fe7 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder2.text.erb @@ -0,0 +1,11 @@ +<%=I18n.t('user_mailer.profile_complete_reminder2.greeting') -%> <%= @user.first_name -%> - + +<%=I18n.t('user_mailer.profile_complete_reminder2.paragraph1') -%> + +<%= APP_CONFIG.spa_origin_url %>/profile + +<%=I18n.t('user_mailer.profile_complete_reminder2.paragraph2') -%> + +<%=I18n.t('user_mailer.profile_complete_reminder2.regards') -%> + +<%=I18n.t('user_mailer.profile_complete_reminder2.signature') -%> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder3.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder3.html.erb new file mode 100644 index 000000000..b469fec07 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder3.html.erb @@ -0,0 +1,29 @@ +

<%=I18n.t('user_mailer.profile_complete_reminder3.greeting') -%> <%= @user.first_name -%> -

+ +

<%=I18n.t('user_mailer.profile_complete_reminder3.paragraph1') -%> +

+ +

+ + <%=I18n.t('user_mailer.profile_complete_reminder3.update_profile') -%> + +

+ +
+

+ <%=I18n.t('user_mailer.profile_complete_reminder3.regards') -%> +
+ <%=I18n.t('user_mailer.profile_complete_reminder3.signature') -%> +

+
\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder3.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder3.text.erb new file mode 100644 index 000000000..d7632644c --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/profile_complete_reminder3.text.erb @@ -0,0 +1,9 @@ +<%=I18n.t('user_mailer.profile_complete_reminder3.greeting') -%><%= @user.first_name -%> - + +<%=I18n.t('user_mailer.profile_complete_reminder3.paragraph1') -%> + +<%= APP_CONFIG.spa_origin_url %>/profile + +<%=I18n.t('user_mailer.profile_complete_reminder3.regards') -%> + +<%=I18n.t('user_mailer.profile_complete_reminder3.signature') -%> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/lib/email_profile_reminder.rb b/ruby/lib/jam_ruby/lib/email_profile_reminder.rb new file mode 100644 index 000000000..a253f0eb7 --- /dev/null +++ b/ruby/lib/jam_ruby/lib/email_profile_reminder.rb @@ -0,0 +1,43 @@ +module JamRuby + class EmailProfileReminder + + def self.send_reminders + #If the user has not updated their profile 1 day after signup, then send reminder email1 + reminder1_users.each do |user| + UserMailer.profile_complete_reminder1(user).deliver_now + user.update(profile_complete_reminder1_sent_at: Time.now) + end + + #If the user has not updated their profile 3 days after signup, then send reminder email2 + reminder2_users.each do |user| + UserMailer.profile_complete_reminder2(user).deliver_now + user.update(profile_complete_reminder2_sent_at: Time.now) + end + + #If the user has not updated their profile 5 days after signup, then send reminder email3 + reminder3_users.each do |user| + UserMailer.profile_complete_reminder3(user).deliver_now + user.update(profile_complete_reminder3_sent_at: Time.now) + end + + end + + def self.prospect_users + User.where("users.profile_completed_at IS NULL AND users.subscribe_email = ?", true) + end + + def self.reminder1_users + EmailProfileReminder.prospect_users.where("users.created_at > ? AND users.profile_complete_reminder1_sent_at IS NULL", 1.day.ago) + end + + def self.reminder2_users + EmailProfileReminder.prospect_users.where("users.created_at > ? AND users.profile_complete_reminder1_sent_at IS NOT NULL AND users.profile_complete_reminder2_sent_at IS NULL", 3.days.ago) + end + + def self.reminder3_users + EmailProfileReminder.prospect_users.where("users.created_at > ? AND users.profile_complete_reminder2_sent_at IS NOT NULL AND users.profile_complete_reminder3_sent_at IS NULL", 5.days.ago) + end + + + end +end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb b/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb index e534e98cf..a73b813b9 100644 --- a/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb +++ b/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb @@ -13,6 +13,7 @@ module JamRuby #TeacherPayment.hourly_check User.hourly_check AffiliatePartner.tally_up(Date.today) + EmailProfileReminder.send_reminders ConnectionManager.new.cleanup_dangling @@log.info("done") diff --git a/ruby/lib/jam_ruby/resque/scheduled/profile_reminder_emailer.rb b/ruby/lib/jam_ruby/resque/scheduled/profile_reminder_emailer.rb new file mode 100644 index 000000000..9eaba001a --- /dev/null +++ b/ruby/lib/jam_ruby/resque/scheduled/profile_reminder_emailer.rb @@ -0,0 +1,15 @@ +module JamRuby + class ProfileReminderEmailer + extend Resque::Plugins::JamLonelyJob + + @queue = :scheduled_profile_reminder_emailer + @@log = Logging.logger[ProfileReminderEmailer] + + def self.perform + @@log.debug("waking up") + EmailProfileReminder.send_reminders + @@log.debug("done") + end + + end +end \ No newline at end of file diff --git a/web/config/locales/en.yml b/web/config/locales/en.yml index 6b0ecd22f..92778cd01 100644 --- a/web/config/locales/en.yml +++ b/web/config/locales/en.yml @@ -71,3 +71,32 @@ en: paragraph2: "Your account was imported for you, so you'll need to set a password. Click the button below to set a password for your JamKazam account." paragraph3: "Thanks for joining JamKazam!" signature: "The JamKazam Team" + profile_complete_reminder1: + subject: "Update your JamKazam profile now & get connected to other musicians" + greeting: "Hello" + paragraph1: "If you may be interested in playing music live online with other musicians, the first thing you should do is fill out your JamKazam profile. The information in your profile lets other musicians with similar interests find, message, and connect with you, and also lets JamKazam’s matchmaking features give you recommendations for great musical connections. Click the button below to update your profile now. It only takes 2 minutes to complete your profile." + update_profile: "Update Profile" + paragraph2: "After you have updated your profile, the next thing you should do is download, install, and run the JamKazam app. You’ll need this app to play online with others, and the app also gives you access to more advanced JamTracks features if you signed up to use our huge catalog of backing tracks. After you download and install the app, we recommend you open the app and then leave the app running for about 10-15 minutes on your computer. The app will use this time to quietly collect Internet data that we use to figure out which other musicians on JamKazam you’ll have the best connections with – i.e. the lowest latency (or lag) when playing together" + paragraph3: "Click a button below to go to the JamKazam app download page. (Most users should click the Download App button, but if you’re on a Mac that can’t run MacOS 10.15 or later, click the Download Legacy App button, as that version of the app supports older MacOS versions back to 10.7.) After you download it, double click the downloaded installer, and follow the on-screen instructions to install the app, then start the app and leave it running for about 15 minutes." + download_app: "Download App" + download_legacy_app: "Download Legacy App" + paragraph4: "For next steps, don’t forget you can always refer back to the Welcome email we sent you when you signed up. And if you run into any problems or get stuck, please send us email at support@jamkazam.com. We’re always happy to help" + regards: "Best Regards," + signature: "JamKazam Team" + + profile_complete_reminder2: + subject: "Complete your JamKazam profile" + greeting: "Hello" + paragraph1: "We share your profile with JamKazam members who may be a good fit to play music with you during your first week on the platform via an automated email feature. Don’t miss this opportunity to connect. Click the button below to update your profile now, before it’s shared with others!" + update_profile: "Update Profile" + paragraph2: "For next steps after your profile, don’t forget you can always refer back to the Welcome email we sent you when you signed up. And if you run into any problems or get stuck, please send us email at support@jamkazam.com. We’re always happy to help!" + regards: "Best Regards," + signature: "JamKazam Team" + + profile_complete_reminder3: + subject: "Complete your JamKazam profile" + greeting: "Hello" + paragraph1: "Your profile is your key to connecting with other musicians on JamKazam. It lets others know what instruments you play at what level of proficiency and what kinds of music you like to play. This lets our existing community find and reach out to you to connect and play, and this information also powers our automated matchmaking features that make recommendations to you. If you think you might want to play music live online on JamKazam, please click the button below now to fill out your profile!" + update_profile: "Update Profile" + regards: "Best Regards," + signature: "JamKazam Team"