Tcl
Tcl
Processing a multipart/report Delivery Status Notification (Bounce Notification)
See more Email Object Examples
This example discusses the format of Delivery Status Notification emails and how to process them.Chilkat Tcl Downloads
load ./chilkat.dll
set success 0
# Here are the MIME structures, showing the content-type and nesting of the MIME parts of three sample
# multipart/report DSN (Delivery Status Notification) emails.
# This 1st sample includes a "text/rfc822-headers" MIME subpart.
# multipart/report
# text/plain
# message/delivery-status
# text/rfc822-headers
# message/rfc822
# This 2nd sample lacks the text/rfc-headers part, but the "report type" information
# is offered in both plain-text and HTML formats.
# multipart/report
# multipart/alternative
# text/plain
# text/html
# message/delivery-status
# message/rfc822
# ----------------------------------------------------------------------------------------------------
# A multipart/report MIME delivery status notification follows a specific format defined by the Internet Engineering Task Force (IETF) in RFC 3464,
# which outlines the "An Extensible Message Format for Delivery Status Notifications" standard. The format consists of multiple parts within a
# multipart/report structure. Here's an overview of the main parts involved:
#
# The 1st sub-part under multipart/report is the body of the DSN to be displayed by the email client (such as Outlook).
# It can be a simple text/plain body, or it can be multipart/alternative and offer a few alternative format, typically plain-text and HTML.
# HTML is best for viewing a program such as Outlook.
# This part of the multipart/report is not structured for programmatic processing. It's meant to be viewed by a human.
# --------------------
# The "message/delivery-status" part within a multipart/report MIME structure follows a specific format to provide details about the delivery status
# of an email message. Here's an overview of the format and the key components within the "message/delivery-status" part:
#
# (1) Content-Type and Reporting-UA:
# The "message/delivery-status" part begins with the Content-Type header specifying "message/delivery-status".
# It may also include a Reporting-UA (Reporting User Agent) field that identifies the software or system generating the delivery status notification.
#
# For example:
#
# Content-Type: message/delivery-status
# Reporting-UA: Example Mail System 1.0
#
# (2) Fields:
# The "message/delivery-status" part contains a series of fields, each providing specific information about the delivery status.
# These fields are structured as key-value pairs.
#
# Common fields include:
#
# Final-Recipient: Specifies the recipient for whom the delivery status is being reported.
# Action: Describes the action performed by the reporting system (e.g., failed, delivered, delayed, etc.).
# Status: Indicates the status code or reason for the delivery attempt result.
# Remote-MTA: Specifies the host or system that attempted the delivery.
# Diagnostic-Code: Provides additional diagnostic information, such as error codes or explanations.
#
# For example:
#
# Final-Recipient: rfc822; john.doe@example.com
# Action: failed
# Status: 5.1.1
# Remote-MTA: smtp.example.com
# Diagnostic-Code: smtp; 550 Requested action not taken: mailbox unavailable
#
# (3) Additional Fields:
# Additional fields may be included in the "message/delivery-status" part to provide further information about the delivery attempt.
# These fields can vary depending on the implementation or specific needs of the system generating the delivery status notification.
# For example:
#
# X-Spam-Flag: YES
# X-Spam-Score: 7.2
#
# Note: The specific fields and their values within the "message/delivery-status" part can vary depending on the implementation
# or the email server/application generating the delivery status notification. The structure described above represents the standard format
# as defined in RFC 3464, but variations may exist in practice.
# --------------------
# The "text/rfc822-headers" MIME part, if included, contains the headers of the original email message
# for which the delivery status notification is being generated. It provides a subset of the headers from the original message,
# typically excluding the message body and attachments.
#
# The purpose of including the "text/rfc822-headers" part is to provide contextual information about the original message.
# It allows the recipient to review the original headers, such as the subject, sender, recipients, date, and other relevant information,
# in order to understand the context and details of the email message for which the delivery status notification is being generated.
#
# Note that the specific headers included in the "text/rfc822-headers" part can vary based on the implementation or requirements
# of the system generating the delivery status notification.
# --------------------
# If the message/rfc822 part is present, it contains the full MIME of the email that was not delivered.
# In Chilkat terminology, this is an attached message.
# OK, let's write code to process a multipart/report email.
set email [new_CkEmail]
set success [CkEmail_LoadEml $email "qa_data/eml/deliveryStatus.eml"]
# success = email.LoadEml("qa_data/eml/sample_multipart_report.eml");
if {$success == 0} then {
puts [CkEmail_lastErrorText $email]
delete_CkEmail $email
exit
}
# Verify this is a multipart/report email..
if {[CkEmail_IsMultipartReport $email] == 0} then {
puts "Not a multipart/report email."
delete_CkEmail $email
exit
}
# Get the body that is to be displayed to a human in an email program (such as Outlook).
if {[CkEmail_HasPlainTextBody $email] == 1} then {
puts "Plain text body:"
# println email.GetPlainTextBody();
} else {
if {[CkEmail_HasHtmlBody $email] == 1} then {
# Convert HTML to plain-text..
set h2t [new_CkHtmlToText]
puts "HTML body converted to plain-text:"
puts [CkHtmlToText_toText $h2t [CkEmail_getHtmlBody $email]]
} else {
puts "Has no plain-text or HTML body..."
}
}
puts "---------------------------------"
# Now get information from the message/delivery-status part (or the message/disposition-notification part)
puts "--- Delivery Status Information:"
puts "Status: [CkEmail_getDeliveryStatusInfo $email Status]"
puts "Action: [CkEmail_getDeliveryStatusInfo $email Action]"
puts "Reporting-MTA: [CkEmail_getDeliveryStatusInfo $email Reporting-MTA]"
set jsonDsnInfo [new_CkJsonObject]
CkEmail_GetDsnInfo $email $jsonDsnInfo
CkJsonObject_put_EmitCompact $jsonDsnInfo 0
puts [CkJsonObject_emit $jsonDsnInfo]
puts "---------------------------------"
# If the multipart/report contains a text/rfc822-headers, it can be retrieved like this:
set headersText [CkEmail_getNthTextPartOfType $email 0 "text/rfc822-headers" 0 0]
if {[CkEmail_get_LastMethodSuccess $email] == 1} then {
puts "The text/rfc822-headers part exists.."
puts
puts "$headersText"
# If you wish to process the headers, you can load them into a MIME object and use the Chilkat MIME functionality to examine the headers.
set mime [new_CkMime]
CkMime_LoadMime $mime $headersText
# Do whatever you want..
# For example, look at the "To" header.
puts "MIME To header:"
puts [CkMime_getHeaderField $mime To]
}
puts "---------------------------------"
# Finally, if the original email was attached, you can load it into another Chilkat Email object instance and
# do what you want with it..
if {[CkEmail_get_NumAttachedMessages $email] > 0} then {
# Get the 1st attachment message (assume we don't have more than one attached message)
set origEmail [new_CkEmail]
set success [CkEmail_GetAttachedEmail $email 0 $origEmail]
if {$success == 1} then {
puts "Attached message subject: [CkEmail_subject $origEmail]"
# Do whatever else you want..
}
}
delete_CkEmail $email
delete_CkHtmlToText $h2t
delete_CkJsonObject $jsonDsnInfo
delete_CkMime $mime
delete_CkEmail $origEmail