Skip to content

Supporting release for Connect 2.4.10 #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions connect/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ module.exports = {
TC_API_V4_BASE_URL: process.env.TC_API_V4_BASE_URL || 'https://api.topcoder-dev.com/v4',
MESSAGE_API_BASE_URL: process.env.MESSAGE_API_BASE_URL || 'https://api.topcoder-dev.com/v5',

// Probably temporary variables for TopCoder role ids for 'Connect Manager', 'Connect Copilot' and 'administrator'
// These are values for development backend. For production backend they may be different.
// These variables are currently being used to retrieve above role members using API V3 `/roles` endpoint.
// As soon as this endpoint is replaced with more suitable one, these variables has to be removed if no need anymore.
CONNECT_MANAGER_ROLE_ID: 8,
CONNECT_COPILOT_ROLE_ID: 4,
ADMINISTRATOR_ROLE_ID: 1,
// id of the BOT user which creates post with various events in discussions
TCWEBSERVICE_ID: process.env.TCWEBSERVICE_ID || '22838965',
CODERBOT_USER_ID: process.env.CODERBOT_USER_ID || 'CoderBot',
Expand Down
47 changes: 39 additions & 8 deletions connect/connectNotificationServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const _ = require('lodash');
const service = require('./service');
const { BUS_API_EVENT } = require('./constants');
const EVENTS = require('./events-config').EVENTS;
const TOPCODER_ROLE_RULES = require('./events-config').TOPCODER_ROLE_RULES;
const PROJECT_ROLE_RULES = require('./events-config').PROJECT_ROLE_RULES;
const PROJECT_ROLE_OWNER = require('./events-config').PROJECT_ROLE_OWNER;
const emailNotificationServiceHandler = require('./notificationServices/email').handler;
Expand All @@ -30,7 +29,7 @@ const getTopCoderMembersNotifications = (eventConfig) => {
}

const getRoleMembersPromises = eventConfig.topcoderRoles.map(topcoderRole => (
service.getRoleMembers(TOPCODER_ROLE_RULES[topcoderRole].id)
service.getRoleMembers(topcoderRole)
));

return Promise.all(getRoleMembersPromises).then((membersPerRole) => {
Expand Down Expand Up @@ -101,6 +100,34 @@ const getNotificationsForMentionedUser = (eventConfig, content) => {
});
};

/**
* Get notifications for users obtained from originator
*
* @param {Object} eventConfig event configuration
* @param {String} originator originator userId
*
* @return {Promise} resolves to a list of notifications
*/
const getNotificationsForOriginator = (eventConfig, originator) => {
// if event doesn't have to be notified to originator, just ignore
if (!eventConfig.originator) {
return Promise.resolve([]);
}

// if we have to send notification to the originator,
// but it's not provided in the message, then throw error
if (!originator) {
return Promise.reject(new Error('Missing originator in the event message.'));
}

return Promise.resolve([{
userId: originator.toString(),
contents: {
originator: true,
},
}]);
};

/**
* Get project members notifications
*
Expand Down Expand Up @@ -307,24 +334,28 @@ const handler = (topic, message, logger, callback) => {
// - check that event has everything required or throw error
getNotificationsForTopicStarter(eventConfig, message.topicId),
getNotificationsForUserId(eventConfig, message.userId),
getNotificationsForOriginator(eventConfig, message.originator),
getNotificationsForMentionedUser(eventConfig, message.postContent),
getProjectMembersNotifications(eventConfig, project),
getTopCoderMembersNotifications(eventConfig),
]).then((notificationsPerSource) => (
]).then((notificationsPerSource) => {
// first found notification for one user will be send, the rest ignored
// NOTE all userId has to be string
_.uniqBy(_.flatten(notificationsPerSource), 'userId')
)).then((notifications) => (
logger.debug('all notifications: ', notificationsPerSource);
return _.uniqBy(_.flatten(notificationsPerSource), 'userId');
}).then((notifications) => (
excludeNotifications(notifications, eventConfig, message, {
project,
})
)).then((notifications) => {
allNotifications = _.filter(notifications, notification => notification.userId !== `${message.initiatorUserId}`);

if (eventConfig.includeUsers && message[eventConfig.includeUsers] && message[eventConfig.includeUsers].length>0){
allNotifications = _.filter(allNotifications, notification => message[eventConfig.includeUsers].contains(notification.userId));
if (eventConfig.includeUsers && message[eventConfig.includeUsers] &&
message[eventConfig.includeUsers].length > 0) {
allNotifications = _.filter(allNotifications,
notification => message[eventConfig.includeUsers].includes(notification.userId));
}

logger.debug('filtered notifications: ', allNotifications);
// now let's retrieve some additional data

// if message has userId such messages will likely need userHandle and user full name
Expand Down
3 changes: 3 additions & 0 deletions connect/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ module.exports = {
ASSIGNED_AS_OWNER: 'notifications.connect.project.member.assignedAsOwner',
INVITE_CREATED: 'notifications.connect.project.member.invite.created',
INVITE_UPDATED: 'notifications.connect.project.member.invite.updated',
INVITE_REQUESTED: 'notifications.connect.project.member.invite.requested',
INVITE_APPROVED: 'notifications.connect.project.member.invite.approved',
INVITE_REJECTED: 'notifications.connect.project.member.invite.rejected',
},
PROJECT: {
ACTIVE: 'notifications.connect.project.active',
Expand Down
40 changes: 25 additions & 15 deletions connect/events-config.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
/**
* Configuration of connect events
*/
const config = require('./config');
const { BUS_API_EVENT } = require('./constants');

// project member role names
const PROJECT_ROLE_OWNER = 'owner';
const PROJECT_ROLE_COPILOT = 'copilot';
const PROJECT_ROLE_MANAGER = 'manager';
const PROJECT_ROLE_MEMBER = 'member';
const PROJECT_ROLE_ACCOUNT_MANAGER = 'account_manager';

// project member role rules
const PROJECT_ROLE_RULES = {
[PROJECT_ROLE_OWNER]: { role: 'customer', isPrimary: true },
[PROJECT_ROLE_COPILOT]: { role: 'copilot' },
[PROJECT_ROLE_MANAGER]: { role: 'manager' },
[PROJECT_ROLE_ACCOUNT_MANAGER]: { role: 'account_manager' },
[PROJECT_ROLE_MEMBER]: {},
};

// TopCoder roles
const ROLE_CONNECT_COPILOT = 'Connect Copilot';
const ROLE_CONNECT_MANAGER = 'Connect Manager';
const ROLE_CONNECT_COPILOT_MANAGER = 'Connect Copilot Manager';
const ROLE_CONNECT_ACCOUNT_MANAGER = 'Connect Account Manager';
const ROLE_ADMINISTRATOR = 'administrator';

// TopCoder role rules
const TOPCODER_ROLE_RULES = {
[ROLE_CONNECT_COPILOT]: { id: config.CONNECT_COPILOT_ROLE_ID },
[ROLE_CONNECT_MANAGER]: { id: config.CONNECT_MANAGER_ROLE_ID },
[ROLE_ADMINISTRATOR]: { id: config.ADMINISTRATOR_ROLE_ID },
};

/**
* Supported events configuration
*
Expand All @@ -51,13 +47,14 @@ const EVENTS = [
{
type: BUS_API_EVENT.CONNECT.PROJECT.CREATED,
projectRoles: [PROJECT_ROLE_OWNER],
topcoderRoles: [ROLE_CONNECT_ACCOUNT_MANAGER],
exclude: {
topcoderRoles: [ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR],
},
}, {
type: BUS_API_EVENT.CONNECT.PROJECT.SUBMITTED_FOR_REVIEW,
projectRoles: [PROJECT_ROLE_OWNER],
topcoderRoles: [ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR],
topcoderRoles: [ROLE_CONNECT_MANAGER, ROLE_CONNECT_ACCOUNT_MANAGER, ROLE_ADMINISTRATOR],
}, {
type: BUS_API_EVENT.CONNECT.PROJECT.APPROVED,
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER],
Expand Down Expand Up @@ -107,6 +104,17 @@ const EVENTS = [
type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_CREATED,
projectRoles: [],
toUserHandle: true,
}, {
type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_REQUESTED,
topcoderRoles: [ROLE_CONNECT_COPILOT_MANAGER],
}, {
type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_APPROVED,
toUserHandle: true,
originator: true,
}, {
type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_REJECTED,
topcoderRoles: [ROLE_CONNECT_COPILOT_MANAGER],
originator: true,
},

// Project activity
Expand Down Expand Up @@ -149,7 +157,7 @@ const EVENTS = [
type: BUS_API_EVENT.CONNECT.PROJECT.FILE_UPLOADED,
version: 2,
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER],
includeUsers: 'allowedUsers'
includeUsers: 'allowedUsers',
}, {
type: BUS_API_EVENT.CONNECT.PROJECT.SPECIFICATION_MODIFIED,
version: 2,
Expand All @@ -160,12 +168,12 @@ const EVENTS = [
}, {
type: BUS_API_EVENT.CONNECT.PROJECT_PLAN.MODIFIED,
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER],
includeUsers: 'allowedUsers'
includeUsers: 'allowedUsers',
}, {
type: BUS_API_EVENT.CONNECT.PROJECT_PLAN.PROGRESS_UPDATED,
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER],
},

// Phase activity
{
type: BUS_API_EVENT.CONNECT.PROJECT_PLAN.PHASE_ACTIVATED,
Expand Down Expand Up @@ -200,8 +208,8 @@ const EVENTS = [
}, {
type: BUS_API_EVENT.CONNECT.PROJECT_PLAN.TIMELINE_ADJUSTED,
projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER],
includeUsers: 'allowedUsers'
}
includeUsers: 'allowedUsers',
},
];

const EVENT_BUNDLES = {
Expand Down Expand Up @@ -263,6 +271,9 @@ const EVENT_BUNDLES = {
BUS_API_EVENT.CONNECT.MEMBER.MANAGER_JOINED,
BUS_API_EVENT.CONNECT.MEMBER.REMOVED,
BUS_API_EVENT.CONNECT.MEMBER.INVITE_CREATED,
BUS_API_EVENT.CONNECT.MEMBER.INVITE_REQUESTED,
BUS_API_EVENT.CONNECT.MEMBER.INVITE_APPROVED,
BUS_API_EVENT.CONNECT.MEMBER.INVITE_REJECTED,
],
},
PROJECT_PLAN: {
Expand Down Expand Up @@ -293,7 +304,6 @@ const EVENT_BUNDLES = {

module.exports = {
PROJECT_ROLE_RULES,
TOPCODER_ROLE_RULES,
EVENTS,
EVENT_BUNDLES,

Expand Down
Loading