Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PushSubscription"/> class.
 /// </summary>
 /// <param name="userId">User id.</param>
 /// <param name="subscription">WebPush subscription.</param>
 public PushSubscription(string userId, WebPush.PushSubscription subscription)
 {
     UserId         = userId;
     Endpoint       = subscription.Endpoint;
     ExpirationTime = null;
     P256Dh         = subscription.P256DH;
     Auth           = subscription.Auth;
 }
Пример #2
0
        public async Task <ActionResult> SendNotification(int id)
        {
            var sub = db.PushSubscriptions.Find(id);

            if (sub == null)
            {
                return(HttpNotFound());
            }
            else
            {
                var publicKey  = ConfigurationManager.AppSettings["VapidPublicKey"];
                var privateKey = ConfigurationManager.AppSettings["VapidPrivateKey"];
                var subject    = @"mailto: [email protected]";

                Uri    uri      = new Uri(sub.Url);
                string audience = $"{uri.Scheme}{Uri.SchemeDelimiter}{uri.Host}";

                var subscription = new WebPush.PushSubscription(sub.Url, sub.P256dh, sub.Auth);
                var vapidDetails = new WebPush.VapidDetails(subject, publicKey, privateKey);

                var client = new WebPush.WebPushClient();
                try
                {
                    var opts = new Dictionary <string, object>();
                    opts["vapidDetails"] = vapidDetails;

                    var notification = new PushNotification();
                    notification.Title          = "Something New Happened!";
                    notification.Body           = "There was some activity on your account and you should go do something about it.";
                    notification.Icon           = "https://s3.amazonaws.com/images.productionhub.com/icons/asterisk.png";
                    notification.Data.Url       = "/";
                    notification.Data.ListingId = "142484";
                    notification.Actions.Add(new NotificationAction {
                        Action = "ignore", Title = "Ignore Lead", Icon = "https://s3.amazonaws.com/images.productionhub.com/icons/icon_remove_red.png"
                    });
                    notification.Actions.Add(new NotificationAction {
                        Action = "buy", Title = "Purchase Lead", Icon = "https://s3.amazonaws.com/images.productionhub.com/icons/icon_credit.png"
                    });

                    var payload = JsonConvert.SerializeObject(notification, new JsonSerializerSettings {
                        ContractResolver = new CamelCasePropertyNamesContractResolver()
                    });

                    var requestDetails = client.GenerateRequestDetails(subscription, payload, opts);


                    //await client.SendNotificationAsync(subscription, "payload", vapidDetails);
                    var httpClient = new HttpClient();
                    await httpClient.SendAsync(requestDetails);

                    return(Json(true));
                }
                catch (WebPush.WebPushException exc)
                {
                    return(new HttpStatusCodeResult(exc.StatusCode));
                }
            }
        }
Пример #3
0
 private static async Task TrySendPushNotification(PushNotification notification, PushSubscription recipient, WebPush.VapidDetails details, WebPush.WebPushClient client, JsonSerializerSettings serializerSettings, ILogger logger)
 {
     // This is run in a background thread. We should not access or update mutable state.
     try
     {
         var payload      = JsonConvert.SerializeObject(notification, serializerSettings);
         var subscription = new WebPush.PushSubscription(recipient.Endpoint, recipient.Keys["p256dh"], recipient.Keys["auth"]);
         await client.SendNotificationAsync(subscription, payload, details);
     }
     catch (Exception error)
     {
         using (logger.BeginKeyValueScope("recipient", recipient))
             using (logger.BeginKeyValueScope("publicKey", details.PublicKey))
                 using (logger.BeginKeyValueScope("publicKey", details.PrivateKey))
                 {
                     logger.LogError(error, "Error sending push notification");
                 }
     }
 }
Пример #4
0
        private static void doPushBackgroundWork()
        {
            try
            {
                WebPush.WebPushClient client = new WebPush.WebPushClient();
                while (true)
                {
                    try
                    {
                        if (!newEvents.IsEmpty)
                        {
                            // Accumulate a list of events we want to notify each subscription about.
                            // Map subscriptionkey > event list
                            Dictionary <string, List <EventToNotifyAbout> > accumulatedEvents = new Dictionary <string, List <EventToNotifyAbout> >();
                            List <User> users = Settings.data.GetAllUsers();
                            while (newEvents.TryDequeue(out EventToNotifyAbout en))
                            {
                                foreach (User u in users)
                                {
                                    string[] subscriptionKeys = u.GetPushNotificationSubscriptions(en.projectName, en.ev.FolderId);
                                    foreach (string key in subscriptionKeys)
                                    {
                                        List <EventToNotifyAbout> events;
                                        if (!accumulatedEvents.TryGetValue(key, out events))
                                        {
                                            accumulatedEvents[key] = events = new List <EventToNotifyAbout>();
                                        }
                                        events.Add(en);
                                    }
                                }
                            }

                            if (accumulatedEvents.Count > 0)
                            {
                                WebPush.VapidDetails vapidDetails = new WebPush.VapidDetails(GetVapidSubject(), Settings.data.vapidPublicKey, Settings.data.vapidPrivateKey);
                                // Build and send one notification to each affected subscription.
                                foreach (KeyValuePair <string, List <EventToNotifyAbout> > kvp in accumulatedEvents)
                                {
                                    string subscriptionKey           = kvp.Key;
                                    List <EventToNotifyAbout> events = kvp.Value;

                                    WebPush.PushSubscription subscription = null;
                                    try
                                    {
                                        dynamic dyn = JsonConvert.DeserializeObject(subscriptionKey);
                                        subscription          = new WebPush.PushSubscription();
                                        subscription.Endpoint = dyn.endpoint;
                                        subscription.P256DH   = dyn.keys.p256dh;
                                        subscription.Auth     = dyn.keys.auth;
                                    }
                                    catch { }

                                    // For now, we'll just ignore any unparseable subscription keys.
                                    // I know this is asking for trouble later on, and I'm sorry for that.
                                    if (subscription != null)
                                    {
                                        StringBuilder sb = new StringBuilder();

                                        PushMessage message = new PushMessage(Settings.data.systemName, events.Count + " new events:");
                                        if (events.Count == 1)
                                        {
                                            EventToNotifyAbout en = events[0];
                                            message.message = en.ev.EventType.ToString() + ": " + en.ev.SubType;
                                            message.eventid = en.ev.EventId;
                                        }

                                        // If all events are in the same project, set message.project so that clicking the notification can open the correct project.
                                        string projectName = events[0].projectName;
                                        if (events.All(en => en.projectName == projectName))
                                        {
                                            message.project = projectName;

                                            // If all events are in the same folder, set message.folderid so that clicking the notification can open the correct folder.
                                            int folderId = events[0].ev.FolderId;
                                            if (events.All(en => en.ev.FolderId == folderId))
                                            {
                                                message.folderid = folderId;
                                            }
                                        }

                                        try
                                        {
                                            client.SendNotification(subscription, message.ToString(), vapidDetails);
                                        }
                                        catch (Exception ex)
                                        {
                                            Logger.Debug(ex, "Failed to send push notification.");
                                        }
                                    }
                                }
                            }
                        }
                        Thread.Sleep(1000);
                    }
                    catch (ThreadAbortException) { }
                    catch (Exception ex)
                    {
                        Emailer.SendError(null, "Error in PushManager", ex);
                    }
                }
            }
            catch (ThreadAbortException) { }
            catch (Exception ex)
            {
                Logger.Debug(ex);
            }
        }