summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Kangas <gabek@real-ity.com>2022-03-07 22:20:02 -0800
committerGabe Kangas <gabek@real-ity.com>2022-03-07 22:20:02 -0800
commitc639e0b1282d23a0fa4e9dda3f66b3fd322dc4e8 (patch)
tree91ebc1587a2bb26fc5be5ec3b9b4d5be6f4637be
parent0cfb423bf36bfec81a90d9b7d6249309dd70f513 (diff)
Handle unsubscribe errors for browser push
-rw-r--r--db/query.sql3
-rw-r--r--db/query.sql.go14
-rw-r--r--notifications/browser/browser.go16
-rw-r--r--notifications/notifications.go8
-rw-r--r--notifications/persistence.go11
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) {