From 1418cd977a10dd7717864fab4b6e5cffe2eec27c Mon Sep 17 00:00:00 2001 From: darkrider97 Date: Sun, 15 Aug 2021 17:02:55 +0530 Subject: [PATCH 1/2] Renamed EmailNotificationService.js to NotificationsSchedulerService.js Modified templates to add links Adding web notifications for post interview candidate action and upcoming resource booking expiry Tasks 476 and 477#issuecomment-898886697 --- app.js | 12 +- config/email_template.config.js | 10 +- data/notifications-email-template.html | 42 +++-- src/services/JobCandidateService.js | 4 +- ...ce.js => NotificationsSchedulerService.js} | 153 ++++++++++++------ 5 files changed, 140 insertions(+), 81 deletions(-) rename src/services/{EmailNotificationService.js => NotificationsSchedulerService.js} (69%) diff --git a/app.js b/app.js index 3e60e0e8..248c386e 100644 --- a/app.js +++ b/app.js @@ -15,7 +15,7 @@ const eventHandlers = require('./src/eventHandlers') const interviewService = require('./src/services/InterviewService') const { processScheduler } = require('./src/services/PaymentSchedulerService') const { sendSurveys } = require('./src/services/SurveyService') -const emailNotificationService = require('./src/services/EmailNotificationService') +const notificationSchedulerService = require('./src/services/NotificationsSchedulerService') // setup express app const app = express() @@ -105,11 +105,11 @@ const server = app.listen(app.get('port'), () => { // schedule payment processing schedule.scheduleJob(config.PAYMENT_PROCESSING.CRON, processScheduler) - schedule.scheduleJob(config.CRON_CANDIDATE_REVIEW, emailNotificationService.sendCandidatesAvailableEmails) - schedule.scheduleJob(config.CRON_INTERVIEW_COMING_UP, emailNotificationService.sendInterviewComingUpEmails) - schedule.scheduleJob(config.CRON_INTERVIEW_COMPLETED, emailNotificationService.sendInterviewCompletedEmails) - schedule.scheduleJob(config.CRON_POST_INTERVIEW, emailNotificationService.sendPostInterviewActionEmails) - schedule.scheduleJob(config.CRON_UPCOMING_RESOURCE_BOOKING, emailNotificationService.sendResourceBookingExpirationEmails) + schedule.scheduleJob(config.CRON_CANDIDATE_REVIEW, notificationSchedulerService.sendCandidatesAvailableNotifications) + schedule.scheduleJob(config.CRON_INTERVIEW_COMING_UP, notificationSchedulerService.sendInterviewComingUpNotifications) + schedule.scheduleJob(config.CRON_INTERVIEW_COMPLETED, notificationSchedulerService.sendInterviewCompletedNotifications) + schedule.scheduleJob(config.CRON_POST_INTERVIEW, notificationSchedulerService.sendPostInterviewActionNotifications) + schedule.scheduleJob(config.CRON_UPCOMING_RESOURCE_BOOKING, notificationSchedulerService.sendResourceBookingExpirationNotifications) }) if (process.env.NODE_ENV === 'test') { diff --git a/config/email_template.config.js b/config/email_template.config.js index a61cd355..524d54f1 100644 --- a/config/email_template.config.js +++ b/config/email_template.config.js @@ -112,7 +112,7 @@ module.exports = { */ notificationEmailTemplates: { 'taas.notification.job-candidate-resume-viewed': { - subject: 'Topcoder - job candidate resume viewed', + subject: 'Topcoder - Client View Resume for Job {{jobName}}', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, @@ -161,14 +161,14 @@ module.exports = { sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID }, 'taas.notification.team-created': { - subject: 'Topcoder - Team Created', + subject: 'Topcoder - New Team {{teamName}} Created', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID }, 'taas.notification.job-created': { - subject: 'Topcoder - Job Created', + subject: 'Topcoder - New Job {{jobTitle}} Created in Team {{teamName}}', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, @@ -182,14 +182,14 @@ module.exports = { sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID }, 'taas.notification.job-candidate-selected': { - subject: 'Topcoder - Job Candidate Selected', + subject: 'Topcoder - Job Candidate {{userHandle}} Selected for {{jobTitle}} in Team {{teamName}}', body: '', recipients: config.NOTIFICATION_OPS_EMAILS, from: config.NOTIFICATION_SENDER_EMAIL, sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID }, 'taas.notification.resource-booking-placed': { - subject: 'Topcoder - Resource Booking Placed', + subject: 'Topcoder - Resource Booking {{userHandle}} Placed for Job {{jobTitle}} in Team {{teamName}}', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, diff --git a/data/notifications-email-template.html b/data/notifications-email-template.html index df1032a5..f0da558d 100644 --- a/data/notifications-email-template.html +++ b/data/notifications-email-template.html @@ -101,25 +101,23 @@ Job title No of resource bookings Candidates - Status + Review {{#each teamJobs}} - {{this.title}} + + {{this.title}} + {{this.nResourceBookings}} - + Link {{/each}} @@ -136,7 +134,9 @@ Date and Time - {{this.jobTitle}} + + {{this.jobTitle}} + {{this.handle}} Link @@ -160,7 +160,9 @@ Interviews - {{this.jobTitle}} + + {{this.jobTitle}} + {{this.startTime}} Link @@ -178,7 +180,9 @@ Interviews - {{this.jobTitle}} + + {{this.jobTitle}} + {{this.handle}} {{this.startTime}} @@ -205,7 +209,9 @@ {{#each teamInterviews}} - {{this.jobTitle}} + + {{this.jobTitle}} + {{this.handle}} {{this.startTime}} @@ -224,7 +230,7 @@ {{#if notificationType.upcomingResourceBookingExpiration}} Team Name: - {{teamName}} + {{teamName}} @@ -233,8 +239,12 @@ {{#each teamResourceBookings}} - - + + {{/each}} @@ -246,7 +256,7 @@ Your resume for the job "{{jobName}}" has been viewed by the client.
{{/if}} - + {{#if notificationType.newTeamCreated}} Team:{{teamName}} diff --git a/src/services/JobCandidateService.js b/src/services/JobCandidateService.js index 8f90da08..e142fbc4 100644 --- a/src/services/JobCandidateService.js +++ b/src/services/JobCandidateService.js @@ -14,7 +14,7 @@ const logger = require('../common/logger') const errors = require('../common/errors') const models = require('../models') const JobService = require('./JobService') -const EmailNotificationService = require('./EmailNotificationService') +const NotificationSchedulerService = require('./NotificationsSchedulerService') const JobCandidate = models.JobCandidate const esClient = helper.getESClient() @@ -376,7 +376,7 @@ async function downloadJobCandidateResume (currentUser, id) { const { handle } = await helper.getUserById(jobCandidate.userId, true) const { email } = await helper.getMemberDetailsByHandle(handle) - await EmailNotificationService.sendEmail(currentUser, { + await NotificationSchedulerService.sendNotification(currentUser, { template: 'taas.notification.job-candidate-resume-viewed', recipients: [email], data: { diff --git a/src/services/EmailNotificationService.js b/src/services/NotificationsSchedulerService.js similarity index 69% rename from src/services/EmailNotificationService.js rename to src/services/NotificationsSchedulerService.js index 10921668..e0c2610b 100644 --- a/src/services/EmailNotificationService.js +++ b/src/services/NotificationsSchedulerService.js @@ -1,5 +1,5 @@ /** - * Email notification service - has the cron handlers for sending different types of email notifications + * Notification scheduler service - has the cron handlers for sending different types of notifications (email, web etc) */ const _ = require('lodash') const { Op } = require('sequelize') @@ -15,9 +15,9 @@ const constants = require('../../app-constants') const logger = require('../common/logger') const localLogger = { - debug: (message, context) => logger.debug({ component: 'EmailNotificationService', context, message }), - error: (message, context) => logger.error({ component: 'EmailNotificationService', context, message }), - info: (message, context) => logger.info({ component: 'EmailNotificationService', context, message }) + debug: (message, context) => logger.debug({ component: 'NotificationSchedulerService', context, message }), + error: (message, context) => logger.error({ component: 'NotificationSchedulerService', context, message }), + info: (message, context) => logger.info({ component: 'NotificationSchedulerService', context, message }) } const emailTemplates = helper.getEmailTemplatesForKey('notificationEmailTemplates') @@ -88,7 +88,8 @@ async function getDataForInterview (interview, jobCandidate, job) { const interviewLink = `${config.TAAS_APP_URL}/${job.projectId}/positions/${job.id}/candidates/interviews` const guestName = _.isEmpty(interview.guestNames) ? '' : interview.guestNames[0] - const startTime = interview.startTimestamp ? interview.startTimestamp.toUTCString() : '' + const startTime = interview.startTimestamp ? helper.formatDateTimeEDT(interview.startTimestamp) : '' + const jobUrl = `${config.TAAS_APP_URL}/${job.projectId}/positions/${job.id}` return { jobTitle: job.title, @@ -99,14 +100,15 @@ async function getDataForInterview (interview, jobCandidate, job) { attendees: interview.guestNames, startTime: startTime, duration: interview.duration, - interviewLink + interviewLink, + jobUrl } } /** - * Sends email notifications to all the teams which have candidates available for review + * Sends notifications to all the teams which have candidates available for review */ -async function sendCandidatesAvailableEmails () { +async function sendCandidatesAvailableNotifications () { const jobsDao = await Job.findAll({ include: [{ model: JobCandidate, @@ -121,7 +123,7 @@ async function sendCandidatesAvailableEmails () { const projectIds = _.uniq(_.map(jobs, job => job.projectId)) - localLogger.debug(`[sendCandidatesAvailableEmails]: Found ${projectIds.length} projects with Job Candidates awaiting for review.`) + localLogger.debug(`[sendCandidatesAvailableNotifications]: Found ${projectIds.length} projects with Job Candidates awaiting for review.`) // for each unique project id, send an email let sentCount = 0 @@ -156,15 +158,17 @@ async function sendCandidatesAvailableEmails () { } }) + const jobUrl = `${config.TAAS_APP_URL}/${projectId}/positions/${projectJob.id}` teamJobs.push({ title: projectJob.title, nResourceBookings, jobCandidates, - reviewLink + reviewLink, + jobUrl }) } - sendEmail({}, { + sendNotification({}, { template: 'taas.notification.candidates-available-for-review', recipients: recipientEmails, data: { @@ -179,13 +183,13 @@ async function sendCandidatesAvailableEmails () { sentCount++ } - localLogger.debug(`[sendCandidatesAvailableEmails]: Sent notifications for ${sentCount} of ${projectIds.length} projects with Job Candidates awaiting for review.`) + localLogger.debug(`[sendCandidatesAvailableNotifications]: Sent notifications for ${sentCount} of ${projectIds.length} projects with Job Candidates awaiting for review.`) } /** - * Sends email reminders to the hosts and guests about their upcoming interview(s) + * Sends reminders to the hosts and guests about their upcoming interview(s) */ -async function sendInterviewComingUpEmails () { +async function sendInterviewComingUpNotifications () { const currentTime = moment.utc() const timestampFilter = { [Op.or]: [] @@ -223,7 +227,7 @@ async function sendInterviewComingUpEmails () { raw: true }) - localLogger.debug(`[sendInterviewComingUpEmails]: Found ${interviews.length} interviews which are coming soon.`) + localLogger.debug(`[sendInterviewComingUpNotifications]: Found ${interviews.length} interviews which are coming soon.`) let sentHostCount = 0 let sentGuestCount = 0 @@ -233,7 +237,7 @@ async function sendInterviewComingUpEmails () { if (!data) { continue } if (!_.isEmpty(interview.hostEmail)) { - sendEmail({}, { + sendNotification({}, { template: 'taas.notification.interview-coming-up-host', recipients: [interview.hostEmail], data: { @@ -247,12 +251,12 @@ async function sendInterviewComingUpEmails () { sentHostCount++ } else { - localLogger.error(`Interview id: ${interview.id} host email not present`, 'sendInterviewComingUpEmails') + localLogger.error(`Interview id: ${interview.id} host email not present`, 'sendInterviewComingUpNotifications') } if (!_.isEmpty(interview.guestEmails)) { // send guest emails - sendEmail({}, { + sendNotification({}, { template: 'taas.notification.interview-coming-up-guest', recipients: interview.guestEmails, data: { @@ -266,17 +270,17 @@ async function sendInterviewComingUpEmails () { sentGuestCount++ } else { - localLogger.error(`Interview id: ${interview.id} guest emails not present`, 'sendInterviewComingUpEmails') + localLogger.error(`Interview id: ${interview.id} guest emails not present`, 'sendInterviewComingUpNotifications') } } - localLogger.debug(`[sendInterviewComingUpEmails]: Sent notifications for ${sentHostCount} hosts and ${sentGuestCount} guest of ${interviews.length} interviews which are coming soon.`) + localLogger.debug(`[sendInterviewComingUpNotifications]: Sent notifications for ${sentHostCount} hosts and ${sentGuestCount} guest of ${interviews.length} interviews which are coming soon.`) } /** - * Sends email reminder to the interview host after it ends to change the interview status + * Sends reminder to the interview host after it ends to change the interview status */ -async function sendInterviewCompletedEmails () { +async function sendInterviewCompletedNotifications () { const window = moment.duration(config.INTERVIEW_COMPLETED_MATCH_WINDOW) const rangeStart = moment.utc().subtract(moment.duration(config.INTERVIEW_COMPLETED_PAST_TIME)) const rangeEnd = rangeStart.clone().add(window) @@ -305,7 +309,7 @@ async function sendInterviewCompletedEmails () { raw: true }) - localLogger.debug(`[sendInterviewCompletedEmails]: Found ${interviews.length} interviews which must be ended by now.`) + localLogger.debug(`[sendInterviewCompletedNotifications]: Found ${interviews.length} interviews which must be ended by now.`) let sentCount = 0 for (const interview of interviews) { @@ -317,7 +321,7 @@ async function sendInterviewCompletedEmails () { const data = await getDataForInterview(interview) if (!data) { continue } - sendEmail({}, { + sendNotification({}, { template: 'taas.notification.interview-awaits-resolution', recipients: [interview.hostEmail], data: { @@ -332,14 +336,14 @@ async function sendInterviewCompletedEmails () { sentCount++ } - localLogger.debug(`[sendInterviewCompletedEmails]: Sent notifications for ${sentCount} of ${interviews.length} interviews which must be ended by now.`) + localLogger.debug(`[sendInterviewCompletedNotifications]: Sent notifications for ${sentCount} of ${interviews.length} interviews which must be ended by now.`) } /** - * Sends email reminder to the all members of teams which have interview completed to take action + * Sends reminder to the all members of teams which have interview completed to take action * to update the job candidate status */ -async function sendPostInterviewActionEmails () { +async function sendPostInterviewActionNotifications () { const completedJobCandidates = await JobCandidate.findAll({ where: { status: constants.JobCandidateStatus.INTERVIEW @@ -366,13 +370,15 @@ async function sendPostInterviewActionEmails () { const projectIds = _.uniq(_.map(jobs, job => job.projectId)) - localLogger.debug(`[sendPostInterviewActionEmails]: Found ${projectIds.length} projects with ${completedJobCandidates.length} Job Candidates with interview completed awaiting for an action.`) + localLogger.debug(`[sendPostInterviewActionNotifications]: Found ${projectIds.length} projects with ${completedJobCandidates.length} Job Candidates with interview completed awaiting for an action.`) let sentCount = 0 + const template = 'taas.notification.post-interview-action-required' + for (const projectId of projectIds) { const project = await getProjectWithId(projectId) if (!project) { continue } - + const webNotifications = [] const recipientEmails = getProjectMembersEmails(project) const projectJobs = _.filter(jobs, job => job.projectId === projectId) const teamInterviews = [] @@ -384,13 +390,30 @@ async function sendPostInterviewActionEmails () { for (const interview of projectJc.interviews) { const d = await getDataForInterview(interview, projectJc, projectJob) if (!d) { continue } + d.jobUrl = `${config.TAAS_APP_URL}/${projectId}/positions/${projectJob.id}` + webNotifications.push({ + serviceId: 'web', + type: template, + details: { + recipients: _.map(_.uniq(recipientEmails), function (re) { return { email: re } }), + contents: { + jobTitle: d.jobTitle, + teamName: project.name, + projectId, + jobId: projectJob.id, + userHandle: d.handle + }, + version: 1 + } + }) + teamInterviews.push(d) } } } - sendEmail({}, { - template: 'taas.notification.post-interview-action-required', + sendNotification({}, { + template, recipients: recipientEmails, data: { teamName: project.name, @@ -401,18 +424,18 @@ async function sendPostInterviewActionEmails () { }, description: 'Post Interview Candidate Action Reminder' } - }) + }, webNotifications) sentCount++ } - localLogger.debug(`[sendPostInterviewActionEmails]: Sent notifications for ${sentCount} of ${projectIds.length} projects with Job Candidates with interview completed awaiting for an action.`) + localLogger.debug(`[sendPostInterviewActionNotifications]: Sent notifications for ${sentCount} of ${projectIds.length} projects with Job Candidates with interview completed awaiting for an action.`) } /** - * Sends reminder emails to all members of teams which have atleast one upcoming resource booking expiration + * Sends reminders to all members of teams which have atleast one upcoming resource booking expiration */ -async function sendResourceBookingExpirationEmails () { +async function sendResourceBookingExpirationNotifications () { const currentTime = moment.utc() const maxEndDate = currentTime.clone().add(moment.duration(config.RESOURCE_BOOKING_EXPIRY_TIME)) @@ -442,9 +465,10 @@ async function sendResourceBookingExpirationEmails () { }) const projectIds = _.uniq(_.map(expiringResourceBookings, rb => rb.projectId)) - localLogger.debug(`[sendResourceBookingExpirationEmails]: Found ${projectIds.length} projects with ${expiringResourceBookings.length} Resource Bookings expiring in less than 3 weeks.`) + localLogger.debug(`[sendResourceBookingExpirationNotifications]: Found ${projectIds.length} projects with ${expiringResourceBookings.length} Resource Bookings expiring in less than 3 weeks.`) let sentCount = 0 + const template = 'taas.notification.resource-booking-expiration' for (const projectId of projectIds) { const project = await getProjectWithId(projectId) if (!project) { continue } @@ -461,16 +485,36 @@ async function sendResourceBookingExpirationEmails () { const user = await getUserWithId(booking.userId) if (!user) { continue } + const jobUrl = `${config.TAAS_APP_URL}/${projectId}/positions/${projectJob.id}` + const resourceBookingUrl = `${config.TAAS_APP_URL}/${projectId}/rb/${booking.id}` teamResourceBookings.push({ jobTitle: projectJob.title, handle: user.handle, - endDate: booking.endDate + endDate: booking.endDate, + jobUrl, + resourceBookingUrl }) } } - sendEmail({}, { - template: 'taas.notification.resource-booking-expiration', + const webData = { + serviceId: 'web', + type: template, + details: { + recipients: _.map(_.uniq(recipientEmails), function (re) { return { email: re } }), + contents: { + teamName: project.name, + projectId, + numOfExpiringResourceBookings: numResourceBookings + }, + version: 1 + } + } + + const teamUrl = `${config.TAAS_APP_URL}/${project.id}` + + sendNotification({}, { + template, recipients: recipientEmails, data: { teamName: project.name, @@ -479,23 +523,24 @@ async function sendResourceBookingExpirationEmails () { notificationType: { upcomingResourceBookingExpiration: true }, + teamUrl, description: 'Upcoming Resource Booking Expiration' } - }) + }, [webData]) sentCount++ } - localLogger.debug(`[sendResourceBookingExpirationEmails]: Sent notifications for ${sentCount} of ${projectIds.length} projects with Resource Bookings expiring in less than 3 weeks.`) + localLogger.debug(`[sendResourceBookingExpirationNotifications]: Sent notifications for ${sentCount} of ${projectIds.length} projects with Resource Bookings expiring in less than 3 weeks.`) } /** - * Send email through a particular template + * Send notification through a particular template * @param {Object} currentUser the user who perform this operation * @param {Object} data the email object - * @returns {undefined} + * @param {Array} webNotifications the optional list of web notifications */ -async function sendEmail (currentUser, data) { +async function sendNotification (currentUser, data, webNotifications = []) { const template = emailTemplates[data.template] const dataCC = data.cc || [] const templateCC = template.cc || [] @@ -511,28 +556,32 @@ async function sendEmail (currentUser, data) { data.data ) } + + const recipients = _.map(_.uniq([...dataRecipients, ...templateRecipients]), function (r) { return { email: r } }) const emailData = { serviceId: 'email', type: data.template, details: { from: data.from || template.from, - recipients: _.map(_.uniq([...dataRecipients, ...templateRecipients]), function (r) { return { email: r } }), + recipients, cc: _.map(_.uniq([...dataCC, ...templateCC]), function (r) { return { email: r } }), data: { ...data.data, ...subjectBody }, sendgridTemplateId: template.sendgridTemplateId, version: 'v3' } } + + const notifications = [emailData, ...webNotifications] await helper.postEvent(config.NOTIFICATIONS_CREATE_TOPIC, { - notifications: [emailData] + notifications }) } module.exports = { - sendEmail, - sendCandidatesAvailableEmails, - sendInterviewComingUpEmails, - sendInterviewCompletedEmails, - sendPostInterviewActionEmails, - sendResourceBookingExpirationEmails + sendNotification, + sendCandidatesAvailableNotifications, + sendInterviewComingUpNotifications, + sendInterviewCompletedNotifications, + sendPostInterviewActionNotifications, + sendResourceBookingExpirationNotifications } From c090db82a98ea88ec5aa33c0e91ba543ee8b8500 Mon Sep 17 00:00:00 2001 From: darkrider97 Date: Mon, 16 Aug 2021 17:56:24 +0530 Subject: [PATCH 2/2] Replacing subject placeholders --- src/eventHandlers/JobCandidateEventHandler.js | 30 +++++++++-------- src/eventHandlers/JobEventHandler.js | 29 ++++++++-------- .../ResourceBookingEventHandler.js | 30 +++++++++-------- src/eventHandlers/TeamEventHandler.js | 33 ++++++++++--------- 4 files changed, 66 insertions(+), 56 deletions(-) diff --git a/src/eventHandlers/JobCandidateEventHandler.js b/src/eventHandlers/JobCandidateEventHandler.js index 127366ee..c2aef63a 100644 --- a/src/eventHandlers/JobCandidateEventHandler.js +++ b/src/eventHandlers/JobCandidateEventHandler.js @@ -155,26 +155,28 @@ async function sendJobCandidateSelectedNotification (payload) { const project = await helper.getProjectById({ isMachine: true }, job.projectId) const jobUrl = `${config.TAAS_APP_URL}/${project.id}/positions/${job.id}` const teamUrl = `${config.TAAS_APP_URL}/${project.id}` + const data = { + subject: template.subject, + teamName: project.name, + teamUrl, + jobTitle: job.title, + jobDuration: job.duration, + jobStartDate: helper.formatDateEDT(job.startDate), + userHandle: user.handle, + jobUrl, + notificationType: { + candidateSelected: true + }, + description: 'Job Candidate Selected' + } + data.subject = await helper.substituteStringByObject(data.subject, data) const emailData = { serviceId: 'email', type: 'taas.notification.job-candidate-selected', details: { from: template.from, recipients: template.recipients, - data: { - subject: template.subject, - teamName: project.name, - teamUrl, - jobTitle: job.title, - jobDuration: job.duration, - jobStartDate: helper.formatDateEDT(job.startDate), - userHandle: user.handle, - jobUrl, - notificationType: { - candidateSelected: true - }, - description: 'Job Candidate Selected' - }, + data, sendgridTemplateId: template.sendgridTemplateId, version: 'v3' } diff --git a/src/eventHandlers/JobEventHandler.js b/src/eventHandlers/JobEventHandler.js index 8f2b75c1..53d7ba13 100644 --- a/src/eventHandlers/JobEventHandler.js +++ b/src/eventHandlers/JobEventHandler.js @@ -84,25 +84,28 @@ async function sendNotifications (payload) { } const template = helper.getEmailTemplatesForKey('notificationEmailTemplates')['taas.notification.job-created'] const project = await helper.getProjectById({ isMachine: true }, payload.value.projectId) + const data = { + subject: template.subject, + teamName: project.name, + teamURL: `${config.TAAS_APP_URL}/${project.id}`, + jobTitle: payload.value.title, + jobURL: `${config.TAAS_APP_URL}/${project.id}/positions/${payload.value.id}`, + jobDuration: payload.value.duration, + jobStartDate: helper.formatDateEDT(payload.value.startDate), + notificationType: { + newJobCreated: true + }, + description: 'New Job Created' + } + data.subject = await helper.substituteStringByObject(data.subject, data) + const emailData = { serviceId: 'email', type: 'taas.notification.job-created', details: { from: template.from, recipients: _.map(project.members, m => _.pick(m, 'email')), - data: { - subject: template.subject, - teamName: project.name, - teamURL: `${config.TAAS_APP_URL}/${project.id}`, - jobTitle: payload.value.title, - jobURL: `${config.TAAS_APP_URL}/${project.id}/positions/${payload.value.id}`, - jobDuration: payload.value.duration, - jobStartDate: helper.formatDateEDT(payload.value.startDate), - notificationType: { - newJobCreated: true - }, - description: 'New Job Created' - }, + data, sendgridTemplateId: template.sendgridTemplateId, version: 'v3' } diff --git a/src/eventHandlers/ResourceBookingEventHandler.js b/src/eventHandlers/ResourceBookingEventHandler.js index 5a1f15a0..67adfeea 100644 --- a/src/eventHandlers/ResourceBookingEventHandler.js +++ b/src/eventHandlers/ResourceBookingEventHandler.js @@ -89,26 +89,28 @@ async function sendPlacedNotifications (payload) { const recipients = _.map(project.members, m => _.pick(m, 'email')) const jobUrl = `${config.TAAS_APP_URL}/${project.id}/positions/${job.id}` const teamUrl = `${config.TAAS_APP_URL}/${project.id}` + const data = { + subject: template.subject, + teamName: project.name, + teamUrl, + jobTitle: job.title, + jobUrl, + userHandle: user.handle, + startDate: resourceBooking.startDate, + endDate: resourceBooking.endDate, + notificationType: { + resourceBookingPlaced: true + }, + description: 'Resource Booking is Placed' + } + data.subject = await helper.substituteStringByObject(data.subject, data) const emailData = { serviceId: 'email', type: 'taas.notification.resource-booking-placed', details: { from: template.from, recipients, - data: { - subject: template.subject, - teamName: project.name, - teamUrl, - jobTitle: job.title, - jobUrl, - userHandle: user.handle, - startDate: resourceBooking.startDate, - endDate: resourceBooking.endDate, - notificationType: { - resourceBookingPlaced: true - }, - description: 'Resource Booking is Placed' - }, + data, sendgridTemplateId: template.sendgridTemplateId, version: 'v3' } diff --git a/src/eventHandlers/TeamEventHandler.js b/src/eventHandlers/TeamEventHandler.js index 7bd11eab..d5ee4b15 100644 --- a/src/eventHandlers/TeamEventHandler.js +++ b/src/eventHandlers/TeamEventHandler.js @@ -15,27 +15,30 @@ const helper = require('../common/helper') */ async function sendNotificationEmail (payload) { const template = helper.getEmailTemplatesForKey('notificationEmailTemplates')['taas.notification.team-created'] + const data = { + subject: template.subject, + teamName: payload.project.name, + teamUrl: `${config.TAAS_APP_URL}/${payload.project.id}`, + jobList: _.map(payload.jobs, j => ({ + title: j.title, + duration: j.duration, + startDate: helper.formatDateEDT(j.startDate), + jobUrl: `${config.TAAS_APP_URL}/${payload.project.id}/positions/${j.id}` + })), + notificationType: { + newTeamCreated: true + }, + description: 'New Team Created' + } + data.subject = await helper.substituteStringByObject(data.subject, data) + const emailData = { serviceId: 'email', type: 'taas.notification.team-created', details: { from: template.from, recipients: _.map(payload.project.members, m => _.pick(m, 'email')), - data: { - subject: template.subject, - teamName: payload.project.name, - teamUrl: `${config.TAAS_APP_URL}/${payload.project.id}`, - jobList: _.map(payload.jobs, j => ({ - title: j.title, - duration: j.duration, - startDate: helper.formatDateEDT(j.startDate), - jobUrl: `${config.TAAS_APP_URL}/${payload.project.id}/positions/${j.id}` - })), - notificationType: { - newTeamCreated: true - }, - description: 'New Team Created' - }, + data, sendgridTemplateId: template.sendgridTemplateId, version: 'v3' }
Job title
{{this.jobTitle}}{{this.handle}} + {{this.jobTitle}} + + {{this.handle}} + {{this.endDate}}