diff --git a/app/schemas/models/mail_task.coffee b/app/schemas/models/mail_task.coffee deleted file mode 100644 index ac450e0ee..000000000 --- a/app/schemas/models/mail_task.coffee +++ /dev/null @@ -1,21 +0,0 @@ -c = require './../schemas' -#This will represent transactional emails which have been sent - -MailTaskSchema = c.object { - title: 'Mail task' - description: 'Mail tasks to call at certain intervals' -} -_.extend MailTaskSchema.properties, - url: - title: 'URL' - description: 'The associated URL of the mailtask to call' - type: 'string' - frequency: - title: 'Frequency' - description: 'The number of seconds the servers should check whether or not to send the email' - type: 'integer' - -c.extendBasicProperties MailTaskSchema, 'mail.task' - -module.exports = MailTaskSchema - \ No newline at end of file diff --git a/server/mail/tasks/MailTask.coffee b/server/mail/tasks/MailTask.coffee deleted file mode 100644 index 10a536787..000000000 --- a/server/mail/tasks/MailTask.coffee +++ /dev/null @@ -1,7 +0,0 @@ -mongoose = require 'mongoose' -plugins = require '../../plugins/plugins' -jsonschema = require '../../../app/schemas/models/mail_task' - -MailTaskSchema = new mongoose.Schema({}, {strict: false}) - -module.exports = MailTask = mongoose.model('mail.task', MailTaskSchema) diff --git a/server/mail/tasks/mail_task_handler.coffee b/server/mail/tasks/mail_task_handler.coffee deleted file mode 100644 index 12b6be53a..000000000 --- a/server/mail/tasks/mail_task_handler.coffee +++ /dev/null @@ -1,12 +0,0 @@ -MailTask = require './MailTask' -Handler = require '../../commons/Handler' - -class MailTaskHandler extends Handler - modelClass: MailTask - editableProperties: ['url','frequency'] - jsonSchema: require '../../../app/schemas/models/mail_task' - - hasAccess: (req) -> - req.user?.isAdmin() - -module.exports = new MailTaskHandler() diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee index 5c3298f44..36c836741 100644 --- a/server/routes/auth.coffee +++ b/server/routes/auth.coffee @@ -143,7 +143,10 @@ module.exports.setup = (app) -> emails.recruitNotes ?= {} emails.recruitNotes.enabled = false msg = "Unsubscribed #{req.query.email} from recruiting emails." - + else if req.query.employerNotes + emails.employerNotes ?= {} + emails.employerNotes.enabled = false + msg = "Unsubscribed #{req.query.email} from employer emails." else msg = "Unsubscribed #{req.query.email} from all CodeCombat emails. Sorry to see you go!" emailSettings.enabled = false for emailSettings in _.values(emails) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 6939d8080..3a41e5316 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -1,5 +1,4 @@ mail = require '../commons/mail' -MailTask = require '../mail/tasks/MailTask' MailSent = require '../mail/sent/MailSent' User = require '../users/User' async = require 'async' @@ -12,42 +11,36 @@ sendwithus = require '../sendwithus' if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones lockManager = require '../commons/LockManager' #TODO: Ask Nick about email unsubscriptions -createMailTask = (req, res) -> #TODO: Ask Nick whether he thinks it is a good idea or not to hardcode the mail tasks - unless req.user?.isAdmin() then return errors.forbidden(res) - unless req.body.url and req.body.frequency then return errors.badInput(res) - console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}" - newMailTask = new MailTask {} - newMailTask.set("url",req.body.url) - newMailTask.set("frequency",req.body.frequency) - newMailTask.save (err) -> - if err? then return errors.serverError(res, err) - res.send("Created mail task!") - res.end() module.exports.setup = (app) -> app.all config.mail.mailchimpWebhook, handleMailchimpWebHook app.get '/mail/cron/ladder-update', handleLadderUpdate - app.post '/mail/task', createMailTask if lockManager setupScheduledEmails() setupScheduledEmails = -> testForLockManager() - mailTaskMap = #TODO: Edit this to include additional emails - "test_mail_task": candidateUpdateProfileTask + mailTasks = [ + taskFunction: candidateUpdateProfileTask + frequencyMs: 30 * 60 * 1000 #30 minutes + , + taskFunction: internalCandidateUpdateTask + frequencyMs: 10 * 60 * 1000 #10 minutes + , + taskFunction: employerNewCandidatesAvailableTask + frequencyMs: 30 * 60 * 1000 #30 minutes + ] + + for mailTask in mailTasks + setInterval mailTask.taskFunction, mailTask.frequencyMs - MailTask.find({}).lean().exec (err, mailTasks) -> #TODO: Ask Nick whether or not to remove this - if err? then throw "Failed to schedule mailTasks! #{err}" - for mailTask in mailTasks - setInterval mailTaskMap[mailTask.url], mailTask.frequency*2 #TODO: Have some random offset to prevent lock contention - testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!" ### Candidate Update Reminder Task ### candidateUpdateProfileTask = -> mailTaskName = "candidateUpdateProfileTask" - lockDurationMs = 20000 #TODO: Change these to something appropriate for the mail frequency (ideally longer than the task but shorter than frequency) + lockDurationMs = 2 * 60 * 1000 currentDate = new Date() timeRanges = [] for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']] @@ -86,10 +79,13 @@ findAllCandidatesWithinTimeRange = (cb) -> $gt: @timeRange.start $lte: @timeRange.end "jobProfileApproved": true - selection = "_id email jobProfile.name jobProfile.updated" + selection = "_id email jobProfile.name jobProfile.updated emails" #make sure to check for anyNotes too. User.find(findParameters).select(selection).lean().exec cb candidateFilter = (candidate, sentEmailFilterCallback) -> + if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false + log.info "Candidate #{candidate.jobProfile.name} opted out of emails, not sending to them." + return sentEmailFilterCallback true findParameters = "user": candidate._id "mailTask": @mailTaskName @@ -139,7 +135,7 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> ### Internal Candidate Update Reminder Email ### internalCandidateUpdateTask = -> mailTaskName = "internalCandidateUpdateTask" - lockDurationMs = 6000 #TODO: Change lock duration + lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!" emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) -> @@ -211,7 +207,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) -> ### Employer New Candidates Available Email ### employerNewCandidatesAvailableTask = -> mailTaskName = "employerNewCandidatesAvailableTask" - lockDurationMs = 6000 #TODO: Update this lock duration + lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> if err? then return log.error "There was an error getting a task lock!" emailEmployerNewCandidatesAvailable.apply {"mailTaskName":mailTaskName}, (err) -> @@ -242,7 +238,7 @@ findAllEmployers = (cb) -> "employerAt": $exists: true permissions: "employer" - selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated" + selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated emails" User.find(findParameters).select(selection).lean().exec cb makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> @@ -254,6 +250,9 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> cb null, allEmployers employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> + if employer.emails?.employerNotes?.enabled is false + log.info "Employer #{employer.name}(#{employer.email}) opted out of emails, not sending to them." + return sentEmailFilterCallback true findParameters = "user": employer._id "mailTask": @mailTaskName