I have a legacy program that I need to add to. What it does is scan a db table every set interval and creates Outlook invitations based on information from the table. This program uses the C# Microsoft Exchange API and I need to add a feature. What I need to do is take responses to events by users and create new db entries to log them. I don’t want to scan the inbox that created the events because not all users will respond with an email and I don’t want to scan all events from the db because there are thousands added per day and that will take too long.
Can anyone help me find a way to retrieve users’ responses as they happen so I can update the table dynamically when people respond to invitations?
I tried scanning all appointments but that is too costly
/// <summary>
/// Get all appointments that haven't occured yet and check invitee status
/// </summary>
private static void checkInviteeStatusAllAppointments()
{
//ENTER ELON QUERY TO SELECT RELEVANT APPOINTMENT IDs
List<int> appointmentIDs = new List<int>();
int numAppointments = appointmentIDs.Count;
writeToLog($"found {} appointment IDs", MESSAGE);
//---------------
//DateTime endDate = Convert.ToDateTime(TABLE_END_DATE);
//DateTime now = Convert.ToDateTime(DateTime.Now);
//string selectQuery = $"select * from {TABLE_NAME} where {TABLE_END_DATE} <> {now}";
//writeToLog($"query: {selectQuery}", MESSAGE);
//m_TableRows = mSqlConnect.GetFromDB(selectQuery);
//writeToLog($"found {m_TableRows.Count} rows", MESSAGE);
if (m_TableRows.Count > 0)
{
initExchangeService();
writeToLog("----------------------------------------------", MESSAGE);
// Iterating rows
foreach (var row in m_TableRows)
{
try
{
string appointmentType = row[TABLE_TYPE];
writeToLog($"working on new line with {TABLE_ID} {row[TABLE_ID]}, type: {appointmentType}", MESSAGE);
switch (appointmentType.ToUpper())
{
case INSERT_APPOINTMENT_LETTER:
createAppointment(row);
break;
case UPDATE_APPOINTMENT_LETTER:
updateAppointment(row);
break;
case CANCEL_APPOINTMENT_LETTER:
deleteAppointment(row);
break;
default:
updateTableOnError(row[TABLE_ID], "Not a valid type");
throw new Exception("Not a valid type");
}
}
catch (Exception ex)
{
writeToLog(ex.Message, ERROR_MESSAGE);
}
finally
{
writeToLog("----------------------------------------------", MESSAGE);
}
}
}
}
/// <summary>
/// Captures the responses of invitees for an appointment given the row denoting it.
/// </summary>
/// <param name="row">The row representing the appointment</param>
private static void CaptureInviteeResponses(Dictionary<string, string> row)
{
string appointmentId = row[TABLE_APPOINTMENT_ID];
try
{
if (string.IsNullOrEmpty(appointmentId))
{
throw new Exception(message: $"Error. No ID for row {row}.");
}
Appointment appointment = Appointment.Bind(m_ExchangeService, appointmentId);
writeToLog($"Successfully bound to appointment with ID: {appointmentId}", MESSAGE);
ThreadPool.QueueUserWorkItem(new WaitCallback(logAttendeeResponses), appointment);
}
catch (Exception ex)
{
writeToLog($"Error capturing responses for appointment ID {appointmentId}: {ex.Message}", ERROR_MESSAGE);
}
}
/// <summary>
/// Iterate all invitees of an appointment and log their responses to the invitation.
/// </summary>
/// <param name="i_appointment">The appointment to be examined</param>
private static void logAttendeeResponses(object i_appointment)
{
Appointment appointment = (Appointment)i_appointment;
// Retrieve the responses of required attendees
foreach (Attendee attendee in appointment.RequiredAttendees)
{
string response = attendee.ResponseType == MeetingResponseType.NoResponseReceived ? "No response received" : attendee.ResponseType.ToString();
writeToLog($"Required Attendee: {attendee.Address}, Response: {response}", MESSAGE);
}
// Retrieve the responses of optional attendees
foreach (Attendee attendee in appointment.OptionalAttendees)
{
string response = attendee.ResponseType == MeetingResponseType.NoResponseReceived ? "No response received" : attendee.ResponseType.ToString();
writeToLog($"Optional Attendee: {attendee.Address}, Response: {response}", MESSAGE);
}
}