Skip to content

Commit 670e18d

Browse files
authored
Merge pull request #600 from PROCOLLAB-github/feature/auto_sending_email
Обновил логи для избежания ложных sent статусов
2 parents d0857a9 + d8b4eba commit 670e18d

File tree

1 file changed

+103
-13
lines changed

1 file changed

+103
-13
lines changed

mailing/tasks.py

Lines changed: 103 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ def _send_scenario_for_program(scenario, program, scheduled_for):
5959
if not user_ids:
6060
return 0
6161

62+
logger.info(
63+
"Scenario %s program=%s scheduled_for=%s recipients=%s",
64+
scenario.code,
65+
program.id,
66+
scheduled_for,
67+
len(user_ids),
68+
)
69+
6270
MailingScenarioLog.objects.filter(
6371
scenario_code=scenario.code,
6472
program=program,
@@ -84,26 +92,88 @@ def _send_scenario_for_program(scenario, program, scheduled_for):
8492
def context_builder(user):
8593
return scenario.context_builder(program, user, deadline_date)
8694

95+
sent_count = 0
96+
failed_count = 0
97+
98+
def _normalize_status(status_value):
99+
if status_value is None:
100+
return set()
101+
if isinstance(status_value, dict):
102+
return {str(key) for key in status_value.keys()}
103+
if isinstance(status_value, (set, list, tuple)):
104+
return {str(item) for item in status_value}
105+
return {str(status_value)}
106+
87107
def status_callback(user, msg):
108+
nonlocal sent_count, failed_count
88109
status = getattr(msg, "anymail_status", None)
89110
message_id = getattr(status, "message_id", None) if status else None
90-
if message_id:
91-
logger.info(
92-
"Scenario %s user=%s anymail_id=%s status=%s",
111+
status_set = _normalize_status(getattr(status, "status", None))
112+
status_str = ",".join(sorted(status_set)) if status_set else "unknown"
113+
is_failed = bool(status_set & {"rejected", "failed", "invalid", "bounced"})
114+
115+
if not message_id:
116+
failed_count += 1
117+
MailingScenarioLog.objects.filter(
118+
scenario_code=scenario.code,
119+
program=program,
120+
scheduled_for=scheduled_for,
121+
status=MailingScenarioLog.Status.PENDING,
122+
user_id=user.id,
123+
).update(
124+
status=MailingScenarioLog.Status.FAILED,
125+
error="anymail_status missing",
126+
)
127+
logger.warning(
128+
"Scenario %s user=%s anymail_status missing",
93129
scenario.code,
94130
user.id,
95-
message_id,
96-
getattr(status, "status", None),
97131
)
98-
else:
99-
logger.info(
100-
"Scenario %s user=%s anymail_status missing",
132+
return
133+
134+
if is_failed:
135+
failed_count += 1
136+
MailingScenarioLog.objects.filter(
137+
scenario_code=scenario.code,
138+
program=program,
139+
scheduled_for=scheduled_for,
140+
status=MailingScenarioLog.Status.PENDING,
141+
user_id=user.id,
142+
).update(
143+
status=MailingScenarioLog.Status.FAILED,
144+
error=f"anymail_status={status_str} anymail_id={message_id}",
145+
)
146+
logger.error(
147+
"Scenario %s user=%s anymail_id=%s status=%s",
101148
scenario.code,
102149
user.id,
150+
message_id,
151+
status_str,
103152
)
153+
return
154+
155+
sent_count += 1
156+
MailingScenarioLog.objects.filter(
157+
scenario_code=scenario.code,
158+
program=program,
159+
scheduled_for=scheduled_for,
160+
status=MailingScenarioLog.Status.PENDING,
161+
user_id=user.id,
162+
).update(
163+
status=MailingScenarioLog.Status.SENT,
164+
sent_at=timezone.now(),
165+
error="",
166+
)
167+
logger.info(
168+
"Scenario %s user=%s anymail_id=%s status=%s",
169+
scenario.code,
170+
user.id,
171+
message_id,
172+
status_str,
173+
)
104174

105175
try:
106-
send_mass_mail_from_template(
176+
num_sent = send_mass_mail_from_template(
107177
recipients_to_send,
108178
scenario.subject,
109179
scenario.template_name,
@@ -123,16 +193,36 @@ def status_callback(user, msg):
123193
)
124194
return 0
125195

126-
MailingScenarioLog.objects.filter(
196+
pending_qs = MailingScenarioLog.objects.filter(
127197
scenario_code=scenario.code,
128198
program=program,
129199
scheduled_for=scheduled_for,
130200
status=MailingScenarioLog.Status.PENDING,
131201
user_id__in=user_ids,
132-
).update(
133-
status=MailingScenarioLog.Status.SENT, sent_at=timezone.now(), error=""
134202
)
135-
return len(user_ids)
203+
pending_count = pending_qs.count()
204+
if pending_count:
205+
pending_qs.update(
206+
status=MailingScenarioLog.Status.FAILED,
207+
error="anymail_status missing",
208+
)
209+
failed_count += pending_count
210+
logger.warning(
211+
"Scenario %s program=%s pending left after send: %s",
212+
scenario.code,
213+
program.id,
214+
pending_count,
215+
)
216+
217+
logger.info(
218+
"Scenario %s program=%s send_messages=%s sent=%s failed=%s",
219+
scenario.code,
220+
program.id,
221+
num_sent,
222+
sent_count,
223+
failed_count,
224+
)
225+
return sent_count
136226

137227

138228
@app.task

0 commit comments

Comments
 (0)