///<summary>Used for creating encrypted Message Disposition Notification (MDN) ack messages for Direct. ///An ack must be sent when a message is received/processed, and other acks are supposed be sent when other events occur (but are not required). ///For example, when the user reads a decrypted message we must send an ack with notification type of Displayed (not required).</summary> private static string SendAckDirect(Health.Direct.Agent.IncomingMessage inMsg,EmailAddress emailAddressFrom,long patNum) { //No need to check RemotingRole; no call to db. //The CreateAcks() function handles the case where the incoming message is an MDN, in which case we do not reply with anything. //The CreateAcks() function also takes care of figuring out where to send the MDN, because the rules are complicated. //According to http://wiki.directproject.org/Applicability+Statement+for+Secure+Health+Transport+Working+Version#x3.0%20Message%20Disposition%20Notification, //The MDN must be sent to the first available of: Disposition-Notification-To header, MAIL FROM SMTP command, Sender header, From header. Health.Direct.Common.Mail.Notifications.MDNStandard.NotificationType notificationType=Health.Direct.Common.Mail.Notifications.MDNStandard.NotificationType.Failed; notificationType=Health.Direct.Common.Mail.Notifications.MDNStandard.NotificationType.Processed; IEnumerable<Health.Direct.Common.Mail.Notifications.NotificationMessage> notificationMsgs=inMsg.CreateAcks("OpenDental "+Assembly.GetExecutingAssembly().GetName().Version,"",notificationType); if(notificationMsgs==null) { return ""; } string strErrorsAll=""; foreach(Health.Direct.Common.Mail.Notifications.NotificationMessage notificationMsg in notificationMsgs) { string strErrors=""; try { //According to RFC3798, section 3 - Format of a Message Disposition Notification http://tools.ietf.org/html/rfc3798#page-3 //A message disposition notification is a MIME message with a top-level //content-type of multipart/report (defined in [RFC-REPORT]). When //multipart/report content is used to transmit an MDN: //(a) The report-type parameter of the multipart/report content is "disposition-notification". //(b) The first component of the multipart/report contains a human-readable explanation of the MDN, as described in [RFC-REPORT]. //(c) The second component of the multipart/report is of content-type message/disposition-notification, described in section 3.1 of this document. //(d) If the original message or a portion of the message is to be returned to the sender, it appears as the third component of the multipart/report. // The decision of whether or not to return the message or part of the message is up to the MUA generating the MDN. However, in the case of // encrypted messages requesting MDNs, encrypted message text MUST be returned, if it is returned at all, only in its original encrypted form. Health.Direct.Agent.OutgoingMessage outMsgDirect=new Health.Direct.Agent.OutgoingMessage(notificationMsg); if(notificationMsg.ToValue.Trim().ToLower()==notificationMsg.FromValue.Trim().ToLower()) { continue;//Do not send an ack to self. } EmailMessage emailMessage=ConvertMessageToEmailMessage(outMsgDirect.Message,false); emailMessage.PatNum=patNum; //First save the ack message to the database in case their is a failure sending the email. This way we can remember to try and send it again later, based on SentOrRecieved. emailMessage.SentOrReceived=EmailSentOrReceived.AckDirectNotSent; MemoryStream ms=new MemoryStream(); notificationMsg.Save(ms); byte[] arrayMdnMessageBytes=ms.ToArray(); emailMessage.BodyText=Encoding.UTF8.GetString(arrayMdnMessageBytes); ms.Dispose(); Insert(emailMessage); } catch(Exception ex) { strErrors=ex.Message; } if(strErrorsAll!="") { strErrorsAll+="\r\n"; } strErrorsAll+=strErrors; } try { SendOldestUnsentAck(emailAddressFrom);//Send the ack(s) we created above. } catch { //Not critical to send the acks here, because they will be sent later if they failed now. } return strErrorsAll; }