rpush 1.0.0 → 2.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +12 -14
- data/bin/rpush +11 -2
- data/lib/generators/rpush_generator.rb +2 -0
- data/lib/generators/templates/add_adm.rb +5 -5
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +1 -1
- data/lib/generators/templates/add_app_to_rapns.rb +2 -2
- data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
- data/lib/generators/templates/add_gcm.rb +32 -32
- data/lib/generators/templates/add_rpush.rb +67 -67
- data/lib/generators/templates/add_wpns.rb +2 -2
- data/lib/generators/templates/create_rapns_apps.rb +5 -5
- data/lib/generators/templates/create_rapns_feedback.rb +2 -2
- data/lib/generators/templates/create_rapns_notifications.rb +15 -15
- data/lib/generators/templates/rpush.rb +10 -7
- data/lib/generators/templates/rpush_2_0_0_updates.rb +23 -0
- data/lib/rpush.rb +4 -28
- data/lib/rpush/client/active_model.rb +21 -0
- data/lib/rpush/client/active_model/adm/app.rb +23 -0
- data/lib/rpush/client/active_model/adm/data_validator.rb +14 -0
- data/lib/rpush/client/active_model/adm/notification.rb +28 -0
- data/lib/rpush/client/active_model/apns/app.rb +37 -0
- data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +16 -0
- data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +14 -0
- data/lib/rpush/client/active_model/apns/notification.rb +90 -0
- data/lib/rpush/client/active_model/gcm/app.rb +19 -0
- data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
- data/lib/rpush/client/active_model/gcm/notification.rb +31 -0
- data/lib/rpush/client/active_model/notification.rb +26 -0
- data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
- data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
- data/lib/rpush/client/active_model/wpns/app.rb +13 -0
- data/lib/rpush/client/active_model/wpns/notification.rb +17 -0
- data/lib/rpush/client/active_record.rb +19 -0
- data/lib/rpush/client/active_record/adm/app.rb +11 -0
- data/lib/rpush/client/active_record/adm/notification.rb +11 -0
- data/lib/rpush/client/active_record/apns/app.rb +11 -0
- data/lib/rpush/client/active_record/apns/feedback.rb +20 -0
- data/lib/rpush/client/active_record/apns/notification.rb +46 -0
- data/lib/rpush/client/active_record/app.rb +17 -0
- data/lib/rpush/client/active_record/gcm/app.rb +11 -0
- data/lib/rpush/client/active_record/gcm/notification.rb +11 -0
- data/lib/rpush/client/active_record/notification.rb +38 -0
- data/lib/rpush/client/active_record/wpns/app.rb +11 -0
- data/lib/rpush/client/active_record/wpns/notification.rb +11 -0
- data/lib/rpush/client/redis.rb +35 -0
- data/lib/rpush/client/redis/adm/app.rb +14 -0
- data/lib/rpush/client/redis/adm/notification.rb +11 -0
- data/lib/rpush/client/redis/apns/app.rb +11 -0
- data/lib/rpush/client/redis/apns/feedback.rb +20 -0
- data/lib/rpush/client/redis/apns/notification.rb +11 -0
- data/lib/rpush/client/redis/app.rb +22 -0
- data/lib/rpush/client/redis/gcm/app.rb +11 -0
- data/lib/rpush/client/redis/gcm/notification.rb +11 -0
- data/lib/rpush/client/redis/notification.rb +68 -0
- data/lib/rpush/client/redis/wpns/app.rb +11 -0
- data/lib/rpush/client/redis/wpns/notification.rb +11 -0
- data/lib/rpush/configuration.rb +27 -6
- data/lib/rpush/daemon.rb +36 -56
- data/lib/rpush/daemon/adm/delivery.rb +50 -52
- data/lib/rpush/daemon/apns.rb +6 -5
- data/lib/rpush/daemon/apns/delivery.rb +20 -44
- data/lib/rpush/daemon/apns/feedback_receiver.rb +11 -8
- data/lib/rpush/daemon/app_runner.rb +67 -60
- data/lib/rpush/daemon/batch.rb +54 -40
- data/lib/rpush/daemon/delivery.rb +13 -3
- data/lib/rpush/daemon/delivery_error.rb +10 -2
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +106 -0
- data/lib/rpush/daemon/dispatcher/http.rb +3 -3
- data/lib/rpush/daemon/dispatcher/tcp.rb +3 -3
- data/lib/rpush/daemon/dispatcher_loop.rb +15 -6
- data/lib/rpush/daemon/errors.rb +18 -0
- data/lib/rpush/daemon/feeder.rb +28 -39
- data/lib/rpush/daemon/gcm/delivery.rb +19 -20
- data/lib/rpush/daemon/interruptible_sleep.rb +26 -45
- data/lib/rpush/daemon/loggable.rb +2 -4
- data/lib/rpush/daemon/proc_title.rb +16 -0
- data/lib/rpush/daemon/queue_payload.rb +12 -0
- data/lib/rpush/daemon/reflectable.rb +3 -5
- data/lib/rpush/daemon/retry_header_parser.rb +6 -6
- data/lib/rpush/daemon/ring_buffer.rb +16 -0
- data/lib/rpush/daemon/service_config_methods.rb +23 -7
- data/lib/rpush/daemon/signal_handler.rb +51 -0
- data/lib/rpush/daemon/store/active_record.rb +71 -38
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +15 -15
- data/lib/rpush/daemon/store/interface.rb +19 -0
- data/lib/rpush/daemon/store/redis.rb +149 -0
- data/lib/rpush/daemon/tcp_connection.rb +6 -11
- data/lib/rpush/daemon/wpns/delivery.rb +21 -30
- data/lib/rpush/deprecatable.rb +4 -3
- data/lib/rpush/deprecation.rb +7 -10
- data/lib/rpush/embed.rb +7 -2
- data/lib/rpush/logger.rb +11 -15
- data/lib/rpush/push.rb +0 -1
- data/lib/rpush/reflection.rb +6 -12
- data/lib/rpush/version.rb +1 -1
- data/lib/tasks/quality.rake +34 -0
- data/spec/.rubocop.yml +4 -0
- data/spec/functional/adm_spec.rb +3 -6
- data/spec/functional/apns_spec.rb +118 -24
- data/spec/functional/embed_spec.rb +22 -20
- data/spec/functional/gcm_spec.rb +4 -7
- data/spec/functional/new_app_spec.rb +61 -0
- data/spec/functional/retry_spec.rb +46 -0
- data/spec/functional/wpns_spec.rb +3 -6
- data/spec/functional_spec_helper.rb +26 -0
- data/spec/integration/rpush_spec.rb +13 -0
- data/spec/integration/support/gcm_success_response.json +1 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/active_record_setup.rb +48 -0
- data/{config → spec/support/config}/database.yml +0 -0
- data/spec/support/install.sh +43 -7
- data/spec/support/simplecov_helper.rb +9 -5
- data/spec/support/simplecov_quality_formatter.rb +10 -6
- data/spec/unit/apns_feedback_spec.rb +3 -3
- data/spec/unit/{adm → client/active_record/adm}/app_spec.rb +3 -3
- data/spec/unit/{adm → client/active_record/adm}/notification_spec.rb +5 -7
- data/spec/unit/client/active_record/apns/app_spec.rb +29 -0
- data/spec/unit/client/active_record/apns/feedback_spec.rb +9 -0
- data/spec/unit/client/active_record/apns/notification_spec.rb +231 -0
- data/spec/unit/client/active_record/app_spec.rb +30 -0
- data/spec/unit/client/active_record/gcm/app_spec.rb +4 -0
- data/spec/unit/{gcm → client/active_record/gcm}/notification_spec.rb +5 -7
- data/spec/unit/client/active_record/notification_spec.rb +15 -0
- data/spec/unit/client/active_record/wpns/app_spec.rb +4 -0
- data/spec/unit/client/active_record/wpns/notification_spec.rb +21 -0
- data/spec/unit/configuration_spec.rb +12 -5
- data/spec/unit/daemon/adm/delivery_spec.rb +57 -54
- data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +3 -3
- data/spec/unit/daemon/apns/delivery_spec.rb +90 -83
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +24 -17
- data/spec/unit/daemon/app_runner_spec.rb +66 -123
- data/spec/unit/daemon/batch_spec.rb +52 -115
- data/spec/unit/daemon/delivery_spec.rb +15 -1
- data/spec/unit/daemon/dispatcher/http_spec.rb +3 -2
- data/spec/unit/daemon/dispatcher/tcp_spec.rb +10 -9
- data/spec/unit/daemon/dispatcher_loop_spec.rb +7 -12
- data/spec/unit/daemon/feeder_spec.rb +40 -39
- data/spec/unit/daemon/gcm/delivery_spec.rb +108 -89
- data/spec/unit/daemon/reflectable_spec.rb +2 -2
- data/spec/unit/daemon/retryable_error_spec.rb +1 -1
- data/spec/unit/daemon/service_config_methods_spec.rb +6 -3
- data/spec/unit/daemon/signal_handler_spec.rb +72 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +9 -9
- data/spec/unit/daemon/store/active_record_spec.rb +38 -47
- data/spec/unit/daemon/tcp_connection_spec.rb +22 -34
- data/spec/unit/daemon/too_many_requests_error_spec.rb +1 -1
- data/spec/unit/daemon/wpns/delivery_spec.rb +61 -50
- data/spec/unit/daemon_spec.rb +46 -81
- data/spec/unit/embed_spec.rb +4 -2
- data/spec/unit/logger_spec.rb +30 -40
- data/spec/unit/notification_shared.rb +9 -79
- data/spec/unit/push_spec.rb +3 -8
- data/spec/unit/reflection_spec.rb +25 -25
- data/spec/unit/rpush_spec.rb +1 -2
- data/spec/unit_spec_helper.rb +33 -88
- metadata +119 -67
- data/lib/rpush/TODO +0 -3
- data/lib/rpush/adm/app.rb +0 -15
- data/lib/rpush/adm/data_validator.rb +0 -11
- data/lib/rpush/adm/notification.rb +0 -29
- data/lib/rpush/apns/app.rb +0 -29
- data/lib/rpush/apns/binary_notification_validator.rb +0 -12
- data/lib/rpush/apns/device_token_format_validator.rb +0 -12
- data/lib/rpush/apns/feedback.rb +0 -16
- data/lib/rpush/apns/notification.rb +0 -84
- data/lib/rpush/app.rb +0 -18
- data/lib/rpush/daemon/apns/certificate_expired_error.rb +0 -20
- data/lib/rpush/daemon/apns/disconnection_error.rb +0 -20
- data/lib/rpush/gcm/app.rb +0 -11
- data/lib/rpush/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +0 -11
- data/lib/rpush/gcm/notification.rb +0 -30
- data/lib/rpush/notification.rb +0 -69
- data/lib/rpush/notifier.rb +0 -52
- data/lib/rpush/payload_data_size_validator.rb +0 -10
- data/lib/rpush/railtie.rb +0 -11
- data/lib/rpush/registration_ids_count_validator.rb +0 -10
- data/lib/rpush/wpns/app.rb +0 -9
- data/lib/rpush/wpns/notification.rb +0 -26
- data/lib/tasks/cane.rake +0 -18
- data/lib/tasks/rpush.rake +0 -16
- data/spec/unit/apns/app_spec.rb +0 -29
- data/spec/unit/apns/feedback_spec.rb +0 -9
- data/spec/unit/apns/notification_spec.rb +0 -208
- data/spec/unit/app_spec.rb +0 -30
- data/spec/unit/daemon/apns/disconnection_error_spec.rb +0 -18
- data/spec/unit/daemon/interruptible_sleep_spec.rb +0 -68
- data/spec/unit/gcm/app_spec.rb +0 -4
- data/spec/unit/notification_spec.rb +0 -15
- data/spec/unit/notifier_spec.rb +0 -49
- data/spec/unit/wpns/app_spec.rb +0 -4
- data/spec/unit/wpns/notification_spec.rb +0 -30
|
@@ -6,11 +6,11 @@ class AddWpns < ActiveRecord::Migration
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def self.up
|
|
9
|
-
add_column :rapns_notifications, :uri, :string, :
|
|
9
|
+
add_column :rapns_notifications, :uri, :string, null: true
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def self.down
|
|
13
|
-
AddWpns::Rapns::Notification.where(:
|
|
13
|
+
AddWpns::Rapns::Notification.where(type: 'Rapns::Wpns::Notification').delete_all
|
|
14
14
|
remove_column :rapns_notifications, :uri
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
class CreateRapnsApps < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
|
3
3
|
create_table :rapns_apps do |t|
|
|
4
|
-
t.string :key, :
|
|
5
|
-
t.string :environment, :
|
|
6
|
-
t.text :certificate, :
|
|
7
|
-
t.string :password, :
|
|
8
|
-
t.integer :connections, :
|
|
4
|
+
t.string :key, null: false
|
|
5
|
+
t.string :environment, null: false
|
|
6
|
+
t.text :certificate, null: false
|
|
7
|
+
t.string :password, null: true
|
|
8
|
+
t.integer :connections, null: false, default: 1
|
|
9
9
|
t.timestamps
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
class CreateRapnsFeedback < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
|
3
3
|
create_table :rapns_feedback do |t|
|
|
4
|
-
t.string :device_token, :
|
|
5
|
-
t.timestamp :failed_at, :
|
|
4
|
+
t.string :device_token, null: false, limit: 64
|
|
5
|
+
t.timestamp :failed_at, null: false
|
|
6
6
|
t.timestamps
|
|
7
7
|
end
|
|
8
8
|
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
class CreateRapnsNotifications < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
|
3
3
|
create_table :rapns_notifications do |t|
|
|
4
|
-
t.integer :badge, :
|
|
5
|
-
t.string :device_token, :
|
|
6
|
-
t.string :sound, :
|
|
7
|
-
t.string :alert, :
|
|
8
|
-
t.text :attributes_for_device, :
|
|
9
|
-
t.integer :expiry, :
|
|
10
|
-
t.boolean :delivered, :
|
|
11
|
-
t.timestamp :delivered_at, :
|
|
12
|
-
t.boolean :failed, :
|
|
13
|
-
t.timestamp :failed_at, :
|
|
14
|
-
t.integer :error_code, :
|
|
15
|
-
t.string :error_description, :
|
|
16
|
-
t.timestamp :deliver_after, :
|
|
4
|
+
t.integer :badge, null: true
|
|
5
|
+
t.string :device_token, null: false, limit: 64
|
|
6
|
+
t.string :sound, null: true, default: "1.aiff"
|
|
7
|
+
t.string :alert, null: true
|
|
8
|
+
t.text :attributes_for_device, null: true
|
|
9
|
+
t.integer :expiry, null: false, default: 1.day.to_i
|
|
10
|
+
t.boolean :delivered, null: false, default: false
|
|
11
|
+
t.timestamp :delivered_at, null: true
|
|
12
|
+
t.boolean :failed, null: false, default: false
|
|
13
|
+
t.timestamp :failed_at, null: true
|
|
14
|
+
t.integer :error_code, null: true
|
|
15
|
+
t.string :error_description, null: true
|
|
16
|
+
t.timestamp :deliver_after, null: true
|
|
17
17
|
t.timestamps
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
add_index :rapns_notifications, [:delivered, :failed, :deliver_after], :
|
|
20
|
+
add_index :rapns_notifications, [:delivered, :failed, :deliver_after], name: 'index_rapns_notifications_multi'
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def self.down
|
|
24
24
|
if index_name_exists?(:rapns_notifications, 'index_rapns_notifications_multi', true)
|
|
25
|
-
remove_index :rapns_notifications, :
|
|
25
|
+
remove_index :rapns_notifications, name: 'index_rapns_notifications_multi'
|
|
26
26
|
end
|
|
27
27
|
drop_table :rapns_notifications
|
|
28
28
|
end
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Rpush.configure do |config|
|
|
4
4
|
|
|
5
|
+
# Supported clients are :active_record and :redis.
|
|
6
|
+
# config.client = :active_record
|
|
7
|
+
|
|
8
|
+
# Options passed to Redis.new
|
|
9
|
+
# config.redis_options = {}
|
|
10
|
+
|
|
5
11
|
# Run in the foreground?
|
|
6
12
|
# config.foreground = false
|
|
7
13
|
|
|
@@ -11,15 +17,12 @@
|
|
|
11
17
|
# Frequency in seconds to check for feedback
|
|
12
18
|
# config.feedback_poll = 60
|
|
13
19
|
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
#
|
|
20
|
+
# The maximum number of notifications to load from the store every `push_poll` seconds.
|
|
21
|
+
# If some notifications are still enqueued internally, Rpush will load the batch_size less
|
|
22
|
+
# the number enqueued. An exception to this is if the service is able to receive multiple
|
|
23
|
+
# notification payloads over the connection with a single write, such as APNs.
|
|
18
24
|
# config.batch_size = 100
|
|
19
25
|
|
|
20
|
-
# Perform updates to the storage backend in batches to reduce IO.
|
|
21
|
-
# config.batch_storage_updates = true
|
|
22
|
-
|
|
23
26
|
# Path to write PID file. Relative to Rails root unless absolute.
|
|
24
27
|
# config.pid_file = '/path/to/rpush.pid'
|
|
25
28
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Rpush200Updates < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
add_column :rpush_notifications, :processing, :boolean, null: false, default: false
|
|
4
|
+
add_column :rpush_notifications, :priority, :integer, null: true
|
|
5
|
+
|
|
6
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
|
|
7
|
+
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
add_index :rpush_notifications, [:processing, :delivered, :failed, :deliver_after], name: 'index_rpush_notifications_multi'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.down
|
|
14
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
|
|
15
|
+
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
add_index :rpush_notifications, [:app_id, :delivered, :failed, :deliver_after], name: 'index_rpush_notifications_multi'
|
|
19
|
+
|
|
20
|
+
remove_column :rpush_notifications, :priority
|
|
21
|
+
remove_column :rpush_notifications, :processing
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/rpush.rb
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
require 'active_record'
|
|
2
1
|
require 'multi_json'
|
|
2
|
+
require 'active_support/all'
|
|
3
3
|
|
|
4
4
|
module Rpush
|
|
5
5
|
def self.attr_accessible_available?
|
|
6
6
|
require 'rails'
|
|
7
7
|
::Rails::VERSION::STRING < '4'
|
|
8
8
|
end
|
|
9
|
-
|
|
10
|
-
require 'rpush/railtie' if defined?(Rails)
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
require 'rpush/version'
|
|
@@ -15,33 +13,11 @@ require 'rpush/deprecation'
|
|
|
15
13
|
require 'rpush/deprecatable'
|
|
16
14
|
require 'rpush/logger'
|
|
17
15
|
require 'rpush/multi_json_helper'
|
|
18
|
-
require 'rpush/notification'
|
|
19
|
-
require 'rpush/app'
|
|
20
16
|
require 'rpush/configuration'
|
|
21
17
|
require 'rpush/reflection'
|
|
22
18
|
require 'rpush/embed'
|
|
23
19
|
require 'rpush/push'
|
|
24
20
|
require 'rpush/apns_feedback'
|
|
25
|
-
require 'rpush/notifier'
|
|
26
|
-
require 'rpush/payload_data_size_validator'
|
|
27
|
-
require 'rpush/registration_ids_count_validator'
|
|
28
|
-
|
|
29
|
-
require 'rpush/apns/binary_notification_validator'
|
|
30
|
-
require 'rpush/apns/device_token_format_validator'
|
|
31
|
-
require 'rpush/apns/notification'
|
|
32
|
-
require 'rpush/apns/feedback'
|
|
33
|
-
require 'rpush/apns/app'
|
|
34
|
-
|
|
35
|
-
require 'rpush/gcm/expiry_collapse_key_mutual_inclusion_validator'
|
|
36
|
-
require 'rpush/gcm/notification'
|
|
37
|
-
require 'rpush/gcm/app'
|
|
38
|
-
|
|
39
|
-
require 'rpush/wpns/notification'
|
|
40
|
-
require 'rpush/wpns/app'
|
|
41
|
-
|
|
42
|
-
require 'rpush/adm/data_validator'
|
|
43
|
-
require 'rpush/adm/notification'
|
|
44
|
-
require 'rpush/adm/app'
|
|
45
21
|
|
|
46
22
|
module Rpush
|
|
47
23
|
def self.jruby?
|
|
@@ -53,10 +29,10 @@ module Rpush
|
|
|
53
29
|
end
|
|
54
30
|
|
|
55
31
|
def self.logger
|
|
56
|
-
@logger ||= Logger.new
|
|
32
|
+
@logger ||= Logger.new
|
|
57
33
|
end
|
|
58
34
|
|
|
59
|
-
|
|
60
|
-
|
|
35
|
+
class << self
|
|
36
|
+
attr_writer :logger
|
|
61
37
|
end
|
|
62
38
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'active_model'
|
|
2
|
+
|
|
3
|
+
require 'rpush/client/active_model/notification'
|
|
4
|
+
require 'rpush/client/active_model/payload_data_size_validator'
|
|
5
|
+
require 'rpush/client/active_model/registration_ids_count_validator'
|
|
6
|
+
|
|
7
|
+
require 'rpush/client/active_model/apns/binary_notification_validator'
|
|
8
|
+
require 'rpush/client/active_model/apns/device_token_format_validator'
|
|
9
|
+
require 'rpush/client/active_model/apns/app'
|
|
10
|
+
require 'rpush/client/active_model/apns/notification'
|
|
11
|
+
|
|
12
|
+
require 'rpush/client/active_model/adm/data_validator'
|
|
13
|
+
require 'rpush/client/active_model/adm/app'
|
|
14
|
+
require 'rpush/client/active_model/adm/notification'
|
|
15
|
+
|
|
16
|
+
require 'rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator'
|
|
17
|
+
require 'rpush/client/active_model/gcm/app'
|
|
18
|
+
require 'rpush/client/active_model/gcm/notification'
|
|
19
|
+
|
|
20
|
+
require 'rpush/client/active_model/wpns/app'
|
|
21
|
+
require 'rpush/client/active_model/wpns/notification'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Adm
|
|
5
|
+
module App
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.instance_eval do
|
|
8
|
+
validates :client_id, :client_secret, presence: true
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def access_token_expired?
|
|
13
|
+
access_token_expiration.nil? || access_token_expiration < Time.now
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def service_name
|
|
17
|
+
'adm'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Adm
|
|
5
|
+
class DataValidator < ::ActiveModel::Validator
|
|
6
|
+
def validate(record)
|
|
7
|
+
return unless record.collapse_key.nil? && record.data.nil?
|
|
8
|
+
record.errors[:data] << 'must be set unless collapse_key is specified'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Adm
|
|
5
|
+
module Notification
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.instance_eval do
|
|
8
|
+
validates :registration_ids, presence: true
|
|
9
|
+
|
|
10
|
+
validates_with Rpush::Client::ActiveModel::PayloadDataSizeValidator, limit: 6144
|
|
11
|
+
validates_with Rpush::Client::ActiveModel::RegistrationIdsCountValidator, limit: 100
|
|
12
|
+
|
|
13
|
+
validates_with Rpush::Client::ActiveModel::Adm::DataValidator
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def as_json
|
|
18
|
+
json = { 'data' => data }
|
|
19
|
+
json['consolidationKey'] = collapse_key if collapse_key
|
|
20
|
+
# number of seconds before message is expired
|
|
21
|
+
json['expiresAfter'] = expiry if expiry
|
|
22
|
+
json
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Apns
|
|
5
|
+
module App
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.instance_eval do
|
|
8
|
+
validates :environment, presence: true, inclusion: { in: %w(development production sandbox) }
|
|
9
|
+
validates :certificate, presence: true
|
|
10
|
+
validate :certificate_has_matching_private_key
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def service_name
|
|
15
|
+
'apns'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def certificate_has_matching_private_key
|
|
21
|
+
result = false
|
|
22
|
+
if certificate.present?
|
|
23
|
+
begin
|
|
24
|
+
x509 = OpenSSL::X509::Certificate.new(certificate)
|
|
25
|
+
pkey = OpenSSL::PKey::RSA.new(certificate, password)
|
|
26
|
+
result = x509 && pkey
|
|
27
|
+
rescue OpenSSL::OpenSSLError
|
|
28
|
+
errors.add :certificate, 'Certificate value must contain a certificate and a private key.'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
result
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Apns
|
|
5
|
+
class BinaryNotificationValidator < ::ActiveModel::Validator
|
|
6
|
+
MAX_BYTES = 256
|
|
7
|
+
|
|
8
|
+
def validate(record)
|
|
9
|
+
return unless record.payload_size > MAX_BYTES
|
|
10
|
+
record.errors[:base] << "APN notification cannot be larger than #{MAX_BYTES} bytes. Try condensing your alert and device attributes."
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Apns
|
|
5
|
+
class DeviceTokenFormatValidator < ::ActiveModel::Validator
|
|
6
|
+
def validate(record)
|
|
7
|
+
return if record.device_token =~ /^[a-z0-9]{64}$/i
|
|
8
|
+
record.errors[:device_token] << "is invalid"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Apns
|
|
5
|
+
module Notification
|
|
6
|
+
APNS_DEFAULT_EXPIRY = 1.day.to_i
|
|
7
|
+
APNS_PRIORITY_IMMEDIATE = 10
|
|
8
|
+
APNS_PRIORITY_CONSERVE_POWER = 5
|
|
9
|
+
APNS_PRIORITIES = [APNS_PRIORITY_IMMEDIATE, APNS_PRIORITY_CONSERVE_POWER]
|
|
10
|
+
|
|
11
|
+
def self.included(base)
|
|
12
|
+
base.instance_eval do
|
|
13
|
+
validates :device_token, presence: true
|
|
14
|
+
validates :badge, numericality: true, allow_nil: true
|
|
15
|
+
validates :priority, inclusion: { in: APNS_PRIORITIES }, allow_nil: true
|
|
16
|
+
|
|
17
|
+
validates_with Rpush::Client::ActiveModel::Apns::DeviceTokenFormatValidator
|
|
18
|
+
validates_with Rpush::Client::ActiveModel::Apns::BinaryNotificationValidator
|
|
19
|
+
|
|
20
|
+
base.const_set('APNS_DEFAULT_EXPIRY', APNS_DEFAULT_EXPIRY) unless base.const_defined?('APNS_DEFAULT_EXPIRY')
|
|
21
|
+
base.const_set('APNS_PRIORITY_IMMEDIATE', APNS_PRIORITY_IMMEDIATE) unless base.const_defined?('APNS_PRIORITY_IMMEDIATE')
|
|
22
|
+
base.const_set('APNS_PRIORITY_CONSERVE_POWER', APNS_PRIORITY_CONSERVE_POWER) unless base.const_defined?('APNS_PRIORITY_CONSERVE_POWER')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def device_token=(token)
|
|
27
|
+
write_attribute(:device_token, token.delete(" <>")) unless token.nil?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
MDM_KEY = '__rpush_mdm__'
|
|
31
|
+
def mdm=(magic)
|
|
32
|
+
self.data = (data || {}).merge(MDM_KEY => magic)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
CONTENT_AVAILABLE_KEY = '__rpush_content_available__'
|
|
36
|
+
def content_available=(bool)
|
|
37
|
+
return unless bool
|
|
38
|
+
self.data = (data || {}).merge(CONTENT_AVAILABLE_KEY => true)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def as_json
|
|
42
|
+
json = ActiveSupport::OrderedHash.new
|
|
43
|
+
|
|
44
|
+
if data && data.key?(MDM_KEY)
|
|
45
|
+
json['mdm'] = data[MDM_KEY]
|
|
46
|
+
else
|
|
47
|
+
json['aps'] = ActiveSupport::OrderedHash.new
|
|
48
|
+
json['aps']['alert'] = alert if alert
|
|
49
|
+
json['aps']['badge'] = badge if badge
|
|
50
|
+
json['aps']['sound'] = sound if sound
|
|
51
|
+
|
|
52
|
+
if data && data[CONTENT_AVAILABLE_KEY]
|
|
53
|
+
json['aps']['content-available'] = 1
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if data
|
|
57
|
+
non_aps_attributes = data.reject { |k, _| k == CONTENT_AVAILABLE_KEY }
|
|
58
|
+
non_aps_attributes.each { |k, v| json[k.to_s] = v }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
json
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def to_binary(options = {})
|
|
66
|
+
frame_id = options[:for_validation] ? 0 : id
|
|
67
|
+
frame = ""
|
|
68
|
+
frame << [1, 32, device_token].pack("cnH*")
|
|
69
|
+
frame << [2, payload.bytesize, payload].pack("cna*")
|
|
70
|
+
frame << [3, 4, frame_id].pack("cnN")
|
|
71
|
+
frame << [4, 4, expiry || APNS_DEFAULT_EXPIRY].pack("cnN")
|
|
72
|
+
frame << [5, 1, priority_for_frame].pack("cnc")
|
|
73
|
+
[2, frame.bytesize].pack("cN") + frame
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def priority_for_frame
|
|
79
|
+
# It is an error to use APNS_PRIORITY_IMMEDIATE for a notification that only contains content-available.
|
|
80
|
+
if as_json['aps'].keys == ['content-available']
|
|
81
|
+
APNS_PRIORITY_CONSERVE_POWER
|
|
82
|
+
else
|
|
83
|
+
priority || APNS_PRIORITY_IMMEDIATE
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|