Add `rpush`

This commit is contained in:
Karina Kwiatek 2022-09-09 18:29:40 +02:00
parent 48f9c01866
commit 92ba2d7c9b
20 changed files with 802 additions and 0 deletions

View File

@ -29,6 +29,7 @@ gem "haml", "~> 6.1"
gem "hcaptcha", "~> 7.0" gem "hcaptcha", "~> 7.0"
gem "mini_magick" gem "mini_magick"
gem "oj" gem "oj"
gem "rpush"
gem "rqrcode" gem "rqrcode"
gem "rolify", "~> 6.0" gem "rolify", "~> 6.0"

View File

@ -197,6 +197,8 @@ GEM
hashie (5.0.0) hashie (5.0.0)
hcaptcha (7.1.0) hcaptcha (7.1.0)
json json
hkdf (0.3.0)
http-2 (0.11.0)
http (4.4.1) http (4.4.1)
addressable (~> 2.3) addressable (~> 2.3)
http-cookie (~> 1.0) http-cookie (~> 1.0)
@ -268,6 +270,10 @@ GEM
multipart-post (2.1.1) multipart-post (2.1.1)
naught (1.1.0) naught (1.1.0)
nested_form (0.3.2) nested_form (0.3.2)
net-http-persistent (4.0.1)
connection_pool (~> 2.2)
net-http2 (0.18.4)
http-2 (~> 0.11)
net-imap (0.3.4) net-imap (0.3.4)
date date
net-protocol net-protocol
@ -370,6 +376,16 @@ GEM
rexml (3.2.5) rexml (3.2.5)
rolify (6.0.0) rolify (6.0.0)
rotp (6.2.0) rotp (6.2.0)
rpush (7.0.1)
activesupport (>= 5.2)
jwt (>= 1.5.6)
multi_json (~> 1.0)
net-http-persistent
net-http2 (~> 0.18, >= 0.18.3)
railties
rainbow
thor (>= 0.18.1, < 2.0)
webpush (~> 1.0)
rqrcode (2.1.2) rqrcode (2.1.2)
chunky_png (~> 1.0) chunky_png (~> 1.0)
rqrcode_core (~> 1.0) rqrcode_core (~> 1.0)
@ -506,6 +522,9 @@ GEM
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
railties (>= 5.2) railties (>= 5.2)
semantic_range (>= 2.3.0) semantic_range (>= 2.3.0)
webpush (1.1.0)
hkdf (~> 0.2)
jwt (~> 2.0)
websocket-driver (0.7.5) websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5) websocket-extensions (0.1.5)
@ -567,6 +586,7 @@ DEPENDENCIES
redcarpet redcarpet
redis redis
rolify (~> 6.0) rolify (~> 6.0)
rpush
rqrcode rqrcode
rspec-its (~> 1.3) rspec-its (~> 1.3)
rspec-mocks rspec-mocks

View File

@ -0,0 +1,136 @@
Rpush.configure do |config|
# Supported clients are :active_record and :redis
config.client = :active_record
# Options passed to Redis.new
# config.redis_options = {}
# Frequency in seconds to check for new notifications.
config.push_poll = 2
# The maximum number of notifications to load from the store every `push_poll` seconds.
# If some notifications are still enqueued internally, Rpush will load the batch_size less
# the number enqueued. An exception to this is if the service is able to receive multiple
# notification payloads over the connection with a single write, such as APNs.
config.batch_size = 100
# Path to write PID file. Relative to current directory unless absolute.
config.pid_file = 'tmp/rpush.pid'
# Path to log file. Relative to current directory unless absolute.
config.log_file = 'log/rpush.log'
config.log_level = (defined?(Rails) && Rails.logger) ? Rails.logger.level : ::Logger::Severity::INFO
# Define a custom logger.
# config.logger = MyLogger.new
# By default in foreground mode logs are directed both to the logger and to stdout.
# If the logger goes to stdout, you can disable foreground logging to avoid duplication.
# config.foreground_logging = false
# config.apns.feedback_receiver.enabled = true
# config.apns.feedback_receiver.frequency = 60
end
Rpush.reflect do |on|
# Called with a Rpush::Apns::Feedback instance when feedback is received
# from the APNs that a notification has failed to be delivered.
# Further notifications should not be sent to the device.
# on.apns_feedback do |feedback|
# end
# Called when a notification is queued internally for delivery.
# The internal queue for each app runner can be inspected:
#
# Rpush::Daemon::AppRunner.status
#
# on.notification_enqueued do |notification|
# end
# Called when a notification is successfully delivered.
# on.notification_delivered do |notification|
# end
# Called when notification delivery failed.
# Call 'error_code' and 'error_description' on the notification for the cause.
# on.notification_failed do |notification|
# end
# Called when the notification delivery failed and only the notification ID
# is present in memory.
# on.notification_id_failed do |app, notification_id, error_code, error_description|
# end
# Called when a notification will be retried at a later date.
# Call 'deliver_after' on the notification for the next delivery date
# and 'retries' for the number of times this notification has been retried.
# on.notification_will_retry do |notification|
# end
# Called when a notification will be retried and only the notification ID
# is present in memory.
# on.notification_id_will_retry do |app, notification_id, retry_after|
# end
# Called when a TCP connection is lost and will be reconnected.
# on.tcp_connection_lost do |app, error|
# end
# Called for each recipient which successfully receives a notification. This
# can occur more than once for the same notification when there are multiple
# recipients.
# on.gcm_delivered_to_recipient do |notification, registration_id|
# end
# Called for each recipient which fails to receive a notification. This
# can occur more than once for the same notification when there are multiple
# recipients. (do not handle invalid registration IDs here)
# on.gcm_failed_to_recipient do |notification, error, registration_id|
# end
# Called when the GCM returns a canonical registration ID.
# You will need to replace old_id with canonical_id in your records.
# on.gcm_canonical_id do |old_id, canonical_id|
# end
# Called when the GCM returns a failure that indicates an invalid registration id.
# You will need to delete the registration_id from your records.
# on.gcm_invalid_registration_id do |app, error, registration_id|
# end
# Called when an SSL certificate will expire within 1 month.
# Implement on.error to catch errors raised when the certificate expires.
# on.ssl_certificate_will_expire do |app, expiration_time|
# end
# Called when an SSL certificate has been revoked.
# on.ssl_certificate_revoked do |app, error|
# end
# Called when the ADM returns a canonical registration ID.
# You will need to replace old_id with canonical_id in your records.
# on.adm_canonical_id do |old_id, canonical_id|
# end
# Called when Failed to deliver to ADM. Check the 'reason' string for further
# explanations.
#
# If the reason is the string 'Unregistered', you should remove
# this registration id from your records.
# on.adm_failed_to_recipient do |notification, registration_id, reason|
# end
# Called when Failed to deliver to WNS. Check the 'reason' string for further
# explanations.
# You should remove this uri from your records
# on.wns_invalid_channel do |notification, uri, reason|
# end
# Called when an exception is raised.
# on.error do |error|
# end
end

View File

@ -0,0 +1,352 @@
# NOTE TO THE CURIOUS.
#
# Congratulations on being a diligent developer and vetting the migrations
# added to your project!
#
# You're probably thinking "This migration is huge!". It is, but that doesn't
# mean it'll take a long time to run, or that the reason for it being
# this size is because of lousy developers.
#
# Rpush used to be known as Rapns. In an effort to reduce clutter in db/migrate
# for new users of Rpush, what you see below is a concatenation of the
# migrations added to Rapns over its lifetime.
#
# The reason for concatenating old migrations - instead of producing a new
# one that attempts to recreate their accumulative state - is that I don't
# want to introduce any bugs by writing a new migration.
#
# So while this looks like a scary amount of code, it is in fact the safest
# approach. The constituent parts of this migration have been executed
# many times, by many people!
class AddRpush < ActiveRecord::Migration[5.0]
def self.migrations
[CreateRapnsNotifications, CreateRapnsFeedback,
AddAlertIsJsonToRapnsNotifications, AddAppToRapns,
CreateRapnsApps, AddGcm, AddWpns, AddAdm, RenameRapnsToRpush,
AddFailAfterToRpushNotifications]
end
def self.up
migrations.map(&:up)
end
def self.down
migrations.reverse.each do |m|
begin
m.down
rescue ActiveRecord::StatementInvalid => e
p e
end
end
end
class CreateRapnsNotifications < ActiveRecord::Migration[5.0]
def self.up
create_table :rapns_notifications do |t|
t.integer :badge, null: true
t.string :device_token, null: false, limit: 64
t.string :sound, null: true, default: "1.aiff"
t.string :alert, null: true
t.text :attributes_for_device, null: true
t.integer :expiry, null: false, default: 1.day.to_i
t.boolean :delivered, null: false, default: false
t.timestamp :delivered_at, null: true
t.boolean :failed, null: false, default: false
t.timestamp :failed_at, null: true
t.integer :error_code, null: true
t.string :error_description, null: true
t.timestamp :deliver_after, null: true
t.timestamps
end
add_index :rapns_notifications, [:delivered, :failed, :deliver_after], name: 'index_rapns_notifications_multi'
end
def self.down
if index_name_exists?(:rapns_notifications, 'index_rapns_notifications_multi')
remove_index :rapns_notifications, name: 'index_rapns_notifications_multi'
end
drop_table :rapns_notifications
end
end
class CreateRapnsFeedback < ActiveRecord::Migration[5.0]
def self.up
create_table :rapns_feedback do |t|
t.string :device_token, null: false, limit: 64
t.timestamp :failed_at, null: false
t.timestamps
end
add_index :rapns_feedback, :device_token
end
def self.down
if index_name_exists?(:rapns_feedback, :index_rapns_feedback_on_device_token)
remove_index :rapns_feedback, name: :index_rapns_feedback_on_device_token
end
drop_table :rapns_feedback
end
end
class AddAlertIsJsonToRapnsNotifications < ActiveRecord::Migration[5.0]
def self.up
add_column :rapns_notifications, :alert_is_json, :boolean, null: true, default: false
end
def self.down
remove_column :rapns_notifications, :alert_is_json
end
end
class AddAppToRapns < ActiveRecord::Migration[5.0]
def self.up
add_column :rapns_notifications, :app, :string, null: true
add_column :rapns_feedback, :app, :string, null: true
end
def self.down
remove_column :rapns_notifications, :app
remove_column :rapns_feedback, :app
end
end
class CreateRapnsApps < ActiveRecord::Migration[5.0]
def self.up
create_table :rapns_apps do |t|
t.string :key, null: false
t.string :environment, null: false
t.text :certificate, null: false
t.string :password, null: true
t.integer :connections, null: false, default: 1
t.timestamps
end
end
def self.down
drop_table :rapns_apps
end
end
class AddGcm < ActiveRecord::Migration[5.0]
module Rapns
class App < ActiveRecord::Base
self.table_name = 'rapns_apps'
end
class Notification < ActiveRecord::Base
belongs_to :app
self.table_name = 'rapns_notifications'
end
end
def self.up
add_column :rapns_notifications, :type, :string, null: true
add_column :rapns_apps, :type, :string, null: true
AddGcm::Rapns::Notification.update_all type: 'Rapns::Apns::Notification'
AddGcm::Rapns::App.update_all type: 'Rapns::Apns::App'
change_column :rapns_notifications, :type, :string, null: false
change_column :rapns_apps, :type, :string, null: false
change_column :rapns_notifications, :device_token, :string, null: true, limit: 64
change_column :rapns_notifications, :expiry, :integer, null: true, default: 1.day.to_i
change_column :rapns_apps, :environment, :string, null: true
change_column :rapns_apps, :certificate, :text, null: true, default: nil
change_column :rapns_notifications, :error_description, :text, null: true, default: nil
change_column :rapns_notifications, :sound, :string, default: 'default'
rename_column :rapns_notifications, :attributes_for_device, :data
rename_column :rapns_apps, :key, :name
add_column :rapns_apps, :auth_key, :string, null: true
add_column :rapns_notifications, :collapse_key, :string, null: true
add_column :rapns_notifications, :delay_while_idle, :boolean, null: false, default: false
reg_ids_type = ActiveRecord::Base.connection.adapter_name.include?('Mysql') ? :mediumtext : :text
add_column :rapns_notifications, :registration_ids, reg_ids_type, null: true
add_column :rapns_notifications, :app_id, :integer, null: true
add_column :rapns_notifications, :retries, :integer, null: true, default: 0
AddGcm::Rapns::Notification.reset_column_information
AddGcm::Rapns::App.reset_column_information
AddGcm::Rapns::App.all.each do |app|
AddGcm::Rapns::Notification.where(app: app.name).update_all(app_id: app.id)
end
change_column :rapns_notifications, :app_id, :integer, null: false
remove_column :rapns_notifications, :app
if index_name_exists?(:rapns_notifications, "index_rapns_notifications_multi")
remove_index :rapns_notifications, name: "index_rapns_notifications_multi"
elsif index_name_exists?(:rapns_notifications, "index_rapns_notifications_on_delivered_failed_deliver_after")
remove_index :rapns_notifications, name: "index_rapns_notifications_on_delivered_failed_deliver_after"
end
add_index :rapns_notifications, [:app_id, :delivered, :failed, :deliver_after], name: "index_rapns_notifications_multi"
end
def self.down
AddGcm::Rapns::Notification.where(type: 'Rapns::Gcm::Notification').delete_all
remove_column :rapns_notifications, :type
remove_column :rapns_apps, :type
change_column :rapns_notifications, :device_token, :string, null: false, limit: 64
change_column :rapns_notifications, :expiry, :integer, null: false, default: 1.day.to_i
change_column :rapns_apps, :environment, :string, null: false
change_column :rapns_apps, :certificate, :text, null: false
change_column :rapns_notifications, :error_description, :string, null: true, default: nil
change_column :rapns_notifications, :sound, :string, default: '1.aiff'
rename_column :rapns_notifications, :data, :attributes_for_device
rename_column :rapns_apps, :name, :key
remove_column :rapns_apps, :auth_key
remove_column :rapns_notifications, :collapse_key
remove_column :rapns_notifications, :delay_while_idle
remove_column :rapns_notifications, :registration_ids
remove_column :rapns_notifications, :retries
add_column :rapns_notifications, :app, :string, null: true
AddGcm::Rapns::Notification.reset_column_information
AddGcm::Rapns::App.reset_column_information
AddGcm::Rapns::App.all.each do |app|
AddGcm::Rapns::Notification.where(app_id: app.id).update_all(app: app.key)
end
if index_name_exists?(:rapns_notifications, :index_rapns_notifications_multi)
remove_index :rapns_notifications, name: :index_rapns_notifications_multi
end
remove_column :rapns_notifications, :app_id
add_index :rapns_notifications, [:delivered, :failed, :deliver_after], name: :index_rapns_notifications_multi
end
end
class AddWpns < ActiveRecord::Migration[5.0]
module Rapns
class Notification < ActiveRecord::Base
self.table_name = 'rapns_notifications'
end
end
def self.up
add_column :rapns_notifications, :uri, :string, null: true
end
def self.down
AddWpns::Rapns::Notification.where(type: 'Rapns::Wpns::Notification').delete_all
remove_column :rapns_notifications, :uri
end
end
class AddAdm < ActiveRecord::Migration[5.0]
module Rapns
class Notification < ActiveRecord::Base
self.table_name = 'rapns_notifications'
end
end
def self.up
add_column :rapns_apps, :client_id, :string, null: true
add_column :rapns_apps, :client_secret, :string, null: true
add_column :rapns_apps, :access_token, :string, null: true
add_column :rapns_apps, :access_token_expiration, :datetime, null: true
end
def self.down
AddAdm::Rapns::Notification.where(type: 'Rapns::Adm::Notification').delete_all
remove_column :rapns_apps, :client_id
remove_column :rapns_apps, :client_secret
remove_column :rapns_apps, :access_token
remove_column :rapns_apps, :access_token_expiration
end
end
class RenameRapnsToRpush < ActiveRecord::Migration[5.0]
module Rpush
class App < ActiveRecord::Base
self.table_name = 'rpush_apps'
end
class Notification < ActiveRecord::Base
self.table_name = 'rpush_notifications'
end
end
def self.update_type(model, from, to)
model.where(type: from).update_all(type: to)
end
def self.up
rename_table :rapns_notifications, :rpush_notifications
rename_table :rapns_apps, :rpush_apps
rename_table :rapns_feedback, :rpush_feedback
if index_name_exists?(:rpush_notifications, :index_rapns_notifications_multi)
rename_index :rpush_notifications, :index_rapns_notifications_multi, :index_rpush_notifications_multi
end
if index_name_exists?(:rpush_feedback, :index_rapns_feedback_on_device_token)
rename_index :rpush_feedback, :index_rapns_feedback_on_device_token, :index_rpush_feedback_on_device_token
end
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rapns::Apns::Notification', 'Rpush::Apns::Notification')
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rapns::Gcm::Notification', 'Rpush::Gcm::Notification')
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rapns::Adm::Notification', 'Rpush::Adm::Notification')
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rapns::Wpns::Notification', 'Rpush::Wpns::Notification')
update_type(RenameRapnsToRpush::Rpush::App, 'Rapns::Apns::App', 'Rpush::Apns::App')
update_type(RenameRapnsToRpush::Rpush::App, 'Rapns::Gcm::App', 'Rpush::Gcm::App')
update_type(RenameRapnsToRpush::Rpush::App, 'Rapns::Adm::App', 'Rpush::Adm::App')
update_type(RenameRapnsToRpush::Rpush::App, 'Rapns::Wpns::App', 'Rpush::Wpns::App')
end
def self.down
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rpush::Apns::Notification', 'Rapns::Apns::Notification')
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rpush::Gcm::Notification', 'Rapns::Gcm::Notification')
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rpush::Adm::Notification', 'Rapns::Adm::Notification')
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rpush::Wpns::Notification', 'Rapns::Wpns::Notification')
update_type(RenameRapnsToRpush::Rpush::App, 'Rpush::Apns::App', 'Rapns::Apns::App')
update_type(RenameRapnsToRpush::Rpush::App, 'Rpush::Gcm::App', 'Rapns::Gcm::App')
update_type(RenameRapnsToRpush::Rpush::App, 'Rpush::Adm::App', 'Rapns::Adm::App')
update_type(RenameRapnsToRpush::Rpush::App, 'Rpush::Wpns::App', 'Rapns::Wpns::App')
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
rename_index :rpush_notifications, :index_rpush_notifications_multi, :index_rapns_notifications_multi
end
if index_name_exists?(:rpush_feedback, :index_rpush_feedback_on_device_token)
rename_index :rpush_feedback, :index_rpush_feedback_on_device_token, :index_rapns_feedback_on_device_token
end
rename_table :rpush_notifications, :rapns_notifications
rename_table :rpush_apps, :rapns_apps
rename_table :rpush_feedback, :rapns_feedback
end
end
class AddFailAfterToRpushNotifications < ActiveRecord::Migration[5.0]
def self.up
add_column :rpush_notifications, :fail_after, :timestamp, null: true
end
def self.down
remove_column :rpush_notifications, :fail_after
end
end
end

View File

@ -0,0 +1,71 @@
class Rpush200Updates < ActiveRecord::Migration[5.0]
module Rpush
class App < ActiveRecord::Base
self.table_name = 'rpush_apps'
end
class Notification < ActiveRecord::Base
self.table_name = 'rpush_notifications'
end
end
def self.update_type(model, from, to)
model.where(type: from).update_all(type: to)
end
def self.up
add_column :rpush_notifications, :processing, :boolean, null: false, default: false
add_column :rpush_notifications, :priority, :integer, null: true
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
end
add_index :rpush_notifications, [:delivered, :failed], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
rename_column :rpush_feedback, :app, :app_id
if postgresql?
execute('ALTER TABLE rpush_feedback ALTER COLUMN app_id TYPE integer USING (trim(app_id)::integer)')
else
change_column :rpush_feedback, :app_id, :integer
end
[:Apns, :Gcm, :Wpns, :Adm].each do |service|
update_type(Rpush200Updates::Rpush::App, "Rpush::#{service}::App", "Rpush::Client::ActiveRecord::#{service}::App")
update_type(Rpush200Updates::Rpush::Notification, "Rpush::#{service}::Notification", "Rpush::Client::ActiveRecord::#{service}::Notification")
end
end
def self.down
[:Apns, :Gcm, :Wpns, :Adm].each do |service|
update_type(Rpush200Updates::Rpush::App, "Rpush::Client::ActiveRecord::#{service}::App", "Rpush::#{service}::App")
update_type(Rpush200Updates::Rpush::Notification, "Rpush::Client::ActiveRecord::#{service}::Notification", "Rpush::#{service}::Notification")
end
change_column :rpush_feedback, :app_id, :string
rename_column :rpush_feedback, :app_id, :app
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
end
add_index :rpush_notifications, [:app_id, :delivered, :failed, :deliver_after], name: 'index_rpush_notifications_multi'
remove_column :rpush_notifications, :priority
remove_column :rpush_notifications, :processing
end
def self.adapter_name
env = (defined?(Rails) && Rails.env) ? Rails.env : 'development'
if ActiveRecord::VERSION::MAJOR > 6
ActiveRecord::Base.configurations.configs_for(env_name: env).first.configuration_hash[:adapter]
else
Hash[ActiveRecord::Base.configurations[env].map { |k,v| [k.to_sym,v] }][:adapter]
end
end
def self.postgresql?
adapter_name =~ /postgresql|postgis/
end
end

View File

@ -0,0 +1,11 @@
class Rpush210Updates < ActiveRecord::Migration[5.0]
def self.up
add_column :rpush_notifications, :url_args, :text, null: true
add_column :rpush_notifications, :category, :string, null: true
end
def self.down
remove_column :rpush_notifications, :url_args
remove_column :rpush_notifications, :category
end
end

View File

@ -0,0 +1,10 @@
class Rpush260Updates < ActiveRecord::Migration[5.0]
def self.up
add_column :rpush_notifications, :content_available, :boolean, default: false
end
def self.down
remove_column :rpush_notifications, :content_available
end
end

View File

@ -0,0 +1,12 @@
class Rpush270Updates < ActiveRecord::Migration[5.0]
def self.up
change_column :rpush_notifications, :alert, :text
add_column :rpush_notifications, :notification, :text
end
def self.down
change_column :rpush_notifications, :alert, :string
remove_column :rpush_notifications, :notification
end
end

View File

@ -0,0 +1,11 @@
class Rpush300Updates < ActiveRecord::Migration[5.0]
def self.up
add_column :rpush_notifications, :mutable_content, :boolean, default: false
change_column :rpush_notifications, :sound, :string, default: nil
end
def self.down
remove_column :rpush_notifications, :mutable_content
change_column :rpush_notifications, :sound, :string, default: 'default'
end
end

View File

@ -0,0 +1,13 @@
class Rpush301Updates < ActiveRecord::Migration[5.0]
def self.up
change_column_null :rpush_notifications, :mutable_content, false
change_column_null :rpush_notifications, :content_available, false
change_column_null :rpush_notifications, :alert_is_json, false
end
def self.down
change_column_null :rpush_notifications, :mutable_content, true
change_column_null :rpush_notifications, :content_available, true
change_column_null :rpush_notifications, :alert_is_json, true
end
end

View File

@ -0,0 +1,9 @@
class Rpush310AddPushy < ActiveRecord::Migration[5.0]
def self.up
add_column :rpush_notifications, :external_device_id, :string, null: true
end
def self.down
remove_column :rpush_notifications, :external_device_id
end
end

View File

@ -0,0 +1,15 @@
class Rpush311Updates < ActiveRecord::Migration[5.0]
def self.up
change_table :rpush_notifications do |t|
t.remove_index name: 'index_rpush_notifications_multi'
t.index [:delivered, :failed, :processing, :deliver_after, :created_at], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
end
end
def self.down
change_table :rpush_notifications do |t|
t.remove_index name: 'index_rpush_notifications_multi'
t.index [:delivered, :failed], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
end
end
end

View File

@ -0,0 +1,15 @@
class Rpush320AddApnsP8 < ActiveRecord::Migration[5.0]
def self.up
add_column :rpush_apps, :apn_key, :string, null: true
add_column :rpush_apps, :apn_key_id, :string, null: true
add_column :rpush_apps, :team_id, :string, null: true
add_column :rpush_apps, :bundle_id, :string, null: true
end
def self.down
remove_column :rpush_apps, :apn_key
remove_column :rpush_apps, :apn_key_id
remove_column :rpush_apps, :team_id
remove_column :rpush_apps, :bundle_id
end
end

View File

@ -0,0 +1,9 @@
class Rpush324Updates < ActiveRecord::Migration[5.0]
def self.up
change_column :rpush_apps, :apn_key, :text, null: true
end
def self.down
change_column :rpush_apps, :apn_key, :string, null: true
end
end

View File

@ -0,0 +1,9 @@
class Rpush330Updates < ActiveRecord::Migration[5.0]
def self.up
add_column :rpush_notifications, :thread_id, :string, null: true
end
def self.down
remove_column :rpush_notifications, :thread_id
end
end

View File

@ -0,0 +1,11 @@
class Rpush331Updates < ActiveRecord::Migration[5.0]
def self.up
change_column :rpush_notifications, :device_token, :string, null: true
change_column :rpush_feedback, :device_token, :string, null: true
end
def self.down
change_column :rpush_notifications, :device_token, :string, null: true, limit: 64
change_column :rpush_feedback, :device_token, :string, null: true, limit: 64
end
end

View File

@ -0,0 +1,9 @@
class Rpush410Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
def self.up
add_column :rpush_notifications, :dry_run, :boolean, null: false, default: false
end
def self.down
remove_column :rpush_notifications, :dry_run
end
end

View File

@ -0,0 +1,9 @@
class Rpush411Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
def self.up
add_column :rpush_apps, :feedback_enabled, :boolean, default: true
end
def self.down
remove_column :rpush_apps, :feedback_enabled
end
end

View File

@ -0,0 +1,10 @@
class Rpush420Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
def self.up
add_column :rpush_notifications, :sound_is_json, :boolean, null: true, default: false
end
def self.down
remove_column :rpush_notifications, :sound_is_json
end
end

View File

@ -183,6 +183,75 @@ ActiveRecord::Schema.define(version: 2022_12_27_065923) do
t.index ["resource_type", "resource_id"], name: "index_roles_on_resource" t.index ["resource_type", "resource_id"], name: "index_roles_on_resource"
end end
create_table "rpush_apps", force: :cascade do |t|
t.string "name", null: false
t.string "environment"
t.text "certificate"
t.string "password"
t.integer "connections", default: 1, null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "type", null: false
t.string "auth_key"
t.string "client_id"
t.string "client_secret"
t.string "access_token"
t.datetime "access_token_expiration"
t.text "apn_key"
t.string "apn_key_id"
t.string "team_id"
t.string "bundle_id"
t.boolean "feedback_enabled", default: true
end
create_table "rpush_feedback", force: :cascade do |t|
t.string "device_token"
t.datetime "failed_at", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "app_id"
t.index ["device_token"], name: "index_rpush_feedback_on_device_token"
end
create_table "rpush_notifications", force: :cascade do |t|
t.integer "badge"
t.string "device_token"
t.string "sound"
t.text "alert"
t.text "data"
t.integer "expiry", default: 86400
t.boolean "delivered", default: false, null: false
t.datetime "delivered_at"
t.boolean "failed", default: false, null: false
t.datetime "failed_at"
t.integer "error_code"
t.text "error_description"
t.datetime "deliver_after"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.boolean "alert_is_json", default: false, null: false
t.string "type", null: false
t.string "collapse_key"
t.boolean "delay_while_idle", default: false, null: false
t.text "registration_ids"
t.integer "app_id", null: false
t.integer "retries", default: 0
t.string "uri"
t.datetime "fail_after"
t.boolean "processing", default: false, null: false
t.integer "priority"
t.text "url_args"
t.string "category"
t.boolean "content_available", default: false, null: false
t.text "notification"
t.boolean "mutable_content", default: false, null: false
t.string "external_device_id"
t.string "thread_id"
t.boolean "dry_run", default: false, null: false
t.boolean "sound_is_json", default: false
t.index ["delivered", "failed", "processing", "deliver_after", "created_at"], name: "index_rpush_notifications_multi", where: "((NOT delivered) AND (NOT failed))"
end
create_table "services", id: :serial, force: :cascade do |t| create_table "services", id: :serial, force: :cascade do |t|
t.string "type", null: false t.string "type", null: false
t.bigint "user_id", null: false t.bigint "user_id", null: false