+1 vote

Hi,

I'm rewriting some code to use Limilabs mail.dll instead of another mail component, and part of it involves sending a DSN message. For reference, this is the old code:

MailMessage envelope = new MailMessage();
envelope.From = new Address("Mail Delivery Subsystem", "MAILER-DAEMON@" + toAddress.Domain);
envelope.To.Add(message.From);
envelope.Subject = "Delivery notification (failure)";

envelope.Body = 
"The original message was received at " + DateTime.Now.ToString("r") +
"\r\n----- The following addresses had permanent fatal errors -----" +
"\r\n<" + toAddress.EMail + ">\r\n" +
"\r\n----- Transcript of session follows -----" +
"\r\n... while talking to " + toAddress.Domain + 
"\r\n>>> RCPT To:<" + toAddress.EMail + ">" +
"\r\n<<< 550 5.1.1 <" + toAddress.EMail + ">... User unknown" +
"\r\n";

// Generate a DSN message that contains the envelope 
// message and the original messages
DSNMessage dsnMessage = new DSNMessage(envelope, message);
dsnMessage.ArrivalDate = DateTime.Now;
dsnMessage.OriginalEnvelopeID = message.MessageID;
dsnMessage.ReportingMTA = toAddress.Domain;

// Specify the recipients that the DSN will be sent to
DSNRecipient recipient = new DSNRecipient();
recipient.Action = DSNAction.Failed;
recipient.OriginalRecipient = message.From;
recipient.FinalRecipient = message.From;
recipient.RemoteMTA = message.From.Domain;

// Add recipients to DSN message
DSNRecipient[] recipients = new DSNRecipient[] { recipient };
dsnMessage.Recipients = recipients;

// Get the final DSN message
MailMessage bounceMail = dsnMessage.CreateDSNMessage();

How can I do something similar with Limilabs mail.dll?

Regards,
Patrick

by (250 points)

1 Answer

0 votes

To create a DSN (Delivery Status Notification) use the following code:

IMail original = ...

// Get some properties from the original message
string sender = original.Sender.Address;
string failedRecipient = original.To.First()
    .GetMailboxes().First().Address;
string originalMessageId = original.MessageID;

// Create a report
MimeFactory f = new MimeFactory();
MimeReport report = f.CreateMimeReport();
report.ReportType = MimeReportType.DeliveryStatus;

string reportBody = $@"Your message was not delivered:

{failedRecipient}... No such user

";

report.Parts.Add(f.CreateMimeText(reportBody));

MimeDeliveryStatusNotification dsn = 
    f.CreateDeliveryStatus();

dsn.Root.ReportingMTA = "dns; server.example.com";
dsn.Root.ArrivalDate = DateTime.UtcNow;

var recipient = 
    new RecipientDeliveryStatusNotification();
recipient.FinalRecipient = failedRecipient;
recipient.Action = DSNAction.Failed;
recipient.Status = "5.3.0";
recipient.DiagnosticCode = 
    $"SMTP; 550 {failedRecipient}... No such user";

dsn.Recipients.Add(recipient);

report.Parts.Add(dsn);
report.Parts.Add(f.CreateMimeRfc822Headers(original));

MailBuilder builder = new MailBuilder();
builder.From.Add(new MailBox("server@example.com"));
builder.To.Add(new MailBox(sender));
builder.AddAlternative(report);
builder.Subject = 
    "Delivery Status Notification (Failure)";
builder.InReplyTo = originalMessageId;
builder.References.Add(originalMessageId);

IMail mail = builder.Create();
by (301k points)

This wasn't working due to an outdated version of mail.dll. So we got a new license but I'm still getting an error with the latest version of mail.dll (3.0.23025.1850):

[CS1729] 'RecipientDeliveryStatusNotification' does not contain a constructor that takes 0 arguments

Apparently this is because this constructor is internal. How do I get this to work?

Yes, this looks like a bug.

As an immediate workaround, you can use Activator class:

RecipientDeliveryStatusNotification recipient =
    Activator.CreateInstance(
        typeof(RecipientDeliveryStatusNotification), 
        true) as RecipientDeliveryStatusNotification;

We'll release the fix as soon as possible.

New version (3.0.23156.1704 2023-06-05) has been released:
https://www.limilabs.com/mail/download

NuGet package will be available as soon as it is accepted.

...