9
9
10
10
import SendMailService from '../server-side/sendMailService' ;
11
11
import CardsExternalDiffusionOpfabServicesInterface from '../server-side/cardsExternalDiffusionOpfabServicesInterface' ;
12
- import CardsRoutingUtilities from './cardRoutingUtilities' ;
13
- import ConfigDTO from '../client-side/configDTO' ;
14
12
import CardsExternalDiffusionDatabaseService from '../server-side/cardsExternaDiffusionDatabaseService' ;
15
- import CardsDiffusionRateLimiter from './cardsDiffusionRateLimiter' ;
16
13
import BusinessConfigOpfabServicesInterface from '../server-side/BusinessConfigOpfabServicesInterface' ;
17
14
18
15
export default class CardsDiffusionControl {
19
16
20
- opfabUrlInMailContent : any ;
17
+ protected opfabUrlInMailContent : any ;
18
+ protected cardsExternalDiffusionOpfabServicesInterface : CardsExternalDiffusionOpfabServicesInterface ;
19
+ protected businessConfigOpfabServicesInterface : BusinessConfigOpfabServicesInterface ;
20
+ protected cardsExternalDiffusionDatabaseService : CardsExternalDiffusionDatabaseService ;
21
+ protected logger : any ;
22
+ protected mailService : SendMailService ;
23
+ protected from : string ;
21
24
22
- private cardsExternalDiffusionOpfabServicesInterface : CardsExternalDiffusionOpfabServicesInterface ;
23
- private businessConfigOpfabServicesInterface : BusinessConfigOpfabServicesInterface ;
24
- private cardsExternalDiffusionDatabaseService : CardsExternalDiffusionDatabaseService ;
25
- private logger : any ;
26
- private secondsAfterPublicationToConsiderCardAsNotRead : number ;
27
- private windowInSecondsForCardSearch : number ;
28
- private mailService : SendMailService ;
29
- private from : string ;
30
- private subjectPrefix : string ;
31
- private bodyPrefix : string ;
32
- private activateCardsDiffusionRateLimiter : boolean ;
33
- private cardsDiffusionRateLimiter : CardsDiffusionRateLimiter ;
25
+ public setOpfabUrlInMailContent ( opfabUrlInMailContent : any ) {
26
+ this . opfabUrlInMailContent = opfabUrlInMailContent ;
27
+ return this ;
28
+ }
34
29
35
- public setOpfabServicesInterface ( cardsExternalDiffusionOpfabServicesInterface : CardsExternalDiffusionOpfabServicesInterface ) {
30
+ public setOpfabServicesInterface (
31
+ cardsExternalDiffusionOpfabServicesInterface : CardsExternalDiffusionOpfabServicesInterface
32
+ ) {
36
33
this . cardsExternalDiffusionOpfabServicesInterface = cardsExternalDiffusionOpfabServicesInterface ;
37
34
return this ;
38
35
}
39
36
40
- public setOpfabBusinessConfigServicesInterface ( businessConfigOpfabServicesInterface : BusinessConfigOpfabServicesInterface ) {
37
+ public setOpfabBusinessConfigServicesInterface (
38
+ businessConfigOpfabServicesInterface : BusinessConfigOpfabServicesInterface
39
+ ) {
41
40
this . businessConfigOpfabServicesInterface = businessConfigOpfabServicesInterface ;
42
41
return this ;
43
42
}
44
43
45
- public setCardsExternalDiffusionDatabaseService ( cardsExternalDiffusionDatabaseService : CardsExternalDiffusionDatabaseService ) {
44
+ public setCardsExternalDiffusionDatabaseService (
45
+ cardsExternalDiffusionDatabaseService : CardsExternalDiffusionDatabaseService
46
+ ) {
46
47
this . cardsExternalDiffusionDatabaseService = cardsExternalDiffusionDatabaseService ;
47
48
return this ;
48
49
}
@@ -62,178 +63,15 @@ export default class CardsDiffusionControl {
62
63
return this ;
63
64
}
64
65
65
- public setSubjectPrefix ( subjectPrefix : string ) {
66
- this . subjectPrefix = subjectPrefix ;
67
- return this ;
68
- }
69
-
70
- public setBodyPrefix ( bodyPrefix : string ) {
71
- this . bodyPrefix = bodyPrefix ;
72
- return this ;
73
- }
74
-
75
- public setOpfabUrlInMailContent ( opfabUrlInMailContent : any ) {
76
- this . opfabUrlInMailContent = opfabUrlInMailContent ;
77
- return this ;
78
- }
79
-
80
- public setSecondsAfterPublicationToConsiderCardAsNotRead ( secondsAfterPublicationToConsiderCardAsNotRead : number ) {
81
- this . secondsAfterPublicationToConsiderCardAsNotRead = secondsAfterPublicationToConsiderCardAsNotRead ;
82
- return this ;
83
- }
84
-
85
- public setWindowInSecondsForCardSearch ( windowInSecondsForCardSearch : number ) {
86
- this . windowInSecondsForCardSearch = windowInSecondsForCardSearch ;
87
- return this ;
88
- }
89
-
90
- public setActivateCardsDiffusionRateLimiter ( activate : boolean ) {
91
- this . activateCardsDiffusionRateLimiter = activate ;
92
- return this ;
93
- }
94
-
95
- public setCardsDiffusionRateLimiter ( cardsDiffusionRateLimiter : CardsDiffusionRateLimiter ) {
96
- this . cardsDiffusionRateLimiter = cardsDiffusionRateLimiter ;
97
- }
98
-
99
- public setConfiguration ( updated : ConfigDTO ) {
100
- this . from = updated . mailFrom ;
101
- this . subjectPrefix = updated . subjectPrefix ;
102
- this . bodyPrefix = updated . bodyPrefix ;
103
- this . secondsAfterPublicationToConsiderCardAsNotRead = updated . secondsAfterPublicationToConsiderCardAsNotRead ;
104
- this . windowInSecondsForCardSearch = updated . windowInSecondsForCardSearch ;
105
- this . activateCardsDiffusionRateLimiter = updated . activateCardsDiffusionRateLimiter ;
106
- if ( this . activateCardsDiffusionRateLimiter ) {
107
- this . cardsDiffusionRateLimiter = new CardsDiffusionRateLimiter ( )
108
- . setLimitPeriodInSec ( updated . sendRateLimitPeriodInSec )
109
- . setSendRateLimit ( updated . sendRateLimit ) ;
110
- }
111
- }
112
-
113
- public async checkUnreadCards ( ) {
114
- const users = this . cardsExternalDiffusionOpfabServicesInterface . getUsers ( ) ;
115
- const userLogins = users . map ( ( u ) => u . login ) ;
116
-
117
- const connectedResponse = await this . cardsExternalDiffusionOpfabServicesInterface . getUsersConnected ( ) ;
118
- if ( connectedResponse . isValid ( ) ) {
119
- const connectedUsers = connectedResponse . getData ( ) . map ( ( u : { login : string ; } ) => u . login ) ;
120
- const usersToCheck = this . removeElementsFromArray ( userLogins , connectedUsers ) ;
121
- this . logger . debug ( 'Disconnected users ' + usersToCheck ) ;
122
- if ( usersToCheck . length > 0 ) {
123
- const dateFrom = Date . now ( ) - this . windowInSecondsForCardSearch * 1000 ;
124
- const cards = await this . cardsExternalDiffusionDatabaseService . getCards ( dateFrom ) ;
125
- if ( cards . length > 0 ) {
126
- this . logger . debug ( 'Found cards: ' + cards . length ) ;
127
- usersToCheck . forEach ( ( login ) => {
128
- this . sendCardsToUserIfNecessary ( cards , login ) . catch ( error =>
129
- this . logger . error ( "error during sendCardsToUserIfNecessary " , error )
130
- )
131
- } ) ;
132
- }
133
- }
134
- await this . cleanCardsAreadySent ( ) ;
135
- }
136
- }
137
-
138
- private async sendCardsToUserIfNecessary ( cards : any [ ] , login : string ) {
139
- this . logger . debug ( 'Check user ' + login ) ;
140
-
141
- const resp = await this . cardsExternalDiffusionOpfabServicesInterface . getUserWithPerimetersByLogin ( login ) ;
142
- if ( resp . isValid ( ) ) {
143
- const userWithPerimeters = resp . getData ( ) ;
144
- const emailToPlainText = this . shouldEmailBePlainText ( userWithPerimeters ) ;
145
- this . logger . debug ( 'Got user with perimeters ' + JSON . stringify ( userWithPerimeters ) ) ;
146
- if ( this . isEmailSettingEnabled ( userWithPerimeters ) ) {
147
- const unreadCards = await this . getCardsForUser ( cards , userWithPerimeters ) ;
148
- for ( let i = 0 ; i < unreadCards . length ; i ++ ) {
149
- await this . sendCardIfAllowed ( unreadCards [ i ] , userWithPerimeters . email , emailToPlainText ) ;
150
- }
151
- }
152
- }
153
- }
154
-
155
- private async sendCardIfAllowed ( unreadCard : any , userEmail : string , emailToPlainText : boolean ) : Promise < void > {
156
- try {
157
- const alreadySent = await this . wasCardsAlreadySentToUser ( unreadCard . uid , userEmail ) ;
158
- if ( ! alreadySent ) {
159
- if ( this . isSendingAllowed ( userEmail ) ) {
160
- await this . sendMail ( unreadCard , userEmail , emailToPlainText ) ;
161
- } else {
162
- this . logger . warn ( `Send rate limit reached for ${ userEmail } , not sending mail for card ${ unreadCard . uid } ` ) ;
163
- await this . cardsExternalDiffusionDatabaseService . persistSentMail ( unreadCard . uid , userEmail ) ;
164
- }
165
- }
166
- } catch ( error ) {
167
- this . logger . error ( "Error occurred while sending mail: " , error ) ;
168
- }
169
- }
170
-
171
- private isSendingAllowed ( email : string ) {
172
- return ! this . activateCardsDiffusionRateLimiter || this . cardsDiffusionRateLimiter . isNewSendingAllowed ( email ) ;
173
- }
174
-
175
- private registerNewSending ( destination : string ) {
176
- if ( this . activateCardsDiffusionRateLimiter )
177
- this . cardsDiffusionRateLimiter . registerNewSending ( destination ) ;
178
- }
179
-
180
- private async getCardsForUser ( cards : any [ ] , userWithPerimeters : any ) : Promise < any [ ] > {
181
-
182
- const perimeters = userWithPerimeters . computedPerimeters ;
183
- this . logger . debug ( 'Got user perimeters' + JSON . stringify ( perimeters ) ) ;
184
- return cards
185
- . filter (
186
- ( card : any ) =>
187
- CardsRoutingUtilities . shouldUserReceiveTheCard (
188
- userWithPerimeters ,
189
- card
190
- ) && this . isCardUnreadForUser ( card , userWithPerimeters . userData )
191
- ) ;
192
- }
193
-
194
- private wasCardsAlreadySentToUser ( cardUid : string , email : string ) {
195
- return this . cardsExternalDiffusionDatabaseService . getSentMail ( cardUid , email ) ;
196
- }
197
-
198
- private isEmailSettingEnabled ( userWithPerimeters : any ) : boolean {
66
+ protected isEmailSettingEnabled ( userWithPerimeters : any ) : boolean {
199
67
return userWithPerimeters . sendCardsByEmail && userWithPerimeters . email ;
200
-
201
68
}
202
69
203
- private shouldEmailBePlainText ( userWithPerimeters : any ) : boolean {
70
+ protected shouldEmailBePlainText ( userWithPerimeters : any ) : boolean {
204
71
return userWithPerimeters . emailToPlainText ? userWithPerimeters . emailToPlainText : false ;
205
72
}
206
73
207
- private isCardUnreadForUser ( card : any , user : any ) : boolean {
208
- return (
209
- card . publishDate < Date . now ( ) - 1000 * this . secondsAfterPublicationToConsiderCardAsNotRead &&
210
- ! card . usersReads ?. includes ( user . login )
211
- ) ;
212
- }
213
-
214
- private async sendMail ( card : any , to : string , emailToPlainText :boolean ) {
215
- this . logger . info ( 'Send Mail to ' + to + ' for card ' + card . uid ) ;
216
- let subject =
217
- this . subjectPrefix +
218
- ' - ' +
219
- card . titleTranslated +
220
- ' - ' +
221
- card . summaryTranslated +
222
- ' - ' +
223
- this . getFormattedDateAndTimeFromEpochDate ( card . startDate ) ;
224
- if ( card . endDate ) subject += ' - ' + this . getFormattedDateAndTimeFromEpochDate ( card . endDate ) ;
225
- const body = await this . processCardTemplate ( card ) ;
226
- try {
227
- await this . mailService . sendMail ( subject , body , this . from , to , emailToPlainText ) ;
228
- this . registerNewSending ( to ) ;
229
- await this . cardsExternalDiffusionDatabaseService . persistSentMail ( card . uid , to ) ;
230
- } catch ( e ) {
231
- this . logger . error ( 'Error sending mail ' , e ) ;
232
- } ;
233
-
234
- }
235
-
236
- private removeElementsFromArray ( arrayToFilter : string [ ] , arrayToDelete : string [ ] ) : string [ ] {
74
+ protected removeElementsFromArray ( arrayToFilter : string [ ] , arrayToDelete : string [ ] ) : string [ ] {
237
75
if ( arrayToDelete && arrayToDelete . length > 0 ) {
238
76
const elementsToDeleteSet = new Set ( arrayToDelete ) ;
239
77
const newArray = arrayToFilter . filter ( ( name ) => {
@@ -245,43 +83,7 @@ export default class CardsDiffusionControl {
245
83
}
246
84
}
247
85
248
- private async processCardTemplate ( card : any ) : Promise < string > {
249
- let cardBodyHtml =
250
- this . bodyPrefix +
251
- ' <a href=" ' +
252
- this . opfabUrlInMailContent +
253
- '/#/feed/cards/' +
254
- card . id +
255
- ' ">' +
256
- this . escapeHtml ( card . titleTranslated ) +
257
- ' - ' +
258
- this . escapeHtml ( card . summaryTranslated ) +
259
- '</a>' ;
260
- try {
261
- const cardConfig = await this . businessConfigOpfabServicesInterface . fetchProcessConfig (
262
- card . process ,
263
- card . processVersion
264
- ) ;
265
- const stateName = card . state ;
266
- if ( cardConfig ?. states ?. [ stateName ] ?. emailBodyTemplate ) {
267
- const cardContentResponse = await this . cardsExternalDiffusionOpfabServicesInterface . getCard ( card . id ) ;
268
- if ( cardContentResponse . isValid ( ) ) {
269
- const cardContent = cardContentResponse . getData ( ) ;
270
- const templateCompiler = await this . businessConfigOpfabServicesInterface . fetchTemplate (
271
- card . process ,
272
- cardConfig . states [ stateName ] . emailBodyTemplate ,
273
- card . processVersion
274
- ) ;
275
- cardBodyHtml = cardBodyHtml + ' <br> ' + templateCompiler ( cardContent ) ;
276
- }
277
- }
278
- } catch ( e ) {
279
- console . warn ( "Couldn't parse email for : " , card . state , e ) ;
280
- }
281
- return cardBodyHtml ;
282
- }
283
-
284
- private escapeHtml ( text : string ) : string {
86
+ protected escapeHtml ( text : string ) : string {
285
87
if ( ! text ) return text ;
286
88
return text
287
89
. replace ( / & / g, '&' )
@@ -291,12 +93,7 @@ export default class CardsDiffusionControl {
291
93
. replace ( / ' / g, ''' ) ;
292
94
}
293
95
294
- private async cleanCardsAreadySent ( ) {
295
- const dateLimit = Date . now ( ) - this . windowInSecondsForCardSearch * 1000 ;
296
- await this . cardsExternalDiffusionDatabaseService . deleteMailsSentBefore ( dateLimit ) ;
297
- }
298
-
299
- private getFormattedDateAndTimeFromEpochDate ( epochDate : number ) : string {
96
+ protected getFormattedDateAndTimeFromEpochDate ( epochDate : number ) : string {
300
97
if ( ! epochDate ) return '' ;
301
98
const date = new Date ( epochDate ) ;
302
99
@@ -313,7 +110,7 @@ export default class CardsDiffusionControl {
313
110
) ;
314
111
}
315
112
316
- private pad ( num : number ) : string {
113
+ protected pad ( num : number ) : string {
317
114
if ( num < 10 ) {
318
115
return '0' + num ;
319
116
}
0 commit comments