private static MessageClass GetInnerMessage(IBodyPart part) { var innerMessage = new MessageClass(); innerMessage.OpenObject(part.GetDecodedContentStream(), "_Stream"); return(innerMessage); }
void IEmailStatusService.AddNotification(Stream httpStream) { const string method = "AddNotification"; try { SetHttpStatusCode(HttpStatusCode.NoContent); // Parse top-level message. var memoryStream = new MemoryStream(); StreamUtil.CopyStream(httpStream, memoryStream); // CDO will need random access to the stream var rootMessage = new MessageClass(); rootMessage.OpenObject(new ReadOnlyIStream(memoryStream), "IStream"); if (rootMessage.ContentMediaType == "test/octet-stream") { SetHttpStatusCode(HttpStatusCode.Accepted); // just testing return; } var deliveryStatusPart = GetDeliveryStatusPart(rootMessage); if (deliveryStatusPart == null) { return; } // Analyze message/delivery-status. var mtaMessage = GetInnerMessage(deliveryStatusPart); var recipientMessage = GetInnerMessage(mtaMessage); var recipientField = (string)recipientMessage.Fields["urn:schemas:mailheader:final-recipient"].Value; if (recipientField == null) { #region Log Log(Event.Warning, method, "Final-Recipient field is missing. Notofication ignored.", null, rootMessage); #endregion return; } var emailAddress = GetEmailAddress(recipientField); if (string.IsNullOrEmpty(emailAddress)) { #region Log Log(Event.Warning, method, "Final-Recipient is invalid. Notification ignored.", null, rootMessage, Event.Arg("Final-Recipient", recipientField)); #endregion return; } var statusField = (string)recipientMessage.Fields["urn:schemas:mailheader:status"].Value; if (statusField == null) { #region Log Log(Event.Warning, method, "Status field is missing. Notification ignored.", null, rootMessage); #endregion return; } if (GetStatusClass(statusField) != "5") { #region Log Log(Event.Trace, method, "Not a permanent error. Notification ignored.", null, rootMessage, Event.Arg("Status", statusField)); #endregion return; } var diagnosticField = (string)recipientMessage.Fields["urn:schemas:mailheader:diagnostic-code"].Value; if (diagnosticField == null) { #region Log Log(Event.Information, method, "Diagnostic-Code field is missing. Notification will be processed.", null, rootMessage); #endregion } else { var replyCode = GetReplyCode(diagnosticField); if (replyCode == null) { #region Log Log(Event.Warning, method, "Unable to interpret the Diagnostic-Code field. Notification will be processed.", null, rootMessage, Event.Arg("Diagnostic-Code", diagnosticField)); #endregion } else if (TransientReplyCodes.Contains(replyCode.Value)) { // Yahoo uses transient codes for permanent errors if (!emailAddress.Contains(Yahoo)) { #region Log Log(Event.Information, method, "Reply code indicates transient condition. Notification ignored.", null, rootMessage, Event.Arg("Diagnostic-Code", diagnosticField)); #endregion return; } } } // Update member record. #region Log Log(Event.Information, method, "Setting EmailBounced flag for the user.", null, rootMessage, Event.Arg("emailAddress", emailAddress), Event.Arg("diagnosticField", diagnosticField)); #endregion _emailVerificationsCommand.UnverifyEmailAddress(emailAddress, diagnosticField); } catch (Exception e) { Logger.Raise(Event.Error, method, "Unexpected exception.", e, new StandardErrorHandler()); throw; } }