diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 26a5e8ed0..e7deb6707 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -1,5 +1,6 @@ mail = require '../commons/mail' MailSent = require '../mail/sent/MailSent' +UserRemark = require '../users/remarks/UserRemark' User = require '../users/User' async = require 'async' errors = require '../commons/errors' @@ -28,6 +29,9 @@ setupScheduledEmails = -> , taskFunction: employerNewCandidatesAvailableTask frequencyMs: 10 * 60 * 1000 #10 minutes + , + taskFunction: unapprovedCandidateFinishProfileTask + frequencyMs: 10 * 60 * 1000 ] for mailTask in mailTasks @@ -35,7 +39,7 @@ setupScheduledEmails = -> testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!" -### Candidate Update Reminder Task ### +### Approved Candidate Update Reminder Task ### candidateUpdateProfileTask = -> mailTaskName = "candidateUpdateProfileTask" @@ -132,7 +136,103 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> sendwithus.api.send context, (err, result) -> log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err sendEmailCallback null -### End Candidate Update Reminder Task ### +### End Approved Candidate Update Reminder Task ### + +### Unapproved Candidate Finish Reminder Task ### +unapprovedCandidateFinishProfileTask = -> + mailTaskName = "unapprovedCandidateFinishProfileTask" + lockDurationMs = 2 * 60 * 1000 + currentDate = new Date() + timeRanges = [] + for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']] + timeRanges.push + start: generateWeekOffset currentDate, weekPair[0] + end: generateWeekOffset currentDate, weekPair[1] + name: weekPair[2] + lockManager.setLock mailTaskName, lockDurationMs, (err) -> + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" + async.each timeRanges, emailUnapprovedCandidateTimeRange.bind({mailTaskName: mailTaskName}), (err) -> + if err + log.error "There was an error sending the candidate profile update reminder emails: #{err}" + else + log.info "Completed mail task #{mailTaskName}" + lockManager.releaseLock mailTaskName, (err) -> + if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}" + +emailUnapprovedCandidateTimeRange = (timeRange, emailTimeRangeCallback) -> + waterfallContext = + "timeRange": timeRange + "mailTaskName": @mailTaskName + async.waterfall [ + findAllUnapprovedCandidatesWithinTimeRange.bind(waterfallContext) + (unfilteredCandidates, cb) -> + async.reject unfilteredCandidates, ignoredCandidateFilter, cb.bind(null,null) + (unfilteredPotentialCandidates, cb) -> + async.reject unfilteredPotentialCandidates, unapprovedCandidateFilter.bind(waterfallContext), cb.bind(null, null) + (filteredCandidates, cb) -> + async.each filteredCandidates, sendReminderEmailToUnapprovedCandidate.bind(waterfallContext), cb + ], emailTimeRangeCallback + +findAllUnapprovedCandidatesWithinTimeRange = (cb) -> + findParameters = + "jobProfile": + $exists: true + "jobProfile.updated": + $gt: @timeRange.start + $lte: @timeRange.end + "jobProfileApproved": false + selection = "_id email jobProfile.name jobProfile.updated emails" + User.find(findParameters).select(selection).lean().exec cb + +ignoredCandidateFilter = (candidate, cb) -> + findParameters = + "user": candidate._id + "contactName": "Ignore" + UserRemark.count findParameters, (err, results) -> + if err? then return true + return cb Boolean(results.length) + +unapprovedCandidateFilter = (candidate, sentEmailFilterCallback) -> + if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false + return sentEmailFilterCallback true + findParameters = + "user": candidate._id + "mailTask": @mailTaskName + "metadata.timeRangeName": @timeRange.name + "metadata.updated": candidate.jobProfile.updated + MailSent.find(findParameters).lean().exec (err, sentMail) -> + if err? + log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!" + sentEmailFilterCallback true + else + sentEmailFilterCallback Boolean(sentMail.length) + +sendReminderEmailToUnapprovedCandidate = (candidate, sendEmailCallback) -> + if err? + log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}" + return sendEmailCallback err + context = + email_id: "tem_RXyjzmc7S2HJH287pfoSPN" + recipient: + address: candidate.email + name: candidate.jobProfile.name + email_data: + user_profile: "http://codecombat.com/account/profile/#{candidate._id}" + recipient_address: encodeURIComponent(candidate.email) + log.info "Sending #{@timeRange.name} finish profile reminder to #{context.recipient.name}(#{context.recipient.address})" + newSentMail = + mailTask: @mailTaskName + user: candidate._id + metadata: + timeRangeName: @timeRange.name + updated: candidate.jobProfile.updated + MailSent.create newSentMail, (err) -> + if err? then return sendEmailCallback err + sendwithus.api.send context, (err, result) -> + log.error "Error sending candidate finish profile reminder email: #{err} with result #{result}" if err + sendEmailCallback null +### End Unapproved Candidate Finish Reminder Task ### + ### Internal Candidate Update Reminder Email ### internalCandidateUpdateTask = -> mailTaskName = "internalCandidateUpdateTask"