rapns_rails_2 3.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/CHANGELOG.md +83 -0
- data/LICENSE +7 -0
- data/README.md +168 -0
- data/bin/rapns +37 -0
- data/config/database.yml +44 -0
- data/lib/generators/rapns_generator.rb +25 -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_gcm.rb +95 -0
- data/lib/generators/templates/create_rapns_apps.rb +16 -0
- data/lib/generators/templates/create_rapns_feedback.rb +15 -0
- data/lib/generators/templates/create_rapns_notifications.rb +26 -0
- data/lib/generators/templates/rapns.rb +87 -0
- data/lib/rapns/TODO +3 -0
- data/lib/rapns/apns/app.rb +25 -0
- data/lib/rapns/apns/binary_notification_validator.rb +12 -0
- data/lib/rapns/apns/device_token_format_validator.rb +12 -0
- data/lib/rapns/apns/feedback.rb +16 -0
- data/lib/rapns/apns/notification.rb +91 -0
- data/lib/rapns/apns_feedback.rb +13 -0
- data/lib/rapns/app.rb +16 -0
- data/lib/rapns/configuration.rb +89 -0
- data/lib/rapns/daemon/apns/app_runner.rb +26 -0
- data/lib/rapns/daemon/apns/certificate_expired_error.rb +20 -0
- data/lib/rapns/daemon/apns/connection.rb +142 -0
- data/lib/rapns/daemon/apns/delivery.rb +64 -0
- data/lib/rapns/daemon/apns/delivery_handler.rb +35 -0
- data/lib/rapns/daemon/apns/disconnection_error.rb +20 -0
- data/lib/rapns/daemon/apns/feedback_receiver.rb +89 -0
- data/lib/rapns/daemon/app_runner.rb +179 -0
- data/lib/rapns/daemon/batch.rb +112 -0
- data/lib/rapns/daemon/delivery.rb +23 -0
- data/lib/rapns/daemon/delivery_error.rb +19 -0
- data/lib/rapns/daemon/delivery_handler.rb +52 -0
- data/lib/rapns/daemon/delivery_handler_collection.rb +33 -0
- data/lib/rapns/daemon/feeder.rb +65 -0
- data/lib/rapns/daemon/gcm/app_runner.rb +13 -0
- data/lib/rapns/daemon/gcm/delivery.rb +228 -0
- data/lib/rapns/daemon/gcm/delivery_handler.rb +20 -0
- data/lib/rapns/daemon/interruptible_sleep.rb +65 -0
- data/lib/rapns/daemon/reflectable.rb +13 -0
- data/lib/rapns/daemon/store/active_record/reconnectable.rb +66 -0
- data/lib/rapns/daemon/store/active_record.rb +128 -0
- data/lib/rapns/daemon.rb +129 -0
- data/lib/rapns/deprecatable.rb +23 -0
- data/lib/rapns/deprecation.rb +23 -0
- data/lib/rapns/embed.rb +28 -0
- data/lib/rapns/gcm/app.rb +7 -0
- data/lib/rapns/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +11 -0
- data/lib/rapns/gcm/notification.rb +37 -0
- data/lib/rapns/gcm/payload_data_size_validator.rb +13 -0
- data/lib/rapns/gcm/registration_ids_count_validator.rb +13 -0
- data/lib/rapns/logger.rb +76 -0
- data/lib/rapns/multi_json_helper.rb +16 -0
- data/lib/rapns/notification.rb +62 -0
- data/lib/rapns/notifier.rb +35 -0
- data/lib/rapns/push.rb +17 -0
- data/lib/rapns/rails-2-compatibility.rb +34 -0
- data/lib/rapns/reflection.rb +44 -0
- data/lib/rapns/upgraded.rb +31 -0
- data/lib/rapns/version.rb +3 -0
- data/lib/rapns_rails_2.rb +67 -0
- data/lib/tasks/cane.rake +18 -0
- data/lib/tasks/test.rake +38 -0
- data/spec/support/cert_with_password.pem +90 -0
- data/spec/support/cert_without_password.pem +59 -0
- data/spec/support/simplecov_helper.rb +13 -0
- data/spec/support/simplecov_quality_formatter.rb +8 -0
- data/spec/tmp/.gitkeep +0 -0
- data/spec/unit/apns/app_spec.rb +29 -0
- data/spec/unit/apns/feedback_spec.rb +9 -0
- data/spec/unit/apns/notification_spec.rb +215 -0
- data/spec/unit/apns_feedback_spec.rb +21 -0
- data/spec/unit/app_spec.rb +16 -0
- data/spec/unit/configuration_spec.rb +55 -0
- data/spec/unit/daemon/apns/app_runner_spec.rb +45 -0
- data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +11 -0
- data/spec/unit/daemon/apns/connection_spec.rb +287 -0
- data/spec/unit/daemon/apns/delivery_handler_spec.rb +59 -0
- data/spec/unit/daemon/apns/delivery_spec.rb +101 -0
- data/spec/unit/daemon/apns/disconnection_error_spec.rb +18 -0
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +134 -0
- data/spec/unit/daemon/app_runner_shared.rb +83 -0
- data/spec/unit/daemon/app_runner_spec.rb +170 -0
- data/spec/unit/daemon/batch_spec.rb +219 -0
- data/spec/unit/daemon/delivery_error_spec.rb +13 -0
- data/spec/unit/daemon/delivery_handler_collection_spec.rb +37 -0
- data/spec/unit/daemon/delivery_handler_shared.rb +45 -0
- data/spec/unit/daemon/feeder_spec.rb +81 -0
- data/spec/unit/daemon/gcm/app_runner_spec.rb +19 -0
- data/spec/unit/daemon/gcm/delivery_handler_spec.rb +44 -0
- data/spec/unit/daemon/gcm/delivery_spec.rb +289 -0
- data/spec/unit/daemon/interruptible_sleep_spec.rb +68 -0
- data/spec/unit/daemon/reflectable_spec.rb +27 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +114 -0
- data/spec/unit/daemon/store/active_record_spec.rb +281 -0
- data/spec/unit/daemon_spec.rb +157 -0
- data/spec/unit/deprecatable_spec.rb +32 -0
- data/spec/unit/deprecation_spec.rb +15 -0
- data/spec/unit/embed_spec.rb +50 -0
- data/spec/unit/gcm/app_spec.rb +4 -0
- data/spec/unit/gcm/notification_spec.rb +52 -0
- data/spec/unit/logger_spec.rb +180 -0
- data/spec/unit/notification_shared.rb +45 -0
- data/spec/unit/notification_spec.rb +4 -0
- data/spec/unit/notifier_spec.rb +32 -0
- data/spec/unit/push_spec.rb +44 -0
- data/spec/unit/rapns_spec.rb +9 -0
- data/spec/unit/reflection_spec.rb +30 -0
- data/spec/unit/upgraded_spec.rb +40 -0
- data/spec/unit_spec_helper.rb +137 -0
- metadata +232 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ODdlNDhlOTIzODkyMDZiODdiNzIwYjAyNDJlNjkzZDYyMmYyZDhjNQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NDlhMWY3NGRmOTUwMmQ1NGRjMjg2MjE2ZDY5NmYwNWE5NjgyZWM1MA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MTkzNDAxZTZmNWM4YTg3OTEzYWJhM2Q1YmE3MzBhZjg0YjUxYWJmMjAwYWMz
|
10
|
+
NGZmMGM0Mzk4MDM1MGU3OTFjZWVlNThhZTg1MDhiMmRmNDFhZjk3ZjcxYTA4
|
11
|
+
OTllMzFjM2NkZWRmYmVhZTlmOTkwYzlhMGI3NmVkZjQ1NjRiMTE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzQ3ZmMzMzU1MzFmYzczZGI4M2FlYWRjMTY3Y2NmNmJlOTY5Y2UxMWNhODUz
|
14
|
+
NTlmY2QwNTEyMmM0MWVkNGExNGJiNjdlYmViNjY3MzkyOWFhM2M3ZWUwY2Jm
|
15
|
+
M2Q0ODNlNmJiMmU1MDI2Mjc3ZGIzYjE1ZWQ1YjgxZmZiNGY3MzU=
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
## 3.4.2 (unreleased)
|
2
|
+
* Fix sqlite3 support (#160).
|
3
|
+
|
4
|
+
## 3.4.1 (Aug 30, 2013)
|
5
|
+
* Silence unintended airbrake_notify deprecation warning (#158).
|
6
|
+
* Add :dependent => :destroy to app notifications (#156).
|
7
|
+
|
8
|
+
## 3.4.0 (Aug 28, 2013)
|
9
|
+
* Rails 4 support.
|
10
|
+
* Add apns_certificate_will_expire reflection.
|
11
|
+
* Perform storage update in batches where possible, to increase throughput.
|
12
|
+
* airbrake_notify is now deprecated, use the Reflection API instead.
|
13
|
+
* Fix calling the notification_delivered reflection twice (#149).
|
14
|
+
|
15
|
+
## 3.3.2 (June 30, 2013)
|
16
|
+
* Fix Rails 3.0.x compatibility (#138) (@yoppi).
|
17
|
+
* Ensure Rails does not set a default value for text columns (#137).
|
18
|
+
* Fix error in down action for add_gcm migration (#135) (@alexperto).
|
19
|
+
|
20
|
+
## 3.3.1 (June 2, 2013)
|
21
|
+
* Fix compatibility with postgres_ext (#104).
|
22
|
+
* Add ability to switch the logger (@maxsz).
|
23
|
+
* Do not validate presence of alert, badge or sound - not actually required by the APNs (#129) (@wilg).
|
24
|
+
* Catch IOError from an APNs connection. (@maxsz).
|
25
|
+
* Allow nested hashes in APNs notification attributes (@perezda).
|
26
|
+
|
27
|
+
## 3.3.0 (April 21, 2013)
|
28
|
+
* GCM: collapse_key is no longer required to set expiry (time_to_live).
|
29
|
+
* Add reflection for GCM canonical IDs.
|
30
|
+
* Add Rapns::Daemon.store to decouple storage backend.
|
31
|
+
|
32
|
+
## 3.2.0 (Apr 1, 2013)
|
33
|
+
* Rapns.apns_feedback for one time feedback retrieval. Rapns.push no longer checks for feedback (#117, #105).
|
34
|
+
* Lazily connect to the APNs only when a notification is to be delivered (#111).
|
35
|
+
* Ensure all notifications are sent when using Rapns.push (#107).
|
36
|
+
* Fix issue with running Rapns.push more than once in the same process (#106).
|
37
|
+
|
38
|
+
## 3.1.0 (Jan 26, 2013)
|
39
|
+
* Rapns.reflect API for fine-grained introspection.
|
40
|
+
* Rapns.embed API for embedding Rapns into an existing process.
|
41
|
+
* Rapns.push API for using Rapns in scheduled jobs.
|
42
|
+
* Fix issue with integration with ActiveScaffold (#98) (@jeffarena).
|
43
|
+
* Fix content-available setter for APNs (#95) (@dup2).
|
44
|
+
* GCM validation fixes (#96) (@DianthuDia).
|
45
|
+
|
46
|
+
## 3.0.1 (Dec 16, 2012)
|
47
|
+
* Fix compatibility with Rails 3.0.x. Fixes #89.
|
48
|
+
|
49
|
+
## 3.0.0 (Dec 15, 2012)
|
50
|
+
* Add support for Google Cloud Messaging.
|
51
|
+
* Fix Heroku logging issue.
|
52
|
+
|
53
|
+
## 2.0.5 (Nov 4, 2012) ##
|
54
|
+
* Support content-available (#68).
|
55
|
+
* Append to log files.
|
56
|
+
* Fire a callback when Feedback is received.
|
57
|
+
|
58
|
+
## 2.0.5.rc1 (Oct 5, 2012) ##
|
59
|
+
* Release db connections back into the pool after use (#72).
|
60
|
+
* Continue to start daemon if a connection cannot be made during startup (#62) (@mattconnolly).
|
61
|
+
|
62
|
+
## 2.0.4 (Aug 6, 2012) ##
|
63
|
+
* Don't exit when there aren't any Rapns::App instances, just warn (#55).
|
64
|
+
|
65
|
+
## 2.0.3 (July 26, 2012) ##
|
66
|
+
* JRuby support.
|
67
|
+
* Explicitly list all attributes instead of calling column_names (#53).
|
68
|
+
|
69
|
+
## 2.0.2 (July 25, 2012) ##
|
70
|
+
* Support MultiJson < 1.3.0.
|
71
|
+
* Make all model attributes accessible.
|
72
|
+
|
73
|
+
## 2.0.1 (July 7, 2012) ##
|
74
|
+
* Fix delivery when using Ruby 1.8.
|
75
|
+
* MultiJson support.
|
76
|
+
|
77
|
+
## 2.0.0 (June 19, 2012) ##
|
78
|
+
|
79
|
+
* Support for multiple apps.
|
80
|
+
* Hot Updates - add/remove apps without restart.
|
81
|
+
* MDM support.
|
82
|
+
* Removed rapns.yml in favour of command line options.
|
83
|
+
* Started the changelog!
|
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2012 Ian Leitch
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
[![Build Status](https://secure.travis-ci.org/ileitch/rapns.png?branch=master)](http://travis-ci.org/ileitch/rapns)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/ileitch/rapns.png)](https://codeclimate.com/github/ileitch/rapns)
|
3
|
+
|
4
|
+
### Rapns - Professional grade APNs and GCM for Ruby.
|
5
|
+
|
6
|
+
* Supports both APNs (iOS) and GCM (Google Cloud Messaging, Android).
|
7
|
+
* Seamless Rails (3, 4) integration.
|
8
|
+
* Scalable - choose the number of persistent connections for each app.
|
9
|
+
* Designed for uptime - signal -HUP to add, update apps.
|
10
|
+
* Stable - reconnects database and network connections when lost.
|
11
|
+
* Run as a daemon or inside an [existing processs](https://github.com/ileitch/rapns/wiki/Embedding-API).
|
12
|
+
* Use in a scheduler for low-workload deployments ([Push API](https://github.com/ileitch/rapns/wiki/Push-API)).
|
13
|
+
* Reflection API for fine-grained instrumentation and error handling ([Reflection API](https://github.com/ileitch/rapns/wiki/Reflection-API)).
|
14
|
+
* Works with MRI, JRuby, Rubinius 1.8 and 1.9.
|
15
|
+
* Built with love.
|
16
|
+
|
17
|
+
### Who uses Rapns?
|
18
|
+
|
19
|
+
[GateGuru](http://gateguruapp.com) and [Desk.com](http://desk.com), among others!
|
20
|
+
|
21
|
+
*I'd love to hear if you use Rapns - @ileitch on twitter.*
|
22
|
+
|
23
|
+
## Getting Started
|
24
|
+
|
25
|
+
Add Rapns to your Gemfile:
|
26
|
+
|
27
|
+
gem 'rapns'
|
28
|
+
|
29
|
+
Generate the migrations, rapns.yml and migrate:
|
30
|
+
|
31
|
+
rails g rapns
|
32
|
+
rake db:migrate
|
33
|
+
|
34
|
+
## Create an App & Notification
|
35
|
+
|
36
|
+
#### APNs
|
37
|
+
|
38
|
+
If this is your first time using the APNs, you will need to generate SSL certificates. See [Generating Certificates](https://github.com/ileitch/rapns/wiki/Generating-Certificates) for instructions.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
app = Rapns::Apns::App.new
|
42
|
+
app.name = "ios_app"
|
43
|
+
app.certificate = File.read("/path/to/sandbox.pem")
|
44
|
+
app.environment = "sandbox" # APNs environment.
|
45
|
+
app.password = "certificate password"
|
46
|
+
app.connections = 1
|
47
|
+
app.save!
|
48
|
+
```
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
n = Rapns::Apns::Notification.new
|
52
|
+
n.app = Rapns::Apns::App.find_by_name("ios_app")
|
53
|
+
n.device_token = "..."
|
54
|
+
n.alert = "hi mom!"
|
55
|
+
n.attributes_for_device = {:foo => :bar}
|
56
|
+
n.save!
|
57
|
+
```
|
58
|
+
|
59
|
+
You should also implement the [apns_certificate_will_expire](https://github.com/ileitch/rapns/wiki/Reflection-API) reflection to monitor when your certificate is due to expire.
|
60
|
+
|
61
|
+
#### GCM
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
app = Rapns::Gcm::App.new
|
65
|
+
app.name = "android_app"
|
66
|
+
app.auth_key = "..."
|
67
|
+
app.connections = 1
|
68
|
+
app.save!
|
69
|
+
```
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
n = Rapns::Gcm::Notification.new
|
73
|
+
n.app = Rapns::Gcm::App.find_by_name("android_app")
|
74
|
+
n.registration_ids = ["..."]
|
75
|
+
n.data = {:message => "hi mom!"}
|
76
|
+
n.save!
|
77
|
+
```
|
78
|
+
|
79
|
+
GCM also requires you to respond to [Canonical IDs](https://github.com/ileitch/rapns/wiki/Canonical-IDs).
|
80
|
+
|
81
|
+
## Starting Rapns
|
82
|
+
|
83
|
+
As a daemon:
|
84
|
+
|
85
|
+
cd /path/to/rails/app
|
86
|
+
rapns <Rails environment> [options]
|
87
|
+
|
88
|
+
Inside an existing process (see [Embedding API](https://github.com/ileitch/rapns/wiki/Embedding-API)):
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Rapns.embed
|
92
|
+
```
|
93
|
+
|
94
|
+
*Please note that only ever a single instance of Rapns should be running.*
|
95
|
+
|
96
|
+
In a scheduler (see [Push API](https://github.com/ileitch/rapns/wiki/Push-API)):
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
Rapns.push
|
100
|
+
Rapns.apns_feedback
|
101
|
+
```
|
102
|
+
|
103
|
+
See [Configuration](https://github.com/ileitch/rapns/wiki/Configuration) for a list of options, or run `rapns --help`.
|
104
|
+
|
105
|
+
## Updating Rapns
|
106
|
+
|
107
|
+
After updating you should run `rails g rapns` to check for any new migrations.
|
108
|
+
|
109
|
+
## Wiki
|
110
|
+
|
111
|
+
### General
|
112
|
+
* [Configuration](https://github.com/ileitch/rapns/wiki/Configuration)
|
113
|
+
* [Upgrading from 2.x to 3.0](https://github.com/ileitch/rapns/wiki/Upgrading-from-version-2.x-to-3.0)
|
114
|
+
* [Deploying to Heroku](https://github.com/ileitch/rapns/wiki/Heroku)
|
115
|
+
* [Hot App Updates](https://github.com/ileitch/rapns/wiki/Hot-App-Updates)
|
116
|
+
* [Signals](https://github.com/ileitch/rapns/wiki/Signals)
|
117
|
+
* [Reflection API](https://github.com/ileitch/rapns/wiki/Reflection-API)
|
118
|
+
* [Push API](https://github.com/ileitch/rapns/wiki/Push-API)
|
119
|
+
* [Embedding API](https://github.com/ileitch/rapns/wiki/Embedding-API)
|
120
|
+
* [Implementing your own storage backend](https://github.com/ileitch/rapns/wiki/Implementing-your-own-storage-backend)
|
121
|
+
|
122
|
+
### APNs
|
123
|
+
* [Generating Certificates](https://github.com/ileitch/rapns/wiki/Generating-Certificates)
|
124
|
+
* [Advanced APNs Features](https://github.com/ileitch/rapns/wiki/Advanced-APNs-Features)
|
125
|
+
* [APNs Delivery Failure Handling](https://github.com/ileitch/rapns/wiki/APNs-Delivery-Failure-Handling)
|
126
|
+
* [Why open multiple connections to the APNs?](https://github.com/ileitch/rapns/wiki/Why-open-multiple-connections-to-the-APNs%3F)
|
127
|
+
* [Silent failures might be dropped connections](https://github.com/ileitch/rapns/wiki/Dropped-connections)
|
128
|
+
|
129
|
+
### GCM
|
130
|
+
* [Notification Options](https://github.com/ileitch/rapns/wiki//GCM-Notification-Options)
|
131
|
+
* [Canonical IDs](https://github.com/ileitch/rapns/wiki/Canonical-IDs)
|
132
|
+
* [Delivery Failures & Retries](https://github.com/ileitch/rapns/wiki/Delivery-Failures-&-Retries)
|
133
|
+
|
134
|
+
## Contributing
|
135
|
+
|
136
|
+
Fork as usual and go crazy!
|
137
|
+
|
138
|
+
When running specs, please note that the ActiveRecord adapter can be changed by setting the `ADAPTER` environment variable. For example: `ADAPTER=postgresql rake`.
|
139
|
+
|
140
|
+
Available adapters for testing are `mysql`, `mysql2` and `postgresql`.
|
141
|
+
|
142
|
+
Note that the database username is changed at runtime to be the currently logged in user's name. So if you're testing
|
143
|
+
with mysql and you're using a user named 'bob', you will need to grant a mysql user 'bob' access to the 'rapns_test'
|
144
|
+
mysql database.
|
145
|
+
|
146
|
+
### Contributors
|
147
|
+
|
148
|
+
Thank you to the following wonderful people for contributing:
|
149
|
+
|
150
|
+
* [@blakewatters](https://github.com/blakewatters)
|
151
|
+
* [@forresty](https://github.com/forresty)
|
152
|
+
* [@sjmadsen](https://github.com/sjmadsen)
|
153
|
+
* [@ivanyv](https://github.com/ivanyv)
|
154
|
+
* [@taybenlor](https://github.com/taybenlor)
|
155
|
+
* [@tompesman](https://github.com/tompesman)
|
156
|
+
* [@EpicDraws](https://github.com/EpicDraws)
|
157
|
+
* [@dei79](https://github.com/dei79)
|
158
|
+
* [@adorr](https://github.com/adorr)
|
159
|
+
* [@mattconnolly](https://github.com/mattconnolly)
|
160
|
+
* [@emeitch](https://github.com/emeitch)
|
161
|
+
* [@jeffarena](https://github.com/jeffarena)
|
162
|
+
* [@DianthuDia](https://github.com/DianthuDia)
|
163
|
+
* [@dup2](https://github.com/dup2)
|
164
|
+
* [@maxsz](https://github.com/maxsz)
|
165
|
+
* [@wilg](https://github.com/wilg)
|
166
|
+
* [@perezda](https://github.com/perezda)
|
167
|
+
* [@alexperto](https://github.com/alexperto)
|
168
|
+
* [@yoppi](https://github.com/yoppi)
|
data/bin/rapns
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'rapns_rails_2'
|
5
|
+
|
6
|
+
environment = ARGV[0]
|
7
|
+
|
8
|
+
config = Rapns::ConfigurationWithoutDefaults.new
|
9
|
+
|
10
|
+
options = ARGV.options do |opts|
|
11
|
+
opts.banner = 'Usage: rapns <Rails environment> [options]'
|
12
|
+
opts.on('-f', '--foreground', 'Run in the foreground.') { config.foreground = true }
|
13
|
+
opts.on('-P N', '--db-poll N', Integer, "Frequency in seconds to check for new notifications.") { |n| config.push_poll = n }
|
14
|
+
opts.on('-F N', '--feedback-poll N', Integer, "Frequency in seconds to check for feedback.") { |n| config.feedback_poll = n }
|
15
|
+
opts.on('-e', '--no-error-checks', 'Disable APNs error checking after notification delivery.') { config.check_for_errors = false }
|
16
|
+
opts.on('-n', '--no-airbrake-notify', 'Disables error notifications via Airbrake.') { config.airbrake_notify = false }
|
17
|
+
opts.on('-p PATH', '--pid-file PATH', String, 'Path to write PID file. Relative to Rails root unless absolute.') { |path| config.pid_file = path }
|
18
|
+
opts.on('-b N', '--batch-size N', Integer, 'Storage backend notification batch size.') { |n| config.batch_size = n }
|
19
|
+
opts.on('-B', '--[no-]batch-storage-updates', 'Perform storage updates in batches.') { |v| config.batch_storage_updates = v }
|
20
|
+
opts.on('-v', '--version', 'Print the version.') { puts "rapns #{Rapns::VERSION}"; exit }
|
21
|
+
opts.on('-h', '--help', 'You\'re looking at it.') { puts opts; exit }
|
22
|
+
end
|
23
|
+
|
24
|
+
if environment.nil? || environment =~ /^-/
|
25
|
+
puts options.to_s
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
|
29
|
+
options.parse!
|
30
|
+
|
31
|
+
ENV['RAILS_ENV'] = environment
|
32
|
+
load 'config/environment.rb'
|
33
|
+
load 'config/initializers/rapns.rb' if File.exist?('config/initializers/rapns.rb')
|
34
|
+
|
35
|
+
Rapns.config.update(config)
|
36
|
+
Rapns.require_for_daemon
|
37
|
+
Rapns::Daemon.start
|
data/config/database.yml
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# postgresql is the default if no ADAPTER environment variable is set when running specs.
|
2
|
+
|
3
|
+
postgresql:
|
4
|
+
adapter: postgresql
|
5
|
+
database: rapns_test
|
6
|
+
host: localhost
|
7
|
+
username: postgres
|
8
|
+
password: ""
|
9
|
+
|
10
|
+
jdbcpostgresql:
|
11
|
+
adapter: jdbcpostgresql
|
12
|
+
database: rapns_test
|
13
|
+
host: localhost
|
14
|
+
username: postgres
|
15
|
+
password: ""
|
16
|
+
|
17
|
+
mysql2:
|
18
|
+
adapter: mysql
|
19
|
+
database: rapns_test
|
20
|
+
host: localhost
|
21
|
+
username: rapns_test
|
22
|
+
password: ""
|
23
|
+
encoding: utf8
|
24
|
+
|
25
|
+
jdbcmysql:
|
26
|
+
adapter: jdbcmysql
|
27
|
+
database: rapns_test
|
28
|
+
host: localhost
|
29
|
+
username: rapns_test
|
30
|
+
password: ""
|
31
|
+
encoding: utf8
|
32
|
+
|
33
|
+
jdbch2:
|
34
|
+
adapter: h2
|
35
|
+
url: jdbc:h2:file:/tmp/rapns_test;AUTO_SERVER=TRUE
|
36
|
+
username: rapns_test
|
37
|
+
password: ""
|
38
|
+
pool: 128
|
39
|
+
timeout: 5000
|
40
|
+
encoding: utf8
|
41
|
+
|
42
|
+
sqlite3:
|
43
|
+
adapter: sqlite3
|
44
|
+
database: spec/tmp/rapns_test.sqlite3
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class RapnsGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
def manifest
|
4
|
+
record do |m|
|
5
|
+
|
6
|
+
puts m.class
|
7
|
+
|
8
|
+
m.file 'rapns.rb', 'config/initializers/rapns.rb'
|
9
|
+
|
10
|
+
create_migration m, "create_rapns_notifications"
|
11
|
+
create_migration m, "create_rapns_feedback"
|
12
|
+
create_migration m, "add_alert_is_json_to_rapns_notifications"
|
13
|
+
create_migration m, "add_app_to_rapns"
|
14
|
+
create_migration m, "create_rapns_apps"
|
15
|
+
create_migration m, "add_gcm"
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_migration(m, filename)
|
22
|
+
m.migration_template "#{filename}.rb", "db/migrate", :migration_file_name => filename
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class AddAppToRapns < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :rapns_notifications, :app, :string, :null => true
|
4
|
+
add_column :rapns_feedback, :app, :string, :null => true
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_column :rapns_notifications, :app
|
9
|
+
remove_column :rapns_feedback, :app
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
class AddGcm < ActiveRecord::Migration
|
2
|
+
module Rapns
|
3
|
+
class App < ActiveRecord::Base
|
4
|
+
self.table_name = 'rapns_apps'
|
5
|
+
end
|
6
|
+
|
7
|
+
class Notification < ActiveRecord::Base
|
8
|
+
belongs_to :app
|
9
|
+
self.table_name = 'rapns_notifications'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.up
|
14
|
+
add_column :rapns_notifications, :type, :string, :null => true
|
15
|
+
add_column :rapns_apps, :type, :string, :null => true
|
16
|
+
|
17
|
+
AddGcm::Rapns::Notification.update_all :type => 'Rapns::Apns::Notification'
|
18
|
+
AddGcm::Rapns::App.update_all :type => 'Rapns::Apns::App'
|
19
|
+
|
20
|
+
change_column :rapns_notifications, :type, :string, :null => false
|
21
|
+
change_column :rapns_apps, :type, :string, :null => false
|
22
|
+
change_column :rapns_notifications, :device_token, :string, { :null => true, :limit => 64 }
|
23
|
+
change_column :rapns_notifications, :expiry, :integer, { :null => true, :default => 1.day.to_i }
|
24
|
+
change_column :rapns_apps, :environment, :string, :null => true
|
25
|
+
change_column :rapns_apps, :certificate, :text, :null => true, :default => nil
|
26
|
+
|
27
|
+
change_column :rapns_notifications, :error_description, :text, :null => true, :default => nil
|
28
|
+
change_column :rapns_notifications, :sound, :string, :default => 'default'
|
29
|
+
|
30
|
+
rename_column :rapns_notifications, :attributes_for_device, :data
|
31
|
+
rename_column :rapns_apps, :key, :name
|
32
|
+
|
33
|
+
add_column :rapns_apps, :auth_key, :string, :null => true
|
34
|
+
|
35
|
+
add_column :rapns_notifications, :collapse_key, :string, :null => true
|
36
|
+
add_column :rapns_notifications, :delay_while_idle, :boolean, :null => false, :default => false
|
37
|
+
|
38
|
+
reg_ids_type = ActiveRecord::Base.connection.adapter_name.include?('Mysql') ? :mediumtext : :text
|
39
|
+
add_column :rapns_notifications, :registration_ids, reg_ids_type, :null => true
|
40
|
+
add_column :rapns_notifications, :app_id, :integer, :null => true
|
41
|
+
add_column :rapns_notifications, :retries, :integer, :null => true, :default => 0
|
42
|
+
|
43
|
+
Rapns::Notification.reset_column_information
|
44
|
+
Rapns::App.reset_column_information
|
45
|
+
|
46
|
+
Rapns::App.all.each do |app|
|
47
|
+
Rapns::Notification.update_all(['app_id = ?', app.id], ['app = ?', app.name])
|
48
|
+
end
|
49
|
+
|
50
|
+
change_column :rapns_notifications, :app_id, :integer, :null => false
|
51
|
+
remove_column :rapns_notifications, :app
|
52
|
+
|
53
|
+
remove_index :rapns_notifications, :name => "index_rapns_notifications_multi"
|
54
|
+
add_index :rapns_notifications, [:app_id, :delivered, :failed, :deliver_after], :name => "index_rapns_notifications_multi"
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.down
|
58
|
+
AddGcm::Rapns::Notification.deleta_all(:type => 'Rapns::Gcm::Notification')
|
59
|
+
|
60
|
+
remove_column :rapns_notifications, :type
|
61
|
+
remove_column :rapns_apps, :type
|
62
|
+
|
63
|
+
change_column :rapns_notifications, :device_token, :string, { :null => false, :limit => 64 }
|
64
|
+
change_column :rapns_notifications, :expiry, :integer, { :null => false, :default => 1.day.to_i }
|
65
|
+
change_column :rapns_apps, :environment, :string, :null => false
|
66
|
+
change_column :rapns_apps, :certificate, :text, :null => false
|
67
|
+
|
68
|
+
change_column :rapns_notifications, :error_description, :string, :null => true, :default => nil
|
69
|
+
change_column :rapns_notifications, :sound, :string, :default => '1.aiff'
|
70
|
+
|
71
|
+
rename_column :rapns_notifications, :data, :attributes_for_device
|
72
|
+
rename_column :rapns_apps, :name, :key
|
73
|
+
|
74
|
+
remove_column :rapns_apps, :auth_key
|
75
|
+
|
76
|
+
remove_column :rapns_notifications, :collapse_key
|
77
|
+
remove_column :rapns_notifications, :delay_while_idle
|
78
|
+
remove_column :rapns_notifications, :registration_ids
|
79
|
+
remove_column :rapns_notifications, :retries
|
80
|
+
|
81
|
+
add_column :rapns_notifications, :app, :string, :null => true
|
82
|
+
|
83
|
+
Rapns::Notification.reset_column_information
|
84
|
+
Rapns::App.reset_column_information
|
85
|
+
|
86
|
+
Rapns::App.all.each do |app|
|
87
|
+
Rapns::Notification.update_all(['app = ?', app.key], ['app_id = ?', app.id])
|
88
|
+
end
|
89
|
+
|
90
|
+
remove_column :rapns_notifications, :app_id
|
91
|
+
|
92
|
+
remove_index :rapns_notifications, :name => "index_rapns_notifications_multi"
|
93
|
+
add_index :rapns_notifications, [:delivered, :failed, :deliver_after], :name => "index_rapns_notifications_multi"
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateRapnsApps < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :rapns_apps do |t|
|
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
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :rapns_apps
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateRapnsFeedback < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :rapns_feedback do |t|
|
4
|
+
t.string :device_token, :null => false, :limit => 64
|
5
|
+
t.timestamp :failed_at, :null => false
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
add_index :rapns_feedback, :device_token
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
drop_table :rapns_feedback
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class CreateRapnsNotifications < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :rapns_notifications do |t|
|
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
|
+
t.timestamps
|
18
|
+
end
|
19
|
+
|
20
|
+
add_index :rapns_notifications, [:delivered, :failed, :deliver_after], :name => "index_rapns_notifications_multi"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.down
|
24
|
+
drop_table :rapns_notifications
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Rapns configuration. Options set here are overridden by command-line options.
|
2
|
+
|
3
|
+
Rapns.configure do |config|
|
4
|
+
|
5
|
+
# Run in the foreground?
|
6
|
+
# config.foreground = false
|
7
|
+
|
8
|
+
# Frequency in seconds to check for new notifications.
|
9
|
+
# config.push_poll = 2
|
10
|
+
|
11
|
+
# Frequency in seconds to check for feedback
|
12
|
+
# config.feedback_poll = 60
|
13
|
+
|
14
|
+
# Disable APNs error checking after notification delivery.
|
15
|
+
# config.check_for_errors = true
|
16
|
+
|
17
|
+
# ActiveRecord notifications batch size.
|
18
|
+
# config.batch_size = 5000
|
19
|
+
|
20
|
+
# Perform updates to the storage backend in batches to reduce IO.
|
21
|
+
# config.batch_storage_updates = true
|
22
|
+
|
23
|
+
# Path to write PID file. Relative to Rails root unless absolute.
|
24
|
+
# config.pid_file = '/path/to/rapns.pid'
|
25
|
+
|
26
|
+
# Define a custom logger.
|
27
|
+
# config.logger = MyLogger.new
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
Rapns.reflect do |on|
|
32
|
+
|
33
|
+
# Called with a Rapns::Apns::Feedback instance when feedback is received
|
34
|
+
# from the APNs that a notification has failed to be delivered.
|
35
|
+
# Further notifications should not be sent to the device.
|
36
|
+
# on.apns_feedback do |feedback|
|
37
|
+
# end
|
38
|
+
|
39
|
+
# Called when a notification is queued internally for delivery.
|
40
|
+
# The internal queue for each app runner can be inspected:
|
41
|
+
#
|
42
|
+
# Rapns::Daemon::AppRunner.runners.each do |app_id, runner|
|
43
|
+
# runner.app
|
44
|
+
# runner.queue_size
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# on.notification_enqueued do |notification|
|
48
|
+
# end
|
49
|
+
|
50
|
+
# Called when a notification is successfully delivered.
|
51
|
+
# on.notification_delivered do |notification|
|
52
|
+
# end
|
53
|
+
|
54
|
+
# Called when notification delivery failed.
|
55
|
+
# Call 'error_code' and 'error_description' on the notification for the cause.
|
56
|
+
# on.notification_failed do |notification|
|
57
|
+
# end
|
58
|
+
|
59
|
+
# Called when a notification will be retried at a later date.
|
60
|
+
# Call 'deliver_after' on the notification for the next delivery date
|
61
|
+
# and 'retries' for the number of times this notification has been retried.
|
62
|
+
# on.notification_will_retry do |notification|
|
63
|
+
# end
|
64
|
+
|
65
|
+
# Called when an APNs connection is lost and will be reconnected.
|
66
|
+
# on.apns_connection_lost do |app, error|
|
67
|
+
# end
|
68
|
+
|
69
|
+
# Called when the GCM returns a canonical registration ID.
|
70
|
+
# You will need to replace old_id with canonical_id in your records.
|
71
|
+
# on.gcm_canonical_id do |old_id, canonical_id|
|
72
|
+
# end
|
73
|
+
|
74
|
+
# Called when the GCM returns a failure that indicates an invalid tegistration id.
|
75
|
+
# You will need to delete the registration_id from your records.
|
76
|
+
# on.gcm_invalid_registration_id do |app, error, registration_id|
|
77
|
+
# end
|
78
|
+
|
79
|
+
# Called when an APNs certificate will expire within 1 month.
|
80
|
+
# Implement on.error to catch errors raised when the certificate expires.
|
81
|
+
# on.apns_certificate_will_expire do |app, expiration_time|
|
82
|
+
# end
|
83
|
+
|
84
|
+
# Called when an exception is raised.
|
85
|
+
# on.error do |error|
|
86
|
+
# end
|
87
|
+
end
|
data/lib/rapns/TODO
ADDED