private static bool IsDuplicateInFolder(Outlook.Folder folder, Outlook.MailItem mail) { Outlook.Items folderItems = null; Outlook.Items resultItems = null; object item = null; try { var dateFrom = mail.SentOn.AddMinutes(-SEARCH_WINDOW_MINUTES).ToString(SEARCH_DATE_FORMAT); var dateTo = mail.SentOn.AddMinutes(SEARCH_WINDOW_MINUTES).ToString(SEARCH_DATE_FORMAT); var mailId = GetMessageId(mail); var restrictCriteria = $"[SentOn] >= '{dateFrom}' And [SentOn] <= '{dateTo}'"; folderItems = folder.Items; resultItems = folderItems.Restrict(restrictCriteria); item = resultItems.GetFirst(); while (item != null) { if (item is Outlook.MailItem mailItem) { if (GetMessageId(mailItem) == mailId) { return(true); } if (mailItem.ReceivedTime == mail.ReceivedTime && mailItem.Subject == mail.Subject) { return(true); } } Marshal.ReleaseComObject(item); item = resultItems.GetNext(); } return(false); } catch (Exception) { return(false); } finally { if (item != null) { Marshal.ReleaseComObject(item); } if (folderItems != null) { Marshal.ReleaseComObject(folderItems); } if (resultItems != null) { Marshal.ReleaseComObject(resultItems); } } }
public void DoNag(Object item) { Outlook.MailItem msg = (Outlook.MailItem)item; // Blah. Creating a new mail from scratch is a problem, because if the user then replies to the AutoLottie, it doesn't // hook up. Creating a new mail using 'reply' is impossible because the one in the Lottie folder is still only a draft. // Going to try looking up the e-mail in regular sent-mail... If this works, then longer term, the approach should be // changed so that the real e-mail gets stored in the Lottie folder, introducing the requirement that mail goes to sent-mail. // Also, we can trigger the Lottie actions with a watch on sent-mail, which has a lot of other benefits. Outlook.MAPIFolder sentmail = outlookNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail); // TODO FALLS OVER WITH PUNCTUATION (like ') in the SUBJECT LINE String sFilter = "[Subject] = '" + msg.Subject + "'"; Outlook.Items sublist = sentmail.Items.Restrict(sFilter); DateTime latestSentTime = new DateTime(0); Outlook.MailItem bestFitMail = null; Outlook.MailItem messageIt = (Outlook.MailItem)sublist.GetFirst(); while (messageIt != null) { if ((((Outlook.MailItem)messageIt).ConversationID == msg.ConversationID) && (((Outlook.MailItem)messageIt).SentOn.CompareTo(latestSentTime) == 1)) { bestFitMail = (Outlook.MailItem)messageIt; latestSentTime = ((Outlook.MailItem)messageIt).SentOn; } messageIt = (Outlook.MailItem)sublist.GetNext(); } if (bestFitMail != null) { Outlook.MailItem eMail = bestFitMail.ReplyAll(); //(Outlook.MailItem)this.Application.CreateItem(Outlook.OlItemType.olMailItem); // if you change the subject, Conversation ID gets changed :-( // eMail.Subject = "[AutoLottie] " + bestFitMail.Subject; // eMail.To = msg.To; eMail.CC = bestFitMail.SenderEmailAddress; eMail.Body = "As far as my Outlook client can tell, you have not yet responded " + "to the message below. Could you do so now, please?\n\n " + "Thanks! \n\n" + "************************************************************\n\n\n" + bestFitMail.Body; eMail.Importance = Outlook.OlImportance.olImportanceNormal; Outlook.UserProperty lottieStartThreadProperty = eMail.UserProperties.Add(AutoLottieAddIn.LottieNoCancelProperty, Outlook.OlUserPropertyType.olText); lottieStartThreadProperty.Value = "True"; ((Outlook._MailItem)eMail).Send(); } // Not sure what to do here: // 1) Set the AutoLottie property so that they get nagged again in the same length of time? // 2) Remove the AutoLottie? // 3) Something random - they get nagged in double the time. I think I'll do that. :-) TimeSpan expiryTimeFromSent; TimeSpan.TryParse(msg.UserProperties[LottieDurationProperty].Value.ToString(), out expiryTimeFromSent); TimeSpan newExpiryTime = new TimeSpan(2 * expiryTimeFromSent.Days, 2 * expiryTimeFromSent.Hours, 2 * expiryTimeFromSent.Minutes, 0); UpdateTimerForMessage(msg, newExpiryTime); }
/// <summary> /// Remove synchronize keys from Outlook contact. In same delete all cache data /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnOutlokSync_Click(object sender, EventArgs e) { LoggerProvider.Instance.Logger.Info("User request for clear synchronize keys in Outlook. I remove all cache data for Google and Outlook."); Utils.RemoveCacheFile(false); Utils.RemoveCacheFile(true); pBar.Value = 1; pBar.Update(); pBar.Refresh(); OutlookProvider op = OutlookProvider.Instance; Outlook.Items it = op.OutlookItems(); int _ouMaxContacts = op.CountContact(); object works = null; Outlook.ContactItem oci = null; int counter = 0; for (int i = 0; i < _ouMaxContacts; i++) { pBar.Value = counter; pBar.PerformStep(); pBar.Refresh(); if (counter > pBar.Maximum) { counter = 0; } if (i == 0) { works = it.GetFirst(); } else { works = it.GetNext(); } if (works is Outlook.DistListItem) { continue; } oci = works as Outlook.ContactItem; if (works == null) { continue; } if (!string.IsNullOrEmpty(oci.User3)) { oci.User3 = string.Empty; oci.Save(); } } }
/// <summary> /// Gets the next mail item /// </summary> /// <returns>next mail item</returns> public MailItem GetNext() { return(new MailItem(_mailItems.GetNext())); }
/// <summary> /// Step first - read all outlook contacts /// </summary> private void Step1ReadOutlook() { bool IsNeedReadAllData = true; bool IsNeedReadNewData = false; List <string> toread = new List <string>(); /// list EntryID for reading List <string> todelete = new List <string>(); /// list EntryID for delete if (SettingsProvider.Instance.IsUseOutlookCache) { LoggerProvider.Instance.Logger.Debug("Read data from cache for Outlook"); ouCacheTime = Utils.LoadCacheDate(true); ouContacts = Utils.ReadOutlookFromCache(ref ouCacheTime); if ((ouCacheTime > DateTime.MinValue) && (ouCacheTime < DateTime.Now) && (ouContacts.Count > 0)) // Data read from cache is good { //_lastStatistic.ouReadContacts = ouContacts.Count; Dictionary <string, DateTime> ouall = OutlookProvider.Instance.GetTableFilter(ouCacheTime); DateTime ouDate; foreach (string s in ouContacts.Keys) { todelete.Add(s); } foreach (string EntID in ouall.Keys) { ouDate = ouall[EntID]; if (ouContacts.ContainsKey(EntID)) /// is EntID found in current cached data { todelete.Remove(EntID); if (((OneContact)ouContacts[EntID])._ModifyDateTime < ouDate) //date from curent select is { ouContacts.Remove(EntID); toread.Add(EntID); } } else { toread.Add(EntID); } } /// in toread now only new EntryID /// in todelete now only contact deleted in outlook, this need clear from cache, because in last two steps it delete from google to foreach (string s in todelete) { ouContacts.Remove(s); } IsNeedReadNewData = toread.Count > 0; } else { LoggerProvider.Instance.Logger.Debug("Data from Outlook cache isn't valid"); } } if (IsNeedReadNewData) // need read new contact data to cache { LoggerProvider.Instance.Logger.Debug("Read only new data from Outlook"); Outlook.Items it = op.OutlookItems(); //_ouMaxContacts = op.CountContact(); syncinfo.OutlookContacts = toread.Count; syncinfo.WorkOnMax = toread.Count; Outlook.ContactItem oci = null; OneContact oc = null; object works = null; int i = 0; int read = 0; syncinfo.WorkOnNextStep(); for (; i < toread.Count; i++) { syncinfo.WorkOn = i + 1; syncinfo.WorkOnNextStep(); works = OutlookProvider.Instance.FindItemfromID(toread[i]); //if (i == 0) // works = it.GetFirst(); //else // works = it.GetNext(); if (works is Outlook.DistListItem) { continue; } oci = works as Outlook.ContactItem; if (works == null) { continue; } if (toread.Contains(oci.EntryID)) { oc = new OneContact(oci); if (SettingsProvider.Instance.IsFirstTime) { oc.ClearReference(); } ouContacts.Add(oci.EntryID, oc); } read++; } _lastStatistic.ouReadContacts += read; syncinfo.OutlookContacts = ouContacts.Count; IsNeedReadAllData = false; } if (IsNeedReadAllData) { /// because need read all data. Before this need remove all cached data ouContacts.Clear(); /// start read all data ouCacheTime = DateTime.MinValue; LoggerProvider.Instance.Logger.Debug("Read all data from Outlook"); Outlook.Items it = op.OutlookItems(); _ouMaxContacts = op.CountContact(); syncinfo.OutlookContacts = _ouMaxContacts; syncinfo.WorkOnMax = _ouMaxContacts; Outlook.ContactItem oci = null; OneContact oc = null; object works = null; int i = 0; int read = 0; syncinfo.WorkOnNextStep(); for (; i < _ouMaxContacts; i++) { syncinfo.WorkOn = i + 1; syncinfo.WorkOnNextStep(); if (i == 0) { works = it.GetFirst(); } else { works = it.GetNext(); } if (works is Outlook.DistListItem) { continue; } oci = works as Outlook.ContactItem; if (works == null) { continue; } oc = new OneContact(oci); if (SettingsProvider.Instance.IsFirstTime) { oc.ClearReference(); } ouContacts.Add(oci.EntryID, oc); read++; } _lastStatistic.ouReadContacts += read; syncinfo.OutlookContacts = ouContacts.Count; } }
private void DeleteTestAppointments() { Outlook.MAPIFolder mapiFolder = null; Outlook.Items items = null; if (string.IsNullOrEmpty(AppointmentsSynchronizer.SyncAppointmentsFolder)) { mapiFolder = Synchronizer.OutlookNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar); } else { mapiFolder = Synchronizer.OutlookNameSpace.GetFolderFromID(AppointmentsSynchronizer.SyncAppointmentsFolder); } Assert.NotNull(mapiFolder); try { items = mapiFolder.Items; Assert.NotNull(items); object item = items.GetFirst(); while (item != null) { if (item is Outlook.AppointmentItem) { var ola = item as Outlook.AppointmentItem; if (ola.Subject == name) { var s = ola.Subject + " - " + ola.Start; ola.Delete(); Logger.Log("Deleted Outlook test appointment: " + s, EventType.Information); } Marshal.ReleaseComObject(ola); } Marshal.ReleaseComObject(item); item = items.GetNext(); } } finally { if (mapiFolder != null) { Marshal.ReleaseComObject(mapiFolder); } if (items != null) { Marshal.ReleaseComObject(items); } } var query = sync.appointmentsSynchronizer.EventRequest.List(AppointmentsSynchronizer.SyncAppointmentsGoogleFolder); Events feed; string pageToken = null; do { query.PageToken = pageToken; feed = query.Execute(); foreach (Event e in feed.Items) { if (!e.Status.Equals("cancelled") && e.Summary != null && e.Summary == name) { sync.appointmentsSynchronizer.EventRequest.Delete(AppointmentsSynchronizer.SyncAppointmentsGoogleFolder, e.Id).Execute(); Logger.Log("Deleted Google test appointment: " + e.Summary + " - " + AppointmentsSynchronizer.GetTime(e), EventType.Information); } } pageToken = feed.NextPageToken; }while (pageToken != null); sync.appointmentsSynchronizer.LoadAppointments(); Assert.AreEqual(0, sync.appointmentsSynchronizer.GoogleAppointments.Count); Assert.AreEqual(0, sync.appointmentsSynchronizer.OutlookAppointments.Count); }