Я работаю над надстройкой Outlook, которая будет отслеживать текущий календарь пользователя и отправлять этому пользователю электронное письмо при получении определенного типа встречи или встречи. У нас есть стороннее приложение/служба, которая отправляет новые запросы на собрания пользователю в Outlook, но уведомление не предоставляется пользователю, зарегистрированному в Outlook. Моя надстройка - это обходной путь, пока мы не заменим стороннее приложение, поэтому пользователи могут быть предупреждены при отправке этого запроса на собрание.
Я использую событие ItemAdd, чтобы отслеживать, когда добавляется встреча/встреча (т.е. отправляется из стороннего приложения). Я вижу, что событие срабатывает дважды (даже если я объявил обработчик только один раз): один раз, когда назначение получено от другого пользователя, и один раз, когда назначение принимается или предварительно принимается текущим пользователем.
Мне нужно, чтобы он срабатывал только тогда, когда назначение было сначала получено, а не когда оно было принято. Я мог следить за входящим ящиком пользователя, чтобы узнать, получили ли они уведомление, но я не думаю, что это сработает, если они фактически не получили электронное письмо до того, как они нажмут "Принять" (задержка сервера?).
Вот мой код. Любые идеи очень приветствуются.
public partial class ThisAddIn
{
Outlook.Items _Appointments = null;
Outlook.Folder _MyAppointmentsFolder = null;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// Initialization.
_MyAppointmentsFolder = (Outlook.Folder)this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
_Appointments = _MyAppointmentsFolder.Items;
_Appointments.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(appointments_Add);
}
private void appointments_Add(object item)
{
// An appointment has been added. Read the title and send an email based on a condition.
Outlook.AppointmentItem meetingItem = item as Outlook.AppointmentItem;
if (meetingItem.Subject.Contains("Service Call"))
{
// Let send ourselves an email.
string emailTo = string.Format("{0}@concurrency.com", Environment.UserName);
string subject = meetingItem.Subject;
string body = meetingItem.Body;
string startDate = meetingItem.Start.ToString();
string endDate = meetingItem.End.ToString();
SendEmailAlert(emailTo, subject, body, startDate, endDate);
}
}
....
Если вы присвойте значение для meetingItem.GlobalAppointmentID
переменной уровня класса после отправки электронной почты и проверьте это значение перед отправкой, это должно помешать отправке письма дважды. Я немного протестировал этот метод и, похоже, хорошо работает. Вот мой обновленный код:
...
string _PreviousMeetingId = string.Empty; // class-level variable
...
private void appointments_Add(object item)
{
// An appointment has been added. Read the title and send an email based on a condition.
Outlook.AppointmentItem meetingItem = item as Outlook.AppointmentItem;
if (meetingItem.Subject.Contains("Service Call") && _PreviousMeetingId != meetingItem.GlobalAppointmentID)
{
// Let send ourselves an email.
string emailTo = string.Format("{0}@concurrency.com", Environment.UserName);
string subject = meetingItem.Subject;
string body = meetingItem.Body;
string startDate = meetingItem.Start.ToString();
string endDate = meetingItem.End.ToString();
SendEmailAlert(emailTo, subject, body, startDate, endDate);
// Save the ID of the meeting so we can check it later (above).
_PreviousMeetingId = meetingItem.GlobalAppointmentID;
}
}
Когда запрос на встречу получен, Outlook создает временное предварительное назначение. После того, как вы его примете, первая встреча будет удалена, а новая добавлена, поэтому неудивительно, что событие срабатывает дважды.
Вы видите такое же поведение в OutlookSpy, если вы перейдете в папку "Календарь", нажмите кнопку "Папка", выберите "Свойства элемента", нажмите "Обзор", перейдите на вкладку "События" и посмотрите журнал в нижней части вкладки?