diff options
author | Gabe Kangas <gabek@real-ity.com> | 2022-03-07 22:20:02 -0800 |
---|---|---|
committer | Gabe Kangas <gabek@real-ity.com> | 2022-03-07 22:20:02 -0800 |
commit | c639e0b1282d23a0fa4e9dda3f66b3fd322dc4e8 (patch) | |
tree | 91ebc1587a2bb26fc5be5ec3b9b4d5be6f4637be | |
parent | 0cfb423bf36bfec81a90d9b7d6249309dd70f513 (diff) |
Handle unsubscribe errors for browser push
-rw-r--r-- | db/query.sql | 3 | ||||
-rw-r--r-- | db/query.sql.go | 14 | ||||
-rw-r--r-- | notifications/browser/browser.go | 16 | ||||
-rw-r--r-- | notifications/notifications.go | 8 | ||||
-rw-r--r-- | notifications/persistence.go | 11 |
5 files changed, 42 insertions, 10 deletions
diff --git a/db/query.sql b/db/query.sql index 11205dc51..2f3ba1829 100644 --- a/db/query.sql +++ b/db/query.sql @@ -75,3 +75,6 @@ INSERT INTO notifications (channel, destination) VALUES($1, $2); -- name: GetNotificationDestinationsForChannel :many SELECT destination FROM notifications WHERE channel = $1; + +-- name: RemoveNotificationDestinationForChannel :exec +DELETE FROM notifications WHERE channel = $1 AND destination = $2; diff --git a/db/query.sql.go b/db/query.sql.go index adb5fee77..20c5ef860 100644 --- a/db/query.sql.go +++ b/db/query.sql.go @@ -530,6 +530,20 @@ func (q *Queries) RemoveIPAddressBan(ctx context.Context, ipAddress string) erro return err } +const removeNotificationDestinationForChannel = `-- name: RemoveNotificationDestinationForChannel :exec +DELETE FROM notifications WHERE channel = $1 AND destination = $2 +` + +type RemoveNotificationDestinationForChannelParams struct { + Channel string + Destination string +} + +func (q *Queries) RemoveNotificationDestinationForChannel(ctx context.Context, arg RemoveNotificationDestinationForChannelParams) error { + _, err := q.db.ExecContext(ctx, removeNotificationDestinationForChannel, arg.Channel, arg.Destination) + return err +} + const updateFollowerByIRI = `-- name: UpdateFollowerByIRI :exec UPDATE ap_followers SET inbox = $1, name = $2, username = $3, image = $4 WHERE iri = $5 ` diff --git a/notifications/browser/browser.go b/notifications/browser/browser.go index 5a042e6cb..9baf1a695 100644 --- a/notifications/browser/browser.go +++ b/notifications/browser/browser.go @@ -39,7 +39,7 @@ func (b *Browser) Send( subscription string, title string, body string, -) error { +) (bool, error) { type message struct { Title string `json:"title"` Body string `json:"body"` @@ -54,13 +54,13 @@ func (b *Browser) Send( d, err := json.Marshal(m) if err != nil { - return errors.Wrap(err, "error marshalling web push message") + return false, errors.Wrap(err, "error marshalling web push message") } // Decode subscription s := &webpush.Subscription{} if err := json.Unmarshal([]byte(subscription), s); err != nil { - return errors.Wrap(err, "error decoding destination subscription") + return false, errors.Wrap(err, "error decoding destination subscription") } // Send Notification @@ -72,12 +72,12 @@ func (b *Browser) Send( // Not really the subscriber, but a contact point for the sender. Subscriber: "owncast@owncast.online", }) - // TODO: Check if this this notification failed due to unsubscription. - // If so, remove their subscription from our notifications table. - if err != nil { - return errors.Wrap(err, "error sending browser push notification") + if resp.StatusCode == 410 { + return true, nil + } else if err != nil { + return false, errors.Wrap(err, "error sending browser push notification") } defer resp.Body.Close() - return err + return false, err } diff --git a/notifications/notifications.go b/notifications/notifications.go index f3a0e5f6b..34bab4826 100644 --- a/notifications/notifications.go +++ b/notifications/notifications.go @@ -107,7 +107,13 @@ func (n *Notifier) notifyBrowserPush() { log.Errorln("error getting browser push notification destinations", err) } for _, destination := range destinations { - if err := n.browser.Send(destination, data.GetServerName(), data.GetBrowserPushConfig().GoLiveMessage); err != nil { + unsubscribed, err := n.browser.Send(destination, data.GetServerName(), data.GetBrowserPushConfig().GoLiveMessage) + if unsubscribed { + // If the error is "unsubscribed", then remove the destination from the database. + if err := RemoveNotificationForChannel(BrowserPushNotification, destination); err != nil { + log.Errorln(err) + } + } else if err != nil { log.Errorln(err) } } diff --git a/notifications/persistence.go b/notifications/persistence.go index bbfd88a5a..283e4e551 100644 --- a/notifications/persistence.go +++ b/notifications/persistence.go @@ -32,13 +32,22 @@ func createNotificationsTable(db *sql.DB) { } // AddNotification saves a new user notification destination. -func AddNotification(channel string, destination string) error { +func AddNotification(channel, destination string) error { return data.GetDatastore().GetQueries().AddNotification(context.Background(), db.AddNotificationParams{ Channel: channel, Destination: destination, }) } +// RemoveNotificationForChannel removes a notification destination.. +func RemoveNotificationForChannel(channel, destination string) error { + log.Println("Removing notification for channel", channel) + return data.GetDatastore().GetQueries().RemoveNotificationDestinationForChannel(context.Background(), db.RemoveNotificationDestinationForChannelParams{ + Channel: channel, + Destination: destination, + }) +} + // GetNotificationDestinationsForChannel will return a collection of // destinations to notify for a given channel. func GetNotificationDestinationsForChannel(channel string) ([]string, error) { |