RSVP options.
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Google;
|
||||
using Google.Apis.Calendar.v3;
|
||||
using Google.Apis.Calendar.v3.Data;
|
||||
using Google.Apis.Gmail.v1;
|
||||
using Google.Apis.Gmail.v1.Data;
|
||||
@@ -1648,7 +1649,7 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
||||
Summary = calendarItem.Title,
|
||||
Description = calendarItem.Description,
|
||||
Location = calendarItem.Location,
|
||||
Status = calendarItem.Status == CalendarItemStatus.Confirmed ? "confirmed" : "tentative"
|
||||
Status = calendarItem.Status == CalendarItemStatus.Accepted ? "confirmed" : "tentative"
|
||||
};
|
||||
|
||||
// Set start and end time
|
||||
@@ -1696,6 +1697,125 @@ public class GmailSynchronizer : WinoSynchronizer<IClientServiceRequest, Message
|
||||
return [new HttpRequestBundle<IClientServiceRequest>(insertRequest, request)];
|
||||
}
|
||||
|
||||
public override List<IRequestBundle<IClientServiceRequest>> AcceptEvent(AcceptEventRequest request)
|
||||
{
|
||||
var calendarItem = request.Item;
|
||||
var calendar = calendarItem.AssignedCalendar;
|
||||
|
||||
if (calendar == null)
|
||||
{
|
||||
throw new InvalidOperationException("Calendar item must have an assigned calendar");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(calendarItem.RemoteEventId))
|
||||
{
|
||||
throw new InvalidOperationException("Cannot accept event without remote event ID");
|
||||
}
|
||||
|
||||
// For Gmail, we need to patch the event with the user's response status
|
||||
// Get the current user's email from the account
|
||||
var userEmail = Account.Address;
|
||||
|
||||
// Create a patch event to update only the attendee response
|
||||
var patchEvent = new Event();
|
||||
|
||||
// We need to get the event first to update the specific attendee
|
||||
// However, for efficiency, we'll use the patch method with sendUpdates parameter
|
||||
var patchRequest = _calendarService.Events.Patch(new Event
|
||||
{
|
||||
// The API will handle updating the current user's attendee status
|
||||
Attendees = new List<EventAttendee>
|
||||
{
|
||||
new EventAttendee
|
||||
{
|
||||
Email = userEmail,
|
||||
ResponseStatus = "accepted"
|
||||
}
|
||||
}
|
||||
}, calendar.RemoteCalendarId, calendarItem.RemoteEventId);
|
||||
|
||||
// Send updates to other attendees if there's a message
|
||||
patchRequest.SendUpdates = !string.IsNullOrEmpty(request.ResponseMessage)
|
||||
? Google.Apis.Calendar.v3.EventsResource.PatchRequest.SendUpdatesEnum.All
|
||||
: Google.Apis.Calendar.v3.EventsResource.PatchRequest.SendUpdatesEnum.None;
|
||||
|
||||
return [new HttpRequestBundle<IClientServiceRequest>(patchRequest, request)];
|
||||
}
|
||||
|
||||
public override List<IRequestBundle<IClientServiceRequest>> DeclineEvent(DeclineEventRequest request)
|
||||
{
|
||||
var calendarItem = request.Item;
|
||||
var calendar = calendarItem.AssignedCalendar;
|
||||
|
||||
if (calendar == null)
|
||||
{
|
||||
throw new InvalidOperationException("Calendar item must have an assigned calendar");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(calendarItem.RemoteEventId))
|
||||
{
|
||||
throw new InvalidOperationException("Cannot decline event without remote event ID");
|
||||
}
|
||||
|
||||
var userEmail = Account.Address;
|
||||
|
||||
var patchRequest = _calendarService.Events.Patch(new Event
|
||||
{
|
||||
Attendees = new List<EventAttendee>
|
||||
{
|
||||
new EventAttendee
|
||||
{
|
||||
Email = userEmail,
|
||||
ResponseStatus = "declined",
|
||||
Comment = request.ResponseMessage
|
||||
}
|
||||
}
|
||||
}, calendar.RemoteCalendarId, calendarItem.RemoteEventId);
|
||||
|
||||
patchRequest.SendUpdates = !string.IsNullOrEmpty(request.ResponseMessage)
|
||||
? Google.Apis.Calendar.v3.EventsResource.PatchRequest.SendUpdatesEnum.All
|
||||
: Google.Apis.Calendar.v3.EventsResource.PatchRequest.SendUpdatesEnum.None;
|
||||
|
||||
return [new HttpRequestBundle<IClientServiceRequest>(patchRequest, request)];
|
||||
}
|
||||
|
||||
public override List<IRequestBundle<IClientServiceRequest>> TentativeEvent(TentativeEventRequest request)
|
||||
{
|
||||
var calendarItem = request.Item;
|
||||
var calendar = calendarItem.AssignedCalendar;
|
||||
|
||||
if (calendar == null)
|
||||
{
|
||||
throw new InvalidOperationException("Calendar item must have an assigned calendar");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(calendarItem.RemoteEventId))
|
||||
{
|
||||
throw new InvalidOperationException("Cannot tentatively accept event without remote event ID");
|
||||
}
|
||||
|
||||
var userEmail = Account.Address;
|
||||
|
||||
var patchRequest = _calendarService.Events.Patch(new Event
|
||||
{
|
||||
Attendees = new List<EventAttendee>
|
||||
{
|
||||
new EventAttendee
|
||||
{
|
||||
Email = userEmail,
|
||||
ResponseStatus = "tentative",
|
||||
Comment = request.ResponseMessage
|
||||
}
|
||||
}
|
||||
}, calendar.RemoteCalendarId, calendarItem.RemoteEventId);
|
||||
|
||||
patchRequest.SendUpdates = !string.IsNullOrEmpty(request.ResponseMessage)
|
||||
? Google.Apis.Calendar.v3.EventsResource.PatchRequest.SendUpdatesEnum.All
|
||||
: Google.Apis.Calendar.v3.EventsResource.PatchRequest.SendUpdatesEnum.None;
|
||||
|
||||
return [new HttpRequestBundle<IClientServiceRequest>(patchRequest, request)];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override async Task KillSynchronizerAsync()
|
||||
|
||||
@@ -1680,6 +1680,9 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
||||
|
||||
foreach (var item in events)
|
||||
{
|
||||
// Declined events are returned as Deleted from the API.
|
||||
// There is no way to distinguish unfortunately atm.
|
||||
|
||||
if (IsResourceDeleted(item.AdditionalData))
|
||||
{
|
||||
await _outlookChangeProcessor.DeleteCalendarItemAsync(item.Id, calendar.Id).ConfigureAwait(false);
|
||||
@@ -1886,6 +1889,80 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
||||
return [new HttpRequestBundle<RequestInformation>(createRequest, request)];
|
||||
}
|
||||
|
||||
public override List<IRequestBundle<RequestInformation>> AcceptEvent(AcceptEventRequest request)
|
||||
{
|
||||
var calendarItem = request.Item;
|
||||
var calendar = calendarItem.AssignedCalendar;
|
||||
|
||||
if (calendar == null)
|
||||
{
|
||||
throw new InvalidOperationException("Calendar item must have an assigned calendar");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(calendarItem.RemoteEventId))
|
||||
{
|
||||
throw new InvalidOperationException("Cannot accept event without remote event ID");
|
||||
}
|
||||
|
||||
var acceptRequestInfo = _graphClient.Me.Calendars[calendar.RemoteCalendarId].Events[calendarItem.RemoteEventId].Accept.ToPostRequestInformation(new Microsoft.Graph.Me.Calendars.Item.Events.Item.Accept.AcceptPostRequestBody
|
||||
{
|
||||
Comment = request.ResponseMessage,
|
||||
SendResponse = !string.IsNullOrEmpty(request.ResponseMessage)
|
||||
});
|
||||
|
||||
return [new HttpRequestBundle<RequestInformation>(acceptRequestInfo, request)];
|
||||
}
|
||||
|
||||
public override List<IRequestBundle<RequestInformation>> OutlookDeclineEvent(OutlookDeclineEventRequest request)
|
||||
{
|
||||
var responseMessage = request.ResponseMessage;
|
||||
|
||||
var calendarItem = request.Item;
|
||||
var calendar = calendarItem.AssignedCalendar;
|
||||
|
||||
if (calendar == null)
|
||||
{
|
||||
throw new InvalidOperationException("Calendar item must have an assigned calendar");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(calendarItem.RemoteEventId))
|
||||
{
|
||||
throw new InvalidOperationException("Cannot decline event without remote event ID");
|
||||
}
|
||||
|
||||
var declineRequestInfo = _graphClient.Me.Calendars[calendar.RemoteCalendarId].Events[calendarItem.RemoteEventId].Decline.ToPostRequestInformation(new Microsoft.Graph.Me.Calendars.Item.Events.Item.Decline.DeclinePostRequestBody
|
||||
{
|
||||
Comment = responseMessage,
|
||||
SendResponse = !string.IsNullOrEmpty(responseMessage)
|
||||
});
|
||||
|
||||
return [new HttpRequestBundle<RequestInformation>(declineRequestInfo, request)];
|
||||
}
|
||||
|
||||
public override List<IRequestBundle<RequestInformation>> TentativeEvent(TentativeEventRequest request)
|
||||
{
|
||||
var calendarItem = request.Item;
|
||||
var calendar = calendarItem.AssignedCalendar;
|
||||
|
||||
if (calendar == null)
|
||||
{
|
||||
throw new InvalidOperationException("Calendar item must have an assigned calendar");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(calendarItem.RemoteEventId))
|
||||
{
|
||||
throw new InvalidOperationException("Cannot tentatively accept event without remote event ID");
|
||||
}
|
||||
|
||||
var tentativelyAcceptRequestInfo = _graphClient.Me.Calendars[calendar.RemoteCalendarId].Events[calendarItem.RemoteEventId].TentativelyAccept.ToPostRequestInformation(new Microsoft.Graph.Me.Calendars.Item.Events.Item.TentativelyAccept.TentativelyAcceptPostRequestBody
|
||||
{
|
||||
Comment = request.ResponseMessage,
|
||||
SendResponse = !string.IsNullOrEmpty(request.ResponseMessage)
|
||||
});
|
||||
|
||||
return [new HttpRequestBundle<RequestInformation>(tentativelyAcceptRequestInfo, request)];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override async Task KillSynchronizerAsync()
|
||||
|
||||
@@ -364,6 +364,22 @@ public abstract class WinoSynchronizer<TBaseRequest, TMessageType, TCalendarEven
|
||||
case CalendarSynchronizerOperation.CreateEvent:
|
||||
nativeRequests.AddRange(CreateCalendarEvent(group.ElementAt(0) as CreateCalendarEventRequest));
|
||||
break;
|
||||
case CalendarSynchronizerOperation.AcceptEvent:
|
||||
nativeRequests.AddRange(AcceptEvent(group.ElementAt(0) as AcceptEventRequest));
|
||||
break;
|
||||
case CalendarSynchronizerOperation.DeclineEvent:
|
||||
if (Account.ProviderType == MailProviderType.Outlook)
|
||||
{
|
||||
nativeRequests.AddRange(OutlookDeclineEvent(group.ElementAt(0) as OutlookDeclineEventRequest));
|
||||
}
|
||||
else
|
||||
{
|
||||
nativeRequests.AddRange(DeclineEvent(group.ElementAt(0) as DeclineEventRequest));
|
||||
}
|
||||
break;
|
||||
case CalendarSynchronizerOperation.TentativeEvent:
|
||||
nativeRequests.AddRange(TentativeEvent(group.ElementAt(0) as TentativeEventRequest));
|
||||
break;
|
||||
case CalendarSynchronizerOperation.UpdateEvent:
|
||||
// TODO: Implement UpdateCalendarEvent
|
||||
break;
|
||||
@@ -494,6 +510,10 @@ public abstract class WinoSynchronizer<TBaseRequest, TMessageType, TCalendarEven
|
||||
#region Calendar Operations
|
||||
|
||||
public virtual List<IRequestBundle<TBaseRequest>> CreateCalendarEvent(CreateCalendarEventRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||
public virtual List<IRequestBundle<TBaseRequest>> AcceptEvent(AcceptEventRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||
public virtual List<IRequestBundle<TBaseRequest>> DeclineEvent(DeclineEventRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||
public virtual List<IRequestBundle<TBaseRequest>> OutlookDeclineEvent(OutlookDeclineEventRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||
public virtual List<IRequestBundle<TBaseRequest>> TentativeEvent(TentativeEventRequest request) => throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedSynchronizerOperation, this.GetType()));
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user