1
1
import { JobNonRetriableError } from '@app/common/errors/job-non-retriable-error'
2
+ import { wait } from '@app/common/utils/async.utils'
2
3
import { XmtpLib } from '@app/definitions/integration-definitions/xmtp/xmtp.lib'
3
4
import { getWalletName } from '@app/definitions/utils/address.utils'
4
5
import { sendXmtpMessage } from '@chainjet/tools/dist/messages'
@@ -62,16 +63,13 @@ export class BroadcastConsumer {
62
63
} )
63
64
const client = await XmtpLib . getClient ( accountCredential . credentials . keys )
64
65
65
- // if this is a retry, filter out contacts that have already been sent a message
66
- if ( job . attemptsMade > 0 ) {
67
- const campaignMessages = await this . campaignMessageService . find ( {
68
- campaign : campaign . _id ,
69
- } )
70
- const campaignMessageAddresses = campaignMessages . map ( ( campaignMessage ) => campaignMessage . address )
71
- contacts = contacts . filter ( ( contact ) => ! campaignMessageAddresses . includes ( contact . address ) )
72
- }
73
-
74
- this . logger . log ( `Sending campaign ${ campaign . _id } to ${ contacts . length } contacts` )
66
+ // filter out contacts that have already been sent a message for this campaign
67
+ const campaignMessages = await this . campaignMessageService . find ( {
68
+ campaign : campaign . _id ,
69
+ } )
70
+ const campaignMessageAddresses = campaignMessages . map ( ( campaignMessage ) => campaignMessage . address )
71
+ const totalContacts = contacts . length
72
+ contacts = contacts . filter ( ( contact ) => ! campaignMessageAddresses . includes ( contact . address ) )
75
73
76
74
if ( campaign . state === CampaignState . Pending ) {
77
75
campaign . state = CampaignState . Running
@@ -87,13 +85,16 @@ export class BroadcastConsumer {
87
85
)
88
86
}
89
87
90
- campaign . delivered = 0
91
- campaign . total = contacts . length
88
+ campaign . delivered = campaignMessages . length
89
+ campaign . total = totalContacts
92
90
const uniqueAddresses = new Set < string > ( )
91
+ let failed = 0
93
92
94
93
const walletName = ( await getWalletName ( user . address ) ) ?? user . address
95
94
const unsubscribeMessage = `To unsubscribe from these messages: https://unsubscribe.chainjet.io/${ walletName } `
96
95
96
+ this . logger . log ( `Sending campaign ${ campaign . _id } to ${ contacts . length } contacts` )
97
+
97
98
for ( const contact of contacts ) {
98
99
const sendTo = contact . notificationAddress ?? contact . address
99
100
if ( uniqueAddresses . has ( sendTo ) ) {
@@ -120,10 +121,21 @@ export class BroadcastConsumer {
120
121
this . logger . log (
121
122
`Sent broadcast message from ${ user . address } to ${ sendTo } (${ campaign . processed } /${ campaign . total } )` ,
122
123
)
123
- } catch { }
124
- campaign . processed ++
125
- job . progress ( campaign . processed / campaign . total )
126
-
124
+ campaign . processed ++
125
+ job . progress ( campaign . processed / campaign . total )
126
+ } catch ( e ) {
127
+ if ( e . message . includes ( 'is not on the XMTP network' ) ) {
128
+ await this . campaignMessageService . createOne ( {
129
+ campaign : campaign . _id ,
130
+ address : contact . address ,
131
+ } )
132
+ campaign . processed ++
133
+ job . progress ( campaign . processed / campaign . total )
134
+ } else {
135
+ this . logger . error ( `Failed to send broadcast message from ${ user . address } to ${ sendTo } : ${ e . message } ` )
136
+ failed ++
137
+ }
138
+ }
127
139
// update the campaign status every 100 contacts
128
140
if ( campaign . processed > 0 && campaign . processed % 100 === 0 ) {
129
141
await this . campaignService . updateOneNative (
@@ -141,6 +153,25 @@ export class BroadcastConsumer {
141
153
}
142
154
}
143
155
156
+ // if any messages failed to send with unexpected reasons, retry the job
157
+ if ( failed > 0 ) {
158
+ await this . campaignService . updateOneNative (
159
+ {
160
+ _id : campaign . _id ,
161
+ } ,
162
+ {
163
+ $set : {
164
+ delivered : campaign . delivered ,
165
+ processed : campaign . processed ,
166
+ total : campaign . total ,
167
+ } ,
168
+ } ,
169
+ )
170
+ this . logger . error ( `Failed to send ${ failed } /${ campaign . total } messages for campaign ${ campaign . _id } . Retrying...` )
171
+ await wait ( 10000 )
172
+ return await this . send ( job )
173
+ }
174
+
144
175
await this . campaignService . updateOneNative (
145
176
{
146
177
_id : campaign . _id ,
0 commit comments