@@ -89,37 +89,23 @@ export class SmsQueueProcessor {
8989 // )
9090
9191 // Mark individual SMS records as failed when their FCM push failed
92+ const failedSmsIds : string [ ] = [ ]
93+ const failedUpdates : Array < {
94+ smsId : string
95+ errorCode : string
96+ errorMessage : string
97+ } > = [ ]
9298 for ( let i = 0 ; i < response . responses . length ; i ++ ) {
9399 if ( ! response . responses [ i ] . success ) {
94100 try {
95101 const smsData = JSON . parse ( fcmMessages [ i ] . data . smsData )
96102 const fcmError = response . responses [ i ] . error
97- const updatedSms = await this . smsModel . findByIdAndUpdate (
98- smsData . smsId ,
99- {
100- $set : {
101- status : 'failed' ,
102- failedAt : new Date ( ) ,
103- errorCode : getFcmErrorCode ( fcmError ?? undefined ) ,
104- errorMessage : getFcmErrorMessage ( fcmError ?? undefined ) ,
105- } ,
106- } ,
107- { new : true } ,
108- )
109- if ( device ?. user && updatedSms ) {
110- await this . webhookService
111- . deliverNotification ( {
112- sms : updatedSms ,
113- user : device . user as any ,
114- event : WebhookEvent . MESSAGE_FAILED ,
115- } )
116- . catch ( ( e ) =>
117- this . logger . warn (
118- `Webhook delivery failed for SMS ${ updatedSms . _id } ` ,
119- e ?. message ,
120- ) ,
121- )
122- }
103+ failedSmsIds . push ( String ( smsData . smsId ) )
104+ failedUpdates . push ( {
105+ smsId : String ( smsData . smsId ) ,
106+ errorCode : getFcmErrorCode ( fcmError ?? undefined ) ,
107+ errorMessage : getFcmErrorMessage ( fcmError ?? undefined ) ,
108+ } )
123109 } catch ( parseError ) {
124110 this . logger . error (
125111 `Failed to mark SMS as failed for FCM message index ${ i } ` ,
@@ -131,13 +117,12 @@ export class SmsQueueProcessor {
131117
132118 // Mark individual SMS records as dispatched when FCM push succeeded
133119 const now = new Date ( )
120+ const dispatchedSmsIds : string [ ] = [ ]
134121 for ( let i = 0 ; i < response . responses . length ; i ++ ) {
135122 if ( response . responses [ i ] . success ) {
136123 try {
137124 const smsData = JSON . parse ( fcmMessages [ i ] . data . smsData )
138- await this . smsModel . findByIdAndUpdate ( smsData . smsId , {
139- $set : { status : 'dispatched' , dispatchedAt : now } ,
140- } )
125+ dispatchedSmsIds . push ( String ( smsData . smsId ) )
141126 } catch ( parseError ) {
142127 this . logger . error (
143128 `Failed to mark SMS as dispatched for FCM message index ${ i } ` ,
@@ -147,6 +132,52 @@ export class SmsQueueProcessor {
147132 }
148133 }
149134
135+ if ( failedUpdates . length > 0 ) {
136+ const failedAt = new Date ( )
137+ for ( const failedUpdate of failedUpdates ) {
138+ await this . smsModel . updateOne (
139+ { _id : failedUpdate . smsId as any } ,
140+ {
141+ $set : {
142+ status : 'failed' ,
143+ failedAt,
144+ errorCode : failedUpdate . errorCode ,
145+ errorMessage : failedUpdate . errorMessage ,
146+ } ,
147+ } ,
148+ )
149+ }
150+ }
151+
152+ if ( dispatchedSmsIds . length > 0 ) {
153+ await this . smsModel . updateMany (
154+ { _id : { $in : dispatchedSmsIds } as any } ,
155+ {
156+ $set : { status : 'dispatched' , dispatchedAt : now } ,
157+ } ,
158+ )
159+ }
160+
161+ if ( device ?. user && failedSmsIds . length > 0 ) {
162+ const failedSmsDocuments = await this . smsModel . find ( {
163+ _id : { $in : failedSmsIds } ,
164+ } )
165+ for ( const failedSms of failedSmsDocuments ) {
166+ await this . webhookService
167+ . deliverNotification ( {
168+ sms : failedSms ,
169+ user : device . user as any ,
170+ event : WebhookEvent . MESSAGE_FAILED ,
171+ } )
172+ . catch ( ( e ) =>
173+ this . logger . warn (
174+ `Webhook delivery failed for SMS ${ failedSms . _id } ` ,
175+ e ?. message ,
176+ ) ,
177+ )
178+ }
179+ }
180+
150181 // Update device SMS count
151182 await this . deviceModel
152183 . findByIdAndUpdate ( deviceId , {
@@ -181,38 +212,11 @@ export class SmsQueueProcessor {
181212 this . logger . error ( `Failed to process SMS job ${ job . id } ` , error )
182213
183214 // Mark all individual SMS in this batch of FCM messages as failed
215+ const failedSmsIds : string [ ] = [ ]
184216 for ( const fcmMessage of fcmMessages ) {
185217 try {
186218 const smsData = JSON . parse ( fcmMessage . data . smsData )
187- const updatedSms = await this . smsModel . findByIdAndUpdate (
188- smsData . smsId ,
189- {
190- $set : {
191- status : 'failed' ,
192- failedAt : new Date ( ) ,
193- errorCode :
194- ( error as any ) ?. code != null
195- ? getFcmErrorCode ( error as any )
196- : 'FCM_SEND_ERROR' ,
197- errorMessage : getFcmErrorMessage ( error as any ) ,
198- } ,
199- } ,
200- { new : true } ,
201- )
202- if ( device ?. user && updatedSms ) {
203- await this . webhookService
204- . deliverNotification ( {
205- sms : updatedSms ,
206- user : device . user as any ,
207- event : WebhookEvent . MESSAGE_FAILED ,
208- } )
209- . catch ( ( e ) =>
210- this . logger . warn (
211- `Webhook delivery failed for SMS ${ updatedSms . _id } ` ,
212- e ?. message ,
213- ) ,
214- )
215- }
219+ failedSmsIds . push ( String ( smsData . smsId ) )
216220 } catch ( parseError ) {
217221 this . logger . error (
218222 'Failed to mark SMS as failed after FCM error' ,
@@ -221,6 +225,44 @@ export class SmsQueueProcessor {
221225 }
222226 }
223227
228+ if ( failedSmsIds . length > 0 ) {
229+ const failedAt = new Date ( )
230+ await this . smsModel . updateMany (
231+ { _id : { $in : failedSmsIds } as any } ,
232+ {
233+ $set : {
234+ status : 'failed' ,
235+ failedAt,
236+ errorCode :
237+ ( error as any ) ?. code != null
238+ ? getFcmErrorCode ( error as any )
239+ : 'FCM_SEND_ERROR' ,
240+ errorMessage : getFcmErrorMessage ( error as any ) ,
241+ } ,
242+ } ,
243+ )
244+ }
245+
246+ if ( device ?. user && failedSmsIds . length > 0 ) {
247+ const failedSmsDocuments = await this . smsModel . find ( {
248+ _id : { $in : failedSmsIds } ,
249+ } )
250+ for ( const failedSms of failedSmsDocuments ) {
251+ await this . webhookService
252+ . deliverNotification ( {
253+ sms : failedSms ,
254+ user : device . user as any ,
255+ event : WebhookEvent . MESSAGE_FAILED ,
256+ } )
257+ . catch ( ( e ) =>
258+ this . logger . warn (
259+ `Webhook delivery failed for SMS ${ failedSms . _id } ` ,
260+ e ?. message ,
261+ ) ,
262+ )
263+ }
264+ }
265+
224266 const smsBatch = await this . smsBatchModel . findByIdAndUpdate (
225267 smsBatchId ,
226268 {
0 commit comments