Skip to content

Commit 186f43b

Browse files
authored
Merge pull request #93 from topcoder-platform/dev
Supporting release for Connect 2.4.10
2 parents 945bc2d + 8645140 commit 186f43b

11 files changed

+404
-116
lines changed

connect/config.js

-7
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@ module.exports = {
88
TC_API_V4_BASE_URL: process.env.TC_API_V4_BASE_URL || 'https://api.topcoder-dev.com/v4',
99
MESSAGE_API_BASE_URL: process.env.MESSAGE_API_BASE_URL || 'https://api.topcoder-dev.com/v5',
1010

11-
// Probably temporary variables for TopCoder role ids for 'Connect Manager', 'Connect Copilot' and 'administrator'
12-
// These are values for development backend. For production backend they may be different.
13-
// These variables are currently being used to retrieve above role members using API V3 `/roles` endpoint.
14-
// As soon as this endpoint is replaced with more suitable one, these variables has to be removed if no need anymore.
15-
CONNECT_MANAGER_ROLE_ID: 8,
16-
CONNECT_COPILOT_ROLE_ID: 4,
17-
ADMINISTRATOR_ROLE_ID: 1,
1811
// id of the BOT user which creates post with various events in discussions
1912
TCWEBSERVICE_ID: process.env.TCWEBSERVICE_ID || '22838965',
2013
CODERBOT_USER_ID: process.env.CODERBOT_USER_ID || 'CoderBot',

connect/connectNotificationServer.js

+39-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const _ = require('lodash');
1111
const service = require('./service');
1212
const { BUS_API_EVENT } = require('./constants');
1313
const EVENTS = require('./events-config').EVENTS;
14-
const TOPCODER_ROLE_RULES = require('./events-config').TOPCODER_ROLE_RULES;
1514
const PROJECT_ROLE_RULES = require('./events-config').PROJECT_ROLE_RULES;
1615
const PROJECT_ROLE_OWNER = require('./events-config').PROJECT_ROLE_OWNER;
1716
const emailNotificationServiceHandler = require('./notificationServices/email').handler;
@@ -30,7 +29,7 @@ const getTopCoderMembersNotifications = (eventConfig) => {
3029
}
3130

3231
const getRoleMembersPromises = eventConfig.topcoderRoles.map(topcoderRole => (
33-
service.getRoleMembers(TOPCODER_ROLE_RULES[topcoderRole].id)
32+
service.getRoleMembers(topcoderRole)
3433
));
3534

3635
return Promise.all(getRoleMembersPromises).then((membersPerRole) => {
@@ -101,6 +100,34 @@ const getNotificationsForMentionedUser = (eventConfig, content) => {
101100
});
102101
};
103102

103+
/**
104+
* Get notifications for users obtained from originator
105+
*
106+
* @param {Object} eventConfig event configuration
107+
* @param {String} originator originator userId
108+
*
109+
* @return {Promise} resolves to a list of notifications
110+
*/
111+
const getNotificationsForOriginator = (eventConfig, originator) => {
112+
// if event doesn't have to be notified to originator, just ignore
113+
if (!eventConfig.originator) {
114+
return Promise.resolve([]);
115+
}
116+
117+
// if we have to send notification to the originator,
118+
// but it's not provided in the message, then throw error
119+
if (!originator) {
120+
return Promise.reject(new Error('Missing originator in the event message.'));
121+
}
122+
123+
return Promise.resolve([{
124+
userId: originator.toString(),
125+
contents: {
126+
originator: true,
127+
},
128+
}]);
129+
};
130+
104131
/**
105132
* Get project members notifications
106133
*
@@ -307,24 +334,28 @@ const handler = (topic, message, logger, callback) => {
307334
// - check that event has everything required or throw error
308335
getNotificationsForTopicStarter(eventConfig, message.topicId),
309336
getNotificationsForUserId(eventConfig, message.userId),
337+
getNotificationsForOriginator(eventConfig, message.originator),
310338
getNotificationsForMentionedUser(eventConfig, message.postContent),
311339
getProjectMembersNotifications(eventConfig, project),
312340
getTopCoderMembersNotifications(eventConfig),
313-
]).then((notificationsPerSource) => (
341+
]).then((notificationsPerSource) => {
314342
// first found notification for one user will be send, the rest ignored
315343
// NOTE all userId has to be string
316-
_.uniqBy(_.flatten(notificationsPerSource), 'userId')
317-
)).then((notifications) => (
344+
logger.debug('all notifications: ', notificationsPerSource);
345+
return _.uniqBy(_.flatten(notificationsPerSource), 'userId');
346+
}).then((notifications) => (
318347
excludeNotifications(notifications, eventConfig, message, {
319348
project,
320349
})
321350
)).then((notifications) => {
322351
allNotifications = _.filter(notifications, notification => notification.userId !== `${message.initiatorUserId}`);
323352

324-
if (eventConfig.includeUsers && message[eventConfig.includeUsers] && message[eventConfig.includeUsers].length>0){
325-
allNotifications = _.filter(allNotifications, notification => message[eventConfig.includeUsers].contains(notification.userId));
353+
if (eventConfig.includeUsers && message[eventConfig.includeUsers] &&
354+
message[eventConfig.includeUsers].length > 0) {
355+
allNotifications = _.filter(allNotifications,
356+
notification => message[eventConfig.includeUsers].includes(notification.userId));
326357
}
327-
358+
logger.debug('filtered notifications: ', allNotifications);
328359
// now let's retrieve some additional data
329360

330361
// if message has userId such messages will likely need userHandle and user full name

connect/constants.js

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ module.exports = {
3030
ASSIGNED_AS_OWNER: 'notifications.connect.project.member.assignedAsOwner',
3131
INVITE_CREATED: 'notifications.connect.project.member.invite.created',
3232
INVITE_UPDATED: 'notifications.connect.project.member.invite.updated',
33+
INVITE_REQUESTED: 'notifications.connect.project.member.invite.requested',
34+
INVITE_APPROVED: 'notifications.connect.project.member.invite.approved',
35+
INVITE_REJECTED: 'notifications.connect.project.member.invite.rejected',
3336
},
3437
PROJECT: {
3538
ACTIVE: 'notifications.connect.project.active',

connect/events-config.js

+25-15
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,31 @@
11
/**
22
* Configuration of connect events
33
*/
4-
const config = require('./config');
54
const { BUS_API_EVENT } = require('./constants');
65

76
// project member role names
87
const PROJECT_ROLE_OWNER = 'owner';
98
const PROJECT_ROLE_COPILOT = 'copilot';
109
const PROJECT_ROLE_MANAGER = 'manager';
1110
const PROJECT_ROLE_MEMBER = 'member';
11+
const PROJECT_ROLE_ACCOUNT_MANAGER = 'account_manager';
1212

1313
// project member role rules
1414
const PROJECT_ROLE_RULES = {
1515
[PROJECT_ROLE_OWNER]: { role: 'customer', isPrimary: true },
1616
[PROJECT_ROLE_COPILOT]: { role: 'copilot' },
1717
[PROJECT_ROLE_MANAGER]: { role: 'manager' },
18+
[PROJECT_ROLE_ACCOUNT_MANAGER]: { role: 'account_manager' },
1819
[PROJECT_ROLE_MEMBER]: {},
1920
};
2021

2122
// TopCoder roles
2223
const ROLE_CONNECT_COPILOT = 'Connect Copilot';
2324
const ROLE_CONNECT_MANAGER = 'Connect Manager';
25+
const ROLE_CONNECT_COPILOT_MANAGER = 'Connect Copilot Manager';
26+
const ROLE_CONNECT_ACCOUNT_MANAGER = 'Connect Account Manager';
2427
const ROLE_ADMINISTRATOR = 'administrator';
2528

26-
// TopCoder role rules
27-
const TOPCODER_ROLE_RULES = {
28-
[ROLE_CONNECT_COPILOT]: { id: config.CONNECT_COPILOT_ROLE_ID },
29-
[ROLE_CONNECT_MANAGER]: { id: config.CONNECT_MANAGER_ROLE_ID },
30-
[ROLE_ADMINISTRATOR]: { id: config.ADMINISTRATOR_ROLE_ID },
31-
};
32-
3329
/**
3430
* Supported events configuration
3531
*
@@ -51,13 +47,14 @@ const EVENTS = [
5147
{
5248
type: BUS_API_EVENT.CONNECT.PROJECT.CREATED,
5349
projectRoles: [PROJECT_ROLE_OWNER],
50+
topcoderRoles: [ROLE_CONNECT_ACCOUNT_MANAGER],
5451
exclude: {
5552
topcoderRoles: [ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR],
5653
},
5754
}, {
5855
type: BUS_API_EVENT.CONNECT.PROJECT.SUBMITTED_FOR_REVIEW,
5956
projectRoles: [PROJECT_ROLE_OWNER],
60-
topcoderRoles: [ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR],
57+
topcoderRoles: [ROLE_CONNECT_MANAGER, ROLE_CONNECT_ACCOUNT_MANAGER, ROLE_ADMINISTRATOR],
6158
}, {
6259
type: BUS_API_EVENT.CONNECT.PROJECT.APPROVED,
6360
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER],
@@ -107,6 +104,17 @@ const EVENTS = [
107104
type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_CREATED,
108105
projectRoles: [],
109106
toUserHandle: true,
107+
}, {
108+
type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_REQUESTED,
109+
topcoderRoles: [ROLE_CONNECT_COPILOT_MANAGER],
110+
}, {
111+
type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_APPROVED,
112+
toUserHandle: true,
113+
originator: true,
114+
}, {
115+
type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_REJECTED,
116+
topcoderRoles: [ROLE_CONNECT_COPILOT_MANAGER],
117+
originator: true,
110118
},
111119

112120
// Project activity
@@ -149,7 +157,7 @@ const EVENTS = [
149157
type: BUS_API_EVENT.CONNECT.PROJECT.FILE_UPLOADED,
150158
version: 2,
151159
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER],
152-
includeUsers: 'allowedUsers'
160+
includeUsers: 'allowedUsers',
153161
}, {
154162
type: BUS_API_EVENT.CONNECT.PROJECT.SPECIFICATION_MODIFIED,
155163
version: 2,
@@ -160,12 +168,12 @@ const EVENTS = [
160168
}, {
161169
type: BUS_API_EVENT.CONNECT.PROJECT_PLAN.MODIFIED,
162170
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER],
163-
includeUsers: 'allowedUsers'
171+
includeUsers: 'allowedUsers',
164172
}, {
165173
type: BUS_API_EVENT.CONNECT.PROJECT_PLAN.PROGRESS_UPDATED,
166174
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER],
167175
},
168-
176+
169177
// Phase activity
170178
{
171179
type: BUS_API_EVENT.CONNECT.PROJECT_PLAN.PHASE_ACTIVATED,
@@ -200,8 +208,8 @@ const EVENTS = [
200208
}, {
201209
type: BUS_API_EVENT.CONNECT.PROJECT_PLAN.TIMELINE_ADJUSTED,
202210
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER],
203-
includeUsers: 'allowedUsers'
204-
}
211+
includeUsers: 'allowedUsers',
212+
},
205213
];
206214

207215
const EVENT_BUNDLES = {
@@ -263,6 +271,9 @@ const EVENT_BUNDLES = {
263271
BUS_API_EVENT.CONNECT.MEMBER.MANAGER_JOINED,
264272
BUS_API_EVENT.CONNECT.MEMBER.REMOVED,
265273
BUS_API_EVENT.CONNECT.MEMBER.INVITE_CREATED,
274+
BUS_API_EVENT.CONNECT.MEMBER.INVITE_REQUESTED,
275+
BUS_API_EVENT.CONNECT.MEMBER.INVITE_APPROVED,
276+
BUS_API_EVENT.CONNECT.MEMBER.INVITE_REJECTED,
266277
],
267278
},
268279
PROJECT_PLAN: {
@@ -293,7 +304,6 @@ const EVENT_BUNDLES = {
293304

294305
module.exports = {
295306
PROJECT_ROLE_RULES,
296-
TOPCODER_ROLE_RULES,
297307
EVENTS,
298308
EVENT_BUNDLES,
299309

0 commit comments

Comments
 (0)