Skip to content

Commit 30b033f

Browse files
authored
Merge pull request #517 from topcoder-platform/dev
[PROD] Next Release Patch
2 parents 5ca8b61 + 01e8e02 commit 30b033f

File tree

5 files changed

+30
-13
lines changed

5 files changed

+30
-13
lines changed

config/default.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ module.exports = {
250250
offered: 'withdrawn'
251251
},
252252
// the sender email
253-
NOTIFICATION_SENDER_EMAIL: process.env.NOTIFICATION_SENDER_EMAIL,
253+
NOTIFICATION_SENDER_EMAIL: process.env.NOTIFICATION_SENDER_EMAIL || '[email protected]',
254254
// the email notification sendgrid template id
255255
NOTIFICATION_SENDGRID_TEMPLATE_ID: process.env.NOTIFICATION_SENDGRID_TEMPLATE_ID,
256256
// frequency of cron checking for available candidates for review
@@ -275,6 +275,8 @@ module.exports = {
275275
INTERVIEW_COMPLETED_PAST_TIME: process.env.INTERVIEW_COMPLETED_PAST_TIME || 'PT4H',
276276
// The time before resource booking expiry when we should start sending notifications
277277
RESOURCE_BOOKING_EXPIRY_TIME: process.env.RESOURCE_BOOKING_EXPIRY_TIME || 'P21D',
278+
// The match window for fetching post interview actions
279+
POST_INTERVIEW_ACTION_MATCH_WINDOW: process.env.POST_INTERVIEW_ACTION_MATCH_WINDOW || 'P1D',
278280
// The Stripe
279281
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
280282
CURRENCY: process.env.CURRENCY || 'usd',

scripts/demo-email-notifications/index.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ async function resetNotificationRecords () {
4242
const jobCandidate = await JobCandidate.findById('881a19de-2b0c-4bb9-b36a-4cb5e223bdb5')
4343
await jobCandidate.update({ status: 'interview' })
4444
const c2Interview = await Interview.findById('077aa2ca-5b60-4ad9-a965-1b37e08a5046')
45-
await c2Interview.update({ startTimestamp: completedStartTimestamp, duration, endTimestamp, guestNames: ['guest1', 'guest2'], hostName: 'hostName' })
45+
await c2Interview.update({ startTimestamp: moment().subtract(moment.duration(config.POST_INTERVIEW_ACTION_MATCH_WINDOW)).subtract(30, 'm').toDate(), duration, endTimestamp, guestNames: ['guest1', 'guest2'], hostName: 'hostName' })
46+
const jobCandidateWithinOneDay = await JobCandidate.findById('827ee401-df04-42e1-abbe-7b97ce7937ff')
47+
await jobCandidateWithinOneDay.update({ status: 'interview' })
48+
const interviewWithinOneDay = await Interview.findById('3144fa65-ea1a-4bec-81b0-7cb1c8845826')
49+
await interviewWithinOneDay.update({ startTimestamp: completedStartTimestamp, duration, endTimestamp, guestNames: ['guest1', 'guest2'], hostName: 'hostName' })
4650

4751
// reset upcoming resource booking expiration records
4852
localLogger.info('reset upcoming resource booking expiration records')

src/common/helper.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,7 @@ async function getProjects (currentUser, criteria = {}) {
10381038
message: `response body: ${JSON.stringify(res.body)}`
10391039
})
10401040
const result = _.map(res.body, (item) => {
1041-
return _.pick(item, ['id', 'name', 'invites', 'members'])
1041+
return _.extend(_.pick(item, ['id', 'invites', 'members']), { name: _.unescape(item.name) })
10421042
})
10431043
return {
10441044
total: Number(_.get(res.headers, 'x-total')),
@@ -1195,7 +1195,7 @@ async function getProjectById (currentUser, id) {
11951195
context: 'getProjectById',
11961196
message: `response body: ${JSON.stringify(res.body)}`
11971197
})
1198-
return _.pick(res.body, ['id', 'name', 'invites', 'members'])
1198+
return _.extend(_.pick(res.body, ['id', 'invites', 'members']), { name: _.unescape(res.body.name) })
11991199
} catch (err) {
12001200
if (err.status === HttpStatus.FORBIDDEN) {
12011201
throw new errors.ForbiddenError(
@@ -1925,7 +1925,8 @@ async function createProject (currentUser, data) {
19251925
context: 'createProject',
19261926
message: `response body: ${JSON.stringify(res)}`
19271927
})
1928-
return _.get(res, 'body')
1928+
const result = _.get(res, 'body')
1929+
return _.extend(result, { name: _.unescape(_.get(result, 'name')) })
19291930
}
19301931

19311932
/**
@@ -2062,6 +2063,8 @@ function formatDateTimeEDT (date) {
20622063
function formatDateEDT (date) {
20632064
if (date) {
20642065
return moment(date).tz('America/New_York').format('MMM D, YYYY')
2066+
} else {
2067+
return 'TBD'
20652068
}
20662069
}
20672070

src/eventHandlers/TeamEventHandler.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ async function sendNotificationEmail (payload) {
4949
logger.debug({
5050
component: 'TeamEventHandler',
5151
context: 'sendNotificationEmail',
52-
message: `project id: ${payload.project.id} created with jobs: ${_.join(_.map(payload.jobs, 'id'), ',')}`
52+
message: `project id: ${payload.project.id}, subject: ${data.subject}, created with jobs: ${_.join(_.map(payload.jobs, 'id'), ',')}`
5353
})
5454
}
5555

src/services/NotificationsSchedulerService.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ async function getDataForInterview (interview, jobCandidate, job) {
109109
* Sends notifications to all the teams which have candidates available for review
110110
*/
111111
async function sendCandidatesAvailableNotifications () {
112+
localLogger.debug('[sendCandidatesAvailableNotifications]: Looking for due records...')
112113
const jobsDao = await Job.findAll({
113114
include: [{
114115
model: JobCandidate,
@@ -190,6 +191,7 @@ async function sendCandidatesAvailableNotifications () {
190191
* Sends reminders to the hosts and guests about their upcoming interview(s)
191192
*/
192193
async function sendInterviewComingUpNotifications () {
194+
localLogger.debug('[sendInterviewComingUpNotifications]: Looking for due records...')
193195
const currentTime = moment.utc()
194196
const timestampFilter = {
195197
[Op.or]: []
@@ -239,7 +241,7 @@ async function sendInterviewComingUpNotifications () {
239241
if (!_.isEmpty(interview.hostEmail)) {
240242
sendNotification({}, {
241243
template: 'taas.notification.interview-coming-up-host',
242-
recipients: [interview.hostEmail],
244+
recipients: [{ email: interview.hostEmail }],
243245
data: {
244246
...data,
245247
notificationType: {
@@ -258,7 +260,7 @@ async function sendInterviewComingUpNotifications () {
258260
// send guest emails
259261
sendNotification({}, {
260262
template: 'taas.notification.interview-coming-up-guest',
261-
recipients: interview.guestEmails,
263+
recipients: interview.guestEmails.map((email) => ({ email })),
262264
data: {
263265
...data,
264266
notificationType: {
@@ -281,6 +283,7 @@ async function sendInterviewComingUpNotifications () {
281283
* Sends reminder to the interview host after it ends to change the interview status
282284
*/
283285
async function sendInterviewCompletedNotifications () {
286+
localLogger.debug('[sendInterviewCompletedNotifications]: Looking for due records...')
284287
const window = moment.duration(config.INTERVIEW_COMPLETED_MATCH_WINDOW)
285288
const rangeStart = moment.utc().subtract(moment.duration(config.INTERVIEW_COMPLETED_PAST_TIME))
286289
const rangeEnd = rangeStart.clone().add(window)
@@ -323,7 +326,7 @@ async function sendInterviewCompletedNotifications () {
323326

324327
sendNotification({}, {
325328
template: 'taas.notification.interview-awaits-resolution',
326-
recipients: [interview.hostEmail],
329+
recipients: [{ email: interview.hostEmail }],
327330
data: {
328331
...data,
329332
notificationType: {
@@ -344,6 +347,7 @@ async function sendInterviewCompletedNotifications () {
344347
* to update the job candidate status
345348
*/
346349
async function sendPostInterviewActionNotifications () {
350+
localLogger.debug('[sendPostInterviewActionNotifications]: Looking for due records...')
347351
const completedJobCandidates = await JobCandidate.findAll({
348352
where: {
349353
status: constants.JobCandidateStatus.INTERVIEW
@@ -353,7 +357,10 @@ async function sendPostInterviewActionNotifications () {
353357
as: 'interviews',
354358
required: true,
355359
where: {
356-
status: constants.Interviews.Status.Completed
360+
status: constants.Interviews.Status.Completed,
361+
startTimestamp: {
362+
[Op.lte]: moment.utc().subtract(moment.duration(config.POST_INTERVIEW_ACTION_MATCH_WINDOW))
363+
}
357364
}
358365
}]
359366
})
@@ -436,6 +443,7 @@ async function sendPostInterviewActionNotifications () {
436443
* Sends reminders to all members of teams which have atleast one upcoming resource booking expiration
437444
*/
438445
async function sendResourceBookingExpirationNotifications () {
446+
localLogger.debug('[sendResourceBookingExpirationNotifications]: Looking for due records...')
439447
const currentTime = moment.utc()
440448
const maxEndDate = currentTime.clone().add(moment.duration(config.RESOURCE_BOOKING_EXPIRY_TIME))
441449

@@ -543,7 +551,7 @@ async function sendResourceBookingExpirationNotifications () {
543551
async function sendNotification (currentUser, data, webNotifications = []) {
544552
const template = emailTemplates[data.template]
545553
const dataCC = data.cc || []
546-
const templateCC = template.cc || []
554+
const templateCC = (template.cc || []).map(email => ({ email }))
547555
const dataRecipients = data.recipients || []
548556
const templateRecipients = (template.recipients || []).map(email => ({ email }))
549557
const subjectBody = {
@@ -557,14 +565,14 @@ async function sendNotification (currentUser, data, webNotifications = []) {
557565
)
558566
}
559567

560-
const recipients = _.map(_.uniq([...dataRecipients, ...templateRecipients]), function (r) { return { email: r } })
568+
const recipients = _.uniq([...dataRecipients, ...templateRecipients])
561569
const emailData = {
562570
serviceId: 'email',
563571
type: data.template,
564572
details: {
565573
from: data.from || template.from,
566574
recipients,
567-
cc: _.map(_.uniq([...dataCC, ...templateCC]), function (r) { return { email: r } }),
575+
cc: _.uniq([...dataCC, ...templateCC]),
568576
data: { ...data.data, ...subjectBody },
569577
sendgridTemplateId: template.sendgridTemplateId,
570578
version: 'v3'

0 commit comments

Comments
 (0)