@@ -88,6 +88,103 @@ function* getUsersByHandles(handles) {
88
88
return yield searchUsersByQuery ( query ) ;
89
89
}
90
90
91
+ /**
92
+ * Get users by handles or userIds.
93
+ * @param {Array<Object> } handles the objects that has user handles.
94
+ * @param {Array<Object> } userIds the objects that has userIds.
95
+ * @returns {Array<Object> } the matched users
96
+ */
97
+ function * getUsersByHandlesAndUserIds ( handles , userIds ) {
98
+ if ( ( ! handles || handles . length === 0 ) && ( ! userIds || userIds . length === 0 ) ) {
99
+ return [ ] ;
100
+ }
101
+ const handlesQuery = _ . map ( handles , h => `handleLower:${ h . handle . toLowerCase ( ) } ` ) ;
102
+ const userIdsQuery = _ . map ( userIds , u => `userId:${ u . userId } ` ) ;
103
+ const query = _ . concat ( handlesQuery , userIdsQuery ) . join ( URI . encodeQuery ( ' OR ' , 'utf8' ) ) ;
104
+ try {
105
+ return yield searchUsersByQuery ( query ) ;
106
+ } catch ( err ) {
107
+ const error = new Error ( err . response . text ) ;
108
+ error . status = err . status ;
109
+ throw error ;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Search users by query string.
115
+ * @param {String } query the query string
116
+ * @returns {Array } the matched users
117
+ */
118
+ function * searchUsersByEmailQuery ( query ) {
119
+ const token = yield getM2MToken ( ) ;
120
+ const res = yield request
121
+ . get ( `${
122
+ config . TC_API_V3_BASE_URL
123
+ } /users?filter=${
124
+ query
125
+ } &fields=id,email,handle`)
126
+ . set ( 'Authorization' , `Bearer ${ token } ` ) ;
127
+ if ( ! _ . get ( res , 'body.result.success' ) ) {
128
+ throw new Error ( `Failed to search users by query: ${ query } ` ) ;
129
+ }
130
+ const records = _ . get ( res , 'body.result.content' ) || [ ] ;
131
+
132
+ logger . verbose ( `Searched users: ${ JSON . stringify ( records , null , 4 ) } ` ) ;
133
+ return records ;
134
+ }
135
+
136
+ /**
137
+ * Get users by emails.
138
+ * @param {Array<Object> } emails the objects that has user emails.
139
+ * @returns {Array<Object> } the matched users
140
+ */
141
+ function * getUsersByEmails ( emails ) {
142
+ if ( ! emails || emails . length === 0 ) {
143
+ return [ ] ;
144
+ }
145
+ const users = [ ] ;
146
+ try {
147
+ for ( const email of emails ) {
148
+ const query = `email%3D${ email . email } ` ;
149
+ const result = yield searchUsersByEmailQuery ( query ) ;
150
+ users . push ( ...result ) ;
151
+ }
152
+ return users ;
153
+ } catch ( err ) {
154
+ const error = new Error ( err . response . text ) ;
155
+ error . status = err . status ;
156
+ throw error ;
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Get users by uuid.
162
+ * @param {Array<Object> } ids the objects that has user uuids.
163
+ * @returns {Array<Object> } the matched users
164
+ */
165
+ function * getUsersByUserUUIDs ( ids , enrich ) {
166
+ if ( ! ids || ids . length === 0 ) {
167
+ return [ ] ;
168
+ }
169
+ const users = [ ] ;
170
+ const token = yield getM2MToken ( ) ;
171
+ try {
172
+ for ( const id of ids ) {
173
+ const res = yield request
174
+ . get ( `${ config . TC_API_V5_BASE_URL } /users/${ id . userUUID } ${ enrich ? '?enrich=true' : '' } ` )
175
+ . set ( 'Authorization' , `Bearer ${ token } ` ) ;
176
+ const user = res . body ;
177
+ logger . verbose ( `Searched users: ${ JSON . stringify ( user , null , 4 ) } ` ) ;
178
+ users . push ( user ) ;
179
+ }
180
+ return users ;
181
+ } catch ( err ) {
182
+ const error = new Error ( err . response . text ) ;
183
+ error . status = err . status ;
184
+ throw error ;
185
+ }
186
+ }
187
+
91
188
/**
92
189
* Send message to bus.
93
190
* @param {Object } data the data to send
@@ -158,21 +255,30 @@ function* checkNotificationSetting(userId, notificationType, serviceId) {
158
255
}
159
256
160
257
/**
161
- * Notify user via email .
258
+ * Notify user via web .
162
259
* @param {Object } message the Kafka message payload
163
- * @return {Object } notification details.
260
+ * @return {Array< Object> } notification details.
164
261
*/
165
262
function * notifyUserViaWeb ( message ) {
166
263
const notificationType = message . type ;
167
- const userId = message . details . userId ;
168
- // if web notification is explicitly disabled for current notification type do nothing
169
- const allowed = yield checkNotificationSetting ( userId , notificationType , constants . SETTINGS_WEB_SERVICE_ID ) ;
170
- if ( ! allowed ) {
171
- logger . verbose ( `Notification '${ notificationType } ' won't be sent by '${ constants . SETTINGS_WEB_SERVICE_ID } '`
264
+ const notifications = [ ] ;
265
+ for ( const recipient of message . details . recipients ) {
266
+ const userId = recipient . userId ;
267
+ if ( _ . isUndefined ( userId ) ) {
268
+ logger . error ( `userId not received for user: ${ JSON . stringify ( recipient , null , 4 ) } ` ) ;
269
+ continue ;
270
+ }
271
+ // if web notification is explicitly disabled for current notification type do nothing
272
+ const allowed = yield checkNotificationSetting ( userId , notificationType , constants . SETTINGS_WEB_SERVICE_ID ) ;
273
+ if ( ! allowed ) {
274
+ logger . verbose ( `Notification '${ notificationType } ' won't be sent by '${ constants . SETTINGS_WEB_SERVICE_ID } '`
172
275
+ ` service to the userId '${ userId } ' due to his notification settings.` ) ;
173
- return ;
276
+ continue ;
277
+ }
278
+ notifications . push ( _ . assign ( { } , _ . pick ( message . details , [ 'contents' , 'version' ] ) , { userId } ) ) ;
174
279
}
175
- return message . details ;
280
+
281
+ return notifications ;
176
282
}
177
283
178
284
/**
@@ -182,31 +288,35 @@ function* notifyUserViaWeb(message) {
182
288
function * notifyUserViaEmail ( message ) {
183
289
const notificationType = message . type ;
184
290
const topic = constants . BUS_API_EVENT . EMAIL . UNIVERSAL ;
291
+ const cc = _ . map ( _ . filter ( message . details . cc , c => ! _ . isUndefined ( c . email ) ) , 'email' ) ;
185
292
for ( const recipient of message . details . recipients ) {
186
293
const userId = recipient . userId ;
187
- // if email notification is explicitly disabled for current notification type do nothing
188
- const allowed = yield checkNotificationSetting ( userId , notificationType , constants . SETTINGS_EMAIL_SERVICE_ID ) ;
189
- if ( ! allowed ) {
190
- logger . verbose ( `Notification '${ notificationType } ' won't be sent by '${ constants . SETTINGS_EMAIL_SERVICE_ID } '`
191
- + ` service to the userId '${ userId } ' due to his notification settings.` ) ;
192
- continue ;
193
- }
194
294
let userEmail ;
195
295
// if dev mode for email is enabled then replace recipient email
196
296
if ( config . ENABLE_DEV_MODE ) {
197
297
userEmail = config . DEV_MODE_EMAIL ;
198
298
} else {
199
299
userEmail = recipient . email ;
200
300
if ( ! userEmail ) {
201
- logger . error ( `Email not received for user: ${ userId } ` ) ;
301
+ logger . error ( `Email not received for user: ${ JSON . stringify ( recipient , null , 4 ) } ` ) ;
302
+ continue ;
303
+ }
304
+ }
305
+ // skip checking notification setting if userId is not found.
306
+ if ( ! _ . isUndefined ( userId ) ) {
307
+ // if email notification is explicitly disabled for current notification type do nothing
308
+ const allowed = yield checkNotificationSetting ( userId , notificationType , constants . SETTINGS_EMAIL_SERVICE_ID ) ;
309
+ if ( ! allowed ) {
310
+ logger . verbose ( `Notification '${ notificationType } ' won't be sent by '${ constants . SETTINGS_EMAIL_SERVICE_ID } '`
311
+ + ` service to the userId '${ userId } ' due to his notification settings.` ) ;
202
312
continue ;
203
313
}
204
314
}
205
315
const recipients = [ userEmail ] ;
206
316
const payload = {
207
317
from : message . details . from ,
208
318
recipients,
209
- cc : message . details . cc || [ ] ,
319
+ cc,
210
320
data : message . details . data || { } ,
211
321
sendgrid_template_id : message . details . sendgridTemplateId ,
212
322
version : message . details . version ,
@@ -496,6 +606,9 @@ module.exports = {
496
606
getM2MToken,
497
607
getUsersBySkills,
498
608
getUsersByHandles,
609
+ getUsersByHandlesAndUserIds,
610
+ getUsersByEmails,
611
+ getUsersByUserUUIDs,
499
612
sendMessageToBus,
500
613
notifySlackChannel,
501
614
checkNotificationSetting,
0 commit comments