From fc9ff191130b0c0d835d6c27602872fba06d3eba Mon Sep 17 00:00:00 2001 From: Samir Date: Tue, 19 Feb 2019 01:16:52 +0100 Subject: [PATCH 1/3] copilot workflow changes --- connect/config.js | 1 + connect/connectNotificationServer.js | 31 ++++++++++++++++++- connect/constants.js | 3 ++ connect/events-config.js | 25 ++++++++++++--- ...ication-server-api.postman_collection.json | 19 ++++++++++-- emails/src/partials/project-team.html | 23 +++++++++++--- 6 files changed, 88 insertions(+), 14 deletions(-) diff --git a/connect/config.js b/connect/config.js index 057dbed..b9337f8 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_COPILOT_ROLE_ID: 4, ADMINISTRATOR_ROLE_ID: 1, // id of the BOT user which creates post with various events in discussions diff --git a/connect/connectNotificationServer.js b/connect/connectNotificationServer.js index 7fa03f9..a71dd05 100644 --- a/connect/connectNotificationServer.js +++ b/connect/connectNotificationServer.js @@ -101,6 +101,34 @@ const getNotificationsForMentionedUser = (eventConfig, content) => { }); }; +/** + * Get notifications for users obtained from createdBy + * + * @param {Object} eventConfig event configuration + * @param {String} createdBy created by + * + * @return {Promise} resolves to a list of notifications + */ +const getNotificationsForCreatedBy = (eventConfig, createdBy) => { + // if event doesn't have to be notified to creator, just ignore + if (!eventConfig.creator) { + return Promise.resolve([]); + } + + // if we have to send notification to the creator, + // but it's not provided in the message, then throw error + if (!createdBy) { + return Promise.reject(new Error('Missing createdBy in the event message.')); + } + + return Promise.resolve([{ + userId: createdBy.toString(), + contents: { + creator: 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), + getNotificationsForCreatedBy(eventConfig, message.createdBy), getNotificationsForMentionedUser(eventConfig, message.postContent), getProjectMembersNotifications(eventConfig, project), getTopCoderMembersNotifications(eventConfig), @@ -321,7 +350,7 @@ 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){ + if (eventConfig.includeUsers && message[eventConfig.includeUsers] && message[eventConfig.includeUsers].length > 0) { allNotifications = _.filter(allNotifications, notification => message[eventConfig.includeUsers].contains(notification.userId)); } diff --git a/connect/constants.js b/connect/constants.js index 5625c62..c0dfb93 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', + COPILOT_ADDED: 'notifications.connect.project.member.copilot.added', + COPILOT_REFUSED: 'notifications.connect.project.member.copilot.refused', }, PROJECT: { ACTIVE: 'notifications.connect.project.active', diff --git a/connect/events-config.js b/connect/events-config.js index 98b2cdb..712745b 100644 --- a/connect/events-config.js +++ b/connect/events-config.js @@ -21,12 +21,14 @@ 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_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_CONNECT_COPILOT_MANAGER]: { id: config.CONNECT_COPILOT_MANAGER_ROLE_ID }, [ROLE_ADMINISTRATOR]: { id: config.ADMINISTRATOR_ROLE_ID }, }; @@ -107,6 +109,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.COPILOT_ADDED, + toUserHandle: true, + creator: true + }, { + type: BUS_API_EVENT.CONNECT.MEMBER.COPILOT_REFUSED, + creator: true }, // Project activity @@ -149,7 +161,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, @@ -160,12 +172,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, @@ -200,8 +212,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 = { @@ -263,6 +275,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.COPILOT_ADDED, + BUS_API_EVENT.CONNECT.MEMBER.COPILOT_REFUSED, ], }, 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..1f0b8de 100644 --- a/emails/src/partials/project-team.html +++ b/emails/src/partials/project-team.html @@ -21,7 +21,7 @@ -
+ @@ -60,12 +60,25 @@ {{#if [notifications.connect.project.member.invite.created]}} Hi {{userFullName}}, you are invited to join the project {{projectName}}. Please click on the button ("View project on Connect") below to join. {{/if}} + {{#if [notifications.connect.project.member.invite.requested]}} + You are requested to add {{userFullName}} as a copilot + {{/if}} + {{#if [notifications.connect.project.member.copilot.added]}} + {{#if [creator]}} + Your request to add invite the copilot was approved + {{else}} + Hi {{userFullName}}, you are added as a copilot + {{/if}} + {{/if}} + {{#if [notifications.connect.project.member.copilot.refused]}} + Your request to add the copilot was refused + {{/if}} - + {{/each}} @@ -76,7 +89,7 @@ -
+ @@ -98,7 +111,7 @@ -
+ -{{/if}} \ No newline at end of file +{{/if}} From 36a2d9f0e3f34b86c2bd547667dedcd9f276645e Mon Sep 17 00:00:00 2001 From: Samir Date: Wed, 20 Feb 2019 11:23:29 +0100 Subject: [PATCH 2/3] rename events --- connect/connectNotificationServer.js | 16 ++++++++-------- connect/constants.js | 4 ++-- connect/events-config.js | 12 ++++++------ emails/src/partials/project-team.html | 8 ++++---- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/connect/connectNotificationServer.js b/connect/connectNotificationServer.js index a71dd05..69756e4 100644 --- a/connect/connectNotificationServer.js +++ b/connect/connectNotificationServer.js @@ -102,14 +102,14 @@ const getNotificationsForMentionedUser = (eventConfig, content) => { }; /** - * Get notifications for users obtained from createdBy + * Get notifications for users obtained from originator * * @param {Object} eventConfig event configuration - * @param {String} createdBy created by + * @param {String} originator originator userId * * @return {Promise} resolves to a list of notifications */ -const getNotificationsForCreatedBy = (eventConfig, createdBy) => { +const getNotificationsForOriginator = (eventConfig, originator) => { // if event doesn't have to be notified to creator, just ignore if (!eventConfig.creator) { return Promise.resolve([]); @@ -117,14 +117,14 @@ const getNotificationsForCreatedBy = (eventConfig, createdBy) => { // if we have to send notification to the creator, // but it's not provided in the message, then throw error - if (!createdBy) { - return Promise.reject(new Error('Missing createdBy in the event message.')); + if (!originator) { + return Promise.reject(new Error('Missing originator in the event message.')); } return Promise.resolve([{ - userId: createdBy.toString(), + userId: originator.toString(), contents: { - creator: true, + originator: true, }, }]); }; @@ -335,7 +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), - getNotificationsForCreatedBy(eventConfig, message.createdBy), + getNotificationsForOriginator(eventConfig, message.originator), getNotificationsForMentionedUser(eventConfig, message.postContent), getProjectMembersNotifications(eventConfig, project), getTopCoderMembersNotifications(eventConfig), diff --git a/connect/constants.js b/connect/constants.js index c0dfb93..bfcf725 100644 --- a/connect/constants.js +++ b/connect/constants.js @@ -31,8 +31,8 @@ module.exports = { INVITE_CREATED: 'notifications.connect.project.member.invite.created', INVITE_UPDATED: 'notifications.connect.project.member.invite.updated', INVITE_REQUESTED: 'notifications.connect.project.member.invite.requested', - COPILOT_ADDED: 'notifications.connect.project.member.copilot.added', - COPILOT_REFUSED: 'notifications.connect.project.member.copilot.refused', + 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 712745b..45f67f5 100644 --- a/connect/events-config.js +++ b/connect/events-config.js @@ -113,12 +113,12 @@ const EVENTS = [ type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_REQUESTED, topcoderRoles: [ROLE_CONNECT_COPILOT_MANAGER], }, { - type: BUS_API_EVENT.CONNECT.MEMBER.COPILOT_ADDED, + type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_APPROVED, toUserHandle: true, - creator: true + originator: true }, { - type: BUS_API_EVENT.CONNECT.MEMBER.COPILOT_REFUSED, - creator: true + type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_REJECTED, + originator: true }, // Project activity @@ -276,8 +276,8 @@ const EVENT_BUNDLES = { 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.COPILOT_ADDED, - BUS_API_EVENT.CONNECT.MEMBER.COPILOT_REFUSED, + BUS_API_EVENT.CONNECT.MEMBER.INVITE_APPROVED, + BUS_API_EVENT.CONNECT.MEMBER.INVITE_REJECTED, ], }, PROJECT_PLAN: { diff --git a/emails/src/partials/project-team.html b/emails/src/partials/project-team.html index 1f0b8de..dc40b77 100644 --- a/emails/src/partials/project-team.html +++ b/emails/src/partials/project-team.html @@ -63,15 +63,15 @@ {{#if [notifications.connect.project.member.invite.requested]}} You are requested to add {{userFullName}} as a copilot {{/if}} - {{#if [notifications.connect.project.member.copilot.added]}} + {{#if [notifications.connect.project.member.invite.approved]}} {{#if [creator]}} - Your request to add invite the copilot was approved + Your request to add invite the member was approved {{else}} Hi {{userFullName}}, you are added as a copilot {{/if}} {{/if}} - {{#if [notifications.connect.project.member.copilot.refused]}} - Your request to add the copilot was refused + {{#if [notifications.connect.project.member.invite.rejected]}} + Your request to add the member was refused {{/if}} From 2769ddc37631b8f3714aea1d12afe869805a5450 Mon Sep 17 00:00:00 2001 From: Samir Date: Wed, 20 Feb 2019 20:04:40 +0100 Subject: [PATCH 3/3] fix lint --- connect/connectNotificationServer.js | 6 +++--- emails/src/partials/project-team.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/connect/connectNotificationServer.js b/connect/connectNotificationServer.js index 69756e4..037bc99 100644 --- a/connect/connectNotificationServer.js +++ b/connect/connectNotificationServer.js @@ -110,12 +110,12 @@ const getNotificationsForMentionedUser = (eventConfig, content) => { * @return {Promise} resolves to a list of notifications */ const getNotificationsForOriginator = (eventConfig, originator) => { - // if event doesn't have to be notified to creator, just ignore - if (!eventConfig.creator) { + // 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 creator, + // 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.')); diff --git a/emails/src/partials/project-team.html b/emails/src/partials/project-team.html index dc40b77..6f2b64d 100644 --- a/emails/src/partials/project-team.html +++ b/emails/src/partials/project-team.html @@ -64,7 +64,7 @@ You are requested to add {{userFullName}} as a copilot {{/if}} {{#if [notifications.connect.project.member.invite.approved]}} - {{#if [creator]}} + {{#if [originator]}} Your request to add invite the member was approved {{else}} Hi {{userFullName}}, you are added as a copilot