rpush 7.0.1 → 9.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -4
- data/README.md +24 -44
- data/lib/generators/rpush_migration_generator.rb +1 -0
- data/lib/generators/templates/rpush.rb +23 -13
- data/lib/generators/templates/rpush_7_1_0_updates.rb +12 -0
- data/lib/rpush/client/active_model/apns/notification.rb +0 -4
- data/lib/rpush/client/active_model/{gcm → fcm}/app.rb +4 -3
- data/lib/rpush/client/active_model/{gcm → fcm}/expiry_collapse_key_mutual_inclusion_validator.rb +1 -1
- data/lib/rpush/client/active_model/fcm/notification.rb +129 -0
- data/lib/rpush/client/active_model/fcm/notification_keys_in_allowed_list_validator.rb +20 -0
- data/lib/rpush/client/active_model.rb +4 -3
- data/lib/rpush/client/active_record/{gcm → fcm}/app.rb +2 -2
- data/lib/rpush/client/active_record/{gcm → fcm}/notification.rb +2 -2
- data/lib/rpush/client/active_record.rb +2 -2
- data/lib/rpush/client/redis/app.rb +2 -0
- data/lib/rpush/client/redis/{gcm → fcm}/app.rb +2 -2
- data/lib/rpush/client/redis/{gcm → fcm}/notification.rb +2 -2
- data/lib/rpush/client/redis.rb +2 -2
- data/lib/rpush/configuration.rb +2 -19
- data/lib/rpush/daemon/apns2/delivery.rb +0 -1
- data/lib/rpush/daemon/apnsp8/delivery.rb +0 -1
- data/lib/rpush/daemon/fcm/delivery.rb +162 -0
- data/lib/rpush/daemon/{gcm.rb → fcm.rb} +1 -1
- data/lib/rpush/daemon/google_credential_cache.rb +41 -0
- data/lib/rpush/daemon/service_config_methods.rb +0 -2
- data/lib/rpush/daemon/store/active_record.rb +15 -12
- data/lib/rpush/daemon/store/interface.rb +3 -3
- data/lib/rpush/daemon/store/redis.rb +13 -9
- data/lib/rpush/daemon/webpush/delivery.rb +2 -2
- data/lib/rpush/daemon.rb +3 -9
- data/lib/rpush/reflection_collection.rb +3 -3
- data/lib/rpush/version.rb +2 -2
- data/lib/rpush.rb +1 -1
- data/spec/functional/apns2_spec.rb +2 -6
- data/spec/functional/cli_spec.rb +41 -15
- data/spec/functional/embed_spec.rb +57 -26
- data/spec/functional/{gcm_priority_spec.rb → fcm_priority_spec.rb} +13 -7
- data/spec/functional/fcm_spec.rb +77 -0
- data/spec/functional/retry_spec.rb +21 -4
- data/spec/functional/synchronization_spec.rb +1 -1
- data/spec/functional_spec_helper.rb +1 -7
- data/spec/spec_helper.rb +4 -1
- data/spec/support/active_record_setup.rb +3 -1
- data/spec/unit/client/active_record/{gcm → fcm}/app_spec.rb +2 -2
- data/spec/unit/client/active_record/fcm/notification_spec.rb +10 -0
- data/spec/unit/client/active_record/shared/app.rb +1 -1
- data/spec/unit/client/redis/fcm/app_spec.rb +5 -0
- data/spec/unit/client/redis/fcm/notification_spec.rb +5 -0
- data/spec/unit/client/shared/apns/notification.rb +0 -15
- data/spec/unit/client/shared/fcm/app.rb +4 -0
- data/spec/unit/client/shared/fcm/notification.rb +92 -0
- data/spec/unit/configuration_spec.rb +1 -1
- data/spec/unit/daemon/apnsp8/delivery_spec.rb +1 -1
- data/spec/unit/daemon/fcm/delivery_spec.rb +127 -0
- data/spec/unit/daemon/service_config_methods_spec.rb +1 -1
- data/spec/unit/daemon/shared/store.rb +0 -42
- data/spec/unit/daemon/wns/delivery_spec.rb +1 -1
- data/spec/unit/logger_spec.rb +1 -1
- data/spec/unit_spec_helper.rb +1 -1
- metadata +127 -69
- data/lib/rpush/apns_feedback.rb +0 -18
- data/lib/rpush/client/active_model/gcm/notification.rb +0 -62
- data/lib/rpush/daemon/apns/delivery.rb +0 -43
- data/lib/rpush/daemon/apns/feedback_receiver.rb +0 -91
- data/lib/rpush/daemon/apns.rb +0 -17
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +0 -152
- data/lib/rpush/daemon/dispatcher/tcp.rb +0 -22
- data/lib/rpush/daemon/gcm/delivery.rb +0 -241
- data/lib/rpush/daemon/tcp_connection.rb +0 -190
- data/spec/functional/apns_spec.rb +0 -162
- data/spec/functional/gcm_spec.rb +0 -46
- data/spec/functional/new_app_spec.rb +0 -44
- data/spec/unit/apns_feedback_spec.rb +0 -39
- data/spec/unit/client/active_record/gcm/notification_spec.rb +0 -14
- data/spec/unit/client/redis/gcm/app_spec.rb +0 -5
- data/spec/unit/client/redis/gcm/notification_spec.rb +0 -5
- data/spec/unit/client/shared/gcm/app.rb +0 -4
- data/spec/unit/client/shared/gcm/notification.rb +0 -77
- data/spec/unit/daemon/apns/delivery_spec.rb +0 -108
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +0 -137
- data/spec/unit/daemon/dispatcher/tcp_spec.rb +0 -32
- data/spec/unit/daemon/gcm/delivery_spec.rb +0 -387
- data/spec/unit/daemon/tcp_connection_spec.rb +0 -292
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4ab9013682357312b9f5050d6c466c62866f78c68cc0fcb72ad89ccdc4409e0
|
4
|
+
data.tar.gz: ab086d28a744140499a6434c5fcec99b6c77c4cd929163a02ac4d9d77f94bb99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 862a057ab8cce2f73eff784838302ac0128214e0f744ed108b91afb33dce0867f7e7f06e131a29b46f6f49be7cca4e809f317ed37c50d1512eaa480a8ad7532d
|
7
|
+
data.tar.gz: 2f2d5cd377c79a1ec1ada2677f5c409d58d27d40a90b899b7fd43b98f122148623a0a78ca17c862b18b38245fe2df9a2f1cc7c68f25dc8cbe3dfa48a1f779c1f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,39 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [Unreleased](https://github.com/rpush/rpush/tree/HEAD)
|
4
|
+
|
5
|
+
**Merged pull requests:**
|
6
|
+
|
7
|
+
[Full Changelog](https://github.com/rpush/rpush/compare/v9.0.0...HEAD)
|
8
|
+
|
9
|
+
## [v9.0.0](https://github.com/rpush/rpush/tree/v9.0.0) (2024-09-09)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
* Support for Ruby 3.2 & 3.3 [\#679](https://github.com/rpush/rpush/pull/679) ([benlangfeld](https://github.com/benlangfeld))
|
14
|
+
|
15
|
+
**Breaking:**
|
16
|
+
|
17
|
+
* Removed legacy APNSv1 implementation (Apple binary protocol) since this was shut down in 2021. [\#680](https://github.com/rpush/rpush/pull/680) ([benlangfeld](https://github.com/benlangfeld))
|
18
|
+
* Removed legacy GCM implementation since this was shut down by Google in August 2024 and replaced by FCM (supported in RPush 8.0.0) [\#688](https://github.com/rpush/rpush/pull/688) ([benlangfeld](https://github.com/benlangfeld))
|
19
|
+
* Drop support for Ruby 2.x [\#672](https://github.com/rpush/rpush/pull/672) ([benlangfeld](https://github.com/benlangfeld))
|
20
|
+
|
21
|
+
[Full Changelog](https://github.com/rpush/rpush/compare/v8.0.0...v9.0.0)
|
22
|
+
|
23
|
+
## [v8.0.0](https://github.com/rpush/rpush/tree/v8.0.0) (2024-09-06)
|
24
|
+
|
25
|
+
**Merged pull requests:**
|
26
|
+
|
27
|
+
* Support for FCMv1 [\#620](https://github.com/rpush/rpush/pull/620) ([mirkode](https://github.com/mirkode)), [\#660](https://github.com/rpush/rpush/pull/660) ([AnilRh](https://github.com/AnilRh)) and [\#673](https://github.com/rpush/rpush/pull/673) ([SixiS](https://github.com/SixiS), [Henridv](https://github.com/Henridv) & [benlangfeld](https://github.com/benlangfeld))
|
28
|
+
* No longer silence content-available notifications for APNs. Reverts the following change from the v6.0.0 release. See https://github.com/rpush/rpush/issues/647.
|
29
|
+
* Fix silent APNS notifications for Apns2 and Apnsp8 [\#596](https://github.com/rpush/rpush/pull/596) ([shved270189](https://github.com/shved270189))
|
30
|
+
|
31
|
+
**Breaking:**
|
32
|
+
|
33
|
+
* Dropped support for Ruby 2.4, 2.5, 2.6 and Rails 5.2.
|
34
|
+
|
35
|
+
[Full Changelog](https://github.com/rpush/rpush/compare/v7.0.1...v8.0.0)
|
36
|
+
|
3
37
|
## [v7.0.1](https://github.com/rpush/rpush/tree/v7.0.1) (2022-03-02)
|
4
38
|
|
5
39
|
[Full Changelog](https://github.com/rpush/rpush/compare/v7.0.0...v7.0.1)
|
@@ -8,10 +42,6 @@
|
|
8
42
|
|
9
43
|
- Fix deprecation warnings from the redis gem [\#636](https://github.com/rpush/rpush/pull/636) ([sharang-d](https://github.com/sharang-d))
|
10
44
|
|
11
|
-
## [Unreleased](https://github.com/rpush/rpush/tree/HEAD)
|
12
|
-
|
13
|
-
[Full Changelog](https://github.com/rpush/rpush/compare/v7.0.0...HEAD)
|
14
|
-
|
15
45
|
## [v7.0.0](https://github.com/rpush/rpush/tree/HEAD)
|
16
46
|
|
17
47
|
[Full Changelog](https://github.com/rpush/rpush/compare/v6.0.1...v7.0.0)
|
data/README.md
CHANGED
@@ -57,10 +57,9 @@ There is a choice of two modes (and one legacy mode) using certificates or using
|
|
57
57
|
|
58
58
|
* `Rpush::Apns2` This requires an annually renewable certificate. see https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns
|
59
59
|
* `Rpush::Apnsp8` This uses encrypted tokens and requires an encryption key id and encryption key (provide as a p8 file). (see https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns)
|
60
|
-
* `Rpush::Apns` There is also the original APNS (the original version using certificates with a binary underlying protocol over TCP directly rather than over Http/2).
|
61
60
|
Apple have [announced](https://developer.apple.com/news/?id=c88acm2b) that this is not supported after March 31, 2021.
|
62
61
|
|
63
|
-
If this is your first time using the APNs, you will need to generate either SSL certificates (for
|
62
|
+
If this is your first time using the APNs, you will need to generate either SSL certificates (for standard Apns) or an Encryption Key (p8) and an Encryption Key ID (for Apnsp8). See [Generating Certificates](https://github.com/rpush/rpush/wiki/Generating-Certificates) for instructions.
|
64
63
|
|
65
64
|
##### Apnsp8
|
66
65
|
|
@@ -83,6 +82,7 @@ n = Rpush::Apnsp8::Notification.new
|
|
83
82
|
n.app = Rpush::Apnsp8::App.find_by_name("ios_app")
|
84
83
|
n.device_token = "..." # hex string
|
85
84
|
n.alert = "hi mom!"
|
85
|
+
# n.alert = { title: "push title", subtitle: "more to say", body: "hi mom!" }
|
86
86
|
n.data = { foo: :bar }
|
87
87
|
n.save!
|
88
88
|
```
|
@@ -107,6 +107,7 @@ n = Rpush::Apns2::Notification.new
|
|
107
107
|
n.app = Rpush::Apns2::App.find_by_name("ios_app")
|
108
108
|
n.device_token = "..." # hex string
|
109
109
|
n.alert = "hi mom!"
|
110
|
+
# n.alert = { title: "push title", subtitle: "more to say", body: "hi mom!" }
|
110
111
|
n.data = {
|
111
112
|
headers: { 'apns-topic': "BUNDLE ID" }, # the bundle id of the app, like com.example.appname. Not necessary if set on the app (see above)
|
112
113
|
foo: :bar
|
@@ -116,61 +117,41 @@ n.save!
|
|
116
117
|
|
117
118
|
You should also implement the [ssl_certificate_will_expire](https://github.com/rpush/rpush/wiki/Reflection-API) reflection to monitor when your certificate is due to expire.
|
118
119
|
|
119
|
-
##### Apns (legacy protocol)
|
120
|
-
|
121
|
-
```ruby
|
122
|
-
app = Rpush::Apns::App.new
|
123
|
-
app.name = "ios_app"
|
124
|
-
app.certificate = File.read("/path/to/sandbox.pem")
|
125
|
-
app.environment = "development" # APNs environment.
|
126
|
-
app.password = "certificate password"
|
127
|
-
app.connections = 1
|
128
|
-
app.save!
|
129
|
-
```
|
130
|
-
|
131
|
-
```ruby
|
132
|
-
n = Rpush::Apns::Notification.new
|
133
|
-
n.app = Rpush::Apns::App.find_by_name("ios_app")
|
134
|
-
n.device_token = "..." # hex string
|
135
|
-
n.alert = "hi mom!"
|
136
|
-
n.data = { foo: :bar }
|
137
|
-
n.save!
|
138
|
-
```
|
139
|
-
|
140
120
|
##### Safari Push Notifications
|
141
121
|
|
142
122
|
Using one of the notifications methods above, the `url_args` attribute is available for Safari Push Notifications.
|
143
123
|
|
144
124
|
##### Environment
|
145
125
|
|
146
|
-
The app `environment` for any Apns* option is "development" for XCode installs, and "production" for app store and TestFlight. Note that
|
126
|
+
The app `environment` for any Apns* option is "development" for XCode installs, and "production" for app store and TestFlight. Note that you can now use one (production + sandbox) certificate (you don't need a separate "sandbox" or development certificate), but if you do generate a development/sandbox certificate it can only be used for "development". With Apnsp8 tokens, you can target either "development" or "production" environments.
|
147
127
|
|
148
128
|
#### Firebase Cloud Messaging
|
149
129
|
|
150
|
-
|
130
|
+
You will need two params to make use of FCM via Rpush.
|
131
|
+
- `firebase_project_id` - The `Project ID` in your Firebase Project Settings
|
132
|
+
- `json_key` - The JSON key file for a service account with the `Firebase Admin SDK Administrator Service Agent` role.
|
133
|
+
|
134
|
+
Create service account in the google cloud account attached to your firebase account:
|
135
|
+
https://console.cloud.google.com/iam-admin/serviceaccounts
|
136
|
+
Make sure it has Role `Firebase Admin SDK Administrator Service Agent`
|
137
|
+
Add + Download the json key for the service account.
|
151
138
|
|
152
|
-
|
139
|
+
Once you have those two params, you can create an FCM app and send notifications.
|
153
140
|
|
154
141
|
```ruby
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
142
|
+
fcm_app = Rpush::Fcm::App.new
|
143
|
+
fcm_app.name = "fcm_app"
|
144
|
+
fcm_app.firebase_project_id = "someapp-123456"
|
145
|
+
fcm_app.json_key = Rails.root.join("your/key/somewhere.json").read # or from a ENV variable - just needs to be the whole json file
|
146
|
+
fcm_app.connections = 30
|
147
|
+
fcm_app.save!
|
160
148
|
```
|
161
149
|
|
162
150
|
```ruby
|
163
|
-
n = Rpush::
|
164
|
-
n.app = Rpush::
|
165
|
-
n.
|
166
|
-
n.data = {
|
167
|
-
n.priority = 'high' # Optional, can be either 'normal' or 'high'
|
168
|
-
n.content_available = true # Optional
|
169
|
-
# Optional notification payload. See the reference below for more keys you can use!
|
170
|
-
n.notification = { body: 'great match!',
|
171
|
-
title: 'Portugal vs. Denmark',
|
172
|
-
icon: 'myicon'
|
173
|
-
}
|
151
|
+
n = Rpush::Fcm::Notification.new
|
152
|
+
n.app = Rpush::Fcm::App.where(name: "fcm_app").first
|
153
|
+
n.device_token = device_token # Note that device_token is used here instead of registration_ids
|
154
|
+
n.data = {}.transform_values(&:to_s) # All values going in here have to be strings, if you have anything else - nothing goes through
|
174
155
|
n.save!
|
175
156
|
```
|
176
157
|
|
@@ -374,7 +355,6 @@ Rpush will deliver all pending notifications and then exit.
|
|
374
355
|
|
375
356
|
```ruby
|
376
357
|
Rpush.push
|
377
|
-
Rpush.apns_feedback
|
378
358
|
```
|
379
359
|
|
380
360
|
See [Push API](https://github.com/rpush/rpush/wiki/Push-API) for more details.
|
@@ -470,7 +450,7 @@ This will run RSpec against all versions of Rails.
|
|
470
450
|
You need to specify a `BUNDLE_GEMFILE` pointing to the gemfile before running the normal test command:
|
471
451
|
|
472
452
|
```
|
473
|
-
BUNDLE_GEMFILE=gemfiles/
|
453
|
+
BUNDLE_GEMFILE=gemfiles/rails_6.0.gemfile rspec spec/unit/apns_feedback_spec.rb
|
474
454
|
```
|
475
455
|
|
476
456
|
##### Multiple database adapter support
|
@@ -53,6 +53,7 @@ class RpushMigrationGenerator < Rails::Generators::Base
|
|
53
53
|
add_rpush_migration('rpush_4_1_0_updates')
|
54
54
|
add_rpush_migration('rpush_4_1_1_updates')
|
55
55
|
add_rpush_migration('rpush_4_2_0_updates')
|
56
|
+
add_rpush_migration('rpush_7_1_0_updates')
|
56
57
|
end
|
57
58
|
|
58
59
|
protected
|
@@ -30,9 +30,6 @@ Rpush.configure do |config|
|
|
30
30
|
# If the logger goes to stdout, you can disable foreground logging to avoid duplication.
|
31
31
|
# config.foreground_logging = false
|
32
32
|
|
33
|
-
# config.apns.feedback_receiver.enabled = true
|
34
|
-
# config.apns.feedback_receiver.frequency = 60
|
35
|
-
|
36
33
|
end
|
37
34
|
|
38
35
|
Rpush.reflect do |on|
|
@@ -76,30 +73,43 @@ Rpush.reflect do |on|
|
|
76
73
|
# on.notification_id_will_retry do |app, notification_id, retry_after|
|
77
74
|
# end
|
78
75
|
|
79
|
-
# Called
|
80
|
-
#
|
76
|
+
# Called for each recipient which successfully receives a notification. This
|
77
|
+
# can occur more than once for the same notification when there are multiple
|
78
|
+
# recipients.
|
79
|
+
# on.fcm_delivered_to_recipient do |notification|
|
80
|
+
# end
|
81
|
+
|
82
|
+
# Called for each recipient which fails to receive a notification. This
|
83
|
+
# can occur more than once for the same notification when there are multiple
|
84
|
+
# recipients. (do not handle invalid device tokens here)
|
85
|
+
# on.fcm_failed_to_recipient do |notification, error|
|
86
|
+
# end
|
87
|
+
|
88
|
+
# Called when the FCM returns a failure that indicates an invalid device token.
|
89
|
+
# You will need to delete the device token from your records.
|
90
|
+
# on.fcm_invalid_device_token do |app, error, device_token|
|
81
91
|
# end
|
82
92
|
|
83
93
|
# Called for each recipient which successfully receives a notification. This
|
84
94
|
# can occur more than once for the same notification when there are multiple
|
85
95
|
# recipients.
|
86
|
-
# on.
|
96
|
+
# on.fcm_delivered_to_recipient do |notification, device_token|
|
87
97
|
# end
|
88
98
|
|
89
99
|
# Called for each recipient which fails to receive a notification. This
|
90
100
|
# can occur more than once for the same notification when there are multiple
|
91
|
-
# recipients. (do not handle invalid
|
92
|
-
# on.
|
101
|
+
# recipients. (do not handle invalid device tokens here)
|
102
|
+
# on.fcm_failed_to_recipient do |notification, error, device_token|
|
93
103
|
# end
|
94
104
|
|
95
|
-
# Called when the
|
105
|
+
# Called when the FCM returns a canonical device token.
|
96
106
|
# You will need to replace old_id with canonical_id in your records.
|
97
|
-
# on.
|
107
|
+
# on.fcm_canonical_id do |old_id, canonical_id|
|
98
108
|
# end
|
99
109
|
|
100
|
-
# Called when the
|
101
|
-
# You will need to delete the
|
102
|
-
# on.
|
110
|
+
# Called when the FCM returns a failure that indicates an invalid device token.
|
111
|
+
# You will need to delete the device_token from your records.
|
112
|
+
# on.fcm_invalid_device_token do |app, error, device_token|
|
103
113
|
# end
|
104
114
|
|
105
115
|
# Called when an SSL certificate will expire within 1 month.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Rpush710Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
2
|
+
def self.up
|
3
|
+
add_column :rpush_apps, :firebase_project_id, :string
|
4
|
+
add_column :rpush_apps, :json_key, :text
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_column :rpush_apps, :firebase_project_id
|
9
|
+
remove_column :rpush_apps, :json_key
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -52,10 +52,6 @@ module Rpush
|
|
52
52
|
self.data = (data || {}).merge(CONTENT_AVAILABLE_KEY => true)
|
53
53
|
end
|
54
54
|
|
55
|
-
def content_available?
|
56
|
-
(self.data || {})[CONTENT_AVAILABLE_KEY]
|
57
|
-
end
|
58
|
-
|
59
55
|
def as_json(options = nil) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
60
56
|
json = ActiveSupport::OrderedHash.new
|
61
57
|
|
@@ -1,16 +1,17 @@
|
|
1
1
|
module Rpush
|
2
2
|
module Client
|
3
3
|
module ActiveModel
|
4
|
-
module
|
4
|
+
module Fcm
|
5
5
|
module App
|
6
6
|
def self.included(base)
|
7
7
|
base.instance_eval do
|
8
|
-
|
8
|
+
# TODO: Add whatever validation is needed here
|
9
|
+
# validates :auth_key, presence: true
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
12
13
|
def service_name
|
13
|
-
'
|
14
|
+
'fcm'
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Rpush
|
2
|
+
module Client
|
3
|
+
module ActiveModel
|
4
|
+
module Fcm
|
5
|
+
module Notification
|
6
|
+
FCM_PRIORITY_HIGH = Rpush::Client::ActiveModel::Apns::Notification::APNS_PRIORITY_IMMEDIATE
|
7
|
+
FCM_PRIORITY_NORMAL = Rpush::Client::ActiveModel::Apns::Notification::APNS_PRIORITY_CONSERVE_POWER
|
8
|
+
FCM_PRIORITIES = [FCM_PRIORITY_HIGH, FCM_PRIORITY_NORMAL]
|
9
|
+
|
10
|
+
ROOT_NOTIFICATION_KEYS = %w[title body image].freeze
|
11
|
+
ANDROID_NOTIFICATION_KEYS = %w[icon tag color click_action body_loc_key body_loc_args title_loc_key
|
12
|
+
title_loc_args channel_id ticker sticky event_time local_only
|
13
|
+
default_vibrate_timings default_light_settings vibrate_timings
|
14
|
+
visibility notification_count light_settings].freeze
|
15
|
+
|
16
|
+
def self.included(base)
|
17
|
+
base.instance_eval do
|
18
|
+
validates :device_token, presence: true
|
19
|
+
validates :priority, inclusion: { in: FCM_PRIORITIES }, allow_nil: true
|
20
|
+
|
21
|
+
validates_with Rpush::Client::ActiveModel::PayloadDataSizeValidator, limit: 4096
|
22
|
+
validates_with Rpush::Client::ActiveModel::RegistrationIdsCountValidator, limit: 1000
|
23
|
+
|
24
|
+
validates_with Rpush::Client::ActiveModel::Fcm::ExpiryCollapseKeyMutualInclusionValidator
|
25
|
+
validates_with Rpush::Client::ActiveModel::Fcm::NotificationKeysInAllowedListValidator
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def payload_data_size
|
30
|
+
multi_json_dump(as_json['message']['data']).bytesize
|
31
|
+
end
|
32
|
+
|
33
|
+
# This is a hack. The schema defines `priority` to be an integer, but FCM expects a string.
|
34
|
+
# But for users of rpush to have an API they might expect (setting priority to `high`, not 10)
|
35
|
+
# we do a little conversion here.
|
36
|
+
def priority=(priority)
|
37
|
+
case priority
|
38
|
+
when 'high', FCM_PRIORITY_HIGH
|
39
|
+
super(FCM_PRIORITY_HIGH)
|
40
|
+
when 'normal', FCM_PRIORITY_NORMAL
|
41
|
+
super(FCM_PRIORITY_NORMAL)
|
42
|
+
else
|
43
|
+
errors.add(:priority, 'must be one of either "normal" or "high"')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def dry_run=(value)
|
48
|
+
fail ArgumentError, 'FCM does not support dry run' if value
|
49
|
+
end
|
50
|
+
|
51
|
+
def as_json(options = nil) # rubocop:disable Metrics/PerceivedComplexity
|
52
|
+
json = {
|
53
|
+
'data' => data,
|
54
|
+
'android' => android_config,
|
55
|
+
'apns' => apns_config,
|
56
|
+
'token' => device_token
|
57
|
+
}
|
58
|
+
|
59
|
+
json['notification'] = root_notification if notification
|
60
|
+
{ 'message' => json }
|
61
|
+
end
|
62
|
+
|
63
|
+
def android_config
|
64
|
+
json = ActiveSupport::OrderedHash.new
|
65
|
+
json['notification'] = android_notification if notification
|
66
|
+
json['collapse_key'] = collapse_key if collapse_key
|
67
|
+
json['priority'] = priority_str if priority
|
68
|
+
json['ttl'] = "#{expiry}s" if expiry
|
69
|
+
json
|
70
|
+
end
|
71
|
+
|
72
|
+
def apns_config
|
73
|
+
json = ActiveSupport::OrderedHash.new
|
74
|
+
json['payload'] = ActiveSupport::OrderedHash.new
|
75
|
+
|
76
|
+
aps = ActiveSupport::OrderedHash.new
|
77
|
+
aps['mutable-content'] = 1 if mutable_content
|
78
|
+
aps['content-available'] = 1 if content_available
|
79
|
+
aps['sound'] = 'default' if sound == 'default'
|
80
|
+
|
81
|
+
json['payload']['aps'] = aps
|
82
|
+
|
83
|
+
json
|
84
|
+
end
|
85
|
+
|
86
|
+
def notification=(value)
|
87
|
+
value = value.with_indifferent_access if value.is_a?(Hash)
|
88
|
+
super(value)
|
89
|
+
end
|
90
|
+
|
91
|
+
def root_notification
|
92
|
+
return {} unless notification
|
93
|
+
|
94
|
+
notification.slice(*ROOT_NOTIFICATION_KEYS)
|
95
|
+
end
|
96
|
+
|
97
|
+
def android_notification
|
98
|
+
json = notification&.slice(*ANDROID_NOTIFICATION_KEYS) || {}
|
99
|
+
json['notification_priority'] = priority_for_notification if priority
|
100
|
+
json['sound'] = sound if sound
|
101
|
+
json['default_sound'] = sound == 'default' ? true : false
|
102
|
+
json
|
103
|
+
end
|
104
|
+
|
105
|
+
def priority_str
|
106
|
+
case
|
107
|
+
when priority <= 5 then 'normal'
|
108
|
+
else
|
109
|
+
'high'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def priority_for_notification
|
114
|
+
case priority
|
115
|
+
when 0 then 'PRIORITY_UNSPECIFIED'
|
116
|
+
when 1 then 'PRIORITY_MIN'
|
117
|
+
when 2 then 'PRIORITY_LOW'
|
118
|
+
when 5 then 'PRIORITY_DEFAULT'
|
119
|
+
when 6 then 'PRIORITY_HIGH'
|
120
|
+
when 10 then 'PRIORITY_MAX'
|
121
|
+
else
|
122
|
+
'PRIORITY_DEFAULT'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rpush
|
2
|
+
module Client
|
3
|
+
module ActiveModel
|
4
|
+
module Fcm
|
5
|
+
class NotificationKeysInAllowedListValidator < ::ActiveModel::Validator
|
6
|
+
def validate(record)
|
7
|
+
return unless record.notification
|
8
|
+
|
9
|
+
allowed_keys = Notification::ROOT_NOTIFICATION_KEYS + Notification::ANDROID_NOTIFICATION_KEYS
|
10
|
+
invalid_keys = record.notification.keys - allowed_keys
|
11
|
+
|
12
|
+
return if invalid_keys.empty?
|
13
|
+
|
14
|
+
record.errors.add(:notification, "contains invalid keys: #{invalid_keys.join(', ')}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -20,9 +20,10 @@ require 'rpush/client/active_model/adm/data_validator'
|
|
20
20
|
require 'rpush/client/active_model/adm/app'
|
21
21
|
require 'rpush/client/active_model/adm/notification'
|
22
22
|
|
23
|
-
require 'rpush/client/active_model/
|
24
|
-
require 'rpush/client/active_model/
|
25
|
-
require 'rpush/client/active_model/
|
23
|
+
require 'rpush/client/active_model/fcm/expiry_collapse_key_mutual_inclusion_validator'
|
24
|
+
require 'rpush/client/active_model/fcm/notification_keys_in_allowed_list_validator'
|
25
|
+
require 'rpush/client/active_model/fcm/app'
|
26
|
+
require 'rpush/client/active_model/fcm/notification'
|
26
27
|
|
27
28
|
require 'rpush/client/active_model/wpns/app'
|
28
29
|
require 'rpush/client/active_model/wpns/notification'
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Rpush
|
2
2
|
module Client
|
3
3
|
module ActiveRecord
|
4
|
-
module
|
4
|
+
module Fcm
|
5
5
|
class Notification < Rpush::Client::ActiveRecord::Notification
|
6
|
-
include Rpush::Client::ActiveModel::
|
6
|
+
include Rpush::Client::ActiveModel::Fcm::Notification
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -16,8 +16,8 @@ require 'rpush/client/active_record/apns2/app'
|
|
16
16
|
require 'rpush/client/active_record/apnsp8/notification'
|
17
17
|
require 'rpush/client/active_record/apnsp8/app'
|
18
18
|
|
19
|
-
require 'rpush/client/active_record/
|
20
|
-
require 'rpush/client/active_record/
|
19
|
+
require 'rpush/client/active_record/fcm/notification'
|
20
|
+
require 'rpush/client/active_record/fcm/app'
|
21
21
|
|
22
22
|
require 'rpush/client/active_record/wpns/notification'
|
23
23
|
require 'rpush/client/active_record/wpns/app'
|
data/lib/rpush/client/redis.rb
CHANGED
@@ -27,8 +27,8 @@ require 'rpush/client/redis/apns2/notification'
|
|
27
27
|
require 'rpush/client/redis/apnsp8/app'
|
28
28
|
require 'rpush/client/redis/apnsp8/notification'
|
29
29
|
|
30
|
-
require 'rpush/client/redis/
|
31
|
-
require 'rpush/client/redis/
|
30
|
+
require 'rpush/client/redis/fcm/app'
|
31
|
+
require 'rpush/client/redis/fcm/notification'
|
32
32
|
|
33
33
|
require 'rpush/client/redis/adm/app'
|
34
34
|
require 'rpush/client/redis/adm/notification'
|
data/lib/rpush/configuration.rb
CHANGED
@@ -16,27 +16,12 @@ module Rpush
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
CURRENT_ATTRS = [:push_poll, :embedded, :pid_file, :batch_size, :push, :client, :logger, :log_file, :foreground, :foreground_logging, :log_level, :plugin
|
19
|
+
CURRENT_ATTRS = [:push_poll, :embedded, :pid_file, :batch_size, :push, :client, :logger, :log_file, :foreground, :foreground_logging, :log_level, :plugin]
|
20
20
|
DEPRECATED_ATTRS = []
|
21
21
|
CONFIG_ATTRS = CURRENT_ATTRS + DEPRECATED_ATTRS
|
22
22
|
|
23
23
|
class ConfigurationError < StandardError; end
|
24
24
|
|
25
|
-
class ApnsFeedbackReceiverConfiguration < Struct.new(:frequency, :enabled) # rubocop:disable Style/StructInheritance
|
26
|
-
def initialize
|
27
|
-
super
|
28
|
-
self.enabled = true
|
29
|
-
self.frequency = 60
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class ApnsConfiguration < Struct.new(:feedback_receiver) # rubocop:disable Style/StructInheritance
|
34
|
-
def initialize
|
35
|
-
super
|
36
|
-
self.feedback_receiver = ApnsFeedbackReceiverConfiguration.new
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
25
|
class Configuration < Struct.new(*CONFIG_ATTRS) # rubocop:disable Style/StructInheritance
|
41
26
|
include Deprecatable
|
42
27
|
|
@@ -55,8 +40,6 @@ module Rpush
|
|
55
40
|
self.foreground = false
|
56
41
|
self.foreground_logging = true
|
57
42
|
|
58
|
-
self.apns = ApnsConfiguration.new
|
59
|
-
|
60
43
|
# Internal options.
|
61
44
|
self.embedded = false
|
62
45
|
self.push = false
|
@@ -106,7 +89,7 @@ module Rpush
|
|
106
89
|
client_module = Rpush::Client.const_get(client.to_s.camelize)
|
107
90
|
Rpush.send(:include, client_module) unless Rpush.ancestors.include?(client_module)
|
108
91
|
|
109
|
-
[:Apns, :
|
92
|
+
[:Apns, :Fcm, :Wpns, :Wns, :Adm, :Pushy, :Webpush].each do |service|
|
110
93
|
Rpush.const_set(service, client_module.const_get(service)) unless Rpush.const_defined?(service)
|
111
94
|
end
|
112
95
|
|
@@ -112,7 +112,6 @@ module Rpush
|
|
112
112
|
headers['apns-expiration'] = '0'
|
113
113
|
headers['apns-priority'] = '10'
|
114
114
|
headers['apns-topic'] = @app.bundle_id
|
115
|
-
headers['apns-push-type'] = 'background' if notification.content_available?
|
116
115
|
|
117
116
|
headers.merge notification_data(notification)[HTTP2_HEADERS_KEY] || {}
|
118
117
|
end
|
@@ -149,7 +149,6 @@ module Rpush
|
|
149
149
|
headers['apns-priority'] = '10'
|
150
150
|
headers['apns-topic'] = @app.bundle_id
|
151
151
|
headers['authorization'] = "bearer #{jwt_token}"
|
152
|
-
headers['apns-push-type'] = 'background' if notification.content_available?
|
153
152
|
|
154
153
|
headers.merge notification_data(notification)[HTTP2_HEADERS_KEY] || {}
|
155
154
|
end
|