public async Task AddAsync(string userId, ReminderRequest request, ReminderRegistration registration) { var user = await context.Users.Where(v => v.Id == userId).SingleOrDefaultAsync(); var storedReminder = new StoredReminder() { ClientState = request.ClientState, Expires = registration.Expires, Id = registration.Id, Minutes = request.Minutes, NotificationUri = request.NotificationUri }; if (null == user) { user = new User() { Id = userId, Reminders = new List <StoredReminder>() { storedReminder } }; await context.Users.AddAsync(user); } else { if (null == user.Reminders) { user.Reminders = new List <StoredReminder>(); } user.Reminders.Add(storedReminder); } await context.SaveChangesAsync(); }
public async Task PostReminder(StoredReminder reminder, ReminderDelivery delivery) { var client = new HttpClient(); var res = await client.PostAsync(reminder.NotificationUri, new StringContent(JsonConvert.SerializeObject(delivery), Encoding.UTF8, "application/json")); if (!res.IsSuccessStatusCode) { throw new ReminderDeliveryException(); } }
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 <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 })); }
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 }); } }