///<summary></summary> public static long Insert(EmailMessageUid emailMessageUid) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { emailMessageUid.EmailMessageUidNum=Meth.GetLong(MethodBase.GetCurrentMethod(),emailMessageUid); return emailMessageUid.EmailMessageUidNum; } return Crud.EmailMessageUidCrud.Insert(emailMessageUid); }
///<summary></summary> public static long Insert(EmailMessageUid emailMessageUid) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { emailMessageUid.EmailMessageUidNum = Meth.GetLong(MethodBase.GetCurrentMethod(), emailMessageUid); return(emailMessageUid.EmailMessageUidNum); } return(Crud.EmailMessageUidCrud.Insert(emailMessageUid)); }
///<summary>Fetches up to fetchCount number of messages from a POP3 server. Set fetchCount=0 for all messages. Typically, fetchCount is 0 or 1. ///Example host name, pop3.live.com. Port is Normally 110 for plain POP3, 995 for SSL POP3.</summary> private static List<EmailMessage> ReceiveFromInboxThreadSafe(int receiveCount,EmailAddress emailAddressInbox) { //No need to check RemotingRole; no call to db. List<EmailMessage> retVal=new List<EmailMessage>(); //This code is modified from the example at: http://hpop.sourceforge.net/exampleFetchAllMessages.php using(OpenPop.Pop3.Pop3Client client=new OpenPop.Pop3.Pop3Client()) {//The client disconnects from the server when being disposed. client.Connect(emailAddressInbox.Pop3ServerIncoming,emailAddressInbox.ServerPortIncoming,emailAddressInbox.UseSSL,180000,180000,null);//3 minute timeout, just as for sending emails. client.Authenticate(emailAddressInbox.EmailUsername.Trim(),emailAddressInbox.EmailPassword,OpenPop.Pop3.AuthenticationMethod.UsernameAndPassword); List <string> listMsgUids=client.GetMessageUids();//Get all unique identifiers for each email in the inbox. List<EmailMessageUid> listDownloadedMsgUids=EmailMessageUids.GetForRecipientAddress(emailAddressInbox.EmailUsername.Trim()); int msgDownloadedCount=0; for(int i=0;i<listMsgUids.Count;i++) { int msgIndex=i+1;//The message indicies are 1-based. string strMsgUid=listMsgUids[i]; if(strMsgUid.Length==0) { //Message Uids are commonly used, but are optional according to the RFC822 email standard. //Uids are assgined by the sending client application, so they could be anything, but are supposed to be unique. //Additionally, most email servers are probably smart enough to create a Uid for any message where the Uid is missing. //In the worst case scenario, we create a Uid for the message based off of the message header information, which takes a little extra time, //but is better than downloading old messages again, especially if some of those messages contain large attachments. OpenPop.Mime.Header.MessageHeader messageHeader=client.GetMessageHeaders(msgIndex);//Takes 1-2 seconds to get this information from the server. The message, minus body and minus attachments. strMsgUid=messageHeader.DateSent.ToString("yyyyMMddHHmmss")+emailAddressInbox.EmailUsername.Trim()+messageHeader.From.Address+messageHeader.Subject; } else if(strMsgUid.Length>4000) {//The EmailMessageUid.MsgId field is only 4000 characters in size. strMsgUid=strMsgUid.Substring(0,4000); } //Skip any email messages matching Uids which have been previously downloaded. bool isDownloaded=false; for(int j=0;j<listDownloadedMsgUids.Count;j++) { if(listDownloadedMsgUids[j].MsgId==strMsgUid) { isDownloaded=true; break; } } if(isDownloaded) { continue; } //At this point, we know that the email is one which we have not downloaded yet. try { OpenPop.Mime.Message openPopMsg=client.GetMessage(msgIndex);//This is where the entire raw email is downloaded. string strRawEmail=openPopMsg.MessagePart.BodyEncoding.GetString(openPopMsg.RawMessage); EmailMessage emailMessage=ProcessRawEmailMessage(strRawEmail,0,emailAddressInbox);//Inserts to db. EmailMessageUid emailMessageUid=new EmailMessageUid(); emailMessageUid.RecipientAddress=emailMessage.RecipientAddress.Trim(); emailMessageUid.MsgId=strMsgUid; EmailMessageUids.Insert(emailMessageUid);//Remember Uid was downloaded, to avoid email duplication the next time the inbox is refreshed. retVal.Add(emailMessage); msgDownloadedCount++; } catch(ThreadAbortException) { //This can happen if the application is exiting. We need to leave right away so the program does not lock up. //Otherwise, this loop could continue for a while if there are a lot of messages to download. throw; } catch { //If one particular email fails to download, then skip it for now and move on to the next email. } if(receiveCount>0 && msgDownloadedCount>=receiveCount) { break; } } } //Since this function is fired automatically based on the inbox check interval, we also try to send the oldest unsent Ack. //The goal is to keep trying to send the Acks at a reasonable interval until they are successfully delivered. SendOldestUnsentAck(emailAddressInbox); return retVal; }
///<summary>Fetches up to fetchCount number of messages from a POP3 server. Set fetchCount=0 for all messages. Typically, fetchCount is 0 or 1. ///Example host name, pop3.live.com. Port is Normally 110 for plain POP3, 995 for SSL POP3.</summary> private static List<EmailMessage> ReceiveFromInboxThreadSafe(int receiveCount,EmailAddress emailAddressInbox) { //No need to check RemotingRole; no call to db. List<EmailMessage> retVal=new List<EmailMessage>(); //This code is modified from the example at: http://hpop.sourceforge.net/exampleFetchAllMessages.php using(OpenPop.Pop3.Pop3Client client=new OpenPop.Pop3.Pop3Client()) {//The client disconnects from the server when being disposed. client.Connect(emailAddressInbox.Pop3ServerIncoming,emailAddressInbox.ServerPortIncoming,emailAddressInbox.UseSSL,180000,180000,null);//3 minute timeout, just as for sending emails. client.Authenticate(emailAddressInbox.EmailUsername.Trim(),emailAddressInbox.EmailPassword,OpenPop.Pop3.AuthenticationMethod.UsernameAndPassword); List <string> listMsgUids=client.GetMessageUids();//Get all unique identifiers for each email in the inbox. List<EmailMessageUid> listDownloadedMsgUids=EmailMessageUids.GetForRecipientAddress(emailAddressInbox.EmailUsername.Trim()); List<string> listDownloadedMsgUidStrs=new List<string>(); for(int i=0;i<listDownloadedMsgUids.Count;i++) { listDownloadedMsgUidStrs.Add(listDownloadedMsgUids[i].MsgId); } int msgDownloadedCount=0; for(int i=0;i<listMsgUids.Count;i++) { int msgIndex=i+1;//The message indicies are 1-based. string strMsgUid=listMsgUids[i];//Example: 1420562540.886638.p3plgemini22-06.prod.phx.2602059520 OpenPop.Mime.Header.MessageHeader messageHeader=null; if(strMsgUid.Length==0) { //Message Uids are commonly used, but are optional according to the RFC822 email standard. //Uids are assgined by the sending client application, so they could be anything, but are supposed to be unique. //Additionally, most email servers are probably smart enough to create a Uid for any message where the Uid is missing. //In the worst case scenario, we create a Uid for the message based off of the message header information, which takes a little extra time, //but is better than downloading old messages again, especially if some of those messages contain large attachments. messageHeader=client.GetMessageHeaders(msgIndex);//Takes 1-2 seconds to get this information from the server. The message, minus body and minus attachments. strMsgUid=messageHeader.DateSent.ToString("yyyyMMddHHmmss")+emailAddressInbox.EmailUsername.Trim()+messageHeader.From.Address+messageHeader.Subject; } if(strMsgUid.Length>4000) {//The EmailMessageUid.MsgId field is only 4000 characters in size. strMsgUid=strMsgUid.Substring(0,4000); } if(listDownloadedMsgUidStrs.Contains(strMsgUid)) { continue;//Skip emails which have already been downloaded. } //messageHeader will only be defined if we created our own unique ID manually above. MessageId is optional, just as the message UIDs are. if(messageHeader!=null && messageHeader.MessageId!="") { //The MessageId is usually generated by the email server. //The message does not have a UID, and the ID that we made up has not been downloaded before. As a last resort we check the MessageId in //the message header. MessageId is different than the UID. We should have used the MessageId as the second option in the past, but now //we are stuck using it as a third option, because using MessageId as a second option would cause old emails to download again. strMsgUid=messageHeader.MessageId;//Example: [email protected] if(strMsgUid.Length>4000) {//The EmailMessageUid.MsgId field is only 4000 characters in size. strMsgUid=strMsgUid.Substring(0,4000); } if(listDownloadedMsgUidStrs.Contains(strMsgUid)) { continue;//Skip emails which have already been downloaded. } } //At this point, we know that the email is one which we have not downloaded yet. try { OpenPop.Mime.Message openPopMsg=client.GetMessage(msgIndex);//This is where the entire raw email is downloaded. bool isEmailFromInbox=true; if(openPopMsg.Headers.From.ToString().ToLower().Contains(emailAddressInbox.EmailUsername.Trim().ToLower())) {//The email Recipient and email From addresses are the same. //The email Recipient and email To or CC or BCC addresses are the same. We have verified that a user can send an email to themself using only CC or BCC. if(String.Join(",",openPopMsg.Headers.To).ToLower().Contains(emailAddressInbox.EmailUsername.Trim().ToLower()) || String.Join(",",openPopMsg.Headers.Cc).ToLower().Contains(emailAddressInbox.EmailUsername.Trim().ToLower()) || String.Join(",",openPopMsg.Headers.Bcc).ToLower().Contains(emailAddressInbox.EmailUsername.Trim().ToLower())) { //Download this message because it was clearly sent from the user to theirself. } else { //Gmail will report sent email as if it is part of the Inbox. These emails will have the From address as the Recipient address, but the To address will be a different address. isEmailFromInbox=false; } } if(isEmailFromInbox) { string strRawEmail=openPopMsg.MessagePart.BodyEncoding.GetString(openPopMsg.RawMessage); EmailMessage emailMessage=ProcessRawEmailMessageIn(strRawEmail,0,emailAddressInbox,true);//Inserts to db. retVal.Add(emailMessage); msgDownloadedCount++; } EmailMessageUid emailMessageUid=new EmailMessageUid(); emailMessageUid.RecipientAddress=emailAddressInbox.EmailUsername.Trim(); emailMessageUid.MsgId=strMsgUid; EmailMessageUids.Insert(emailMessageUid);//Remember Uid was downloaded, to avoid email duplication the next time the inbox is refreshed. } catch(ThreadAbortException) { //This can happen if the application is exiting. We need to leave right away so the program does not lock up. //Otherwise, this loop could continue for a while if there are a lot of messages to download. throw; } catch { //If one particular email fails to download, then skip it for now and move on to the next email. } if(receiveCount>0 && msgDownloadedCount>=receiveCount) { break; } } } //Since this function is fired automatically based on the inbox check interval, we also try to send the oldest unsent Ack. //The goal is to keep trying to send the Acks at a reasonable interval until they are successfully delivered. SendOldestUnsentAck(emailAddressInbox); return retVal; }