Skip to content

Commit 51d07b0

Browse files
authoredMay 11, 2023
Merge pull request #125 from topcoder-platform/develop
feat: send registration email
2 parents 2701fe5 + a3ce242 commit 51d07b0

File tree

5 files changed

+60
-17
lines changed

5 files changed

+60
-17
lines changed
 

‎.circleci/config.yml

+6-4
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ parameters:
88
type: boolean
99
defaults: &defaults
1010
docker:
11-
- image: circleci/python:2.7-stretch-browsers
11+
- image: cimg/python:3.11.0-browsers
1212
install_dependency: &install_dependency
1313
name: Installation of build and deployment dependencies.
1414
command: |
15-
sudo apt install jq python3-pip
15+
sudo apt update
16+
sudo apt install jq
17+
sudo apt install python3-pip
1618
sudo pip3 install awscli --upgrade
17-
# sudo pip install docker-compose
19+
sudo pip3 install docker-compose
1820
install_deploysuite: &install_deploysuite
1921
name: Installation of install_deploysuite.
2022
command: |
21-
git clone --branch v1.4.14 https://github.com/topcoder-platform/tc-deploy-scripts ../buildscript
23+
git clone --branch v1.4.15 https://github.com/topcoder-platform/tc-deploy-scripts ../buildscript
2224
cp ./../buildscript/master_deploy.sh .
2325
cp ./../buildscript/buildenv.sh .
2426
cp ./../buildscript/awsconfiguration.sh .

‎config/default.js

+10
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ module.exports = {
6868
RESOURCE_DELETE_TOPIC: process.env.RESOURCE_DELETE_TOPIC || 'challenge.action.resource.delete',
6969
RESOURCE_ROLE_CREATE_TOPIC: process.env.RESOURCE_ROLE_CREATE_TOPIC || 'challenge.action.resource.role.create',
7070
RESOURCE_ROLE_UPDATE_TOPIC: process.env.RESOURCE_ROLE_UPDATE_TOPIC || 'challenge.action.resource.role.update',
71+
EMAIL_NOTIFICATIN_TOPIC: process.env.EMAIL_NOTIFICATIN_TOPIC || 'external.action.email',
72+
REGISTRATION_EMAIL: {
73+
EMAIL_FROM: process.env.EMAIL_FROM || 'no-reply@topcoder.com',
74+
SENDGRID_TEMPLATE_ID: process.env.SENDGRID_TEMPLATE_ID || '',
75+
SENDGRID_TEMPLATE_ID_NO_FORUM: process.env.SENDGRID_TEMPLATE_ID_NO_FORUM || '',
76+
SUBMIT_URL: process.env.SUBMIT_URL || 'https://www.topcoder.com/challenges/:id/submit/',
77+
REVIEW_APP_URL: process.env.REVIEW_APP_URL || 'https://software.topcoder.com/review/actions/ViewProjectDetails?pid=',
78+
HELP_URL: process.env.HELP_URL || 'https://help.topcoder.com',
79+
SUPPORT_EMAIL: process.env.SUPPORT_EMAIL || 'support@topcoder.com'
80+
},
7181

7282
AUTOMATED_TESTING_NAME_PREFIX: process.env.AUTOMATED_TESTING_NAME_PREFIX || 'POSTMANE2E-'
7383
}

‎src/common/helper.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -176,26 +176,30 @@ async function getMemberById (id) {
176176
* @param {String} handle The member handle
177177
* @returns {Promise<void>}
178178
*/
179-
async function getMemberIdByHandle (handle) {
179+
async function getMemberDetailsByHandle (handle) {
180180
try {
181181
// logger.warn(`getMemberIdByHandle ${handle}`)
182182
const profile = await MemberProfile.query('handleLower').eq(_.toLower(handle)).exec().then(r => r[0])
183-
return profile.userId
183+
return { memberId: profile.userId, email: profile.email }
184184
} catch (e) {
185185
// fall back to v3 api...
186-
logger.warn(`Get MemberID by Handle from Dynamo Failed, trying v3 Members API. Error: ${JSON.stringify(e)}`)
187-
return getMemberIdByHandleFromV3Members(handle)
186+
logger.warn(`Get Member by Handle from Dynamo Failed, trying v3 Members API. Error: ${JSON.stringify(e)}`)
187+
return getMemberDetailsByHandleFromV3Members(handle)
188188
}
189189
}
190190

191-
async function getMemberIdByHandleFromV3Members (handle) {
191+
async function getMemberDetailsByHandleFromV3Members (handle) {
192192
let memberId
193+
let email
193194
try {
194-
logger.warn(`getMemberIdByHandle ${handle} from v5`)
195+
logger.warn(`getMemberByHandle ${handle} from v5`)
195196
const res = await getRequest(`${config.MEMBER_API_URL}/${handle}`)
196197
if (_.get(res, 'body.userId')) {
197198
memberId = String(res.body.userId)
198199
}
200+
if (_.get(res, 'body.email')) {
201+
email = String(res.body.email)
202+
}
199203
// handle return from v3 API, handle and memberHandle are the same under case-insensitive condition
200204
handle = _.get(res, 'body.handle')
201205
} catch (error) {
@@ -209,7 +213,7 @@ async function getMemberIdByHandleFromV3Members (handle) {
209213
throw new errors.BadRequestError(`User with handle: ${handle} doesn't exist`)
210214
}
211215

212-
return memberId
216+
return { memberId, email }
213217
}
214218

215219
/**
@@ -481,7 +485,7 @@ module.exports = {
481485
wrapExpress,
482486
autoWrapExpress,
483487
getMemberInfoById,
484-
getMemberIdByHandle,
488+
getMemberDetailsByHandle,
485489
checkIfExists,
486490
hasAdminRole,
487491
getById,

‎src/models/MemberProfile.js

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ const schema = new Schema({
2323
name: 'handleLower-index',
2424
project: true
2525
}
26+
},
27+
email: {
28+
type: String
2629
}
2730
},
2831
{

‎src/services/ResourceService.js

+29-5
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ async function init (currentUser, challengeId, resource, isCreated) {
245245

246246
// get member information using v3 API
247247
const handle = resource.memberHandle
248-
const memberId = await helper.getMemberIdByHandle(resource.memberHandle)
248+
const { memberId, email } = await helper.getMemberDetailsByHandle(resource.memberHandle)
249249

250250
// check if the resource is reviewer role and has already made a submission in the challenge
251251
if (resource.roleId === config.REVIEWER_RESOURCE_ROLE_ID || resource.roleId === config.ITERATIVE_REVIEWER_RESOURCE_ROLE_ID) {
@@ -284,11 +284,11 @@ async function init (currentUser, challengeId, resource, isCreated) {
284284
}
285285
// skip phase dependency checks for tasks
286286
if (_.get(challenge, 'task.isTask', false)) {
287-
return { resources, memberId, handle }
287+
return { resources, memberId, handle, email, challenge }
288288
}
289289
// bypass phase dependency checks if the caller is an m2m/admin
290290
if (currentUser.isMachine || helper.hasAdminRole(currentUser)) {
291-
return { resources, memberId, handle }
291+
return { resources, memberId, handle, email, challenge }
292292
}
293293
// check phases dependencies
294294
const dependencies = await ResourceRolePhaseDependencyService.getDependencies({ resourceRoleId: resource.roleId })
@@ -316,7 +316,7 @@ async function init (currentUser, challengeId, resource, isCreated) {
316316
})
317317

318318
// return resources and the member id
319-
return { resources, memberId, handle }
319+
return { resources, memberId, handle, email, challenge }
320320
}
321321

322322
/**
@@ -331,7 +331,7 @@ async function createResource (currentUser, resource) {
331331

332332
// handle doesn't change in current version
333333
// Seems we don't need handle auto-correction(e.g. "THomaskranitsas"->"thomaskranitsas")
334-
const { resources, memberId } = await init(currentUser, challengeId, resource, true)
334+
const { resources, memberId, handle, email, challenge } = await init(currentUser, challengeId, resource, true)
335335

336336
if (_.reduce(resources,
337337
(result, r) => _.toString(r.memberId) === _.toString(memberId) && r.roleId === resource.roleId ? true : result,
@@ -358,6 +358,30 @@ async function createResource (currentUser, resource) {
358358

359359
logger.debug(`Created resource: ${JSON.stringify(_.pick(ret, payloadFields))}`)
360360
await helper.postEvent(config.RESOURCE_CREATE_TOPIC, _.pick(ret, payloadFields))
361+
if (!_.get(challenge, 'task.isTask', false) && resource.roleId === config.SUBMITTER_RESOURCE_ROLE_ID) {
362+
const forumUrl = _.get(challenge, 'discussions[0].url')
363+
let templateId = config.REGISTRATION_EMAIL.SENDGRID_TEMPLATE_ID
364+
if (_.isUndefined(forumUrl)) {
365+
templateId = config.REGISTRATION_EMAIL.SENDGRID_TEMPLATE_ID_NO_FORUM
366+
}
367+
await helper.postEvent(config.EMAIL_NOTIFICATIN_TOPIC, {
368+
from: config.REGISTRATION_EMAIL.EMAIL_FROM,
369+
replyTo: config.REGISTRATION_EMAIL.EMAIL_FROM,
370+
recipients: [email],
371+
data: {
372+
handle,
373+
challengeName: challenge.name,
374+
forum: forumUrl,
375+
submissionEndTime: new Date(_.get(_.find(challenge.phases, phase => phase.name === 'Submission'), 'scheduledEndDate')).toUTCString(),
376+
submitUrl: _.replace(config.REGISTRATION_EMAIL.SUBMIT_URL, ':id', challengeId),
377+
reviewAppUrl: config.REGISTRATION_EMAIL.REVIEW_APP_URL + challenge.legacyId,
378+
helpUrl: config.REGISTRATION_EMAIL.HELP_URL,
379+
support: config.REGISTRATION_EMAIL.SUPPORT_EMAIL
380+
},
381+
sendgrid_template_id: templateId,
382+
version: 'v3'
383+
})
384+
}
361385

362386
return ret
363387
} catch (err) {

0 commit comments

Comments
 (0)
Please sign in to comment.