diff --git a/connect/config.js b/connect/config.js index a0f00a1..5f939c8 100644 --- a/connect/config.js +++ b/connect/config.js @@ -13,6 +13,7 @@ module.exports = { // 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_MANAGER_ROLE_ID: 113, CONNECT_ACCOUNT_MANAGER_ROLE_ID: 114, CONNECT_COPILOT_ROLE_ID: 4, ADMINISTRATOR_ROLE_ID: 1, diff --git a/connect/connectNotificationServer.js b/connect/connectNotificationServer.js index 7fa03f9..fa62b1f 100644 --- a/connect/connectNotificationServer.js +++ b/connect/connectNotificationServer.js @@ -101,6 +101,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 * @@ -307,6 +335,7 @@ 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), @@ -321,8 +350,8 @@ const handler = (topic, message, logger, callback) => { )).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)); } // now let's retrieve some additional data diff --git a/connect/constants.js b/connect/constants.js index 5625c62..bfcf725 100644 --- a/connect/constants.js +++ b/connect/constants.js @@ -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', diff --git a/connect/events-config.js b/connect/events-config.js index 68772a1..27c9247 100644 --- a/connect/events-config.js +++ b/connect/events-config.js @@ -23,6 +23,7 @@ const PROJECT_ROLE_RULES = { // 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'; @@ -30,6 +31,7 @@ const ROLE_ADMINISTRATOR = 'administrator'; const TOPCODER_ROLE_RULES = { [ROLE_CONNECT_COPILOT]: { id: config.CONNECT_COPILOT_ROLE_ID }, [ROLE_CONNECT_MANAGER]: { id: config.CONNECT_MANAGER_ROLE_ID }, + [ROLE_CONNECT_COPILOT_MANAGER]: { id: config.CONNECT_COPILOT_MANAGER_ROLE_ID }, [ROLE_CONNECT_ACCOUNT_MANAGER]: { id: config.CONNECT_ACCOUNT_MANAGER_ROLE_ID }, [ROLE_ADMINISTRATOR]: { id: config.ADMINISTRATOR_ROLE_ID }, }; @@ -112,6 +114,16 @@ 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, + originator: true }, // Project activity @@ -268,6 +280,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: { diff --git a/docs/tc-notification-server-api.postman_collection.json b/docs/tc-notification-server-api.postman_collection.json index e3b1c4e..f7c65c0 100644 --- a/docs/tc-notification-server-api.postman_collection.json +++ b/docs/tc-notification-server-api.postman_collection.json @@ -23,7 +23,7 @@ "description": "", "auth": null, "events": null, - "collection": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "folder": null, "order": [ "1b3b6480-ea94-4027-8898-f82f28e2bea6", @@ -40,6 +40,7 @@ "requests": [ { "id": "19332a51-03e8-4f5c-8f85-4d28d6dfe6f4", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "name": "getSettings", "url": "{{URL}}/settings", "description": "", @@ -71,6 +72,7 @@ }, { "id": "1b3b6480-ea94-4027-8898-f82f28e2bea6", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "name": "listNotifications - invalid read filter", "url": "{{URL}}/list?offset=0&limit=20&type=notifications.connect.project.updated&read=yes", "description": "", @@ -131,6 +133,7 @@ }, { "id": "543cab06-2c7d-4aed-8cf3-0808463254d5", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "name": "markAllRead", "url": "{{URL}}/read", "description": "", @@ -162,6 +165,7 @@ }, { "id": "59fc9f2b-28c5-4cff-b21b-11ab51bf67d8", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "name": "getSettings - invalid token", "url": "{{URL}}/settings", "description": "", @@ -193,6 +197,7 @@ }, { "id": "76779830-a8a4-4636-8c03-1801b3d1863d", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "name": "markAsRead", "url": "{{URL}}/1/read", "description": "", @@ -226,6 +231,7 @@ "id": "cb2299a5-dac7-4c40-80c4-7b1694138354", "name": "TC API - get project", "url": "https://api.topcoder-dev.com/v4/projects/1936", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "description": "", "data": [], "dataMode": "raw", @@ -339,7 +345,7 @@ ], "cookies": [], "request": "cb2299a5-dac7-4c40-80c4-7b1694138354", - "collection": "3f30c4e3-3b7a-491b-bdb2-6629d081a452" + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452" } ], "rawModeData": "", @@ -351,6 +357,7 @@ "name": "markAsRead - not found", "url": "{{URL}}/1111111/read", "description": "", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "data": [], "dataMode": "raw", "headerData": [ @@ -380,6 +387,7 @@ { "id": "d293d2c5-230d-4f34-8c97-1adc1f2f89b4", "name": "listNotifications - invalid limit", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "url": "{{URL}}/list?offset=0&limit=abc&type=notifications.connect.project.updated", "description": "", "data": [], @@ -441,6 +449,7 @@ "id": "d57ba947-a5e7-410a-b978-76882f33c86e", "name": "updateSettings", "url": "{{URL}}/settings", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "description": "", "data": [], "dataMode": "raw", @@ -471,6 +480,7 @@ { "id": "da23d550-55b3-4f7d-9131-735956d62f6d", "name": "markAllRead - missing token", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "url": "{{URL}}/read", "description": "", "data": [], @@ -495,6 +505,7 @@ }, { "id": "f2246cf7-7aae-4ea0-9d92-1d932d340302", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "name": "updateSettings - invalid body", "url": "{{URL}}/settings", "description": "", @@ -527,6 +538,7 @@ { "id": "f3f3a847-46f6-4059-b167-b436078fb112", "name": "listNotifications - invalid offset", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "url": "{{URL}}/list?offset=-1&limit=20&type=notifications.connect.project.updated", "description": "", "data": [], @@ -586,6 +598,7 @@ }, { "id": "fce69847-5bf8-4b07-bcaf-6352db4ba923", + "collectionId": "3f30c4e3-3b7a-491b-bdb2-6629d081a452", "name": "listNotifications", "url": "{{URL}}/list?offset=0&limit=20", "description": "", @@ -645,4 +658,4 @@ "pathVariables": {} } ] -} \ No newline at end of file +} diff --git a/emails/src/partials/project-team.html b/emails/src/partials/project-team.html index 733ee86..6f2b64d 100644 --- a/emails/src/partials/project-team.html +++ b/emails/src/partials/project-team.html @@ -21,7 +21,7 @@