diff --git a/app/mail_sender.py b/app/mail_sender.py index 5f300026..7aba3707 100644 --- a/app/mail_sender.py +++ b/app/mail_sender.py @@ -32,6 +32,7 @@ class SendRequest: rcpt_options: Dict = {} is_forward: bool = False ignore_smtp_errors: bool = False + retries: int = 0 def to_bytes(self) -> bytes: if not config.SAVE_UNSENT_DIR: @@ -67,6 +68,30 @@ class SendRequest: is_forward=decoded_data["is_forward"], ) + def save_request_to_unsent_dir(self, prefix: str = "DeliveryFail"): + file_name = ( + f"{prefix}-{int(time.time())}-{uuid.uuid4()}.{SendRequest.SAVE_EXTENSION}" + ) + file_path = os.path.join(config.SAVE_UNSENT_DIR, file_name) + self.save_request_to_file(file_path) + + @staticmethod + def save_request_to_failed_dir(self, prefix: str = "DeliveryRetryFail"): + file_name = ( + f"{prefix}-{int(time.time())}-{uuid.uuid4()}.{SendRequest.SAVE_EXTENSION}" + ) + dir_name = os.path.join(config.SAVE_UNSENT_DIR, "failed") + if not os.path.isdir(dir_name): + os.makedirs(dir_name) + file_path = os.path.join(dir_name, file_name) + self.save_request_to_file(file_path) + + def save_request_to_file(self, file_path: str): + file_contents = self.to_bytes() + with open(file_path, "wb") as fd: + fd.write(file_contents) + LOG.i(f"Saved unsent message {file_path}") + class MailSender: def __init__(self): @@ -171,21 +196,9 @@ class MailSender: f"Could not send message to smtp server {config.POSTFIX_SERVER}:{config.POSTFIX_PORT}" ) if config.SAVE_UNSENT_DIR: - self._save_request_to_unsent_dir(send_request) + send_request.save_request_to_unsent_dir() return False - def _save_request_to_unsent_dir( - self, send_request: SendRequest, prefix: str = "DeliveryFail" - ): - file_name = ( - f"{prefix}-{int(time.time())}-{uuid.uuid4()}.{SendRequest.SAVE_EXTENSION}" - ) - file_path = os.path.join(config.SAVE_UNSENT_DIR, file_name) - file_contents = send_request.to_bytes() - with open(file_path, "wb") as fd: - fd.write(file_contents) - LOG.i(f"Saved unsent message {file_path}") - mail_sender = MailSender() @@ -219,6 +232,7 @@ def load_unsent_mails_from_fs_and_resend(): LOG.i(f"Trying to re-deliver email {filename}") try: send_request = SendRequest.load_from_file(full_file_path) + send_request.retries += 1 except Exception as e: LOG.e(f"Cannot load {filename}. Error {e}") continue @@ -230,6 +244,11 @@ def load_unsent_mails_from_fs_and_resend(): "DeliverUnsentEmail", {"delivered": "true"} ) else: + if send_request.retries > 2: + os.unlink(full_file_path) + send_request.save_request_to_failed_dir() + else: + send_request.save_request_to_file(full_file_path) newrelic.agent.record_custom_event( "DeliverUnsentEmail", {"delivered": "false"} )