@@ -2,6 +2,7 @@ defmodule Keila.Mailings.Worker do
2
2
@ moduledoc """
3
3
This worker builds and delivers queued emails.
4
4
"""
5
+ use Keila.Repo
5
6
6
7
use Oban.Worker ,
7
8
queue: :mailer ,
@@ -12,8 +13,10 @@ defmodule Keila.Mailings.Worker do
12
13
keys: [ :recipient_id ]
13
14
]
14
15
15
- use Keila.Repo
16
+ alias Ecto.Multi
17
+ alias Keila.Contacts.Contact
16
18
alias Keila.Mailings . { Recipient , Builder , RateLimiter }
19
+
17
20
require Logger
18
21
19
22
@ impl true
@@ -91,10 +94,8 @@ defmodule Keila.Mailings.Worker do
91
94
defp handle_result ( { :ok , raw_receipt } , recipient ) do
92
95
receipt = get_receipt ( raw_receipt )
93
96
94
- from ( r in Recipient ,
95
- where: r . id == ^ recipient . id ,
96
- update: [ set: [ sent_at: fragment ( "NOW()" ) , receipt: ^ receipt ] ]
97
- )
97
+ recipient
98
+ |> set_recipient_sent_query ( receipt )
98
99
|> Repo . update_all ( [ ] )
99
100
100
101
:ok
@@ -106,19 +107,70 @@ defmodule Keila.Mailings.Worker do
106
107
# Email was already sent
107
108
defp handle_result ( { :error , :already_sent } , _ ) , do: { :cancel , :already_sent }
108
109
110
+ # Email is invalid
111
+ defp handle_result ( { :error , :invalid_email } , recipient ) do
112
+ Multi . new ( )
113
+ |> Multi . update_all (
114
+ :update_recipient ,
115
+ set_recipient_failed_query ( recipient ) ,
116
+ [ ]
117
+ )
118
+ |> Multi . update_all (
119
+ :update_contact ,
120
+ set_contact_unreachable_query ( recipient ) ,
121
+ [ ]
122
+ )
123
+ |> Repo . transaction ( )
124
+
125
+ { :cancel , :invalid_email }
126
+ end
127
+
109
128
# Another error occurred. Sending is not retried.
110
129
defp handle_result ( { :error , reason } , recipient ) do
111
130
Logger . warning (
112
131
"Failed sending email to #{ recipient . contact . email } for campaign #{ recipient . campaign . id } : #{ inspect ( reason ) } "
113
132
)
114
133
134
+ recipient
135
+ |> set_recipient_failed_query ( )
136
+ |> Repo . update_all ( [ ] )
137
+
138
+ { :cancel , reason }
139
+ end
140
+
141
+ defp set_recipient_sent_query ( recipient , receipt ) do
115
142
from ( r in Recipient ,
116
143
where: r . id == ^ recipient . id ,
117
- update: [ set: [ failed_at: fragment ( "NOW()" ) ] ]
144
+ update: [
145
+ set: [
146
+ sent_at: fragment ( "NOW()" ) ,
147
+ receipt: ^ receipt
148
+ ]
149
+ ]
118
150
)
119
- |> Repo . update_all ( [ ] )
151
+ end
120
152
121
- { :cancel , reason }
153
+ defp set_recipient_failed_query ( recipient ) do
154
+ from ( r in Recipient ,
155
+ where: r . id == ^ recipient . id ,
156
+ update: [
157
+ set: [
158
+ failed_at: fragment ( "NOW()" )
159
+ ]
160
+ ]
161
+ )
162
+ end
163
+
164
+ defp set_contact_unreachable_query ( recipient ) do
165
+ from ( c in Contact ,
166
+ where: c . id == ^ recipient . contact_id ,
167
+ update: [
168
+ set: [
169
+ status: :unreachable ,
170
+ updated_at: fragment ( "NOW()" )
171
+ ]
172
+ ]
173
+ )
122
174
end
123
175
124
176
defp get_receipt ( % { id: receipt } ) , do: receipt
0 commit comments