add get_mailbox_bounce_info()

This commit is contained in:
Son 2021-10-14 15:10:16 +02:00
parent e5a7aeb3fb
commit 3bdeda3e04
3 changed files with 162 additions and 8 deletions

View File

@ -598,22 +598,53 @@ def mailbox_already_used(email: str, user) -> bool:
return False
def get_orig_message_from_bounce(msg: Message) -> Message:
def get_orig_message_from_bounce(bounce_report: Message) -> Optional[Message]:
"""parse the original email from Bounce"""
i = 0
for part in msg.walk():
for part in bounce_report.walk():
i += 1
# the original message is the 4th part
# 1st part is the root part, multipart/report
# 2nd is text/plain, Postfix log
# 1st part is the container (bounce report)
# 2nd part is the report from our own Postfix
# 3rd is report from other mailbox
# 4th is the container of the original message
# ...
# 7th is original message
if i == 7:
return part
def get_orig_message_from_hotmail_complaint(msg: Message) -> Message:
def get_mailbox_bounce_info(bounce_report: Message) -> Optional[Message]:
"""
Return the bounce info from the bounce report
An example of bounce info:
Final-Recipient: rfc822; not-existing@gmail.com
Original-Recipient: rfc822;not-existing@gmail.com
Action: failed
Status: 5.1.1
Remote-MTA: dns; gmail-smtp-in.l.google.com
Diagnostic-Code: smtp;
550-5.1.1 The email account that you tried to reach does
not exist. Please try 550-5.1.1 double-checking the recipient's email
address for typos or 550-5.1.1 unnecessary spaces. Learn more at 550 5.1.1
https://support.google.com/mail/?p=NoSuchUser z127si6173191wmc.132 - gsmtp
"""
i = 0
for part in bounce_report.walk():
i += 1
# 1st part is the container (bounce report)
# 2nd part is the report from our own Postfix
# 3rd is report from other mailbox
# 4th is the container of the original message
# 5th is a child of 3rd that contains more info about the bounce
if i == 5:
return part
def get_orig_message_from_hotmail_complaint(msg: Message) -> Optional[Message]:
i = 0
for part in msg.walk():
i += 1
@ -625,7 +656,7 @@ def get_orig_message_from_hotmail_complaint(msg: Message) -> Message:
return part
def get_orig_message_from_yahoo_complaint(msg: Message) -> Message:
def get_orig_message_from_yahoo_complaint(msg: Message) -> Optional[Message]:
i = 0
for part in msg.walk():
i += 1

View File

@ -0,0 +1,102 @@
Received: by mx1.sl.co (Postfix)
id F09806333D; Thu, 14 Oct 2021 09:14:44 +0000 (UTC)
Date: Thu, 14 Oct 2021 09:14:44 +0000 (UTC)
From: mailer-daemon@bounce.sl.co (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender
To: bounce+5352+@sl.co
Auto-Submitted: auto-replied
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status;
boundary="8A32A6333B.1634202884/mx1.sl.co"
Content-Transfer-Encoding: 8bit
Message-Id: <20211014091444.F09806333D@mx1.sl.co>
This is a MIME-encapsulated message.
--8A32A6333B.1634202884/mx1.sl.co
Content-Description: Notification
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
This is the mail system at host mx1.sl.co.
I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.
For further assistance, please send mail to <postmaster@sl.co>
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The mail system
<not-existing@gmail.com>: host
gmail-smtp-in.l.google.com[142.251.5.27] said: 550-5.1.1 The email account
that you tried to reach does not exist. Please try 550-5.1.1
double-checking the recipient's email address for typos or 550-5.1.1
unnecessary spaces. Learn more at 550 5.1.1
https://support.google.com/mail/?p=NoSuchUser z127si6173191wmc.132 - gsmtp
(in reply to RCPT TO command)
--8A32A6333B.1634202884/mx1.sl.co
Content-Description: Delivery report
Content-Type: message/delivery-status
Reporting-MTA: dns; mx1.sl.co
X-Postfix-Queue-ID: 8A32A6333B
X-Postfix-Sender: rfc822; bounce+5352+@sl.co
Arrival-Date: Thu, 14 Oct 2021 09:14:44 +0000 (UTC)
Final-Recipient: rfc822; not-existing@gmail.com
Original-Recipient: rfc822;not-existing@gmail.com
Action: failed
Status: 5.1.1
Remote-MTA: dns; gmail-smtp-in.l.google.com
Diagnostic-Code: smtp;
550-5.1.1 The email account that you tried to reach does
not exist. Please try 550-5.1.1 double-checking the recipient's email
address for typos or 550-5.1.1 unnecessary spaces. Learn more at 550 5.1.1
https://support.google.com/mail/?p=NoSuchUser z127si6173191wmc.132 - gsmtp
--8A32A6333B.1634202884/mx1.sl.co
Content-Description: Undelivered Message
Content-Type: message/rfc822
Content-Transfer-Encoding: 8bit
Return-Path: <bounce+5352+@sl.co>
X-SimpleLogin-Client-IP: 90.127.20.84
Received: from 2a01cb00008c9c001a3eeffffec79eea.ipv6.abo.wanadoo.fr
(lfbn-idf1-1-2034-84.w90-127.abo.wanadoo.fr [90.127.20.84])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
(No client certificate requested)
by mx1.sl.co (Postfix) with ESMTPS id 8A32A6333B
for <not-existing@gmail.com>;
Thu, 14 Oct 2021 09:14:44 +0000 (UTC)
Content-Type: text/plain;
charset=us-ascii
Content-Transfer-Encoding: 7bit
Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.120.0.1.13\))
Subject: bounce 5
Message-Id: <F2EFE3CE-3967-49EC-8639-9A5900230F2E@gmail.com>
X-SimpleLogin-Type: Forward
X-SimpleLogin-EmailLog-ID: 5352
X-SimpleLogin-Envelope-From: sender@gmail.com
X-SimpleLogin-Envelope-To: heyheyalo@sl.co
date: Thu, 14 Oct 2021 09:14:44 -0000
From: "First Last - sender at gmail.com"
<ra+sender.at.gmail.com+bsppvaap@sl.co>
To: heyheyalo@sl.co
List-Unsubscribe: <mailto:unsubsribe@sl.co?subject=26561=>
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=sl.co;
i=@sl.co; q=dns/txt; s=dkim; t=1634202884;
h=message-id : date : subject : from : to;
bh=ktjzaMYZHA8J5baAHC3QyOmFwAAv/MvNtIz1dvmI3V0=;
b=mzf2ZDIVshKSSjw4AQnrOttgRRjzYzZ+49PaPRobt0xFH0E02a2C9Rl/qLEshLHA7amba
8iNTzdTkp9UJquzjk3NwM9GCakmSzd9DmFsalkgeErDAKWNo2O2c7aYDHZlK/sp2vgsIcSO
1w6sp8sVIRr2JrnFPxFOfsOSkSabeOA=
Alo quoi
--8A32A6333B.1634202884/mx1.sl.co--

View File

@ -1,9 +1,10 @@
import email
import os
from email.message import EmailMessage
import arrow
from app.config import MAX_ALERT_24H, EMAIL_DOMAIN, BOUNCE_EMAIL
from app.config import MAX_ALERT_24H, EMAIL_DOMAIN, BOUNCE_EMAIL, ROOT_DIR
from app.db import Session
from app.email_utils import (
get_email_domain_part,
@ -31,6 +32,8 @@ from app.email_utils import (
should_ignore_bounce,
get_header_unicode,
parse_full_address,
get_orig_message_from_bounce,
get_mailbox_bounce_info,
)
from app.models import User, CustomDomain, Alias, Contact, EmailLog, IgnoreBounceSender
@ -748,3 +751,21 @@ def test_should_ignore_bounce(flask_client):
def test_get_header_unicode():
assert get_header_unicode("ab@cd.com") == "ab@cd.com"
assert get_header_unicode("=?utf-8?B?w6nDqQ==?=@example.com") == "éé@example.com"
def test_get_orig_message_from_bounce():
with open(os.path.join(ROOT_DIR, "local_data", "email_tests", "bounce.eml")) as f:
bounce_report = email.message_from_file(f)
orig_msg = get_orig_message_from_bounce(bounce_report)
assert orig_msg["X-SimpleLogin-Type"] == "Forward"
assert orig_msg["X-SimpleLogin-Envelope-From"] == "sender@gmail.com"
def test_get_mailbox_bounce_info():
with open(os.path.join(ROOT_DIR, "local_data", "email_tests", "bounce.eml")) as f:
bounce_report = email.message_from_file(f)
orig_msg = get_mailbox_bounce_info(bounce_report)
assert orig_msg["Final-Recipient"] == "rfc822; not-existing@gmail.com"
assert orig_msg["Original-Recipient"] == "rfc822;not-existing@gmail.com"