rpush_extended 3.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +365 -0
- data/LICENSE +7 -0
- data/README.md +393 -0
- data/bin/rpush +4 -0
- data/lib/generators/rpush_config_generator.rb +7 -0
- data/lib/generators/rpush_migration_generator.rb +66 -0
- data/lib/generators/templates/add_adm.rb +23 -0
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +9 -0
- data/lib/generators/templates/add_app_to_rapns.rb +11 -0
- data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +9 -0
- data/lib/generators/templates/add_gcm.rb +117 -0
- data/lib/generators/templates/add_rpush.rb +402 -0
- data/lib/generators/templates/add_wpns.rb +16 -0
- data/lib/generators/templates/create_rapns_apps.rb +16 -0
- data/lib/generators/templates/create_rapns_feedback.rb +25 -0
- data/lib/generators/templates/create_rapns_notifications.rb +36 -0
- data/lib/generators/templates/rename_rapns_to_rpush.rb +87 -0
- data/lib/generators/templates/rpush.rb +135 -0
- data/lib/generators/templates/rpush_2_0_0_updates.rb +79 -0
- data/lib/generators/templates/rpush_2_1_0_updates.rb +11 -0
- data/lib/generators/templates/rpush_2_6_0_updates.rb +10 -0
- data/lib/generators/templates/rpush_2_7_0_updates.rb +12 -0
- data/lib/generators/templates/rpush_3_0_0_updates.rb +11 -0
- data/lib/generators/templates/rpush_3_0_1_updates.rb +13 -0
- data/lib/generators/templates/rpush_3_1_0_add_pushy.rb +9 -0
- data/lib/generators/templates/rpush_3_1_1_updates.rb +15 -0
- data/lib/generators/templates/rpush_3_2_0_add_apns_p8.rb +15 -0
- data/lib/generators/templates/rpush_3_2_4_updates.rb +9 -0
- data/lib/generators/templates/rpush_3_3_0_updates.rb +9 -0
- data/lib/generators/templates/rpush_3_3_1_updates.rb +11 -0
- data/lib/rpush/apns_feedback.rb +17 -0
- data/lib/rpush/cli.rb +213 -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 +104 -0
- data/lib/rpush/client/active_model/apns2/app.rb +15 -0
- data/lib/rpush/client/active_model/apns2/notification.rb +9 -0
- data/lib/rpush/client/active_model/apnsp8/app.rb +23 -0
- data/lib/rpush/client/active_model/apnsp8/notification.rb +9 -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 +59 -0
- data/lib/rpush/client/active_model/notification.rb +22 -0
- data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
- data/lib/rpush/client/active_model/pushy/app.rb +20 -0
- data/lib/rpush/client/active_model/pushy/notification.rb +31 -0
- data/lib/rpush/client/active_model/pushy/time_to_live_validator.rb +14 -0
- data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
- data/lib/rpush/client/active_model/wns/app.rb +23 -0
- data/lib/rpush/client/active_model/wns/notification.rb +32 -0
- data/lib/rpush/client/active_model/wpns/app.rb +13 -0
- data/lib/rpush/client/active_model/wpns/notification.rb +28 -0
- data/lib/rpush/client/active_model.rb +34 -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 +18 -0
- data/lib/rpush/client/active_record/apns/notification.rb +40 -0
- data/lib/rpush/client/active_record/apns2/app.rb +11 -0
- data/lib/rpush/client/active_record/apns2/notification.rb +10 -0
- data/lib/rpush/client/active_record/apnsp8/app.rb +11 -0
- data/lib/rpush/client/active_record/apnsp8/notification.rb +10 -0
- data/lib/rpush/client/active_record/app.rb +13 -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 +42 -0
- data/lib/rpush/client/active_record/pushy/app.rb +11 -0
- data/lib/rpush/client/active_record/pushy/notification.rb +11 -0
- data/lib/rpush/client/active_record/wns/app.rb +11 -0
- data/lib/rpush/client/active_record/wns/badge_notification.rb +15 -0
- data/lib/rpush/client/active_record/wns/notification.rb +11 -0
- data/lib/rpush/client/active_record/wns/raw_notification.rb +13 -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/active_record.rb +33 -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/apns2/app.rb +11 -0
- data/lib/rpush/client/redis/apns2/notification.rb +11 -0
- data/lib/rpush/client/redis/apnsp8/app.rb +11 -0
- data/lib/rpush/client/redis/apnsp8/notification.rb +11 -0
- data/lib/rpush/client/redis/app.rb +29 -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 +74 -0
- data/lib/rpush/client/redis/pushy/app.rb +16 -0
- data/lib/rpush/client/redis/pushy/notification.rb +18 -0
- data/lib/rpush/client/redis/wns/app.rb +14 -0
- data/lib/rpush/client/redis/wns/badge_notification.rb +15 -0
- data/lib/rpush/client/redis/wns/notification.rb +11 -0
- data/lib/rpush/client/redis/wns/raw_notification.rb +11 -0
- data/lib/rpush/client/redis/wpns/app.rb +11 -0
- data/lib/rpush/client/redis/wpns/notification.rb +11 -0
- data/lib/rpush/client/redis.rb +56 -0
- data/lib/rpush/configuration.rb +115 -0
- data/lib/rpush/daemon/adm/delivery.rb +226 -0
- data/lib/rpush/daemon/adm.rb +9 -0
- data/lib/rpush/daemon/apns/delivery.rb +43 -0
- data/lib/rpush/daemon/apns/feedback_receiver.rb +90 -0
- data/lib/rpush/daemon/apns.rb +17 -0
- data/lib/rpush/daemon/apns2/delivery.rb +127 -0
- data/lib/rpush/daemon/apns2.rb +10 -0
- data/lib/rpush/daemon/apnsp8/delivery.rb +166 -0
- data/lib/rpush/daemon/apnsp8/token.rb +43 -0
- data/lib/rpush/daemon/apnsp8.rb +10 -0
- data/lib/rpush/daemon/app_runner.rb +190 -0
- data/lib/rpush/daemon/batch.rb +138 -0
- data/lib/rpush/daemon/constants.rb +59 -0
- data/lib/rpush/daemon/delivery.rb +46 -0
- data/lib/rpush/daemon/delivery_error.rb +27 -0
- data/lib/rpush/daemon/dispatcher/apns_http2.rb +51 -0
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +152 -0
- data/lib/rpush/daemon/dispatcher/apnsp8_http2.rb +33 -0
- data/lib/rpush/daemon/dispatcher/http.rb +21 -0
- data/lib/rpush/daemon/dispatcher/tcp.rb +22 -0
- data/lib/rpush/daemon/dispatcher_loop.rb +73 -0
- data/lib/rpush/daemon/errors.rb +18 -0
- data/lib/rpush/daemon/feeder.rb +69 -0
- data/lib/rpush/daemon/gcm/delivery.rb +241 -0
- data/lib/rpush/daemon/gcm.rb +9 -0
- data/lib/rpush/daemon/interruptible_sleep.rb +24 -0
- data/lib/rpush/daemon/loggable.rb +33 -0
- data/lib/rpush/daemon/proc_title.rb +17 -0
- data/lib/rpush/daemon/pushy/delivery.rb +90 -0
- data/lib/rpush/daemon/pushy.rb +9 -0
- data/lib/rpush/daemon/queue_payload.rb +12 -0
- data/lib/rpush/daemon/retry_header_parser.rb +23 -0
- data/lib/rpush/daemon/retryable_error.rb +22 -0
- data/lib/rpush/daemon/ring_buffer.rb +16 -0
- data/lib/rpush/daemon/rpc/client.rb +27 -0
- data/lib/rpush/daemon/rpc/server.rb +82 -0
- data/lib/rpush/daemon/rpc.rb +9 -0
- data/lib/rpush/daemon/service_config_methods.rb +51 -0
- data/lib/rpush/daemon/signal_handler.rb +75 -0
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +80 -0
- data/lib/rpush/daemon/store/active_record.rb +214 -0
- data/lib/rpush/daemon/store/interface.rb +20 -0
- data/lib/rpush/daemon/store/redis.rb +166 -0
- data/lib/rpush/daemon/string_helpers.rb +15 -0
- data/lib/rpush/daemon/synchronizer.rb +62 -0
- data/lib/rpush/daemon/tcp_connection.rb +190 -0
- data/lib/rpush/daemon/wns/badge_request.rb +32 -0
- data/lib/rpush/daemon/wns/delivery.rb +178 -0
- data/lib/rpush/daemon/wns/post_request.rb +33 -0
- data/lib/rpush/daemon/wns/raw_request.rb +22 -0
- data/lib/rpush/daemon/wns/toast_request.rb +54 -0
- data/lib/rpush/daemon/wns.rb +9 -0
- data/lib/rpush/daemon/wpns/delivery.rb +132 -0
- data/lib/rpush/daemon/wpns.rb +9 -0
- data/lib/rpush/daemon.rb +179 -0
- data/lib/rpush/deprecatable.rb +24 -0
- data/lib/rpush/deprecation.rb +26 -0
- data/lib/rpush/embed.rb +41 -0
- data/lib/rpush/logger.rb +92 -0
- data/lib/rpush/multi_json_helper.rb +16 -0
- data/lib/rpush/plugin.rb +44 -0
- data/lib/rpush/push.rb +11 -0
- data/lib/rpush/reflectable.rb +13 -0
- data/lib/rpush/reflection_collection.rb +44 -0
- data/lib/rpush/reflection_public_methods.rb +11 -0
- data/lib/rpush/version.rb +14 -0
- data/lib/rpush.rb +43 -0
- data/lib/tasks/quality.rake +35 -0
- data/lib/tasks/test.rake +69 -0
- data/spec/.rubocop.yml +4 -0
- data/spec/functional/adm_spec.rb +50 -0
- data/spec/functional/apns2_spec.rb +232 -0
- data/spec/functional/apns_spec.rb +162 -0
- data/spec/functional/cli_spec.rb +36 -0
- data/spec/functional/embed_spec.rb +49 -0
- data/spec/functional/gcm_spec.rb +46 -0
- data/spec/functional/new_app_spec.rb +44 -0
- data/spec/functional/pushy_spec.rb +22 -0
- data/spec/functional/retry_spec.rb +42 -0
- data/spec/functional/synchronization_spec.rb +97 -0
- data/spec/functional/wpns_spec.rb +71 -0
- data/spec/functional_spec_helper.rb +32 -0
- data/spec/spec_helper.rb +69 -0
- data/spec/support/active_record_setup.rb +73 -0
- data/spec/support/cert_with_password.pem +90 -0
- data/spec/support/cert_without_password.pem +59 -0
- data/spec/support/config/database.yml +44 -0
- data/spec/support/simplecov_helper.rb +24 -0
- data/spec/support/simplecov_quality_formatter.rb +12 -0
- data/spec/tmp/.gitkeep +0 -0
- data/spec/unit/apns_feedback_spec.rb +28 -0
- data/spec/unit/client/active_record/adm/app_spec.rb +58 -0
- data/spec/unit/client/active_record/adm/notification_spec.rb +43 -0
- 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 +324 -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/client/active_record/gcm/notification_spec.rb +67 -0
- data/spec/unit/client/active_record/notification_spec.rb +21 -0
- data/spec/unit/client/active_record/pushy/app_spec.rb +17 -0
- data/spec/unit/client/active_record/pushy/notification_spec.rb +65 -0
- data/spec/unit/client/active_record/wns/badge_notification_spec.rb +15 -0
- data/spec/unit/client/active_record/wns/raw_notification_spec.rb +26 -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 +46 -0
- data/spec/unit/daemon/adm/delivery_spec.rb +253 -0
- data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +11 -0
- data/spec/unit/daemon/apns/delivery_spec.rb +108 -0
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +119 -0
- data/spec/unit/daemon/app_runner_spec.rb +188 -0
- data/spec/unit/daemon/batch_spec.rb +169 -0
- data/spec/unit/daemon/delivery_error_spec.rb +13 -0
- data/spec/unit/daemon/delivery_spec.rb +51 -0
- data/spec/unit/daemon/dispatcher/http_spec.rb +34 -0
- data/spec/unit/daemon/dispatcher/tcp_spec.rb +32 -0
- data/spec/unit/daemon/dispatcher_loop_spec.rb +53 -0
- data/spec/unit/daemon/feeder_spec.rb +96 -0
- data/spec/unit/daemon/gcm/delivery_spec.rb +387 -0
- data/spec/unit/daemon/proc_title_spec.rb +11 -0
- data/spec/unit/daemon/pushy/delivery_spec.rb +159 -0
- data/spec/unit/daemon/retryable_error_spec.rb +14 -0
- data/spec/unit/daemon/service_config_methods_spec.rb +36 -0
- data/spec/unit/daemon/signal_handler_spec.rb +99 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +165 -0
- data/spec/unit/daemon/store/active_record_spec.rb +357 -0
- data/spec/unit/daemon/store/redis_spec.rb +365 -0
- data/spec/unit/daemon/tcp_connection_spec.rb +292 -0
- data/spec/unit/daemon/wns/delivery_spec.rb +176 -0
- data/spec/unit/daemon/wns/post_request_spec.rb +117 -0
- data/spec/unit/daemon/wpns/delivery_spec.rb +167 -0
- data/spec/unit/daemon_spec.rb +138 -0
- data/spec/unit/deprecatable_spec.rb +32 -0
- data/spec/unit/deprecation_spec.rb +15 -0
- data/spec/unit/embed_spec.rb +47 -0
- data/spec/unit/logger_spec.rb +127 -0
- data/spec/unit/notification_shared.rb +53 -0
- data/spec/unit/plugin_spec.rb +36 -0
- data/spec/unit/push_spec.rb +34 -0
- data/spec/unit/reflectable_spec.rb +27 -0
- data/spec/unit/reflection_collection_spec.rb +26 -0
- data/spec/unit/rpush_spec.rb +8 -0
- data/spec/unit_spec_helper.rb +26 -0
- metadata +709 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
Rpush.configure do |config|
|
2
|
+
|
3
|
+
# Supported clients are :active_record and :redis
|
4
|
+
config.client = :active_record
|
5
|
+
|
6
|
+
# Options passed to Redis.new
|
7
|
+
# config.redis_options = {}
|
8
|
+
|
9
|
+
# Frequency in seconds to check for new notifications.
|
10
|
+
config.push_poll = 2
|
11
|
+
|
12
|
+
# The maximum number of notifications to load from the store every `push_poll` seconds.
|
13
|
+
# If some notifications are still enqueued internally, Rpush will load the batch_size less
|
14
|
+
# the number enqueued. An exception to this is if the service is able to receive multiple
|
15
|
+
# notification payloads over the connection with a single write, such as APNs.
|
16
|
+
config.batch_size = 100
|
17
|
+
|
18
|
+
# Path to write PID file. Relative to current directory unless absolute.
|
19
|
+
config.pid_file = 'tmp/rpush.pid'
|
20
|
+
|
21
|
+
# Path to log file. Relative to current directory unless absolute.
|
22
|
+
config.log_file = 'log/rpush.log'
|
23
|
+
|
24
|
+
config.log_level = (defined?(Rails) && Rails.logger) ? Rails.logger.level : ::Logger::Severity::INFO
|
25
|
+
|
26
|
+
# Define a custom logger.
|
27
|
+
# config.logger = MyLogger.new
|
28
|
+
|
29
|
+
# config.apns.feedback_receiver.enabled = true
|
30
|
+
# config.apns.feedback_receiver.frequency = 60
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
Rpush.reflect do |on|
|
35
|
+
|
36
|
+
# Called with a Rpush::Apns::Feedback instance when feedback is received
|
37
|
+
# from the APNs that a notification has failed to be delivered.
|
38
|
+
# Further notifications should not be sent to the device.
|
39
|
+
# on.apns_feedback do |feedback|
|
40
|
+
# end
|
41
|
+
|
42
|
+
# Called when a notification is queued internally for delivery.
|
43
|
+
# The internal queue for each app runner can be inspected:
|
44
|
+
#
|
45
|
+
# Rpush::Daemon::AppRunner.runners.each do |app_id, runner|
|
46
|
+
# runner.app
|
47
|
+
# runner.queue_size
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# on.notification_enqueued do |notification|
|
51
|
+
# end
|
52
|
+
|
53
|
+
# Called when a notification is successfully delivered.
|
54
|
+
# on.notification_delivered do |notification|
|
55
|
+
# end
|
56
|
+
|
57
|
+
# Called when notification delivery failed.
|
58
|
+
# Call 'error_code' and 'error_description' on the notification for the cause.
|
59
|
+
# on.notification_failed do |notification|
|
60
|
+
# end
|
61
|
+
|
62
|
+
# Called when the notification delivery failed and only the notification ID
|
63
|
+
# is present in memory.
|
64
|
+
# on.notification_id_failed do |app, notification_id, error_code, error_description|
|
65
|
+
# end
|
66
|
+
|
67
|
+
# Called when a notification will be retried at a later date.
|
68
|
+
# Call 'deliver_after' on the notification for the next delivery date
|
69
|
+
# and 'retries' for the number of times this notification has been retried.
|
70
|
+
# on.notification_will_retry do |notification|
|
71
|
+
# end
|
72
|
+
|
73
|
+
# Called when a notification will be retried and only the notification ID
|
74
|
+
# is present in memory.
|
75
|
+
# on.notification_id_will_retry do |app, notification_id, retry_after|
|
76
|
+
# end
|
77
|
+
|
78
|
+
# Called when a TCP connection is lost and will be reconnected.
|
79
|
+
# on.tcp_connection_lost do |app, error|
|
80
|
+
# end
|
81
|
+
|
82
|
+
# Called for each recipient which successfully receives a notification. This
|
83
|
+
# can occur more than once for the same notification when there are multiple
|
84
|
+
# recipients.
|
85
|
+
# on.gcm_delivered_to_recipient do |notification, registration_id|
|
86
|
+
# end
|
87
|
+
|
88
|
+
# Called for each recipient which fails to receive a notification. This
|
89
|
+
# can occur more than once for the same notification when there are multiple
|
90
|
+
# recipients. (do not handle invalid registration IDs here)
|
91
|
+
# on.gcm_failed_to_recipient do |notification, error, registration_id|
|
92
|
+
# end
|
93
|
+
|
94
|
+
# Called when the GCM returns a canonical registration ID.
|
95
|
+
# You will need to replace old_id with canonical_id in your records.
|
96
|
+
# on.gcm_canonical_id do |old_id, canonical_id|
|
97
|
+
# end
|
98
|
+
|
99
|
+
# Called when the GCM returns a failure that indicates an invalid registration id.
|
100
|
+
# You will need to delete the registration_id from your records.
|
101
|
+
# on.gcm_invalid_registration_id do |app, error, registration_id|
|
102
|
+
# end
|
103
|
+
|
104
|
+
# Called when an SSL certificate will expire within 1 month.
|
105
|
+
# Implement on.error to catch errors raised when the certificate expires.
|
106
|
+
# on.ssl_certificate_will_expire do |app, expiration_time|
|
107
|
+
# end
|
108
|
+
|
109
|
+
# Called when an SSL certificate has been revoked.
|
110
|
+
# on.ssl_certificate_revoked do |app, error|
|
111
|
+
# end
|
112
|
+
|
113
|
+
# Called when the ADM returns a canonical registration ID.
|
114
|
+
# You will need to replace old_id with canonical_id in your records.
|
115
|
+
# on.adm_canonical_id do |old_id, canonical_id|
|
116
|
+
# end
|
117
|
+
|
118
|
+
# Called when Failed to deliver to ADM. Check the 'reason' string for further
|
119
|
+
# explanations.
|
120
|
+
#
|
121
|
+
# If the reason is the string 'Unregistered', you should remove
|
122
|
+
# this registration id from your records.
|
123
|
+
# on.adm_failed_to_recipient do |notification, registration_id, reason|
|
124
|
+
# end
|
125
|
+
|
126
|
+
# Called when Failed to deliver to WNS. Check the 'reason' string for further
|
127
|
+
# explanations.
|
128
|
+
# You should remove this uri from your records
|
129
|
+
# on.wns_invalid_channel do |notification, uri, reason|
|
130
|
+
# end
|
131
|
+
|
132
|
+
# Called when an exception is raised.
|
133
|
+
# on.error do |error|
|
134
|
+
# end
|
135
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
class Rpush200Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
module Rpush
|
3
|
+
class App < ActiveRecord::Base
|
4
|
+
self.table_name = 'rpush_apps'
|
5
|
+
end
|
6
|
+
|
7
|
+
class Notification < ActiveRecord::Base
|
8
|
+
self.table_name = 'rpush_notifications'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.update_type(model, from, to)
|
13
|
+
model.where(type: from).update_all(type: to)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.up
|
17
|
+
add_column :rpush_notifications, :processing, :boolean, null: false, default: false
|
18
|
+
add_column :rpush_notifications, :priority, :integer, null: true
|
19
|
+
|
20
|
+
if ActiveRecord::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MINOR >= 1
|
21
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
|
22
|
+
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
23
|
+
end
|
24
|
+
else
|
25
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
|
26
|
+
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
add_index :rpush_notifications, [:delivered, :failed], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
|
31
|
+
|
32
|
+
rename_column :rpush_feedback, :app, :app_id
|
33
|
+
|
34
|
+
if postgresql?
|
35
|
+
execute('ALTER TABLE rpush_feedback ALTER COLUMN app_id TYPE integer USING (trim(app_id)::integer)')
|
36
|
+
else
|
37
|
+
change_column :rpush_feedback, :app_id, :integer
|
38
|
+
end
|
39
|
+
|
40
|
+
[:Apns, :Gcm, :Wpns, :Adm].each do |service|
|
41
|
+
update_type(Rpush200Updates::Rpush::App, "Rpush::#{service}::App", "Rpush::Client::ActiveRecord::#{service}::App")
|
42
|
+
update_type(Rpush200Updates::Rpush::Notification, "Rpush::#{service}::Notification", "Rpush::Client::ActiveRecord::#{service}::Notification")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.down
|
47
|
+
[:Apns, :Gcm, :Wpns, :Adm].each do |service|
|
48
|
+
update_type(Rpush200Updates::Rpush::App, "Rpush::Client::ActiveRecord::#{service}::App", "Rpush::#{service}::App")
|
49
|
+
update_type(Rpush200Updates::Rpush::Notification, "Rpush::Client::ActiveRecord::#{service}::Notification", "Rpush::#{service}::Notification")
|
50
|
+
end
|
51
|
+
|
52
|
+
change_column :rpush_feedback, :app_id, :string
|
53
|
+
rename_column :rpush_feedback, :app_id, :app
|
54
|
+
|
55
|
+
if ActiveRecord::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MINOR >= 1
|
56
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
|
57
|
+
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
58
|
+
end
|
59
|
+
else
|
60
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
|
61
|
+
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
add_index :rpush_notifications, [:app_id, :delivered, :failed, :deliver_after], name: 'index_rpush_notifications_multi'
|
66
|
+
|
67
|
+
remove_column :rpush_notifications, :priority
|
68
|
+
remove_column :rpush_notifications, :processing
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.adapter_name
|
72
|
+
env = (defined?(Rails) && Rails.env) ? Rails.env : 'development'
|
73
|
+
Hash[ActiveRecord::Base.configurations[env].map { |k,v| [k.to_sym,v] }][:adapter]
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.postgresql?
|
77
|
+
adapter_name =~ /postgresql|postgis/
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Rpush210Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :rpush_notifications, :url_args, :text, null: true
|
4
|
+
add_column :rpush_notifications, :category, :string, null: true
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_column :rpush_notifications, :url_args
|
9
|
+
remove_column :rpush_notifications, :category
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Rpush260Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :rpush_notifications, :content_available, :boolean, default: false
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.down
|
7
|
+
remove_column :rpush_notifications, :content_available
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Rpush270Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_column :rpush_notifications, :alert, :text
|
4
|
+
add_column :rpush_notifications, :notification, :text
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
change_column :rpush_notifications, :alert, :string
|
9
|
+
remove_column :rpush_notifications, :notification
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Rpush300Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :rpush_notifications, :mutable_content, :boolean, default: false
|
4
|
+
change_column :rpush_notifications, :sound, :string, default: nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_column :rpush_notifications, :mutable_content
|
9
|
+
change_column :rpush_notifications, :sound, :string, default: 'default'
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Rpush301Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_column_null :rpush_notifications, :mutable_content, false
|
4
|
+
change_column_null :rpush_notifications, :content_available, false
|
5
|
+
change_column_null :rpush_notifications, :alert_is_json, false
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.down
|
9
|
+
change_column_null :rpush_notifications, :mutable_content, true
|
10
|
+
change_column_null :rpush_notifications, :content_available, true
|
11
|
+
change_column_null :rpush_notifications, :alert_is_json, true
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class Rpush310AddPushy < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :rpush_notifications, :external_device_id, :string, null: true
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.down
|
7
|
+
remove_column :rpush_notifications, :external_device_id
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Rpush311Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_table :rpush_notifications do |t|
|
4
|
+
t.remove_index name: 'index_rpush_notifications_multi'
|
5
|
+
t.index [:delivered, :failed, :processing, :deliver_after, :created_at], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
change_table :rpush_notifications do |t|
|
11
|
+
t.remove_index name: 'index_rpush_notifications_multi'
|
12
|
+
t.index [:delivered, :failed], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Rpush320AddApnsP8 < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :rpush_apps, :apn_key, :string, null: true
|
4
|
+
add_column :rpush_apps, :apn_key_id, :string, null: true
|
5
|
+
add_column :rpush_apps, :team_id, :string, null: true
|
6
|
+
add_column :rpush_apps, :bundle_id, :string, null: true
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
remove_column :rpush_apps, :apn_key
|
11
|
+
remove_column :rpush_apps, :apn_key_id
|
12
|
+
remove_column :rpush_apps, :team_id
|
13
|
+
remove_column :rpush_apps, :bundle_id
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class Rpush324Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_column :rpush_apps, :apn_key, :text, null: true
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.down
|
7
|
+
change_column :rpush_apps, :apn_key, :string, null: true
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class Rpush330Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :rpush_notifications, :thread_id, :string, null: true
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.down
|
7
|
+
remove_column :rpush_notifications, :thread_id
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Rpush331Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_column :rpush_notifications, :device_token, :text, null: true
|
4
|
+
change_column :rpush_feedback, :device_token, :text, null: true
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
change_column :rpush_notifications, :device_token, :string, { null: true, limit: 64 }
|
9
|
+
change_column :rpush_feedback, :device_token, :string, { null: true, limit: 64 }
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Rpush
|
2
|
+
def self.apns_feedback
|
3
|
+
require 'rpush/daemon'
|
4
|
+
Rpush::Daemon.common_init
|
5
|
+
|
6
|
+
Rpush::Apns::App.all.each do |app|
|
7
|
+
# Redis stores every App type on the same namespace, hence the
|
8
|
+
# additional filtering
|
9
|
+
next unless app.service_name == 'apns'
|
10
|
+
|
11
|
+
receiver = Rpush::Daemon::Apns::FeedbackReceiver.new(app)
|
12
|
+
receiver.check_for_feedback
|
13
|
+
end
|
14
|
+
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
data/lib/rpush/cli.rb
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'ansi/code'
|
5
|
+
|
6
|
+
module Rpush
|
7
|
+
class CLI < Thor
|
8
|
+
def self.detect_rails?
|
9
|
+
['bin/rails', 'script/rails'].any? { |path| File.exist?(path) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.default_config_path
|
13
|
+
detect_rails? ? 'config/initializers/rpush.rb' : 'config/rpush.rb'
|
14
|
+
end
|
15
|
+
|
16
|
+
class_option :config, type: :string, aliases: '-c', default: default_config_path
|
17
|
+
class_option 'rails-env', type: :string, aliases: '-e', default: 'development'
|
18
|
+
|
19
|
+
option :foreground, type: :boolean, aliases: '-f', default: false
|
20
|
+
option 'pid-file', type: :string, aliases: '-p'
|
21
|
+
desc 'start', 'Start Rpush'
|
22
|
+
def start
|
23
|
+
config_setup
|
24
|
+
|
25
|
+
require 'rpush/daemon'
|
26
|
+
Rpush::Daemon.start
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'stop', 'Stop Rpush'
|
30
|
+
option 'pid-file', type: :string, aliases: '-p'
|
31
|
+
def stop
|
32
|
+
config_setup
|
33
|
+
pid = rpush_process_pid
|
34
|
+
return unless pid
|
35
|
+
|
36
|
+
STDOUT.write "* Stopping Rpush (pid #{pid})... "
|
37
|
+
STDOUT.flush
|
38
|
+
Process.kill('TERM', pid)
|
39
|
+
|
40
|
+
loop do
|
41
|
+
begin
|
42
|
+
Process.getpgid(pid)
|
43
|
+
sleep 0.05
|
44
|
+
rescue Errno::ESRCH
|
45
|
+
break
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
puts ANSI.green { '✔' }
|
50
|
+
end
|
51
|
+
|
52
|
+
desc 'init', 'Initialize Rpush into the current directory'
|
53
|
+
option 'active-record', type: :boolean, desc: 'Install ActiveRecord migrations'
|
54
|
+
def init
|
55
|
+
underscore_option_names
|
56
|
+
check_ruby_version
|
57
|
+
require 'rails/generators'
|
58
|
+
|
59
|
+
puts "* " + ANSI.green { 'Installing config...' }
|
60
|
+
$RPUSH_CONFIG_PATH = default_config_path # rubocop:disable Style/GlobalVars
|
61
|
+
Rails::Generators.invoke('rpush_config')
|
62
|
+
|
63
|
+
install_migrations = options['active_record']
|
64
|
+
|
65
|
+
unless options.key?('active_record')
|
66
|
+
has_answer = false
|
67
|
+
until has_answer
|
68
|
+
STDOUT.write "\n* #{ANSI.green { 'Install ActiveRecord migrations?' }} [y/n]: "
|
69
|
+
STDOUT.flush
|
70
|
+
answer = STDIN.gets.chomp.downcase
|
71
|
+
has_answer = %w(y n).include?(answer)
|
72
|
+
end
|
73
|
+
|
74
|
+
install_migrations = answer == 'y'
|
75
|
+
end
|
76
|
+
|
77
|
+
Rails::Generators.invoke('rpush_migration', ['--force']) if install_migrations
|
78
|
+
|
79
|
+
puts "\n* #{ANSI.green { 'Next steps:' }}"
|
80
|
+
puts " - Run 'bundle exec rake db:migrate'." if install_migrations
|
81
|
+
puts " - Review and update your configuration in #{default_config_path}."
|
82
|
+
puts " - Create your first app, see https://github.com/rpush/rpush for examples."
|
83
|
+
puts " - Run 'rpush help' for commands and options."
|
84
|
+
end
|
85
|
+
|
86
|
+
desc 'push', 'Deliver all pending notifications and then exit'
|
87
|
+
def push
|
88
|
+
config_setup
|
89
|
+
Rpush.config.foreground = true
|
90
|
+
|
91
|
+
Rpush.push
|
92
|
+
end
|
93
|
+
|
94
|
+
desc 'status', 'Show the internal status of the running Rpush instance.'
|
95
|
+
def status
|
96
|
+
config_setup
|
97
|
+
|
98
|
+
require 'rpush/daemon'
|
99
|
+
rpc = Rpush::Daemon::Rpc::Client.new(rpush_process_pid)
|
100
|
+
status = rpc.status
|
101
|
+
rpc.close
|
102
|
+
puts humanize_json(status)
|
103
|
+
end
|
104
|
+
|
105
|
+
desc 'version', 'Print Rpush version'
|
106
|
+
def version
|
107
|
+
puts Rpush::VERSION
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def config_setup
|
113
|
+
underscore_option_names
|
114
|
+
check_ruby_version
|
115
|
+
configure_rpush
|
116
|
+
end
|
117
|
+
|
118
|
+
def configure_rpush
|
119
|
+
load_rails_environment || load_standalone
|
120
|
+
end
|
121
|
+
|
122
|
+
def load_rails_environment
|
123
|
+
if detect_rails? && options['rails_env']
|
124
|
+
STDOUT.write "* Booting Rails '#{options[:rails_env]}' environment... "
|
125
|
+
STDOUT.flush
|
126
|
+
ENV['RAILS_ENV'] = options['rails_env']
|
127
|
+
load 'config/environment.rb'
|
128
|
+
Rpush.config.update(options)
|
129
|
+
puts ANSI.green { '✔' }
|
130
|
+
|
131
|
+
return true
|
132
|
+
end
|
133
|
+
|
134
|
+
false
|
135
|
+
end
|
136
|
+
|
137
|
+
def load_standalone
|
138
|
+
if !File.exist?(options[:config])
|
139
|
+
STDERR.puts(ANSI.red { 'ERROR: ' } + "#{options[:config]} does not exist. Please run 'rpush init' to generate it or specify the --config option.")
|
140
|
+
exit 1
|
141
|
+
else
|
142
|
+
load options[:config]
|
143
|
+
Rpush.config.update(options)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def detect_rails?
|
148
|
+
self.class.detect_rails?
|
149
|
+
end
|
150
|
+
|
151
|
+
def default_config_path
|
152
|
+
self.class.default_config_path
|
153
|
+
end
|
154
|
+
|
155
|
+
def check_ruby_version
|
156
|
+
STDERR.puts(ANSI.yellow { 'WARNING: ' } + "You are using an old and unsupported version of Ruby.") if RUBY_VERSION < '2.2.2' && RUBY_ENGINE == 'ruby'
|
157
|
+
end
|
158
|
+
|
159
|
+
def underscore_option_names
|
160
|
+
# Underscore option names so that they map directly to Configuration options.
|
161
|
+
new_options = options.dup
|
162
|
+
|
163
|
+
options.each do |k, v|
|
164
|
+
new_k = k.to_s.tr('-', '_')
|
165
|
+
|
166
|
+
if k != new_k
|
167
|
+
new_options.delete(k)
|
168
|
+
new_options[new_k] = v
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
new_options.freeze
|
173
|
+
self.options = new_options
|
174
|
+
end
|
175
|
+
|
176
|
+
def rpush_process_pid
|
177
|
+
if Rpush.config.pid_file.blank?
|
178
|
+
STDERR.puts(ANSI.red { 'ERROR: ' } + 'config.pid_file is not set.')
|
179
|
+
exit 1
|
180
|
+
end
|
181
|
+
|
182
|
+
unless File.exist?(Rpush.config.pid_file)
|
183
|
+
STDERR.puts("* Rpush isn't running? #{Rpush.config.pid_file} does not exist.")
|
184
|
+
exit 1
|
185
|
+
end
|
186
|
+
|
187
|
+
File.read(Rpush.config.pid_file).strip.to_i
|
188
|
+
end
|
189
|
+
|
190
|
+
def humanize_json(node, str = '', depth = 0) # rubocop:disable Metrics/PerceivedComplexity
|
191
|
+
if node.is_a?(Hash)
|
192
|
+
node = node.sort_by { |_, v| [Array, Hash].include?(v.class) ? 1 : 0 }
|
193
|
+
node.each do |k, v|
|
194
|
+
if [Array, Hash].include?(v.class)
|
195
|
+
str << "\n#{' ' * depth}#{k}:\n"
|
196
|
+
humanize_json(v, str, depth + 1)
|
197
|
+
else
|
198
|
+
str << "#{' ' * depth}#{k}: #{v}\n"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
elsif node.is_a?(Array)
|
202
|
+
node.each do |v|
|
203
|
+
str << "\n" if v.is_a?(Hash)
|
204
|
+
humanize_json(v, str, depth)
|
205
|
+
end
|
206
|
+
else
|
207
|
+
str << "#{' ' * depth}#{node}\n"
|
208
|
+
end
|
209
|
+
|
210
|
+
str
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -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(options = nil)
|
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
|