@@ -22,6 +22,7 @@ const PROJECT_ROLE_OWNER = require('./events-config').PROJECT_ROLE_OWNER;
22
22
* @return {Promise } resolves to a list of notifications
23
23
*/
24
24
const getTopCoderMembersNotifications = ( eventConfig ) => {
25
+ // if event doesn't have to be notified to topcoder member, just ignore
25
26
if ( ! eventConfig . topcoderRoles ) {
26
27
return Promise . resolve ( [ ] ) ;
27
28
}
@@ -91,8 +92,13 @@ const getNotificationsForMentionedUser = (eventConfig, content) => {
91
92
*
92
93
* @return {Promise } resolves to a list of notifications
93
94
*/
94
- const getProjectMembersNotifications = ( eventConfig , project ) => (
95
- new Promise ( ( resolve ) => {
95
+ const getProjectMembersNotifications = ( eventConfig , project ) => {
96
+ // if event doesn't have to be notified to project member, just ignore
97
+ if ( ! eventConfig . projectRoles ) {
98
+ return Promise . resolve ( [ ] ) ;
99
+ }
100
+
101
+ return new Promise ( ( resolve ) => {
96
102
let notifications = [ ] ;
97
103
const projectMembers = _ . get ( project , 'members' , [ ] ) ;
98
104
@@ -128,8 +134,8 @@ const getProjectMembersNotifications = (eventConfig, project) => (
128
134
notifications = _ . uniqBy ( notifications , 'userId' ) ;
129
135
130
136
resolve ( notifications ) ;
131
- } )
132
- ) ;
137
+ } ) ;
138
+ } ;
133
139
134
140
/**
135
141
* Get notifications for users obtained from userId
@@ -179,12 +185,64 @@ const getNotificationsForTopicStarter = (eventConfig, topicId) => {
179
185
return Promise . reject ( new Error ( 'Missing topicId in the event message.' ) ) ;
180
186
}
181
187
182
- return service . getTopic ( topicId ) . then ( ( topic ) => ( {
183
- userId : topic . userId . toString ( ) ,
184
- contents : {
185
- toTopicStarter : true ,
186
- } ,
187
- } ) ) ;
188
+ return service . getTopic ( topicId ) . then ( ( topic ) => {
189
+ const userId = topic . userId . toString ( ) ;
190
+
191
+ // special case: if topic created by CoderBot, don't send notification to him
192
+ if ( userId === 'CoderBot' ) {
193
+ return [ ] ;
194
+ }
195
+
196
+ return [ {
197
+ userId,
198
+ contents : {
199
+ toTopicStarter : true ,
200
+ } ,
201
+ } ] ;
202
+ } ) ;
203
+ } ;
204
+
205
+ /**
206
+ * Exclude notifications using exclude rules of the event config
207
+ *
208
+ * @param {Array } notifications notifications list
209
+ * @param {Object } eventConfig event configuration
210
+ * @param {Object } message message
211
+ * @param {Object } data any additional data which is retrieved once
212
+ *
213
+ * @returns {Promise } resolves to the list of filtered notifications
214
+ */
215
+ const excludeNotifications = ( notifications , eventConfig , message , data ) => {
216
+ // if there are no rules to exclude notifications, just return all of them untouched
217
+ if ( ! eventConfig . exclude ) {
218
+ return Promise . resolve ( notifications ) ;
219
+ }
220
+
221
+ const { project } = data ;
222
+ // create event config using rules to exclude notifications
223
+ const excludeEventConfig = Object . assign ( {
224
+ type : eventConfig . type ,
225
+ } , eventConfig . exclude ) ;
226
+
227
+ // get notifications using rules for exclude notifications
228
+ // and after filter out such notifications from the notifications list
229
+ // TODO move this promise all together with `_.uniqBy` to one function
230
+ // and reuse it here and in `handler` function
231
+ return Promise . all ( [
232
+ getNotificationsForTopicStarter ( excludeEventConfig , message . topicId ) ,
233
+ getNotificationsForUserId ( excludeEventConfig , message . userId ) ,
234
+ getProjectMembersNotifications ( excludeEventConfig , project ) ,
235
+ getTopCoderMembersNotifications ( excludeEventConfig ) ,
236
+ ] ) . then ( ( notificationsPerSource ) => (
237
+ _ . uniqBy ( _ . flatten ( notificationsPerSource ) , 'userId' )
238
+ ) ) . then ( ( excludedNotifications ) => {
239
+ const excludedUserIds = _ . map ( excludedNotifications , 'userId' ) ;
240
+ const filteredNotifications = notifications . filter ( ( notification ) => (
241
+ ! _ . includes ( excludedUserIds , notification . userId )
242
+ ) ) ;
243
+
244
+ return filteredNotifications ;
245
+ } ) ;
188
246
} ;
189
247
190
248
// set configuration for the server, see ../config/default.js for available config parameters
@@ -233,12 +291,16 @@ const handler = (topic, message, callback) => {
233
291
// first found notification for one user will be send, the rest ignored
234
292
// NOTE all userId has to be string
235
293
_ . uniqBy ( _ . flatten ( notificationsPerSource ) , 'userId' )
294
+ ) ) . then ( ( notifications ) => (
295
+ excludeNotifications ( notifications , eventConfig , message , {
296
+ project,
297
+ } )
236
298
) ) . then ( ( notifications ) => {
237
299
allNotifications = notifications ;
238
300
239
301
// now let's retrieve some additional data
240
302
241
- // if message has userId such messages will likely need userHandle
303
+ // if message has userId such messages will likely need userHandle and user full name
242
304
// so let's get it
243
305
if ( message . userId ) {
244
306
const ids = [ message . userId ] ;
@@ -247,10 +309,12 @@ const handler = (topic, message, callback) => {
247
309
return [ ] ;
248
310
} ) . then ( ( users ) => {
249
311
_ . map ( allNotifications , ( notification ) => {
312
+ notification . version = eventConfig . version ;
250
313
notification . contents . projectName = project . name ;
251
314
// if found a user then add user handle
252
315
if ( users . length ) {
253
316
notification . contents . userHandle = users [ 0 ] . handle ;
317
+ notification . contents . userFullName = `${ users [ 0 ] . firstName } ${ users [ 0 ] . lastName } ` ;
254
318
}
255
319
} ) ;
256
320
callback ( null , allNotifications ) ;
0 commit comments