private async Task NotifyOrInstall(string userId, FocusItemWithExternalData item) { var timeToDeparture = item.IndicateTime - DateTimeOffset.Now; if (timeToDeparture < FocusConstants.NotifyTime.Add(FocusConstants.ButlerInaccuracy)) { var notifySemaphore = _notifySempahores.GetOrAdd(userId, s => new SemaphoreSlim(1)); await notifySemaphore.WaitAsync(); try { if (!await _focusStore.FocusItemNotifiedAsync(item.Id)) { try { await _digitPushServiceClient[userId].Push.Create(new DigitPushService.Models.PushRequest() { ChannelOptions = new Dictionary <string, string>() { { "digit.notify", null } }, Payload = JsonConvert.SerializeObject(new { notification = new { tag = item.Id, title = item.CalendarEvent == null ? "Losgehen" : $"Losgehen zu {item.CalendarEvent.Subject}", body = NotificationBody(item) } }) }); } catch (Exception e) { await _logger.LogForFocusItem(userId, item.Id, $"Could notify user ({e.Message}).", logLevel : LogLevel.Error); } await _focusStore.SetFocusItemNotifiedAsync(item.Id); // always set notified for now to prevent massive notification spam } } finally { notifySemaphore.Release(); } } else { // plan the notification anyways, even if the location might be updated, in case no update is received (low phone battery for example) // it will be ignored if any of the conditions (user location, traffic, event start time) changed await _butler.InstallAsync(new WebhookRequest() { When = item.IndicateTime.Add(-FocusConstants.NotifyTime).UtcDateTime, Data = new NotifyUserRequest() { UserId = userId, FocusItemId = item.Id }, Url = options.NotifyUserCallbackUri }); } }
public async Task ActiveItemChanged(string userId, FocusItemWithExternalData currentItem) { var devices = await _deviceSyncStore.GetForUserAsync(userId); foreach (var device in devices) { await _digitPushServiceClient[userId].DigitSync.Device(new DeviceSyncRequest() { DeviceId = device.Id }); await _digitLogger.LogForUser(userId, $"Requested device sync", Abstractions.Models.DigitTraceAction.RequestPush, new Dictionary <string, object>() { { "deviceId", device.Id } }); } }
private string NotificationBody(FocusItemWithExternalData item) { var leave = $"Geh in {Minutes(item.IndicateTime)} los."; if (null != item.Directions) { var step = item.Directions.Routes[item.DirectionsMetadata.PeferredRoute].Steps.FirstOrDefault(); if (null != step) { return($"{leave} {step.Line.ShortName} kommt in {Minutes(step.DepartureTime)}."); } } if (null != item.CalendarEvent) { return($"{leave} {item.CalendarEvent.Subject} beginnt in {Minutes(item.CalendarEvent.Start)}."); } return(leave); }
private IEnumerable <GeofenceRequest> GetGeofences(FocusItemWithExternalData item) { var route = item.Directions.Routes[item.DirectionsMetadata.PeferredRoute]; yield return(new GeofenceRequest() { Id = $"start#{item.Id}", FocusItemId = item.Id, End = item.End, Start = route.DepatureTime.AddMinutes(-15), Lat = route.StartLocation.Lat, Lng = route.StartLocation.Lng, Exit = true, Radius = 50 }); for (var i = 0; i < route.Steps.Length; i++) { var step = route.Steps[i]; yield return(new GeofenceRequest() { Id = $"step{i}#{item.Id}", FocusItemId = item.Id, End = item.End, Start = route.DepatureTime.AddMinutes(-15), Lat = step.DepartureStop.Location.Lat, Lng = step.DepartureStop.Location.Lng, Exit = false, Radius = 150 }); } yield return(new GeofenceRequest() { Id = $"end#{item.Id}", FocusItemId = item.Id, End = item.End, Start = route.DepatureTime.AddMinutes(-15), Lat = route.EndLocation.Lat, Lng = route.EndLocation.Lng, Exit = false, Radius = 100 }); }
public Task ActiveItemChanged(string userId, FocusItemWithExternalData currentItem) { return(Task.CompletedTask); }
public async Task ActiveItemChanged(string userId, FocusItemWithExternalData currentItem) { }