public async Task AddInstanceAsync(string reminderId, ReminderInstance instance) { var reminder = await context.Reminders.Include(v => v.Instances).Where(v => v.Id == reminderId).SingleAsync(); if (reminder.Instances == null) { reminder.Instances = new List <ReminderInstance>(); } reminder.Instances.Add(instance); await context.SaveChangesAsync(); }
private async Task UpdateReminderAsync(StoredReminder reminder) { //add a small threshold to prevent off by one errors var futureTime = Math.Max(MinReminderFuture.TotalMinutes, reminder.Minutes) + EventDiscoveryOverlap; var evts = (await calendarService.Get(reminder.UserId, DateTimeOffset.Now, DateTimeOffset.Now.AddMinutes(futureTime))) ?? new Event[0]; var events = (evts).Where(v => v.Start >= DateTimeOffset.Now); var existingInstances = new List <ReminderInstance>(reminder.Instances); foreach (var e in events) { var instance = reminder.Instances.Where(v => v.EventId == e.Id && v.FeedId == e.FeedId).FirstOrDefault(); var shouldFire = e.Start.AddMinutes(-reminder.Minutes) <= DateTimeOffset.Now; var eventHash = e.GenerateHash(); if (null != instance) { existingInstances.Remove(instance); if (instance.Hash != eventHash) { instance = await reminderRepository.UpdateInstanceAsync(instance.Id, eventHash); await FireOrInstallAsync(reminder, e, instance, shouldFire, eventHash); } } else { instance = new ReminderInstance() { Id = Guid.NewGuid().ToString(), EventId = e.Id, FeedId = e.FeedId, Hash = eventHash }; await reminderRepository.AddInstanceAsync(reminder.Id, instance); await FireOrInstallAsync(reminder, e, instance, shouldFire, eventHash); } } foreach (var instance in existingInstances) { if (instance.RemindRemovalUntil.HasValue && instance.RemindRemovalUntil > DateTimeOffset.Now.UtcDateTime) { await PostReminder(reminder, new ReminderDelivery { ReminderId = reminder.Id, ClientState = reminder.ClientState, Event = null, EventId = instance.EventId, FeedId = instance.FeedId, Removed = true }); } await reminderRepository.RemoveInstanceAsync(instance.Id); } }
private async Task FireOrInstallAsync(StoredReminder reminder, Event e, ReminderInstance instance, bool shouldFire, string eventHash) { if (!shouldFire) { await InstallButlerForInstance(reminder, instance, e); } else { await ProcessReminderAsync(new ReminderProcessRequest() { InstanceId = instance.Id, ReminderId = reminder.Id, Hash = eventHash }); } }
private async Task <string> InstallButlerForInstance(StoredReminder reminder, ReminderInstance instance, Event e) { return(await butler.InstallAsync(new WebhookRequest() { Data = new ReminderProcessRequest() { InstanceId = instance.Id, ReminderId = reminder.Id, Hash = instance.Hash }, Url = options.ProcessReminderUri, When = e.Start.AddMinutes(-reminder.Minutes).UtcDateTime })); }