1
- import type { AdditionalOptions } from '../../Interfaces/AdditionalOptions' ;
2
- import { type AlertMethodMethod } from '../../Interfaces/AlertMethod' ;
1
+ import type { AdditionalOptions } from '../../Interfaces/AdditionalOptions' ;
2
+ import { type AlertMethodMethod } from '../../Interfaces/AlertMethod' ;
3
3
import type DataRecord from '../../Interfaces/DataRecord' ;
4
- import { type NotificationParameters } from '../../Interfaces/NotificationParameters' ;
5
- import { getLocalTime } from '../../../src/utils/date' ;
6
- import { env } from '../../env.mjs' ;
7
- import { prisma } from '../../server/db' ;
8
- import { logger } from '../../server/logger' ;
4
+ import { type NotificationParameters } from '../../Interfaces/NotificationParameters' ;
5
+ import { getLocalTime } from '../../../src/utils/date' ;
6
+ import { env } from '../../env.mjs' ;
7
+ import { prisma } from '../../server/db' ;
8
+ import { logger } from '../../server/logger' ;
9
9
import NotifierRegistry from '../Notifier/NotifierRegistry' ;
10
- import { NOTIFICATION_METHOD } from '../Notifier/methodConstants' ;
10
+ import { NOTIFICATION_METHOD } from '../Notifier/methodConstants' ;
11
11
12
- const MAX_RETRIES = 0 ;
12
+ // Removed MAX_RETRIES - we now process all batches until no more notifications remain
13
13
const ALERT_SMS_DISABLED = env . ALERT_SMS_DISABLED ;
14
14
const ALERT_WHATSAPP_DISABLED = env . ALERT_WHATSAPP_DISABLED ;
15
15
16
16
// get all undelivered Notifications and using relation from SiteAlert, get the data on Site
17
17
// for each notification, send the notification to the destination
18
18
// After sending notification update the notification table to set isDelivered to true and sentAt to current time
19
19
// If notification fails to send, increment the failCount in all alertMethods table where destination and method match.
20
- const sendNotifications = async ( { req} : AdditionalOptions ) : Promise < number > => {
20
+ const sendNotifications = async ( { req } : AdditionalOptions ) : Promise < number > => {
21
21
const alertMethodsExclusionList = [ ] ;
22
22
if ( ALERT_SMS_DISABLED )
23
23
alertMethodsExclusionList . push ( NOTIFICATION_METHOD . SMS ) ;
24
24
if ( ALERT_WHATSAPP_DISABLED )
25
25
alertMethodsExclusionList . push ( NOTIFICATION_METHOD . WHATSAPP ) ;
26
26
27
- const take = 10 ;
27
+ const BATCH_SIZE = parseInt ( env . NOTIFICATION_BATCH_SIZE || '10' , 10 ) ;
28
+ const take = BATCH_SIZE ;
28
29
let successCount = 0 ;
29
30
let continueProcessing = true ;
30
- let retries = 0 ;
31
+ let batchCount = 0 ;
31
32
while ( continueProcessing ) {
32
33
const notifications = await prisma . notification . findMany ( {
33
34
where : {
34
35
isSkipped : false ,
35
36
isDelivered : false ,
36
37
sentAt : null ,
37
- alertMethod : { notIn : alertMethodsExclusionList } ,
38
+ alertMethod : { notIn : alertMethodsExclusionList } ,
38
39
} ,
39
40
include : {
40
41
siteAlert : {
@@ -64,7 +65,7 @@ const sendNotifications = async ({req}: AdditionalOptions): Promise<number> => {
64
65
await Promise . all (
65
66
notifications . map ( async notification => {
66
67
try {
67
- const { id, destination, siteAlert} = notification ;
68
+ const { id, destination, siteAlert } = notification ;
68
69
const alertMethod = notification . alertMethod as AlertMethodMethod ;
69
70
const {
70
71
id : alertId ,
@@ -173,20 +174,19 @@ const sendNotifications = async ({req}: AdditionalOptions): Promise<number> => {
173
174
const isDelivered = await notifier . notify (
174
175
destination ,
175
176
notificationParameters ,
176
- { req} ,
177
+ { req } ,
177
178
) ;
178
179
179
180
if ( isDelivered === true ) {
180
181
successfulNotificationIds . push ( id ) ;
181
182
successfulDestinations . push ( destination ) ;
182
183
successCount ++ ;
183
184
} else {
184
- failedAlertMethods . push ( { destination, method : alertMethod } ) ;
185
+ failedAlertMethods . push ( { destination, method : alertMethod } ) ;
185
186
}
186
187
} catch ( error ) {
187
188
logger (
188
- `Error processing notification ${ notification . id } : ${
189
- ( error as Error ) ?. message
189
+ `Error processing notification ${ notification . id } : ${ ( error as Error ) ?. message
190
190
} `,
191
191
'error' ,
192
192
) ;
@@ -197,34 +197,35 @@ const sendNotifications = async ({req}: AdditionalOptions): Promise<number> => {
197
197
// UpdateMany notification
198
198
if ( successfulNotificationIds . length > 0 ) {
199
199
await prisma . notification . updateMany ( {
200
- where : { id : { in : successfulNotificationIds } } ,
201
- data : { isDelivered : true , sentAt : new Date ( ) } ,
200
+ where : { id : { in : successfulNotificationIds } } ,
201
+ data : { isDelivered : true , sentAt : new Date ( ) } ,
202
202
} ) ;
203
203
await prisma . alertMethod . updateMany ( {
204
- where : { destination : { in : successfulDestinations } } ,
205
- data : { failCount : 0 } ,
204
+ where : { destination : { in : successfulDestinations } } ,
205
+ data : { failCount : 0 } ,
206
206
} ) ;
207
207
}
208
208
209
- retries += 1 ;
210
- if ( retries >= MAX_RETRIES ) {
211
- const unsuccessfulNotifications = notifications . filter (
212
- ( { id} ) => ! successfulNotificationIds . includes ( id ) ,
213
- ) ;
209
+ batchCount += 1 ;
210
+
211
+ // Handle failed notifications - mark them as skipped if they failed
212
+ const unsuccessfulNotifications = notifications . filter (
213
+ ( { id } ) => ! successfulNotificationIds . includes ( id ) ,
214
+ ) ;
214
215
216
+ if ( unsuccessfulNotifications . length > 0 ) {
215
217
const unsuccessfulNotificationIds = unsuccessfulNotifications . map (
216
- ( { id } ) => id ,
218
+ ( { id } ) => id ,
217
219
) ;
218
220
219
221
await prisma . notification . updateMany ( {
220
- where : { id : { in : unsuccessfulNotificationIds } } ,
221
- data : { isSkipped : true , isDelivered : false , sentAt : null } ,
222
+ where : { id : { in : unsuccessfulNotificationIds } } ,
223
+ data : { isSkipped : true , isDelivered : false , sentAt : null } ,
222
224
} ) ;
223
-
224
- continueProcessing = false ;
225
- break ;
226
225
}
227
226
227
+ logger ( `Completed batch ${ batchCount } . Successful: ${ successfulNotificationIds . length } , Failed: ${ unsuccessfulNotifications . length } ` , 'info' ) ;
228
+
228
229
// skip += take; No need to skip take as we update the notifications to isDelivered = true
229
230
// wait .7 seconds before starting the next round to ensure we aren't hitting any rate limits.
230
231
// Todo: make this configurable and adjust as needed.
0 commit comments