|
| 1 | +import logging |
| 2 | +from django_email_learning.ports.email_sender_protocol import EmailSenderProtocol |
| 3 | +from django.core.mail import EmailMultiAlternatives |
| 4 | +from django.core.mail.message import BadHeaderError |
| 5 | +from smtplib import SMTPException |
| 6 | + |
| 7 | +logger = logging.getLogger(__name__) |
| 8 | + |
| 9 | + |
| 10 | +class DjangoEmailSender(EmailSenderProtocol): |
| 11 | + def _mask_email(self, email_address: str) -> str: |
| 12 | + """Mask email address for logging privacy.""" |
| 13 | + try: |
| 14 | + username, domain = email_address.split("@") |
| 15 | + masked_username = username[0] + "***" |
| 16 | + return f"{masked_username}@{domain}" |
| 17 | + except ValueError: |
| 18 | + return "***@***" |
| 19 | + |
| 20 | + def _mask_recipients(self, recipients: list[str]) -> str: |
| 21 | + """Mask all recipient email addresses for logging.""" |
| 22 | + if not recipients: |
| 23 | + return "no recipients" |
| 24 | + masked = [self._mask_email(recipient) for recipient in recipients] |
| 25 | + return ", ".join(masked) |
| 26 | + |
| 27 | + def send_email(self, email: EmailMultiAlternatives) -> None: |
| 28 | + try: |
| 29 | + masked_recipients = self._mask_recipients(email.to) |
| 30 | + logger.info(f"Sending email to {masked_recipients}") |
| 31 | + email.send() |
| 32 | + logger.info(f"Email sent successfully to {masked_recipients}") |
| 33 | + except (SMTPException, BadHeaderError) as e: |
| 34 | + masked_recipients = self._mask_recipients(email.to) |
| 35 | + logger.error(f"Failed to send email to {masked_recipients}: {str(e)}") |
| 36 | + raise |
0 commit comments