VRFS-3300 : Reminder notification functionality -- sends in-app/1-day/upcoming emails as necessary.

This commit is contained in:
Steven Miers 2015-07-09 17:52:26 -05:00
parent 521b0f4ba7
commit 84293ed637
3 changed files with 151 additions and 66 deletions

View File

@ -26,7 +26,9 @@ module NotificationTypes
SCHEDULED_SESSION_RSVP_CANCELLED_ORG = "SCHEDULED_SESSION_RSVP_CANCELLED_ORG"
SCHEDULED_SESSION_CANCELLED = "SCHEDULED_SESSION_CANCELLED"
SCHEDULED_SESSION_RESCHEDULED = "SCHEDULED_SESSION_RESCHEDULED"
SCHEDULED_SESSION_REMINDER = "SCHEDULED_SESSION_REMINDER"
SCHEDULED_SESSION_REMINDER_DAY = "SCHEDULED_SESSION_REMINDER_DAY"
SCHEDULED_SESSION_REMINDER_UPCOMING = "SCHEDULED_SESSION_REMINDER_UPCOMING"
SCHEDULED_SESSION_REMINDER_IMMINENT = "SCHEDULED_SESSION_REMINDER_IMMINENT"
SCHEDULED_SESSION_COMMENT = "SCHEDULED_SESSION_COMMENT"
# recording notifications

View File

@ -73,6 +73,10 @@ module JamRuby
@@message_factory = MessageFactory.new
################### HELPERS ###################
def notified?(music_session, notification_type)
Notification.where("session_id=? AND description=?", music_session, notification_type).count != 0
end
def retrieve_friends(connection, user_id)
friend_ids = []
connection.exec("SELECT f.friend_id as friend_id FROM friendships f WHERE f.user_id = $1", [user_id]) do |friend_results|
@ -203,9 +207,15 @@ module JamRuby
when NotificationTypes::SCHEDULED_SESSION_RESCHEDULED
return "The following session has been rescheduled."
when NotificationTypes::SCHEDULED_SESSION_REMINDER
when NotificationTypes::SCHEDULED_SESSION_REMINDER_DAY
return "A session to which you have RSVPd will begin in one hour, so get ready to play!"
when NotificationTypes::SCHEDULED_SESSION_REMINDER_UPCOMING
return "A session to which you have RSVPd will begin in one hour, so get ready to play!"
when NotificationTypes::SCHEDULED_SESSION_REMINDER_IMMINENT
return "A session to which you have RSVPd is scheduled to start in 5 minutes!"
when NotificationTypes::SCHEDULED_SESSION_COMMENT
return "New message about session."
@ -515,7 +525,7 @@ module JamRuby
end
def send_session_join(active_music_session, connection, user)
notification_msg = format_msg(NotificationTypes::SESSION_JOIN, {:user => user})
msg = @@message_factory.session_join(
@ -553,8 +563,8 @@ module JamRuby
end
def send_musician_session_join(music_session, user)
if music_session.musician_access || music_session.fan_access
if music_session.musician_access || music_session.fan_access
friends = Friendship.where(:friend_id => user.id)
user_followers = user.followers
@ -804,7 +814,7 @@ module JamRuby
def send_scheduled_session_cancelled(music_session)
return if music_session.nil?
rsvp_requests = RsvpRequest.index(music_session)
target_users = rsvp_requests.where(:canceled => false).map { |r| r.user }
@ -890,33 +900,52 @@ module JamRuby
end
end
def send_scheduled_session_reminder(music_session)
# Send session reminders to sessions that
# start in less than 24 hours, and haven't been
# notified for a particular interval yet:
def send_session_reminders
MusicSession.where("scheduled_start > NOW() AND scheduled_start <= (NOW()+INTERVAL '1 DAYS')").each do |candidate_session|
tm = candidate_session.scheduled_start
if (tm>(12.hours.from_now) && !notified?(candidate_session, NotificationTypes::SCHEDULED_SESSION_REMINDER_DAY))
# Send 24 hour reminders:
send_session_reminder_day(candidate_session)
elsif (tm<=(65.minutes.from_now) && tm>(15.minutes.from_now) && !notified?(candidate_session, NotificationTypes::SCHEDULED_SESSION_REMINDER_UPCOMING))
# Send 1 hour reminders:
send_session_reminder_upcoming(candidate_session)
elsif (tm<=(10.minutes.from_now) && !notified?(candidate_session, NotificationTypes::SCHEDULED_SESSION_REMINDER_IMMINENT))
# Send 5 minute reminders:
send_session_reminder_imminent(candidate_session)
end
end
end
return if music_session.nil?
def send_session_reminder_day(music_session)
send_session_reminder(music_session, NotificationTypes::SCHEDULED_SESSION_REMINDER_DAY) do |music_session, target_user, notification|
begin
UserMailer.scheduled_session_reminder_day(target_user, music_session).deliver
rescue => e
@@log.error("Unable to send SCHEDULED_SESSION_REMINDER_DAY email to user #{target_user.email} #{e}")
end
end
end
rsvp_requests = RsvpRequest.index(music_session)
target_users = rsvp_requests.where(:canceled => false).map { |r| r.user }
# remove the creator from the array
target_users = target_users.uniq - [music_session.creator]
target_users.each do |target_user|
source_user = music_session.creator
notification = Notification.new
notification.description = NotificationTypes::SCHEDULED_SESSION_REMINDER
notification.source_user_id = source_user.id
notification.target_user_id = target_user.id
notification.session_id = music_session.id
notification.save
notification_msg = format_msg(notification.description, {:session => music_session})
def send_session_reminder_upcoming(music_session)
send_session_reminder(music_session, NotificationTypes::SCHEDULED_SESSION_REMINDER_UPCOMING) do |music_session, target_user, notification|
begin
UserMailer.scheduled_session_reminder_upcoming(target_user, music_session).deliver
rescue => e
@@log.error("Unable to send SCHEDULED_SESSION_REMINDER_UPCOMING email to user #{target_user.email} #{e}")
end
end
end
def send_session_reminder_imminent(music_session)
send_session_reminder(music_session, NotificationTypes::SCHEDULED_SESSION_REMINDER_IMMINENT) do |music_session, target_user, notification|
if target_user.online
msg = @@message_factory.scheduled_session_reminder(
target_user.id,
music_session.id,
notification_msg,
format_msg(notification.description, {:session => music_session}),
music_session.name,
music_session.pretty_scheduled_start(false),
notification.id,
@ -925,12 +954,27 @@ module JamRuby
@@mq_router.publish_to_user(target_user.id, msg)
end
end
end
begin
UserMailer.scheduled_session_reminder(target_user, notification_msg, music_session).deliver
rescue => e
@@log.error("Unable to send SCHEDULED_SESSION_REMINDER email to user #{target_user.email} #{e}")
end
# @param music_session - the session for which to send reminder
# @param reminder_type - the type of reminder; one of:
# => SCHEDULED_SESSION_REMINDER_DAY 24 hours
# => SCHEDULED_SESSION_REMINDER_UPCOMING 15 minutes
# => SCHEDULED_SESSION_REMINDER_IMMINENT 5 minutes (in-app)
def send_session_reminder(music_session, reminder_type)
raise ArgumentError, "Block required" unless block_given?
source_user = music_session.creator
rsvp_requests = RsvpRequest.index(music_session)
rsvp_requests.where(:canceled => false).each do |rsvp|
target_user = rsvp.user
notification = Notification.new
notification.description = reminder_type
notification.source_user_id = source_user.id
notification.target_user_id = target_user.id
notification.session_id = music_session.id
notification.save
yield(music_session, target_user, notification)
end
end
@ -984,12 +1028,12 @@ module JamRuby
def send_band_session_join(music_session, band)
# if the session is private, don't send any notifications
if music_session.musician_access || music_session.fan_access
if music_session.musician_access || music_session.fan_access
notification_msg = format_msg(NotificationTypes::BAND_SESSION_JOIN, {:band => band})
followers = band.followers.map { |bf| bf.user }
# do not send band session notifications to band members
followers = followers - band.users
@ -1328,7 +1372,7 @@ module JamRuby
end
def send_band_invitation_accepted(band, band_invitation, sender, receiver)
notification = Notification.new
notification.band_id = band.id
notification.description = NotificationTypes::BAND_INVITATION_ACCEPTED
@ -1362,7 +1406,7 @@ module JamRuby
msg = @@message_factory.musician_session_fresh(
music_session.id,
user.id,
user.id,
user.name,
user.photo_url
)

View File

@ -18,6 +18,13 @@ describe Notification do
@session = FactoryGirl.create(:music_session)
@band = FactoryGirl.create(:band)
@slot1 = FactoryGirl.build(:rsvp_slot, :music_session => @session, :instrument => JamRuby::Instrument.find('electric guitar'))
@slot1.save
@slot2 = FactoryGirl.build(:rsvp_slot, :music_session => @session, :instrument => JamRuby::Instrument.find('drums'))
@slot2.save
@friend_request = FactoryGirl.create(:friend_request, user: @sender, friend: @receiver)
end
@ -199,7 +206,7 @@ describe Notification do
it "does not send email when user is offline and opts out of emails" do
FactoryGirl.create(:friendship, :user => @receiver, :friend => @recording.owner)
FactoryGirl.create(:friendship, :user => @recording.owner, :friend => @receiver)
@receiver.subscribe_email = false
@receiver.save!
@ -284,7 +291,7 @@ describe Notification do
@recording.band = @band
@recording.save!
follower.subscribe_email = false
follower.save!
@ -671,35 +678,14 @@ describe Notification do
end
end
describe "send scheduled session reminder" do
# it "sends email when user is offline and subscribes to emails" do
# session.creator = sender
# session.save!
# calls = count_publish_to_user_calls
# notification = Notification.send_scheduled_session_cancelled(session)
# UserMailer.deliveries.length.should == 1
# calls[:count].should == 1
# end
# it "does not send email when user is offline and opts out of emails" do
# session.creator = sender
# session.save!
# receiver.subscribe_email = false
# receiver.save!
# calls = count_publish_to_user_calls
# notification = Notification.send_scheduled_session_cancelled(session)
# UserMailer.deliveries.length.should == 0
# calls[:count].should == 1
# end
describe "reminders" do
let(:mail) { UserMailer.deliveries[0] }
before :each do
UserMailer.deliveries.clear
end
it "sends no notification if session is nil" do
calls = count_publish_to_user_calls
notification = Notification.send_scheduled_session_reminder(nil)
notification = Notification.send_session_reminders()
UserMailer.deliveries.length.should == 0
calls[:count].should == 0
@ -707,12 +693,65 @@ describe Notification do
it "sends no notification if there are no rsvp requests" do
calls = count_publish_to_user_calls
notification = Notification.send_scheduled_session_reminder(@session)
notification = Notification.send_session_reminders()
UserMailer.deliveries.length.should == 0
calls[:count].should == 0
end
end
it "sends email 24 hours before" do
@session.creator = @sender
@session.scheduled_start = Time.now + 23.hours
@session.save!
notification = Notification.send_session_reminders()
UserMailer.deliveries.length.should == 1
calls = count_publish_to_user_calls
calls[:count].should == 0
mail.html_part.body.include?("is scheduled for tomorrow").should be_true
mail.text_part.body.include?("is scheduled for tomorrow").should be_true
mail.html_part.body.include?("starts in 1 hour").should be_false
mail.text_part.body.include?("starts in 1 hour").should be_false
end
it "sends email 1 hour before" do
@session.creator = @sender
@session.scheduled_start = Time.now + 59.minutes
@session.save!
notification = Notification.send_session_reminders()
UserMailer.deliveries.length.should == 1
calls = count_publish_to_user_calls
calls[:count].should == 0
mail.html_part.body.include?("is scheduled for tomorrow").should be_false
mail.text_part.body.include?("is scheduled for tomorrow").should be_false
mail.html_part.body.include?("starts in 1 hour").should be_true
mail.text_part.body.include?("starts in 1 hour").should be_true
end
it "sends notice 5 minutes before" do
UserMailer.deliveries.length.should == 0
receiver_connection = FactoryGirl.create(:connection, user: @receiver)
@receiver.reload
rsvp = RsvpRequest.create({:session_id => @session.id, :rsvp_slots => [@slot1.id, @slot2.id], :message => "We be jammin!"}, @receiver)
UserMailer.deliveries.clear
calls = count_publish_to_user_calls
@session.creator = @sender
@session.scheduled_start = Time.now + 4.minutes
@session.save!
notification = Notification.send_session_reminders()
calls[:count].should == 1
UserMailer.deliveries.length.should == 0
end
end # reminders
describe "send scheduled session comment" do
# it "sends email when user is offline and subscribes to emails" do