Skip to content

Commit eba5412

Browse files
author
sachin-maheshwari
authored
Merge pull request #110 from topcoder-platform/feature/general-purpose-notifications-usage
General processor - fixing api response by introducing notification node before dumping in DB
2 parents 9507ff7 + 4ddf248 commit eba5412

File tree

6 files changed

+102
-16
lines changed

6 files changed

+102
-16
lines changed

config/default.js

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,56 @@ module.exports = {
4646

4747
KAFKA_CONSUMER_RULESETS: {
4848
// key is Kafka topic name, value is array of ruleset which have key as handler function name defined in src/processors/index.js
49-
'challenge.notification.events': [{ handleChallenge: { type: 'UPDATE_DRAFT_CHALLENGE', roles: ["Submitter" /** Competitor */, "Copilot", "Reviewer"] } }],
50-
'notifications.autopilot.events': [{ handleAutoPilot: { phaseTypeName: 'Checkpoint Screening', state: 'START', roles: ["Copilot", "Reviewer"] } }],
51-
'submission.notification.create': [{ handleSubmission: { resource: 'submission', roles: ["Copilot", "Reviewer"], selfOnly: true /** Submitter only */ } }],
49+
'challenge.notification.events': [
50+
{
51+
handleChallenge: /** topic handler name */
52+
{
53+
type: 'UPDATE_DRAFT_CHALLENGE',
54+
roles: ["Submitter" /** Competitor */, "Copilot", "Reviewer"],
55+
notification:
56+
{
57+
id: 0, /** challengeid or projectid */
58+
name: '', /** challenge name */
59+
group: 'Challenge',
60+
title: 'Challenge specification is modified.'
61+
}
62+
}
63+
}
64+
],
65+
'notifications.autopilot.events': [
66+
{
67+
handleAutoPilot:
68+
{
69+
phaseTypeName: 'Checkpoint Screening',
70+
state: 'START',
71+
roles: ["Copilot", "Reviewer"],
72+
notification:
73+
{
74+
id: 0, /** challengeid or projectid */
75+
name: '', /** challenge name */
76+
group: 'Challenge',
77+
title: 'Challenge checkpoint review.'
78+
}
79+
}
80+
}
81+
],
82+
'submission.notification.create': [
83+
{
84+
handleSubmission:
85+
{
86+
resource: 'submission',
87+
roles: ["Copilot", "Reviewer"],
88+
selfOnly: true /** Submitter only */,
89+
notification:
90+
{
91+
id: 0, /** challengeid or projectid */
92+
name: '', /** challenge name */
93+
group: 'Submission',
94+
title: 'A new submission is uploaded.'
95+
}
96+
}
97+
}
98+
],
5299
//'notifications.community.challenge.created': ['handleChallengeCreated'],
53100
//'notifications.community.challenge.phasewarning': ['handleChallengePhaseWarning'],
54101
},

consumer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ function startKafkaConsumer() {
8383
yield models.Notification.bulkCreate(_.map(notifications, (n) => ({
8484
userId: n.userId,
8585
type: n.type || topic,
86-
contents: n.contents || messageJSON.payload || {},
86+
contents: n.contents || n.notification || messageJSON.payload || {},
8787
read: false,
8888
seen: false,
8989
version: n.version || null,

src/common/tcApiHelper.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,9 @@ function* notifyUserViaEmail(user, message) {
188188
*/
189189
function* getChallenge(challengeId) {
190190
// this is public API, M2M token is not needed
191-
const res = yield request.get(`${config.TC_API_V4_BASE_URL}/challenges/${challengeId}`);
191+
const url = `${config.TC_API_V4_BASE_URL}/challenges/${challengeId}`
192+
logger.info(`calling public challenge api ${url}`)
193+
const res = yield request.get(url);
192194
if (!_.get(res, 'body.result.success')) {
193195
throw new Error(`Failed to get challenge by id ${challengeId}`);
194196
}
@@ -198,10 +200,10 @@ function* getChallenge(challengeId) {
198200
/**
199201
* Notify users of message.
200202
* @param {Array} users the users
201-
* @param {Object} message the Kafka message
203+
* @param {Object} notification notifcation node
202204
* @returns {Array} the notifications
203205
*/
204-
function* notifyUsersOfMessage(users, message) {
206+
function* notifyUsersOfMessage(users, notification) {
205207
if (!users || users.length === 0) {
206208
logger.info('No users to notify message.');
207209
return [];
@@ -212,7 +214,7 @@ function* notifyUsersOfMessage(users, message) {
212214
for (let i = 0; i < users.length; i += 1) {
213215
const user = users[i];
214216
// construct notification, rest fields are set in consumer.js
215-
notifications.push({ userId: user.userId });
217+
notifications.push({ userId: user.userId, notification: notification });
216218

217219
/* TODO Sachin disabled this code
218220
if (config.ENABLE_EMAILS) {
@@ -287,6 +289,34 @@ function filterChallengeUsers(usersInfo, filterOnRoles = [], filterOnUsers = [])
287289
return users
288290
}
289291

292+
/**
293+
* modify notification template
294+
* @param {Object} ruleSet rule
295+
* @param {Object} data values to be filled
296+
*
297+
* @returns {Object} notification node
298+
*/
299+
function* modifyNotificationNode(ruleSet, data) {
300+
const notification = _.get(ruleSet, "notification")
301+
const id = data.id || data.challengeId || 0
302+
const name = _.get(data, "name")
303+
304+
notification.id = id
305+
306+
if (name) {
307+
notification.name = name
308+
} else {
309+
try {
310+
const challenge = yield getChallenge(id)
311+
notification.name = _.get(challenge, "challengeTitle")
312+
} catch (error) {
313+
notification.name = ''
314+
logger.error(`Error in fetching challenge detail : ${error}`)
315+
}
316+
}
317+
return notification
318+
}
319+
290320
module.exports = {
291321
getM2MToken,
292322
getUsersBySkills,
@@ -297,4 +327,5 @@ module.exports = {
297327
notifyUsersOfMessage,
298328
getUsersInfoFromChallenge,
299329
filterChallengeUsers,
330+
modifyNotificationNode,
300331
};

src/services/AutoPilotService.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ function* handle(message, ruleSets) {
2020
if ((message.payload.phaseTypeName === _.get(ruleSets, "phaseTypeName"))
2121
&& (message.payload.state === _.get(ruleSets, "state"))) {
2222
const challengeId = message.payload.projectId
23-
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)
2423
const filerOnRoles = _.get(ruleSets, "roles")
24+
25+
const notification = yield tcApiHelper.modifyNotificationNode(ruleSets, { id: challengeId})
26+
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)
2527
const users = tcApiHelper.filterChallengeUsers(usersInfo, filerOnRoles)
28+
2629
logger.info(`Successfully filetered ${users.length} users on rulesets ${JSON.stringify(filerOnRoles)} `)
2730
// notify users of message
28-
return yield tcApiHelper.notifyUsersOfMessage(users, message);
31+
return yield tcApiHelper.notifyUsersOfMessage(users, notification);
2932
}
3033
return {}
3134
}

src/services/ChallengeService.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ function* handle(message, ruleSets) {
1919

2020
if (message.payload.type === _.get(ruleSets, "type")) {
2121
const challengeId = message.payload.data.id
22-
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)
2322
const filterOnRoles = _.get(ruleSets, "roles")
23+
const challengeTitle = _.get(message.payload, "data.name")
24+
25+
const notification = yield tcApiHelper.modifyNotificationNode(ruleSets, { id: challengeId, name: challengeTitle })
26+
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)
2427
const users = tcApiHelper.filterChallengeUsers(usersInfo, filterOnRoles)
2528
logger.info(`Successfully filetered ${users.length} users on rulesets ${JSON.stringify(filterOnRoles)} `)
2629
// notify users of message
27-
return yield tcApiHelper.notifyUsersOfMessage(users, message);
30+
return yield tcApiHelper.notifyUsersOfMessage(users, notification);
2831
}
2932
return {}
3033
}

src/services/SubmissionService.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,20 @@ function* handle(message, ruleSets) {
1919

2020
if (message.payload.resource === _.get(ruleSets, "resource")) {
2121
const challengeId = message.payload.challengeId
22-
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)
22+
const filterOnRoles = _.get(ruleSets, "roles")
2323

2424
const filterOnUsers = []
2525
if (_.get(ruleSets, 'selfOnly')) {
2626
const memberId = _.get(message.payload, "memberId")
2727
filterOnUsers.push(memberId)
2828
}
29-
const filterOnRoles = _.get(ruleSets, "roles")
29+
30+
const usersInfo = yield tcApiHelper.getUsersInfoFromChallenge(challengeId)
3031
const users = tcApiHelper.filterChallengeUsers(usersInfo, filterOnRoles, filterOnUsers)
32+
const notification = yield tcApiHelper.modifyNotificationNode(ruleSets, { id: challengeId})
3133
logger.info(`Successfully filetered ${users.length} users on rulesets ${JSON.stringify(filterOnRoles)} `)
3234
// notify users of message
33-
return yield tcApiHelper.notifyUsersOfMessage(users, message);
35+
return yield tcApiHelper.notifyUsersOfMessage(users, notification);
3436
}
3537
return {}
3638
}
@@ -42,7 +44,7 @@ handle.schema = {
4244
timestamp: joi.date().required(),
4345
'mime-type': joi.string().required(),
4446
payload: joi.object().keys({
45-
resource: joi.string().required()
47+
resource: joi.string().required()
4648
}).unknown(true).required(),
4749
}).required(),
4850
ruleSets: joi.object()

0 commit comments

Comments
 (0)