#if WINDOWS using MeetingAssistant.MeetingNotes; namespace MeetingAssistant.Calendar; public sealed class OutlookClassicCalendarMeetingProvider : ICalendarMeetingProvider { private readonly ILogger logger; public OutlookClassicCalendarMeetingProvider(ILogger logger) { this.logger = logger; } public Task> GetRecordingPromptCandidatesForDayAsync( DateOnly day, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); try { return OutlookClassicCom.RunStaAsync( () => GetTeamsMeetingsForDay(day), cancellationToken, "Meeting Assistant Outlook Calendar Prompt Lookup"); } catch (Exception exception) when (exception is not OperationCanceledException) { logger.LogDebug(exception, "Outlook Classic calendar meetings were not available"); return Task.FromResult>([]); } } private IReadOnlyList GetTeamsMeetingsForDay(DateOnly day) { using var calendar = OutlookClassicCom.OpenDefaultCalendar(logger, "calendar prompt lookup"); if (calendar is null) { return []; } var dayStart = day.ToDateTime(TimeOnly.MinValue); var dayEnd = dayStart.AddDays(1); var meetings = new List(); foreach (var item in OutlookClassicCom.EnumerateItems(calendar.Items)) { try { if (item is null || !OutlookClassicCom.IsAppointment(item)) { continue; } var start = Convert.ToDateTime(OutlookClassicCom.GetProperty(item, "Start")); if (start >= dayEnd) { break; } var end = Convert.ToDateTime(OutlookClassicCom.GetProperty(item, "End")); if (end <= dayStart || start < dayStart || !IsTeamsAppointment(item)) { continue; } var rawSubject = Convert.ToString(OutlookClassicCom.GetProperty(item, "Subject"))?.Trim(); var subject = string.IsNullOrWhiteSpace(rawSubject) ? "Teams meeting" : rawSubject; meetings.Add(new CalendarMeeting( GetAppointmentId(item, start, end, subject), subject, OutlookClassicCom.ToLocalOffset(start), OutlookClassicCom.ToLocalOffset(end))); } finally { OutlookClassicCom.ReleaseComObject(item); } } return meetings; } private static string GetAppointmentId( object appointment, DateTime start, DateTime end, string subject) { var id = Convert.ToString(OutlookClassicCom.TryGetProperty(appointment, "GlobalAppointmentID")); if (string.IsNullOrWhiteSpace(id)) { id = Convert.ToString(OutlookClassicCom.TryGetProperty(appointment, "EntryID")); } return string.IsNullOrWhiteSpace(id) ? $"{start:O}|{end:O}|{subject}" : $"{id}|{start:O}"; } private static bool IsTeamsAppointment(object appointment) { var subject = Convert.ToString(OutlookClassicCom.GetProperty(appointment, "Subject")) ?? ""; var location = Convert.ToString(OutlookClassicCom.GetProperty(appointment, "Location")) ?? ""; var body = Convert.ToString(OutlookClassicCom.GetProperty(appointment, "Body")) ?? ""; return TeamsMeetingMarkerDetector.IsTeamsAppointment(subject, location, body); } } #endif