2

I am doing some automation on outlook mail box, previously it was lotus notes.So i am looking for equivalent properties in outlook. The lotus notes mail items has a item named FAILUREREASON which has the details about why the email is failed such as delivery failure reason etc. This item will be available when the mail is a delivery failure email. So when i loop through mails in inbox i can recognize which mail is a delivery failure email in inbox and which is actual required mail to be processed. But in outlook MailItem object i didn't find any option to get it. I searched for any solutuion but not able to find any. We can search subject for words such as 'failure' but it's not good approach. Can anyone know the property that i need to look or any other approach for the same.

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
Navaneet
  • 1,367
  • 1
  • 19
  • 44

2 Answers2

3

Standard bounce or undeliverable emails are received in Outlook as special items using the "REPORT.IPM.Note.NDR" message class and are available as a ReportItem object in the Outlook Object Model. You can also read the mail header information via the PR_TRANSPORT_MESSAGE_HEADERS_W MAPI property on any kind of email.

One way of retrieving the value is by using PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001F")

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
Eric Legault
  • 5,706
  • 2
  • 22
  • 38
  • May i know the url GetProperty method that need to be used? Also where i can find the list of schema urls. – Navaneet Jul 03 '17 at 14:49
  • 1
    I've updated my answer. The best way to find the DASL name for a MAPI property is to use OutlookSpy. You can also construct the DASL name if you know the namespace and property type. See https://msdn.microsoft.com/en-us/library/office/cc815492.aspx and https://msdn.microsoft.com/en-us/library/office/cc979184.aspx – Eric Legault Jul 03 '17 at 21:00
  • I fetched the property and found that there exists a node "X-Failed-Recipients" . So do i need to find for this string and if exists do i need to consider it as a delivery failed mail? Is it a good approach ? Also how can i get failure reason? (Example of failure reason: Your message wasn't delivered to ******@gmail.com because the address couldn't be found. Check for typos or unnecessary spaces and try again. ) – Navaneet Jul 04 '17 at 12:45
  • 1
    Yes, you'll have to parse the strings in PR_TRANSPORT_MESSAGE_HEADERS manually. AFAIK all delivery error messages should be stored in there, as well as in the email body – Eric Legault Jul 04 '17 at 16:34
  • Keep in mind that if the NDR was generated by your Exchange Server, `PR_TRANSPORT_MESSAGE_HEADERS ` will **not** contain any error info, it is only stored in the recipient table. – Dmitry Streblechenko Apr 20 '22 at 19:12
0

ReportItem object in the Outlook Object Model (not related to the MailItem object) exposes NDR information through the ReportItem.Body property. On the Extended MAPI level (C++ or Delphi only) the properties are stored in the recipient table - you can see the data in OutlookSpy (I am its author) - click IMessage button, go to the GetRecipientTable tab:

enter image description here

For the MailItem objects, you can access that information using Recipient.PropetyAccessor.GetProperty method, but ReportItem object does not expose the Recipients collection (unlike the MailItem object). In theory, you can change the MessageClass property to "IPM.Note", remember the value of the EntryID property, save the NDR, release the original, reopen the item as a regular MailItem object by calling Namespace.GetItemFromID, and then read the data from the recipient table. But that means modifying the original NDR (its modification time will change etc.).

If using Redemption is an option (I am its author), its RDOReportItem object (derived from the RDOMail object) exposes the Recipients collection. You can reopen Outlook's NDR in Redemption by creating an instance of the RDOSession object and calling RDOSession.GetRDOObjectFromOutlookObject method. The recipient properties will be accessible using RDORecipient.Fields[].

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78