Request delivery and reading confirmation

If you just need to request read and delivery receipts for your e-mail, refer to Set "Request delivery confirmation" and "Request read confirmation" flags topic. The current guide is the much more detailed version of that topic.


Comparison of various methods of requesting delivery and reading confirmations

MailBee.NET supports several methods of requesting read receipts (reading confirmation) and delivery receipts (delivery confirmation).

"Request read receipt" methods:

"Request delivery receipt" methods:

Here and below, we assume mailer is an Smtp object instance.

You can use various methods together as there is no 100% reliable method of getting reading or delivery confirmations. The question is even not technical but rather social. People don't like to be tracked. So, you can request read and delivery receipts but you can never rely on them.

Generally speaking, if you got a delivery confirmation, you can safely assume the event described in this delivery confirmation has actually occurred. But if you haven't got any confirmation, this does not yet mean the actual event has never happened.


Request delivery and reading confirmation via message headers

This code snippet inserts message headers which will notify the receiving part to send delivery and reading confirmation to the specified e-mail address:

mailer.Message.ConfirmRead = "john.doe@company.com";
mailer.Message.ConfirmReceipt = "john.doe@company.com";
mailer.Message.ConfirmRead = "john.doe@company.com"
mailer.Message.ConfirmReceipt = "john.doe@company.com"

The e-mail server of the receiving part must support Return-Receipt-To header to send delivery confirmation, and the e-mail client program of the recipient must support Disposition-Notification-To header to send reading confirmation.


Request delivery status notification with ESMTP DSN

This method uses DSN (Delivery Status Notification) extension to SMTP protocol. If your server supports it, it includes DSN in the list of capabilities which is sent to the client in response to EHLO command.

This code snippet will cause MailBee.NET to notify the SMTP server that it needs to send delivery confirmation back to the sender in both cases (if the message was or wasn't delivered):

mailer.DeliveryNotification.NotifyCondition = DsnNotifyCondition.Always;
mailer.DeliveryNotification.NotifyCondition = DsnNotifyCondition.Always

The SMTP server must support DSN extension to send delivery confirmation.

Note that the only way to set the e-mail address where these notifications will arrive to is to set the actual sender of the message. See Set different From and Return-Path (use "real" sender address different from "From" address)topic on how to set the actual sender.


Use ESMTP DSN and message headers together

ESMTP DSN, Return-Receipt-To and Disposition-Notification-To message headers can be used all together because they are completely independent from each other:

// Request reading confirmation to the From address.
// Requires support from the recipient's e-mail reader.
// Most e-mail reader support this but it's often disabled.
mailer.Message.ConfirmRead = "john.doe@company.com";

// Request delivery confirmation to the From address.
// Requires support from the recipient's e-mail server.
// Most new servers don't support this but old servers often do.
mailer.Message.ConfirmReceipt = "john.doe@company.com";

// Request delivery confirmation for both delivery and non-delivery.
// Requires DSN support in the e-mail servers of yours and your recipient.
// Most new servers support this. If your server supports DSN but your
// recipient's server doesn't, delivery notifications will still work
// in most cases (unless there are more than 2 SMTP servers in the chain).
mailer.DeliveryNotification.NotifyCondition = DsnNotifyCondition.Always;
' Request reading confirmation to the From address.
' Requires support from the recipient's e-mail reader.
' Most e-mail reader support this but it's often disabled.
mailer.Message.ConfirmRead = "john.doe@company.com"

' Request delivery confirmation to the From address.
' Requires support from the recipient's e-mail server.
' Most new servers don't support this but old servers often do.
mailer.Message.ConfirmReceipt = "john.doe@company.com"

' Request delivery confirmation for both delivery and non-delivery.
' Requires DSN support in the e-mail servers of yours and your recipient.
' Most new servers support this. If your server supports DSN but your
' recipient's server doesn't, delivery notifications will still work
' in most cases (unless there are more than 2 SMTP servers in the chain).
mailer.DeliveryNotification.NotifyCondition = DsnNotifyCondition.Always

ESMTP DSN in detail

In practice, ESMTP DSN method is the most reliable method of getting delivery confirmation. However, this method uses SMTP envelope rather than message headers. For instance, if you save the message into a file and then restore it back, the delivery confirmation flag will be lost. To overcome this within your own system, you can save this flag into your own custom message header and examine this header when you later load the message back.Send to undisclosed recipients (use "real" recipient addresses different from "To", "CC", "BCC" addresses) topic explains this.

Unfortunately, you can't pass DSN-related information to external sending systems (like you can sometimes do with X-Sender and X-Receiver headers in order to pass real sender and recipients). However, you can often configure DSN settings in the sending e-mail system itself.

Another specifics of ESMTP DSN method is that it always sends notifications to the "real sender" of the message. Be aware of that if you set "real sender" different from "From" sender, as described in Set different From and Return-Path (use "real" sender address different from "From" address) topic.

But unlike "request read receipt" or "request delivery receipt" message header flags which do not provide any mechanism to check if the receiving side supports these flags, ESMTP DSN method has the advantage that you can check if your SMTP server supports DSN:

Smtp mailer = new Smtp();

// Use SMTP relay with authentication.
mailer.SmtpServers.Add("mail.company.com", "john.doe@company.com", "secret");

// Set From address.
mailer.Message.From.Email = "john.doe@company.com";
mailer.Message.From.DisplayName = "John Doe";

// Set the recipient.
mailer.Message.To.Add("jane.doe@domain.com", "Jane Doe");

// Set subject and body.
mailer.Message.Subject = "Hello";
mailer.Message.BodyPlainText = "Can we meet tomorrow?";

// Request delivery confirmation for both delivery and non-delivery.
// Requires DSN support in the e-mail servers of yours and your recipient.
// Most new servers support this. If your server supports DSN but your
// recipient's server doesn't, delivery notifications will still work
// in most cases (unless there are more than 2 SMTP servers in the chain).
mailer.DeliveryNotification.NotifyCondition = DsnNotifyCondition.Always;

// To determine if DSN is supported before sending the message, we
// need to explicitly connect to the server and say hello. The server
// responds with its capabilities to that. Still, even if your server
// supports DSN, this does not yet mean the recipient's server does.
mailer.Connect();
mailer.Hello();
if (mailer.GetExtension("DSN") != null)
{
    Console.WriteLine("Delivery Status Notification supported");
}
else
{
    Console.WriteLine("Delivery Status Notification not supported");
}

// Authenticate and send the message.
mailer.Login();
mailer.Send();

// Since we connected manually, we need to disconnect manually either.
mailer.Disconnect();
Dim mailer As Smtp = New Smtp()

' Use SMTP relay with authentication.
mailer.SmtpServers.Add("mail.company.com", "john.doe@company.com", "secret")

' Set From address.
mailer.Message.From.Email = "john.doe@company.com"
mailer.Message.From.DisplayName = "John Doe"

' Set the recipient.
mailer.Message.To.Add("jane.doe@domain.com", "Jane Doe")

' Set subject and body.
mailer.Message.Subject = "Hello"
mailer.Message.BodyPlainText = "Can we meet tomorrow?"

' Request delivery confirmation for both delivery and non-delivery.
' Requires DSN support in the e-mail servers of yours and your recipient.
' Most new servers support this. If your server supports DSN but your
' recipient's server doesn't, delivery notifications will still work
' in most cases (unless there are more than 2 SMTP servers in the chain).
mailer.DeliveryNotification.NotifyCondition = DsnNotifyCondition.Always

' To determine if DSN is supported before sending the message, we
' need to explicitly connect to the server and say hello. The server
' responds with its capabilities to that. Still, even if your server
' supports DSN, this does not yet mean the recipient's server does.
mailer.Connect()
mailer.Hello()
If Not mailer.GetExtension("DSN") Is Nothing Then
    Console.WriteLine("Delivery Status Notification supported")
Else
    Console.WriteLine("Delivery Status Notification not supported")
End If

' Authenticate and send the message.
mailer.Login()
mailer.Send()

' Since we connected manually, we need to disconnect manually either.
mailer.Disconnect()

Fine-tune ESMTP DSN and assign Tracking ID to e-mail

With DSN, you can not only set which condition must trigger the delivery notification to be sent (delivery, non-delivery, delay) but also specify which part of the original message to return with the notification, and even assign a unique value for each e-mail so that you can expect this value to appear in the notification messages.

Tracking ID lets you match your original e-mails and delivery notifications you receive upon delivery (or, sadly, non-delivery) of these e-mails to recipients. This is important if you implement processing bounced messages to automatically unsubscribe dead addresses, etc.

MailBee.NET BounceMail component allows you to extract Tracking ID as long as any other information from delivery notifications. This component is part of MailBee.NET assembly and it doesn't need any license key (free functionality). For details, see DeliveryStatusParser class documentation.

The sample below sets Tracking ID and informs the receiving part to send delivery notification only in case of troubles (delivery failure or delay).

We also request the receiving part to include the entire original message in response, not just the message header section (this is not required for Tracking ID to work, we do this just for demonstration purposes):

mailer.DeliveryNotification.NotifyCondition = DsnNotifyCondition.Always;
mailer.DeliveryNotification.ReturnPortion = DsnReturnPortion.FullMessage;
mailer.DeliveryNotification.TrackingID = "702345_Newsletter_Mar_2011";
mailer.DeliveryNotification.NotifyCondition = DsnNotifyCondition.Always
mailer.DeliveryNotification.ReturnPortion = DsnReturnPortion.FullMessage
mailer.DeliveryNotification.TrackingID = "702345_Newsletter_Mar_2011"

If you send bulk e-mail using mail merge feature, you may find it useful that mailer.DeliveryNotification.TrackingID (DeliveryNotificationOptions.TrackingID) can be the part of the e-mail template so that you can automatically assign the unique Tracking ID to every e-mail being generated. For instance, something like this:

mailer.DeliveryNotification.TrackingID = "##subscriber_id##_Newsletter_Mar_2011";
mailer.DeliveryNotification.TrackingID = "##subscriber_id##_Newsletter_Mar_2011"

It's assumed subscriber_id is the column name in System.Data.DataTable object which is used as the data source for mail merge (see Smtp.SendMailMerge method documentation for details).


Send feedback to AfterLogic

Copyright © 2006-2023 AfterLogic Corporation. All rights reserved.