1
+ import type { AdditionalOptions } from '../../Interfaces/AdditionalOptions' ;
1
2
import { type AlertMethodMethod } from '../../Interfaces/AlertMethod' ;
2
- import NotifierRegistry from '../Notifier/NotifierRegistry' ;
3
- import { type NotificationParameters } from '../../Interfaces/NotificationParameters' ;
4
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' ;
5
7
import { prisma } from '../../server/db' ;
6
8
import { logger } from '../../server/logger' ;
7
- import { getLocalTime } from '../../../src/utils/date' ;
9
+ import NotifierRegistry from '../Notifier/NotifierRegistry' ;
10
+ import { NOTIFICATION_METHOD } from '../Notifier/methodConstants' ;
11
+
12
+ const MAX_RETRIES = 0 ;
13
+ const ALERT_SMS_DISABLED = env . ALERT_SMS_DISABLED ;
14
+ const ALERT_WHATSAPP_DISABLED = env . ALERT_WHATSAPP_DISABLED ;
8
15
9
16
// get all undelivered Notifications and using relation from SiteAlert, get the data on Site
10
17
// for each notification, send the notification to the destination
11
18
// After sending notification update the notification table to set isDelivered to true and sentAt to current time
12
19
// If notification fails to send, increment the failCount in all alertMethods table where destination and method match.
13
- const sendNotifications = async ( ) : Promise < number > => {
20
+ const sendNotifications = async ( { req} : AdditionalOptions ) : Promise < number > => {
21
+ const alertMethodsExclusionList = [ ] ;
22
+ if ( ALERT_SMS_DISABLED )
23
+ alertMethodsExclusionList . push ( NOTIFICATION_METHOD . SMS ) ;
24
+ if ( ALERT_WHATSAPP_DISABLED )
25
+ alertMethodsExclusionList . push ( NOTIFICATION_METHOD . WHATSAPP ) ;
26
+
14
27
const take = 10 ;
15
28
let successCount = 0 ;
16
29
let continueProcessing = true ;
30
+ let retries = 0 ;
17
31
while ( continueProcessing ) {
18
32
const notifications = await prisma . notification . findMany ( {
19
33
where : {
34
+ isSkipped : false ,
20
35
isDelivered : false ,
21
36
sentAt : null ,
22
- alertMethod : { notIn : [ 'sms' , 'whatsapp' ] }
37
+ alertMethod : { notIn : alertMethodsExclusionList } ,
23
38
} ,
24
39
include : {
25
40
siteAlert : {
@@ -40,13 +55,17 @@ const sendNotifications = async (): Promise<number> => {
40
55
logger ( `Notifications to be sent: ${ notifications . length } ` , 'info' ) ;
41
56
42
57
const successfulNotificationIds : string [ ] = [ ] ;
43
- const failedAlertMethods : { destination : string ; method : AlertMethodMethod } [ ] = [ ] ;
58
+ const successfulDestinations : string [ ] = [ ] ;
59
+ const failedAlertMethods : {
60
+ destination : string ;
61
+ method : AlertMethodMethod ;
62
+ } [ ] = [ ] ;
44
63
45
64
await Promise . all (
46
65
notifications . map ( async notification => {
47
66
try {
48
67
const { id, destination, siteAlert} = notification ;
49
- const alertMethod = notification . alertMethod as AlertMethodMethod
68
+ const alertMethod = notification . alertMethod as AlertMethodMethod ;
50
69
const {
51
70
id : alertId ,
52
71
confidence,
@@ -59,6 +78,8 @@ const sendNotifications = async (): Promise<number> => {
59
78
eventDate,
60
79
site,
61
80
} = siteAlert ;
81
+ // const siteId = site.id;
82
+ // const userId = site.userId;
62
83
63
84
// if distance = 0 then the fire is inside the site's original geometry
64
85
// if distance > 0 then the fire is outside the site's original geometry
@@ -144,53 +165,64 @@ const sendNotifications = async (): Promise<number> => {
144
165
siteName : siteName ,
145
166
data : data as DataRecord ,
146
167
} ,
168
+ // site: {id: siteId},
169
+ // user: {id: userId!},
147
170
} ;
148
171
const notifier = NotifierRegistry . get ( alertMethod ) ;
149
172
150
173
const isDelivered = await notifier . notify (
151
174
destination ,
152
175
notificationParameters ,
176
+ { req} ,
153
177
) ;
154
178
155
179
if ( isDelivered === true ) {
156
180
successfulNotificationIds . push ( id ) ;
181
+ successfulDestinations . push ( destination ) ;
157
182
successCount ++ ;
158
183
} else {
159
- failedAlertMethods . push ( { destination, method : alertMethod } ) ;
184
+ failedAlertMethods . push ( { destination, method : alertMethod } ) ;
160
185
}
161
186
} catch ( error ) {
162
- logger ( `Error processing notification ${ notification . id } :` , 'error' ) ;
187
+ logger (
188
+ `Error processing notification ${ notification . id } : ${
189
+ ( error as Error ) ?. message
190
+ } `,
191
+ 'error' ,
192
+ ) ;
163
193
}
164
- } )
194
+ } ) ,
165
195
) ;
166
196
167
- // UpdateMany notification
197
+ // UpdateMany notification
168
198
if ( successfulNotificationIds . length > 0 ) {
169
199
await prisma . notification . updateMany ( {
170
- where : {
171
- id : {
172
- in : successfulNotificationIds ,
173
- } ,
174
- } ,
175
- data : {
176
- isDelivered : true ,
177
- sentAt : new Date ( ) ,
178
- } ,
200
+ where : { id : { in : successfulNotificationIds } } ,
201
+ data : { isDelivered : true , sentAt : new Date ( ) } ,
179
202
} ) ;
180
- }
181
- // Handle failed notifications
182
- for ( const { destination, method } of failedAlertMethods ) {
183
203
await prisma . alertMethod . updateMany ( {
184
- where : {
185
- destination : destination ,
186
- method : method ,
187
- } ,
188
- data : {
189
- failCount : {
190
- increment : 1 ,
191
- } ,
192
- } ,
204
+ where : { destination : { in : successfulDestinations } } ,
205
+ data : { failCount : 0 } ,
206
+ } ) ;
207
+ }
208
+
209
+ retries += 1 ;
210
+ if ( retries >= MAX_RETRIES ) {
211
+ const unsuccessfulNotifications = notifications . filter (
212
+ ( { id} ) => ! successfulNotificationIds . includes ( id ) ,
213
+ ) ;
214
+
215
+ const unsuccessfulNotificationIds = unsuccessfulNotifications . map (
216
+ ( { id} ) => id ,
217
+ ) ;
218
+
219
+ await prisma . notification . updateMany ( {
220
+ where : { id : { in : unsuccessfulNotificationIds } } ,
221
+ data : { isSkipped : true , isDelivered : false , sentAt : null } ,
193
222
} ) ;
223
+
224
+ continueProcessing = false ;
225
+ break ;
194
226
}
195
227
196
228
// skip += take; No need to skip take as we update the notifications to isDelivered = true
0 commit comments