Skip to content

Commit d16fc75

Browse files
Update worker to set contacts as unreachable when email bounces.
1 parent 7dbf09c commit d16fc75

File tree

1 file changed

+60
-8
lines changed

1 file changed

+60
-8
lines changed

lib/keila/mailings/worker.ex

+60-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ defmodule Keila.Mailings.Worker do
22
@moduledoc """
33
This worker builds and delivers queued emails.
44
"""
5+
use Keila.Repo
56

67
use Oban.Worker,
78
queue: :mailer,
@@ -12,8 +13,10 @@ defmodule Keila.Mailings.Worker do
1213
keys: [:recipient_id]
1314
]
1415

15-
use Keila.Repo
16+
alias Ecto.Multi
17+
alias Keila.Contacts.Contact
1618
alias Keila.Mailings.{Recipient, Builder, RateLimiter}
19+
1720
require Logger
1821

1922
@impl true
@@ -91,10 +94,8 @@ defmodule Keila.Mailings.Worker do
9194
defp handle_result({:ok, raw_receipt}, recipient) do
9295
receipt = get_receipt(raw_receipt)
9396

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)
9899
|> Repo.update_all([])
99100

100101
:ok
@@ -106,19 +107,70 @@ defmodule Keila.Mailings.Worker do
106107
# Email was already sent
107108
defp handle_result({:error, :already_sent}, _), do: {:cancel, :already_sent}
108109

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+
109128
# Another error occurred. Sending is not retried.
110129
defp handle_result({:error, reason}, recipient) do
111130
Logger.warning(
112131
"Failed sending email to #{recipient.contact.email} for campaign #{recipient.campaign.id}: #{inspect(reason)}"
113132
)
114133

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
115142
from(r in Recipient,
116143
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+
]
118150
)
119-
|> Repo.update_all([])
151+
end
120152

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+
)
122174
end
123175

124176
defp get_receipt(%{id: receipt}), do: receipt

0 commit comments

Comments
 (0)