Skip to content Skip to sidebar Skip to footer

Detecting If An Email Is A "delivery Status Notification" And Extract Information - Python

I'm using the Python email module to parse emails. I need to be able to tell if an email is a 'Delivery Status Notification', find out what the status is, and extract information o

Solution 1:

The docs you cited says that the message is multi-part if it is DSN:

import email

msg = email.message_from_string(emailstr)

if (msg.is_multipart() andlen(msg.get_payload()) > 1and 
    msg.get_payload(1).get_content_type() == 'message/delivery-status'):
    # email is DSNprint(msg.get_payload(0).get_payload()) # human-readable sectionfor dsn in msg.get_payload(1).get_payload():
        print('action: %s' % dsn['action']) # e.g., "failed", "delivered"iflen(msg.get_payload()) > 2:
        print(msg.get_payload(2)) # original message

Format of a Delivery Status Notification (from rfc 3464):

A DSN is a MIME message with a top-level content-type of
multipart/report (defined in [REPORT]).  When a multipart/report
content is used to transmit a DSN:

(a) The report-type parameter of the multipart/report content is"delivery-status".

(b) The first component of the multipart/report contains a human-
    readable explanation of the DSN, as described in [REPORT].

(c) The second component of the multipart/report isof content-type
    message/delivery-status, described in section 2.1of this
    document.

(d) If the original message or a portion of the message isto be
    returned to the sender, it appears as the third component of the
    multipart/report.

Solution 2:

I don't use Python but I suppose Gmail improved its support to DSN because my tests are successfull:

You can see in the sample below this is a multipart message with "Content-Type: multipart/report; report-type=delivery-status".

The way I identify reliably that it is a DSN:

  • The first row is "Return-path: <>"
  • Content-Type is "multipart/report" with "report-type=delivery-status"

Then, I know that:

  • The report content is in the part with Content-Type = "message/delivery-status"
  • Status and Action fields are always present in the report content.
  • Note the Status field can be less precise than other status eventually present in the Diagnostic-Code field (not mandatory). However, the sample below is good (same status in all fields)
  • The original message is in the part with Content-Type = "message/rfc822". Sometimes, MTA returns only original message headers without content. In this case, Content-Type is "text/rfc822-headers".

Sample DSN received after an e-mail sent to test-dsn-failure@gmail.com:

Return-path:<>Received:fromxxx([xxx])byxxxwithESMTP;Fri,04May2012 16:18:13+0200From:<Mailer-Daemon@xxx>(MailDeliverySystem)To:xxxSubject:UndeliveredMailReturnedtoSenderDate:Fri,04May2012 15:25:09+0200MIME-Version:1.0Content-Type:multipart/report;report-type=delivery-status;boundary="HTB3nt3RR7vw/QMPR4kDPbKg+XWjXIKdC/rfHQ=="ThisisaMIME-encapsulatedmessage.--HTB3nt3RR7vw/QMPR4kDPbKg+XWjXIKdC/rfHQ==Content-Description:NotificationContent-Type:text/plainI'msorrytohavetoinformyouthatyourmessagecouldnotbedeliveredtooneormorerecipients.It'sattachedbelow.Forfurtherassistance,pleasesendmailto<postmaster@xxx>Ifyoudoso,pleaseincludethisproblemreport.Youcandeleteyourowntextfromtheattachedreturnedmessage.<test-dsn-failure@gmail.com>:550-5.1.1Theemailaccountthatyoutriedtoreachdoesnotexist.Pleasetry550-5.1.1double-checkingtherecipient'semailaddressfortyposor550-5.1.1unnecessaryspaces.Learnmoreat5505.1.1http://support.google.com/mail/bin/answer.py?answer=6596t12si10077186weq.36--HTB3nt3RR7vw/QMPR4kDPbKg+XWjXIKdC/rfHQ==Content-Description:DeliveryreportContent-Type:message/delivery-statusReporting-MTA:dns;xxxArrival-Date:Fri,04May2012 15:25:09+0200Final-Recipient:rfc822;test-dsn-failure@gmail.comStatus:5.1.1Action:failedLast-Attempt-Date:Fri,04May2012 15:25:09+0200Diagnostic-Code:smtp;550-5.1.1Theemailaccountthatyoutriedtoreachdoesnotexist.Pleasetry550-5.1.1double-checkingtherecipient'semailaddressfortyposor550-5.1.1unnecessaryspaces.Learnmoreat5505.1.1http://support.google.com/mail/bin/answer.py?answer=6596t12si10077186weq.36--HTB3nt3RR7vw/QMPR4kDPbKg+XWjXIKdC/rfHQ==Content-Description:UndeliveredMessageContent-Type:message/rfc822

[originalmessage...]

Solution 3:

The X-Failed-Recipients header seems to be the quickest way to identify gmail DSN. After that, it seems you must parse the text/plain content.

Post a Comment for "Detecting If An Email Is A "delivery Status Notification" And Extract Information - Python"