From 1ae258737d487987b708af00163c36dfdfb245f2 Mon Sep 17 00:00:00 2001 From: Samir Date: Tue, 8 Jan 2019 00:34:17 +0100 Subject: [PATCH 1/9] add email invites support --- emails/src/partials/invites.html | 68 ++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 emails/src/partials/invites.html diff --git a/emails/src/partials/invites.html b/emails/src/partials/invites.html new file mode 100644 index 0000000..8c10bc7 --- /dev/null +++ b/emails/src/partials/invites.html @@ -0,0 +1,68 @@ +{{#if [EMAIL_INVITES]}} + + + + + + + + + + + + +
IMG + Project invitation. +
+ + + + + + +
+ + + + + + + + + + +
You are invited to join the {{projectName}} on Topcoder Connect
+ + + + + + + + +
+ + + + + + + + + + +
+ + Register a Topcoder account to join the project + +
+ + + + + + +
+ + +{{/if}} \ No newline at end of file From 0eec29bb4aa57b6fe89defaee33063e69bdcc9b1 Mon Sep 17 00:00:00 2001 From: Samir Date: Tue, 8 Jan 2019 00:37:54 +0100 Subject: [PATCH 2/9] update invites template --- emails/src/partials/invites.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emails/src/partials/invites.html b/emails/src/partials/invites.html index 8c10bc7..bf08283 100644 --- a/emails/src/partials/invites.html +++ b/emails/src/partials/invites.html @@ -49,7 +49,7 @@ - + Register a Topcoder account to join the project From 48deee31a815c3fdf8443ce6f8febfc5f493c839 Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Tue, 8 Jan 2019 15:51:28 +0530 Subject: [PATCH 3/9] Sending notification email to invited registered user --- connect/constants.js | 2 ++ connect/events-config.js | 5 +++++ emails/src/partials/invites.html | 8 ++++---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/connect/constants.js b/connect/constants.js index fd46cf8..5625c62 100644 --- a/connect/constants.js +++ b/connect/constants.js @@ -28,6 +28,8 @@ module.exports = { MANAGER_JOINED: 'notifications.connect.project.member.managerJoined', COPILOT_JOINED: 'notifications.connect.project.member.copilotJoined', ASSIGNED_AS_OWNER: 'notifications.connect.project.member.assignedAsOwner', + INVITE_CREATED: 'notifications.connect.project.member.invite.created', + INVITE_UPDATED: 'notifications.connect.project.member.invite.updated', }, PROJECT: { ACTIVE: 'notifications.connect.project.active', diff --git a/connect/events-config.js b/connect/events-config.js index 142d8aa..4c442bd 100644 --- a/connect/events-config.js +++ b/connect/events-config.js @@ -103,6 +103,10 @@ const EVENTS = [ }, { type: BUS_API_EVENT.CONNECT.MEMBER.MANAGER_JOINED, projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], + }, { + type: BUS_API_EVENT.CONNECT.MEMBER.INVITE_CREATED, + projectRoles: [], + toUserHandle: true, }, // Project activity @@ -255,6 +259,7 @@ const EVENT_BUNDLES = { BUS_API_EVENT.CONNECT.MEMBER.LEFT, BUS_API_EVENT.CONNECT.MEMBER.MANAGER_JOINED, BUS_API_EVENT.CONNECT.MEMBER.REMOVED, + BUS_API_EVENT.CONNECT.MEMBER.INVITE_CREATED, ], }, PROJECT_PLAN: { diff --git a/emails/src/partials/invites.html b/emails/src/partials/invites.html index bf08283..d8eb8f3 100644 --- a/emails/src/partials/invites.html +++ b/emails/src/partials/invites.html @@ -10,7 +10,7 @@ IMG - Project invitation. + {{title}}. @@ -29,7 +29,7 @@ - +
You are invited to join the {{projectName}} on Topcoder ConnectYou are invited to join the {{projectName}} on Topcoder Connect. To join the project, please register for a Topcoder account using Register button below.
@@ -49,8 +49,8 @@ - - Register a Topcoder account to join the project + + Register From 450f415c87ea0d57ff630f132fe87117d6ce097e Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Tue, 8 Jan 2019 15:53:58 +0530 Subject: [PATCH 4/9] Content for project invite in notification email for project team invite event --- emails/src/partials/project-team.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/emails/src/partials/project-team.html b/emails/src/partials/project-team.html index 62c169b..03c7398 100644 --- a/emails/src/partials/project-team.html +++ b/emails/src/partials/project-team.html @@ -53,6 +53,9 @@ {{#if [notifications.connect.project.member.joined]}} {{userFullName}} joined the project {{/if}} + {{#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}} From 4a666efca133b9781e29628e26fcf297f912e0db Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Tue, 8 Jan 2019 15:55:52 +0530 Subject: [PATCH 5/9] Trying to handle different copy for affected user --- connect/notificationServices/email.js | 1 + emails/src/partials/project-team.html | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/connect/notificationServices/email.js b/connect/notificationServices/email.js index f7a20cc..9eddbb7 100644 --- a/connect/notificationServices/email.js +++ b/connect/notificationServices/email.js @@ -233,6 +233,7 @@ function handler(topicName, messageJSON, notification) { authorFullName: notification.contents.userFullName, photoURL: notification.contents.photoURL, type: notificationType, + emailToAffectedUser: notification.contents.userEmail === userEmail, }, recipients, version:"v3", diff --git a/emails/src/partials/project-team.html b/emails/src/partials/project-team.html index 03c7398..733ee86 100644 --- a/emails/src/partials/project-team.html +++ b/emails/src/partials/project-team.html @@ -45,7 +45,11 @@ {{userFullName}} joined the project as Manager {{/if}} {{#if [notifications.connect.project.member.removed]}} - {{userFullName}} left the project + {{#if [emailToAffectedUser]}} + You are removed from the project + {{else}} + {{userFullName}} left the project + {{/if}} {{/if}} {{#if [notifications.connect.project.member.left]}} {{userFullName}} left the project From 2995d5abe0ee8dbc5a5657cc9749ab467318aa09 Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Tue, 8 Jan 2019 17:00:42 +0530 Subject: [PATCH 6/9] =?UTF-8?q?Using=20first=20event=20in=20the=20category?= =?UTF-8?q?=20of=20the=20notification=20type=20in=20case=20we=20don?= =?UTF-8?q?=E2=80=99t=20find=20a=20setting=20for=20the=20notification=20ty?= =?UTF-8?q?pe.=20This=20mostly=20happens=20for=20a=20new=20notification=20?= =?UTF-8?q?type.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- connect/notificationServices/email.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/connect/notificationServices/email.js b/connect/notificationServices/email.js index 9eddbb7..27aa187 100644 --- a/connect/notificationServices/email.js +++ b/connect/notificationServices/email.js @@ -292,6 +292,19 @@ function handler(topicName, messageJSON, notification) { bundlePeriod = bundlePeriod && bundlePeriod.trim().length > 0 ? bundlePeriod : null; // if bundling is not explicitly set and the event is not a messaging event, assume bundling enabled if (!bundlePeriod && !messagingEvent) { + // finds the event category for the notification type + let eventBundleCategory = _.findKey(EVENT_BUNDLES, b => b.types && b.types.indexOf(notificationType) !== -1); + if (eventBundleCategory) { + const eventBundle = EVENT_BUNDLES[eventBundleCategory]; + // if we find the event category for the notification, use the bundle settings from the first event + if (eventBundle && eventBundle.types && eventBundle.types.length) { + const firstEvtInBundle = eventBundle.types[0]; + const firstEvtBundleSettingPath = `notifications['${firstEvtInBundle}'].${SETTINGS_EMAIL_SERVICE_ID}.bundlePeriod` + let firstEvtBundlePeriod = _.get(settings, firstEvtBundleSettingPath); + bundlePeriod = firstEvtBundlePeriod + logger.debug('Assuming bundle period of first event in the event category=>', bundlePeriod); + } + } // if bundle period is not set, assume it to be daily for default case bundlePeriod = !bundlePeriod ? 'daily' : bundlePeriod; } From 6f8baffeb07b1d58a609b19a6e675e83ac275de1 Mon Sep 17 00:00:00 2001 From: vikasrohit Date: Thu, 10 Jan 2019 12:56:14 +0530 Subject: [PATCH 7/9] Updated ReadMe Added more description about the tc-notifications and how its components work. It also describes steps needed for other topcoder apps to use this system for notifications. --- README.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 03cf299..0ebacbc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,23 @@ -# TOPCODER NOTIFICATIONS SERIES - NOTIFICATIONS SERVER - +# TOPCODER NOTIFICATIONS + +## Description +This repository hosts the API and processors for enabling notifications in various topcoder apps. Currently it is limited to provide this facility to the [Connect](https://github.com/appirio-tech/connect-app) application. Theoretcially, it is a generic framework and application which could be used for sending and consuming notificaitons by any other topcoder app. In very simple words to send notifications using this application: + +1. Send an event to bus +2. Listen that event in tc-notifications +3. There is a config in tc-notifications for each event it want to listen and we can specify rules who are the target users to whom we should send notifications for this event +4. By default it saves all notifications which are generated after parsing the rules specified in step 3 and these are the treated web notifications which we show in the app directly +5. Then there is option to add notification handlers where we get all these notifications one by one and we can process them further for more channels e.g. we send notification emails for each of notification generated +6. When one wants to show the notifications, we use the notifications api (hosted inside the tc-notifications itself as separate service) to fetch notifications, mark notifications read or unread etc. + +tc-notifications (as a standard nodejs app) provides generic framework around notifications, it does not have config (used in step 3 of previous list) for specific apps. So, to have config for specific apps, we have to start the notification consumers per app e.g. for connect, we have a folder [`connect`](https://github.com/topcoder-platform/tc-notifications/blob/dev/connect) which hosts start script to start notification consumers with connect specific configuration ([`events-config.js`](https://github.com/topcoder-platform/tc-notifications/blob/dev/connect/events-config.js)). It also adds email notification service which sends emails for notifications as per notification settings (coming from common framework laid by tc-notifications) for the user. + +### Steps needed to enable other apps to use the notifications are: +1. Have a separate start up script (in a new folder at the root of the repo) for the concerned app. I would call this as notification consumer/processor. +2. Write [`events-config.js`](https://github.com/topcoder-platform/tc-notifications/blob/dev/connect/events-config.js) (name is not important, we have to read this file in the start up script written in step 1) for app specific notifications +3. Write additional notification services (eg. if you want to send email or slack or any other notification) and add them to startup script +4. Specify a node script in package.json to launch the start up script written in step 1 +5. Either add deployment for this new notification consumer/processor in existing deployment script (if you want to host the processor as separate service in the same ECS cluster) or write a new script if you want to keep the deployment separate. ## Dependencies - nodejs https://nodejs.org/en/ (v6+) From a3b035be2c3f7574cb8782b3a1af66654b97fb88 Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Tue, 15 Jan 2019 11:19:36 +0530 Subject: [PATCH 8/9] Fixed style issue with new user invite email template --- emails/src/partials/invites.html | 1 + 1 file changed, 1 insertion(+) diff --git a/emails/src/partials/invites.html b/emails/src/partials/invites.html index d8eb8f3..8e0da62 100644 --- a/emails/src/partials/invites.html +++ b/emails/src/partials/invites.html @@ -29,6 +29,7 @@ +
You are invited to join the {{projectName}} on Topcoder Connect. To join the project, please register for a Topcoder account using Register button below.
From 66329d4c591b8ef8d288990770864058ca988dfc Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Tue, 15 Jan 2019 12:34:38 +0530 Subject: [PATCH 9/9] Trying to get more information of initiator user --- connect/connectNotificationServer.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/connect/connectNotificationServer.js b/connect/connectNotificationServer.js index e6ed1f4..c315321 100644 --- a/connect/connectNotificationServer.js +++ b/connect/connectNotificationServer.js @@ -323,8 +323,9 @@ const handler = (topic, message, logger, callback) => { // if message has userId such messages will likely need userHandle and user full name // so let's get it + const ids = [message.initiatorUserId]; if (message.userId) { - const ids = [message.userId]; + ids.push(message.userId); return service.getUsersById(ids); } return []; @@ -335,10 +336,15 @@ const handler = (topic, message, logger, callback) => { notification.contents.timestamp = (new Date()).toISOString(); // if found a user then add user handle if (users.length) { - notification.contents.userHandle = users[0].handle; - notification.contents.userFullName = `${users[0].firstName} ${users[0].lastName}`; - notification.contents.userEmail = users[0].email; - notification.contents.photoURL = users[0].photoURL; + const affectedUser = _.find(users, u => u.userId === message.userId); + const initiatorUser = _.find(users, u => u.userId === message.initiatorUserId); + if (affectedUser) { + notification.contents.userHandle = affectedUser.handle; + notification.contents.userFullName = `${affectedUser.firstName} ${affectedUser.lastName}`; + notification.contents.userEmail = affectedUser.email; + notification.contents.photoURL = affectedUser.photoURL; + } + notification.contents.initiatorUser = initiatorUser; } }); callback(null, allNotifications);