do not consider out-of-office as bounce
This commit is contained in:
parent
2ed7c5fcdb
commit
5e2ea81a6c
|
@ -42,3 +42,7 @@ MIME_HEADERS = [
|
||||||
]
|
]
|
||||||
# convert to lowercase to facilitate header look up
|
# convert to lowercase to facilitate header look up
|
||||||
MIME_HEADERS = [h.lower() for h in MIME_HEADERS]
|
MIME_HEADERS = [h.lower() for h in MIME_HEADERS]
|
||||||
|
|
||||||
|
# if any of these headers are present, that means automatic out of office email
|
||||||
|
AUTO_REPLY1 = "X-Autoreply"
|
||||||
|
AUTO_REPLY2 = "Auto-Submitted"
|
||||||
|
|
|
@ -1751,6 +1751,22 @@ def handle_spam(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_automatic_out_of_office(msg: Message) -> bool:
|
||||||
|
if msg[headers.AUTO_REPLY1] is not None:
|
||||||
|
LOG.d(
|
||||||
|
"out-of-office email %s:%s", headers.AUTO_REPLY1, msg[headers.AUTO_REPLY1]
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
if msg[headers.AUTO_REPLY2] is not None:
|
||||||
|
LOG.d(
|
||||||
|
"out-of-office email %s:%s", headers.AUTO_REPLY2, msg[headers.AUTO_REPLY2]
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def handle_unsubscribe(envelope: Envelope, msg: Message) -> str:
|
def handle_unsubscribe(envelope: Envelope, msg: Message) -> str:
|
||||||
"""return the SMTP status"""
|
"""return the SMTP status"""
|
||||||
# format: alias_id:
|
# format: alias_id:
|
||||||
|
@ -2060,13 +2076,19 @@ def handle(envelope: Envelope) -> str:
|
||||||
len(rcpt_tos) == 1
|
len(rcpt_tos) == 1
|
||||||
and rcpt_tos[0].startswith(BOUNCE_PREFIX)
|
and rcpt_tos[0].startswith(BOUNCE_PREFIX)
|
||||||
and rcpt_tos[0].endswith(BOUNCE_SUFFIX)
|
and rcpt_tos[0].endswith(BOUNCE_SUFFIX)
|
||||||
|
# out of office is sent to the mail_from
|
||||||
|
# more info on https://support.google.com/mail/thread/21246740/my-auto-reply-filter-isn-t-replying-to-original-sender-address?hl=en&msgid=21261237
|
||||||
|
and not is_automatic_out_of_office(msg)
|
||||||
):
|
):
|
||||||
|
|
||||||
email_log_id = parse_id_from_bounce(rcpt_tos[0])
|
email_log_id = parse_id_from_bounce(rcpt_tos[0])
|
||||||
email_log = EmailLog.get(email_log_id)
|
email_log = EmailLog.get(email_log_id)
|
||||||
return handle_bounce(envelope, email_log, msg)
|
return handle_bounce(envelope, email_log, msg)
|
||||||
|
|
||||||
if len(rcpt_tos) == 1 and rcpt_tos[0].startswith(
|
if (
|
||||||
f"{BOUNCE_PREFIX_FOR_REPLY_PHASE}+"
|
len(rcpt_tos) == 1
|
||||||
|
and rcpt_tos[0].startswith(f"{BOUNCE_PREFIX_FOR_REPLY_PHASE}+")
|
||||||
|
and not is_automatic_out_of_office(msg)
|
||||||
):
|
):
|
||||||
email_log_id = parse_id_from_bounce(rcpt_tos[0])
|
email_log_id = parse_id_from_bounce(rcpt_tos[0])
|
||||||
email_log = EmailLog.get(email_log_id)
|
email_log = EmailLog.get(email_log_id)
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
|
from email.message import EmailMessage
|
||||||
|
|
||||||
|
from app.email import headers
|
||||||
from app.models import User, Alias, AuthorizedAddress, IgnoredEmail
|
from app.models import User, Alias, AuthorizedAddress, IgnoredEmail
|
||||||
from email_handler import get_mailbox_from_mail_from, should_ignore
|
from email_handler import (
|
||||||
|
get_mailbox_from_mail_from,
|
||||||
|
should_ignore,
|
||||||
|
is_automatic_out_of_office,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_get_mailbox_from_mail_from(flask_client):
|
def test_get_mailbox_from_mail_from(flask_client):
|
||||||
|
@ -40,3 +47,17 @@ def test_should_ignore(flask_client):
|
||||||
assert not should_ignore("mail_from", ["rcpt_to"])
|
assert not should_ignore("mail_from", ["rcpt_to"])
|
||||||
IgnoredEmail.create(mail_from="mail_from", rcpt_to="rcpt_to", commit=True)
|
IgnoredEmail.create(mail_from="mail_from", rcpt_to="rcpt_to", commit=True)
|
||||||
assert should_ignore("mail_from", ["rcpt_to"])
|
assert should_ignore("mail_from", ["rcpt_to"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_automatic_out_of_office():
|
||||||
|
msg = EmailMessage()
|
||||||
|
assert not is_automatic_out_of_office(msg)
|
||||||
|
|
||||||
|
msg[headers.AUTO_REPLY1] = "yes"
|
||||||
|
assert is_automatic_out_of_office(msg)
|
||||||
|
|
||||||
|
del msg[headers.AUTO_REPLY1]
|
||||||
|
assert not is_automatic_out_of_office(msg)
|
||||||
|
|
||||||
|
msg[headers.AUTO_REPLY2] = "auto-replied"
|
||||||
|
assert is_automatic_out_of_office(msg)
|
||||||
|
|
Loading…
Reference in a new issue