InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Correlating a Non-Delivery-Notification to its original message with the Exchange Managed API

If you are automatically process emails in an Exchange Mailbox, you might also need to process non delivery reports (NDRs) and correlate these NDRs to their original values. Luckily, Exchange does most of the heavy lifting, as long as the NDR conforms to the RFC 3461, which defines the proper structure for an NDR that can be automatically parsed. Not all MTAs (Mail transfer agents) do generate these types of NDRs.

First of all, you need to check whether the mail item in question is actually a non delivery report. This is done by examining the Item Class of the mail. An NDR has an item class of REPORT.IPM.Note.NDR. Next, you need to retrieve the property PidTagParentKey from the item. This property contains the PidTagSearchKey of the original mail.

Unfortunately, the PidTagSearchKey cannot be used to bind to the item directly. Instead, you have to issue a FindItem operation to get it. Normally, sent items are all stored in the SentItems folder, so this narrows the search down.

Here is a sample method which describes the process:

 

   1:  class Program
   2:  {
   3:      private static readonly ExtendedPropertyDefinition PidTagParentKeyProperty = new ExtendedPropertyDefinition(0x25, MapiPropertyType.Binary);
   4:      private static readonly ExtendedPropertyDefinition PidTagSeachKeyProperty = new ExtendedPropertyDefinition(0x300B, MapiPropertyType.Binary);
   5:   
   6:   
   7:      private static bool TryGetOriginalMail(string ndrId, ExchangeService service, out Item originalItem)
   8:      {
   9:          byte[] value;
  10:   
  11:          var item = service.BindToItems(new[] {new ItemId(ndrId)},
  12:                                          new PropertySet(BasePropertySet.IdOnly,
  13:                                                          PidTagParentKeyProperty, ItemSchema.Subject)).First().Item;
  14:   
  15:          if (!item.TryGetProperty(PidTagParentKeyProperty, out value))
  16:          {
  17:              Console.Out.WriteLine("Correlationtoken not found.");
  18:              originalItem = null;
  19:              return false;
  20:          }
  21:   
  22:          originalItem = service
  23:              .FindItems(WellKnownFolderName.SentItems,
  24:                          new SearchFilter.IsEqualTo(PidTagSeachKeyProperty, Convert.ToBase64String(value)),
  25:                          new ItemView(1) {PropertySet = PropertySet.FirstClassProperties})
  26:              .FirstOrDefault();
  27:   
  28:          return true;
  29:      }
  30:  }

Posted by Henning Krause on Monday, June 27, 2011 8:12 PM, last modified on Monday, June 27, 2011 8:12 PM
Permalink | Post RSSRSS comment feed

Comments (4) -

On 11/9/2011 12:39:12 PM Vijay wrote:

Vijay

I checked the MAPI API reference. msdn.microsoft.com/en-us/library/cc765775.aspx
PidTagSearchKey is defined. But PidTagParentKey is not defined.

I tried this sample with Exchange 2010 and I am not able to retrieve the original sent item.

On 11/9/2011 12:43:01 PM hkrause wrote:

hkrause

The property is defined in msdn.microsoft.com/.../ee160861(v=exchg.80).aspx.

On 1/28/2012 1:23:14 AM Ganga wrote:

Ganga

Henning, is there an easy way to get the Diagnostic Code and/or the body of the NDR using EWS Managed API? Email.Bind to the NDR returns the Body property as empty. I can see the complete NDR message in the MimeContent property as a byte array, but wanted to check if there is an easier way than to parse the MimeContent?

Thanks in advance,
Ganga

On 10/11/2013 1:05:07 PM Danny wrote:

Danny

Can I use PidTagSeachKeyProperty for checking if an item i am copying from one mailbox to another is alreade copied before?

 +Pingbacks and trackbacks (2)