Track failures on Web Push subscriptions

This commit is contained in:
Karina Kwiatek 2022-12-27 23:22:51 +00:00
parent ba3c406bc7
commit 1cfd3250c0
6 changed files with 21 additions and 4 deletions

View File

@ -4,6 +4,6 @@ class Settings::PushNotificationsController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
def index def index
@subscriptions = current_user.web_push_subscriptions @subscriptions = current_user.web_push_subscriptions.active
end end
end end

View File

@ -4,7 +4,7 @@ module User::PushNotificationMethods
def push_notification(app, resource) def push_notification(app, resource)
raise ArgumentError("Resource must respond to `as_push_notification`") unless resource.respond_to? :as_push_notification raise ArgumentError("Resource must respond to `as_push_notification`") unless resource.respond_to? :as_push_notification
web_push_subscriptions.each do |s| web_push_subscriptions.active.find_each do |s|
n = Rpush::Webpush::Notification.new n = Rpush::Webpush::Notification.new
n.app = app n.app = app
n.registration_ids = [s.subscription.symbolize_keys] n.registration_ids = [s.subscription.symbolize_keys]

View File

@ -2,4 +2,7 @@
class WebPushSubscription < ApplicationRecord class WebPushSubscription < ApplicationRecord
belongs_to :user belongs_to :user
scope :active, -> { where(failures: ...3) }
scope :failed, -> { where(failures: 3..) }
end end

View File

@ -57,8 +57,14 @@ Rpush.reflect do |on|
# Called when notification delivery failed. # Called when notification delivery failed.
# Call 'error_code' and 'error_description' on the notification for the cause. # Call 'error_code' and 'error_description' on the notification for the cause.
# on.notification_failed do |notification| on.notification_failed do |notification|
# end # See: https://developer.apple.com/documentation/usernotifications/sending_web_push_notifications_in_safari_and_other_browsers#3994594
if %i[403 410].include? notification.error_code
subscription = WebPushSubscription::where("subscription ->> 'endpoint' = ?", notification.registration_ids.first[:endpoint])
subscription.increment :failures
subscription.save
end
end
# Called when the notification delivery failed and only the notification ID # Called when the notification delivery failed and only the notification ID
# is present in memory. # is present in memory.

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddFailuresToWebPushSubscriptions < ActiveRecord::Migration[6.1]
def change
add_column :web_push_subscriptions, :failures, :integer, default: 0
end
end

View File

@ -387,6 +387,7 @@ ActiveRecord::Schema.define(version: 2022_12_27_065923) do
t.json "subscription" t.json "subscription"
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.integer "failures", default: 0
t.index ["user_id"], name: "index_web_push_subscriptions_on_user_id" t.index ["user_id"], name: "index_web_push_subscriptions_on_user_id"
end end