apnotic 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +29 -8
- data/apnotic.gemspec +1 -1
- data/lib/apnotic/connection.rb +22 -5
- data/lib/apnotic/notification.rb +6 -3
- data/lib/apnotic/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5cb5a06e46cf7b22e0c960e30007dcd7dcd2fe33
|
4
|
+
data.tar.gz: f97f34e8538fd271cb0a169780136575a85d49b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3036c76078e4d49bc86f314237ef7c731497028f899e39285a99178f3f1357196eb55f9f3e680e5cd2070e08ce9234fe486449394c889ee1a040caec4edf5218
|
7
|
+
data.tar.gz: a396a147c7667c004e483895719a7b6ab8f89291c45d423636bf3568c40a9e2513506dbe3134149bdaab4016ae5c848b8be25113b7c5387666c5c1b4f017624e
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
[](https://travis-ci.org/ostinelli/apnotic)
|
2
2
|
[](https://codeclimate.com/github/ostinelli/apnotic)
|
3
|
+
[](https://badge.fury.io/rb/apnotic)
|
3
4
|
|
4
5
|
# Apnotic
|
5
6
|
|
@@ -7,7 +8,7 @@ Apnotic is a gem for sending Apple Push Notifications using the [HTTP-2 specific
|
|
7
8
|
|
8
9
|
|
9
10
|
## Why "Yet Another APN" gem?
|
10
|
-
If you have used the previous Apple Push Notification specifications you may have noticed that it was hard to know whether a Push Notification was successful or not. It
|
11
|
+
If you have used the previous Apple Push Notification specifications you may have noticed that it was hard to know whether a Push Notification was successful or not. It was a common problem that has been reported multiple times. In addition, you had to run a separate Feedback service to retrieve the list of the device tokens that were no longer valid, and ensure to purge them from your systems.
|
11
12
|
|
12
13
|
All of this is solved by using the HTTP-2 APN specifications. Every Push Notification you make returns a response stating if the Push was successful or, if not, which problems were encountered. This includes the case when invalid device tokens are used, hence making it unnecessary to have a separate Feedback service.
|
13
14
|
|
@@ -52,14 +53,14 @@ response.body # => ""
|
|
52
53
|
connection.close
|
53
54
|
```
|
54
55
|
|
55
|
-
### With Sidekiq / Rescue
|
56
|
-
A practical
|
56
|
+
### With Sidekiq / Rescue / ...
|
57
|
+
A practical usage of a Sidekiq / Rescue worker probably has to:
|
57
58
|
|
58
59
|
* Use a pool of persistent connections.
|
59
60
|
* Send a push notification.
|
60
61
|
* Remove a device with an invalid token.
|
61
62
|
|
62
|
-
An example of a Sidekiq worker with such features follows.
|
63
|
+
An example of a Sidekiq worker with such features follows. This presumes a Rails environment, and a model `Device`.
|
63
64
|
|
64
65
|
```ruby
|
65
66
|
require 'apnotic'
|
@@ -105,7 +106,7 @@ Apnotic::Connection.new(options)
|
|
105
106
|
|
106
107
|
| Option | Description
|
107
108
|
|-----|-----
|
108
|
-
| :cert_path | Required. The path to a valid APNS push certificate in .pem format
|
109
|
+
| :cert_path | Required. The path to a valid APNS push certificate in .pem or .p12 format, or any object that responds to `:read`.
|
109
110
|
| :cert_pass | Optional. The certificate's password.
|
110
111
|
| :uri | Optional. Defaults to https://api.push.apple.com:443.
|
111
112
|
|
@@ -120,12 +121,15 @@ Apnotic::Connection.development(options)
|
|
120
121
|
#### Methods
|
121
122
|
|
122
123
|
* **uri** → **`URI`**
|
124
|
+
|
123
125
|
Returns the URI of the APNS endpoint.
|
124
126
|
|
125
127
|
* **cert_path** → **`string`**
|
128
|
+
|
126
129
|
Returns the path to the certificate
|
127
130
|
|
128
131
|
* **push(notification, timeout=30)** → **`Apnotic::Response` or `nil`**
|
132
|
+
|
129
133
|
Sends a notification. Returns `nil` in case a timeout occurs.
|
130
134
|
|
131
135
|
|
@@ -162,10 +166,11 @@ These are all Accessor attributes.
|
|
162
166
|
| `content_available` | "
|
163
167
|
| `category` | "
|
164
168
|
| `custom_payload` | "
|
165
|
-
| `apns_id` | Refer to the [APNs Provider API](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html) for details.
|
169
|
+
| `apns_id` | Refer to the [APNs Provider API](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html) for details.
|
166
170
|
| `expiration` | "
|
167
171
|
| `priority` | "
|
168
172
|
| `topic` | "
|
173
|
+
| `url_args` | Values for [Safari push notifications](https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html#//apple_ref/doc/uid/TP40013225-CH3-SW12).
|
169
174
|
|
170
175
|
For example:
|
171
176
|
|
@@ -177,6 +182,18 @@ notification.sound = "bells.wav"
|
|
177
182
|
notification.priority = 5
|
178
183
|
```
|
179
184
|
|
185
|
+
For a [Safari push notification](https://developer.apple.com/notifications/safari-push-notifications/):
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
notification = Apnotic::Notification.new(token)
|
189
|
+
|
190
|
+
notification.alert = {
|
191
|
+
title: "Flight A998 Now Boarding",
|
192
|
+
body: "Boarding has begun for Flight A998.",
|
193
|
+
action: "View"
|
194
|
+
}
|
195
|
+
notification.url_args = ["boarding", "A998"]
|
196
|
+
```
|
180
197
|
|
181
198
|
### `Apnotic::Response`
|
182
199
|
The response to a call to `connection.push`.
|
@@ -184,19 +201,23 @@ The response to a call to `connection.push`.
|
|
184
201
|
#### Methods
|
185
202
|
|
186
203
|
* **headers** → **`hash`**
|
204
|
+
|
187
205
|
Returns a Hash containing the Headers of the response.
|
188
206
|
|
189
207
|
* **status** → **`string`**
|
208
|
+
|
190
209
|
Returns the status code.
|
191
210
|
|
192
211
|
* **body** → **`hash` or `string`**
|
212
|
+
|
193
213
|
Returns the body of the response in Hash format if a valid JSON was returned, otherwise just the RAW body.
|
194
214
|
|
195
215
|
* **headers** → **`boolean`**
|
216
|
+
|
196
217
|
Returns if the push was successful.
|
197
218
|
|
198
219
|
|
199
|
-
##
|
220
|
+
## Getting Your APNs Certificate
|
200
221
|
|
201
222
|
> These instructions come from another great gem, [apn_on_rails](https://github.com/PRX/apn_on_rails).
|
202
223
|
|
@@ -206,7 +227,7 @@ Once you have the certificate from Apple for your application, export your key a
|
|
206
227
|
2. Right click and choose `Export 2 items…`.
|
207
228
|
3. Choose the p12 format from the drop down and name it `cert.p12`.
|
208
229
|
|
209
|
-
|
230
|
+
Optionally, you may covert the p12 file to a pem file (this step is optional because Apnotic natively supports p12 files):
|
210
231
|
```
|
211
232
|
$ openssl pkcs12 -in cert.p12 -out apple_push_notification_production.pem -nodes -clcerts
|
212
233
|
```
|
data/apnotic.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "net-http2", "~> 0.
|
21
|
+
spec.add_dependency "net-http2", "~> 0.9.2"
|
22
22
|
spec.add_dependency "connection_pool", "~> 2.0"
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.3"
|
data/lib/apnotic/connection.rb
CHANGED
@@ -21,7 +21,7 @@ module Apnotic
|
|
21
21
|
@cert_path = options[:cert_path]
|
22
22
|
@cert_pass = options[:cert_pass]
|
23
23
|
|
24
|
-
raise "Cert file not found: #{@cert_path}" unless @cert_path && File.exist?(@cert_path)
|
24
|
+
raise "Cert file not found: #{@cert_path}" unless @cert_path && (@cert_path.respond_to?(:read) || File.exist?(@cert_path))
|
25
25
|
|
26
26
|
@client = NetHttp2::Client.new(@url, ssl_context: ssl_context)
|
27
27
|
end
|
@@ -44,12 +44,29 @@ module Apnotic
|
|
44
44
|
|
45
45
|
def ssl_context
|
46
46
|
@ssl_context ||= begin
|
47
|
-
ctx
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
48
|
+
begin
|
49
|
+
p12 = OpenSSL::PKCS12.new(certificate, @cert_pass)
|
50
|
+
ctx.key = p12.key
|
51
|
+
ctx.cert = p12.certificate
|
52
|
+
rescue OpenSSL::PKCS12::PKCS12Error
|
53
|
+
ctx.key = OpenSSL::PKey::RSA.new(certificate, @cert_pass)
|
54
|
+
ctx.cert = OpenSSL::X509::Certificate.new(certificate)
|
55
|
+
end
|
51
56
|
ctx
|
52
57
|
end
|
53
58
|
end
|
59
|
+
|
60
|
+
def certificate
|
61
|
+
@certificate ||= begin
|
62
|
+
if @cert_path.respond_to?(:read)
|
63
|
+
cert = @cert_path.read
|
64
|
+
@cert_path.rewind if @cert_path.respond_to?(:rewind)
|
65
|
+
else
|
66
|
+
cert = File.read(@cert_path)
|
67
|
+
end
|
68
|
+
cert
|
69
|
+
end
|
70
|
+
end
|
54
71
|
end
|
55
72
|
end
|
data/lib/apnotic/notification.rb
CHANGED
@@ -5,7 +5,7 @@ module Apnotic
|
|
5
5
|
|
6
6
|
class Notification
|
7
7
|
attr_reader :token
|
8
|
-
attr_accessor :alert, :badge, :sound, :content_available, :category, :custom_payload
|
8
|
+
attr_accessor :alert, :badge, :sound, :content_available, :category, :custom_payload, :url_args
|
9
9
|
attr_accessor :apns_id, :expiration, :priority, :topic
|
10
10
|
|
11
11
|
def initialize(token)
|
@@ -20,11 +20,14 @@ module Apnotic
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def to_hash
|
23
|
-
aps = {
|
23
|
+
aps = {}
|
24
|
+
|
25
|
+
aps.merge!(alert: alert) if alert
|
24
26
|
aps.merge!(badge: badge) if badge
|
25
27
|
aps.merge!(sound: sound) if sound
|
26
|
-
aps.merge!(content_available: content_available) if content_available
|
27
28
|
aps.merge!(category: category) if category
|
29
|
+
aps.merge!('content-available' => content_available) if content_available
|
30
|
+
aps.merge!('url-args' => url_args) if url_args
|
28
31
|
|
29
32
|
n = { aps: aps }
|
30
33
|
n.merge!(custom_payload) if custom_payload
|
data/lib/apnotic/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apnotic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roberto Ostinelli
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-http2
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.9.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.9.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: connection_pool
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|