Skip to content

Commit

Permalink
Ignore undeliverable emails
Browse files Browse the repository at this point in the history
Our bounce rate was too high. We used external validations to check a
percentage of the scheduled emails. Rather than changing the datamodel
to store this information, provide the full underliverable email list
csv as an argument.
  • Loading branch information
ccunningham101 committed Feb 11, 2024
1 parent b365711 commit 97c01e1
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions retractions/management/commands/send_retraction_emails.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import email.utils
import logging
import mailbox
import pathlib

import anymail.exceptions
import anymail.utils
import django.core.exceptions
import django.db
import html2text
import pandas
from django.core.mail import EmailMultiAlternatives
from django.core.management.base import BaseCommand

Expand Down Expand Up @@ -59,6 +61,11 @@ def add_arguments(self, parser):
help="Maximum number of authors to send to",
default=None,
)
parser.add_argument(
"--undeliverable-file",
type=pathlib.Path,
help="File with validation result",
)

def handle(self, *args, **options):
setup.setup_logger(options["verbosity"])
Expand All @@ -78,6 +85,11 @@ def handle(self, *args, **options):

self.test_email = options["test-email"]

if options["undeliverable_file"]:
self.undeliverable = self._get_undeliverable(options["undeliverable_file"])
else:
self.undeliverable = None

# Filter for the authors who we would send mail to
authors = (
Author.objects.filter(pairs__retractedpaper__rct_group="i")
Expand All @@ -97,6 +109,15 @@ def handle(self, *args, **options):

self._send_for_author(author)

def _get_undeliverable(self, results_path):
results_df = pandas.read_csv(results_path)
assert "result" in results_df.columns
undeliverable = results_df[
(results_df.result == "undeliverable")
| (results_df.result == "do_not_send")
]
return undeliverable.address

def _send_for_author(self, author):
"""
Create and send mails for the author.
Expand Down Expand Up @@ -148,6 +169,16 @@ def _get_mail_to_send(self, author, intervention_pairs):
)
valid = False

if (
self.undeliverable is not None
and author_alias.email_address in self.undeliverable.values
):
logging.warning(
" Ignoring undeliverable email %s",
author_alias.email_address,
)
valid = False

if valid:
if self.test_email:
logging.warning(
Expand Down Expand Up @@ -376,6 +407,8 @@ def _actually_send_mails(self, author, pairs, mail_to_send):
)
except anymail.exceptions.AnymailError as e:
logging.exception(" Error trying to send email: %s", str(e))
except UnicodeError as e:
logging.exception(" Unicode error trying to send email: %s", str(e))
except django.db.utils.Error as e:
logging.exception(" Database error while mailing: %s", str(e))
raise

0 comments on commit 97c01e1

Please sign in to comment.