Пример #1
0
        public async Task SendBatchNotifications(NotificationType type, bool useHttps, string host, int?count = null)
        {
            if (!type.ShouldBeBatched())
            {
                throw new InvalidOperationException($"Notifications of type {type} can't be batched");
            }

            using (var db = _dbService.GetConnection())
            {
                var userIds = await db.QueryAsync <int>($@"
Select Id
From   Users
Where  {type.GetUserColumnName()} < @now", new { now = DateTime.UtcNow });

                var successfulUserIds = new List <int>();
                foreach (var userId in userIds)
                {
                    var message = new Models.Services.PushNotificationMessage(
                        type.GetTitle(count),
                        type.GetUrl(useHttps, host, userId),
                        type.GetBody(),
                        type.ToString(),
                        true);
                    if (await SendNotification(userId, message))
                    {
                        successfulUserIds.Add(userId);
                    }
                }

                await db.ExecuteAsync($@"
Update Users
Set    {type.GetUserColumnName()} = DateAdd(minute, NotificationsIntervalId * NotificationsIntervalValue, @now)
Where  Id In @successfulUserIds", new { successfulUserIds, columnName = type.GetUserColumnName(), now = DateTime.UtcNow });
            }
        }
Пример #2
0
        private async Task <bool> SendNotification(int userId, Models.Services.PushNotificationMessage message)
        {
            using (var db = _dbService.GetConnection())
            {
                var endpointsToRemove = new List <string>();
                var success           = false;

                var currentSubscriptions = await GetCurrentSubscriptions(userId, db);

                var options = new Dictionary <string, object> {
                    ["vapidDetails"] = _vapidDetails
                };
                if (message.Topic.HasValue())
                {
                    options["headers"] = new Dictionary <string, object>
                    {
                        ["topic"] = message.Topic
                    };
                }

                foreach (var subscriptionData in currentSubscriptions)
                {
                    var subscription = new PushSubscription(subscriptionData.Endpoint, subscriptionData.P256dh, subscriptionData.Auth);
                    try
                    {
                        await _webPushClient.SendNotificationAsync(subscription, Jil.JSON.Serialize(message, Jil.Options.CamelCase), options);

                        success = true;
                    }
                    catch (WebPushException exception)
                    {
                        if (exception.StatusCode == HttpStatusCode.NotFound || exception.StatusCode == HttpStatusCode.Gone)
                        {
                            endpointsToRemove.Add(subscriptionData.Endpoint);
                        }
                    }
                }

                if (endpointsToRemove.Count > 0)
                {
                    await SetCurrentSubscriptions(userId, currentSubscriptions.Where(s => !endpointsToRemove.Contains(s.Endpoint)), db);
                }

                return(success);
            }
        }
Пример #3
0
        public async Task <bool> SendNotification(int userId, NotificationType type, bool useHttps, string host)
        {
            if (type.ShouldBeBatched())
            {
                throw new InvalidOperationException($"Notifications of type {type} should be batched");
            }

            using (var db = _dbService.GetConnection())
            {
                var shouldSendIt = await db.QueryFirstOrDefaultAsync <bool>($@"
Select Top 1 1
From   Users
Where  Id = @userId
And    {type.GetUserColumnName()} < @now", new { userId, now = DateTime.UtcNow });

                if (shouldSendIt)
                {
                    var message = new Models.Services.PushNotificationMessage(
                        type.GetTitle(),
                        type.GetUrl(useHttps, host, userId),
                        type.GetBody(),
                        type.ToString(),
                        true);
                    var success = await SendNotification(userId, message);

                    if (success)
                    {
                        await db.ExecuteAsync($@"
Update Users
Set    {type.GetUserColumnName()} = DateAdd(minute, NotificationsIntervalId * NotificationsIntervalValue, @now)
Where  Id = @userId", new { userId, now = DateTime.UtcNow });
                    }

                    return(success);
                }
            }

            return(false);
        }