While @Chase is technically correct, it's possible to get delivery status notifications if the SMTP servers along the route support this extension.
I'm not aware of a way to do this with System.Net.Mail, but with MailKit, you can actually request delivery status notifications for your recipients.
In MailKit, the first thing you'll need to do (until I figure out a nicer API for this) is to setup your own SmtpClient class like this:
class MySmtpClient : SmtpClient
{
public MySmtpClient ()
{
}
/// <summary>
/// Get the envelope identifier to be used with delivery status notifications.
/// </summary>
/// <remarks>
/// <para>The envelope identifier, if non-empty, is useful in determining which message
/// a delivery status notification was issued for.</para>
/// <para>The envelope identifier should be unique and may be up to 100 characters in
/// length, but must consist only of printable ASCII characters and no white space.</para>
/// <para>For more information, see rfc3461, section 4.4.</para>
/// </remarks>
/// <returns>The envelope identifier.</returns>
/// <param name="message">The message.</param>
protected override string GetEnvelopeId (MimeMessage message)
{
// The Message-Id header is probably the easiest way to go...
return message.MessageId;
}
/// <summary>
/// Get the types of delivery status notification desired for the specified recipient mailbox.
/// </summary>
/// <remarks>
/// Gets the types of delivery status notification desired for the specified recipient mailbox.
/// </remarks>
/// <returns>The desired delivery status notification type.</returns>
/// <param name="message">The message being sent.</param>
/// <param name="mailbox">The mailbox.</param>
protected override DeliveryStatusNotification? GetDeliveryStatusNotifications (MimeMessage message, MailboxAddress mailbox)
{
// Since you want to know whether the message got delivered or not,
// you'll probably want to get notifications for Success and Failure.
return DeliveryStatusNotification.Success | DeliveryStatusNotification.Failure;
}
}
Then, once you have that, you'd use it like this:
using (var client = new MySmtpClient ()) {
client.Connect ("smtp.gmail.com", 465, true);
client.Authenticate ("username", "password");
client.Send (message);
client.Disconnect (true);
}
What will now happen is that whenever there is a success or failure notification, you'll get an email delivered to your account's Inbox (POP3 or IMAP depending on what you use) that will contain a multipart/report
MIME part which will typically contain 3 other MIME parts: a human readable explanation, a message/delivery-status
MIME part which will have a body that contains some key/value pairs and a third part which contains the original message (or sometimes just the headers).
Currently, MailKit does not have a special MIME class for dealing with message/delivery-status
MIME parts, but you can work around this by parsing the content like this:
var mds = message.BodyParts.OfType<MimePart>.Where (x => x.ContentType.Matches ("message", "delivery-status")).FirstOrDefault ();
if (mds != null) {
using (var memory = new MemoryStream ()) {
mds.ContentObject.DecodeTo (memory);
memory.Position = 0;
// the content of a message/delivery-status MIME part is a
// collection of header groups. The first group of headers
// will contain the per-message status headers while each
// group after that will contain status headers for a
// particular recipient.
var groups = new List<HeaderList> ();
while (memory.Position < memory.Length)
groups.Add (HeaderList.Load (memory));
// TODO: take a look at the specific "headers" to get the info we
// care about. For more info on what these header field names and
// values are, take a look at https://tools.ietf.org/html/rfc3464
}
}
Update: I've added a MessageDeliveryStatus class to MimeKit that handles parsing the content of message/delivery-status
MIME parts for you, but it may take up to 2 weeks before I make another release since I just made a release 2 days ago. Expect to find this new class in MimeKit 1.2.8 when I do release it.