Chilkat HOME .NET Core C# Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi ActiveX Delphi DLL Go Java Lianja Mono C# Node.js Objective-C PHP ActiveX PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(Unicode C) Processing a multipart/report Delivery Status Notification (Bounce Notification)See more Email Object ExamplesThis example discusses the format of Delivery Status Notification emails and how to process them.
#include <C_CkEmailW.h> #include <C_CkHtmlToTextW.h> #include <C_CkStringArrayW.h> #include <C_CkMimeW.h> void ChilkatSample(void) { BOOL success; HCkEmailW email; HCkHtmlToTextW h2t; HCkStringArrayW sa; int numFinalRecipients; int i; const wchar_t *headersText; HCkMimeW mime; HCkEmailW origEmail; // 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. email = CkEmailW_Create(); success = CkEmailW_LoadEml(email,L"qa_data/eml/deliveryStatus.eml"); // success = email.LoadEml("qa_data/eml/sample_multipart_report.eml"); if (success == FALSE) { wprintf(L"%s\n",CkEmailW_lastErrorText(email)); CkEmailW_Dispose(email); return; } // Verify this is a multipart/report email.. if (CkEmailW_IsMultipartReport(email) == FALSE) { wprintf(L"Not a multipart/report email.\n"); CkEmailW_Dispose(email); return; } // Get the body that is to be displayed to a human in an email program (such as Outlook). if (CkEmailW_HasPlainTextBody(email) == TRUE) { wprintf(L"Plain text body:\n"); // println email.GetPlainTextBody(); } else { if (CkEmailW_HasHtmlBody(email) == TRUE) { // Convert HTML to plain-text.. h2t = CkHtmlToTextW_Create(); wprintf(L"HTML body converted to plain-text:\n"); wprintf(L"%s\n",CkHtmlToTextW_toText(h2t,CkEmailW_getHtmlBody(email))); } else { wprintf(L"Has no plain-text or HTML body...\n"); } } wprintf(L"---------------------------------\n"); // Now get information from the message/delivery-status part (or the message/disposition-notification part) wprintf(L"--- Delivery Status Information:\n"); wprintf(L"Status: %s\n",CkEmailW_getDeliveryStatusInfo(email,L"Status")); wprintf(L"Action: %s\n",CkEmailW_getDeliveryStatusInfo(email,L"Action")); wprintf(L"Reporting-MTA: %s\n",CkEmailW_getDeliveryStatusInfo(email,L"Reporting-MTA")); sa = CkEmailW_GetDsnFinalRecipients(email); numFinalRecipients = CkStringArrayW_getCount(sa); i = 0; while (i < numFinalRecipients) { wprintf(L"final recipient: %s\n",CkStringArrayW_getString(sa,i)); i = i + 1; } CkStringArrayW_Dispose(sa); wprintf(L"---------------------------------\n"); // If the multipart/report contains a text/rfc822-headers, it can be retrieved like this: headersText = CkEmailW_getNthTextPartOfType(email,0,L"text/rfc822-headers",FALSE,FALSE); if (CkEmailW_getLastMethodSuccess(email) == TRUE) { wprintf(L"The text/rfc822-headers part exists..\n"); wprintf(L"\n"); wprintf(L"%s\n",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. mime = CkMimeW_Create(); CkMimeW_LoadMime(mime,headersText); // Do whatever you want.. // For example, look at the "To" header. wprintf(L"MIME To header:\n"); wprintf(L"%s\n",CkMimeW_getHeaderField(mime,L"To")); } wprintf(L"---------------------------------\n"); // 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 (CkEmailW_getNumAttachedMessages(email) > 0) { // Get the 1st attachment message (assume we don't have more than one attached message) origEmail = CkEmailW_GetAttachedMessage(email,0); if (CkEmailW_getLastMethodSuccess(email) == TRUE) { wprintf(L"Attached message subject: %s\n",CkEmailW_subject(origEmail)); // Do whatever else you want.. CkEmailW_Dispose(origEmail); } } CkEmailW_Dispose(email); CkHtmlToTextW_Dispose(h2t); CkMimeW_Dispose(mime); } |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.