ruby-push-notifications 0.4.0 → 1.0.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/.travis.yml +0 -1
- data/CHANGELOG.md +21 -0
- data/Gemfile.lock +2 -2
- data/README.md +18 -0
- data/examples/apns.rb +3 -0
- data/examples/gcm.rb +3 -0
- data/examples/mpns.rb +2 -0
- data/lib/ruby-push-notifications/apns/apns_connection.rb +5 -2
- data/lib/ruby-push-notifications/apns/apns_pusher.rb +6 -3
- data/lib/ruby-push-notifications/gcm/gcm_connection.rb +6 -1
- data/lib/ruby-push-notifications/gcm/gcm_pusher.rb +6 -2
- data/lib/ruby-push-notifications/mpns/mpns_connection.rb +7 -2
- data/lib/ruby-push-notifications/mpns/mpns_pusher.rb +6 -2
- data/lib/ruby-push-notifications/version.rb +1 -1
- data/ruby-push-notifications.gemspec +1 -1
- data/spec/ruby-push-notifications/apns/apns_connection_spec.rb +3 -3
- data/spec/ruby-push-notifications/apns/apns_pusher_spec.rb +5 -5
- 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: 738a575f80f0cd2e1a1944232642c792f13e0bea
|
4
|
+
data.tar.gz: 8486e81fc3ab988335c233845ebee636b5d9ef89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43fbc9c2a9544ebd9f5cc7a8b8a6ccd9955177fafb6604ac08076830fb87c7bc98238601ea1579d10d438c77854f7f872903da8518276886b44634adc6a4f5a7
|
7
|
+
data.tar.gz: 24846b4b7d52519915de9bd02cd2d5bda4bf732fd109dc9a44b6cc32eb09dce256a548c3bee721eb4cedb115326c0080c16b0b42608664dbfd61e9b0c07f1761
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# CHANGELOG™
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
|
+
|
5
|
+
## [unrealeased] - [unrealease date]
|
6
|
+
|
7
|
+
## 1.0.0 - 2016-12-01
|
8
|
+
- **Added**: Configurable timeouts for connecting external services.
|
9
|
+
- **Removed**: Ruby 1.9.3 support.
|
10
|
+
|
11
|
+
## 0.4.0 - 2016-02-23
|
12
|
+
- **Added**: Option to provide a password for the PEM file for APNS connection
|
13
|
+
|
14
|
+
## 0.3.0 - 2015-04-21
|
15
|
+
- **Added**: Unified response interface through `Notifications Results Manager`
|
16
|
+
|
17
|
+
## 0.2.0 - 2015-04-15
|
18
|
+
- **Added**: Microsoft Push Notifications Service Support
|
19
|
+
|
20
|
+
## 0.1.0 - 2015-03-31
|
21
|
+
- First release
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -61,3 +61,21 @@ Feel free to contribute!!
|
|
61
61
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
62
62
|
4. Push to the branch (`git push origin my-new-feature`)
|
63
63
|
5. Create a new Pull Request
|
64
|
+
|
65
|
+
## Troubleshooting
|
66
|
+
|
67
|
+
**If you see "255 Unknown Error" error code**
|
68
|
+
|
69
|
+
This error code is assigned when the connection to push notification server wasn't successful
|
70
|
+
<a href="https://github.com/calonso/ruby-push-notifications/blob/master/lib/ruby-push-notifications/apns/apns_pusher.rb#L56-L58">255 UNKnown Error code</a>
|
71
|
+
|
72
|
+
Checking your connection configuration for example with APNS connection.
|
73
|
+
When your pem file and token are development make sure you configure the pusher for sandbox mode
|
74
|
+
``` RubyPushNotifications::APNS::APNSPusher.new('the certificate', true)) ```
|
75
|
+
|
76
|
+
or when your pem file and token are production you should configure the pusher for production mode (Set the sandbox mode to false when creating your pusher)
|
77
|
+
``` RubyPushNotifications::APNS::APNSPusher.new('the certificate', false)) ```
|
78
|
+
|
79
|
+
## Changelog
|
80
|
+
|
81
|
+
Refer to the [CHANGELOG.md](https://github.com/calonso/ruby-push-notifications/blob/master/CHANGELOG.md) file for detailed changes across versions.
|
data/examples/apns.rb
CHANGED
@@ -13,6 +13,9 @@ password = nil # optional password for .pem file
|
|
13
13
|
notification = RubyPushNotifications::APNS::APNSNotification.new tokens, { aps: { alert: 'Hello APNS World!', sound: 'true', badge: 1 } }
|
14
14
|
|
15
15
|
pusher = RubyPushNotifications::APNS::APNSPusher.new(File.read('/path/to/your/apps/certificate.pem'), true, password) # enter the password if present
|
16
|
+
# Connect timeout defaults to 30s
|
17
|
+
# pusher = RubyPushNotifications::APNS::APNSPusher.new(File.read('/path/to/your/apps/certificate.pem'), true, password, { connect_timeout: 20 })
|
18
|
+
|
16
19
|
pusher.push [notification]
|
17
20
|
p 'Notification sending results:'
|
18
21
|
p "Success: #{notification.success}, Failed: #{notification.failed}"
|
data/examples/gcm.rb
CHANGED
@@ -12,6 +12,9 @@ registration_ids = [
|
|
12
12
|
notification = RubyPushNotifications::GCM::GCMNotification.new registration_ids, { text: 'Hello GCM World!' }
|
13
13
|
|
14
14
|
pusher = RubyPushNotifications::GCM::GCMPusher.new "Your app's GCM key"
|
15
|
+
# Open and read timeouts default to 30s
|
16
|
+
# pusher = RubyPushNotifications::GCM::GCMPusher.new "Your app's GCM key", { open_timeout: 10, read_timeout: 10 }
|
17
|
+
|
15
18
|
pusher.push [notification]
|
16
19
|
p 'Notification sending results:'
|
17
20
|
p "Success: #{notification.success}, Failed: #{notification.failed}"
|
data/examples/mpns.rb
CHANGED
@@ -13,6 +13,8 @@ device_urls = [
|
|
13
13
|
notification = RubyPushNotifications::MPNS::MPNSNotification.new device_urls, { title: 'Title', message: 'Hello MPNS World!', type: :toast }
|
14
14
|
|
15
15
|
pusher = RubyPushNotifications::MPNS::MPNSPusher.new
|
16
|
+
# Open and read timeouts default to 30s
|
17
|
+
# pusher = RubyPushNotifications::MPNS::MPNSPusher.new optional_certificate, { open_timeout: 10, read_timeout: 10 }
|
16
18
|
pusher.push [notification]
|
17
19
|
p 'Notification sending results:'
|
18
20
|
p "Success: #{notification.success}, Failed: #{notification.failed}"
|
@@ -26,14 +26,17 @@ module RubyPushNotifications
|
|
26
26
|
#
|
27
27
|
# @param cert [String]. Contents of the PEM encoded certificate
|
28
28
|
# @param sandbox [Boolean]. Whether to use the sandbox environment or not.
|
29
|
+
# @param pass [String] optional. Passphrase for the certificate.
|
30
|
+
# @param options [Hash] optional. Options for #open. Currently supports:
|
31
|
+
# * connect_timeout [Integer]: how long the socket will wait for when opening the APNS socket. Defaults to 30.
|
29
32
|
# @return [APNSConnection]. The recently stablished connection.
|
30
|
-
def self.open(cert, sandbox, pass = nil)
|
33
|
+
def self.open(cert, sandbox, pass = nil, options = {})
|
31
34
|
ctx = OpenSSL::SSL::SSLContext.new
|
32
35
|
ctx.key = OpenSSL::PKey::RSA.new cert, pass
|
33
36
|
ctx.cert = OpenSSL::X509::Certificate.new cert
|
34
37
|
|
35
38
|
h = host sandbox
|
36
|
-
socket =
|
39
|
+
socket = Socket.tcp h, APNS_PORT, nil, nil, connect_timeout: options.fetch(:connect_timeout, 30)
|
37
40
|
ssl = OpenSSL::SSL::SSLSocket.new socket, ctx
|
38
41
|
ssl.connect
|
39
42
|
|
@@ -15,10 +15,13 @@ module RubyPushNotifications
|
|
15
15
|
|
16
16
|
# @param certificate [String]. The PEM encoded APNS certificate.
|
17
17
|
# @param sandbox [Boolean]. Whether the certificate is an APNS sandbox or not.
|
18
|
-
|
18
|
+
# @param options [Hash] optional. Options for APNSPusher. Currently supports:
|
19
|
+
# * connect_timeout [Integer]: Number of seconds to wait for the connection to open. Defaults to 30.
|
20
|
+
def initialize(certificate, sandbox, password = nil, options = {})
|
19
21
|
@certificate = certificate
|
20
22
|
@pass = password
|
21
23
|
@sandbox = sandbox
|
24
|
+
@options = options
|
22
25
|
end
|
23
26
|
|
24
27
|
# Pushes the notifications.
|
@@ -31,7 +34,7 @@ module RubyPushNotifications
|
|
31
34
|
#
|
32
35
|
# @param notifications [Array]. All the APNSNotifications to be sent.
|
33
36
|
def push(notifications)
|
34
|
-
conn = APNSConnection.open @certificate, @sandbox, @pass
|
37
|
+
conn = APNSConnection.open @certificate, @sandbox, @pass, @options
|
35
38
|
|
36
39
|
binaries = notifications.each_with_object([]) do |notif, binaries|
|
37
40
|
notif.each_message(binaries.count) do |msg|
|
@@ -61,7 +64,7 @@ module RubyPushNotifications
|
|
61
64
|
results.slice! err[2]..-1
|
62
65
|
results << err[1]
|
63
66
|
i = err[2]
|
64
|
-
conn = APNSConnection.open @certificate, @sandbox, @pass
|
67
|
+
conn = APNSConnection.open @certificate, @sandbox, @pass, @options
|
65
68
|
end
|
66
69
|
else
|
67
70
|
results << NO_ERROR_STATUS_CODE
|
@@ -27,8 +27,11 @@ module RubyPushNotifications
|
|
27
27
|
# @param notification [String]. The text to POST
|
28
28
|
# @param key [String]. The GCM sender id to use
|
29
29
|
# (https://developer.android.com/google/gcm/gcm.html#senderid)
|
30
|
+
# @param options [Hash] optional. Options for #post. Currently supports:
|
31
|
+
# * open_timeout [Integer]: Number of seconds to wait for the connection to open. Defaults to 30.
|
32
|
+
# * read_timeout [Integer]: Number of seconds to wait for one block to be read. Defaults to 30.
|
30
33
|
# @return [GCMResponse]. The GCMResponse that encapsulates the received response
|
31
|
-
def self.post(notification, key)
|
34
|
+
def self.post(notification, key, options = {})
|
32
35
|
headers = {
|
33
36
|
CONTENT_TYPE_HEADER => JSON_CONTENT_TYPE,
|
34
37
|
AUTHORIZATION_HEADER => "key=#{key}"
|
@@ -38,6 +41,8 @@ module RubyPushNotifications
|
|
38
41
|
http = Net::HTTP.new url.host, url.port
|
39
42
|
http.use_ssl = true
|
40
43
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
44
|
+
http.open_timeout = options.fetch(:open_timeout, 30)
|
45
|
+
http.read_timeout = options.fetch(:read_timeout, 30)
|
41
46
|
|
42
47
|
response = http.post url.path, notification, headers
|
43
48
|
|
@@ -11,8 +11,12 @@ module RubyPushNotifications
|
|
11
11
|
#
|
12
12
|
# @param key [String]. GCM sender id to use
|
13
13
|
# ((https://developer.android.com/google/gcm/gcm.html#senderid))
|
14
|
-
|
14
|
+
# @param options [Hash] optional. Options for GCMPusher. Currently supports:
|
15
|
+
# * open_timeout [Integer]: Number of seconds to wait for the connection to open. Defaults to 30.
|
16
|
+
# * read_timeout [Integer]: Number of seconds to wait for one block to be read. Defaults to 30.
|
17
|
+
def initialize(key, options = {})
|
15
18
|
@key = key
|
19
|
+
@options = options
|
16
20
|
end
|
17
21
|
|
18
22
|
# Actually pushes the given notifications.
|
@@ -22,7 +26,7 @@ module RubyPushNotifications
|
|
22
26
|
# @param notifications [Array]. Array of GCMNotification to send.
|
23
27
|
def push(notifications)
|
24
28
|
notifications.each do |notif|
|
25
|
-
notif.results = GCMConnection.post notif.as_gcm_json, @key
|
29
|
+
notif.results = GCMConnection.post notif.as_gcm_json, @key, @options
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -33,15 +33,20 @@ module RubyPushNotifications
|
|
33
33
|
# submit the given notifications.
|
34
34
|
#
|
35
35
|
# @param n [MPNSNotification]. The notification object to POST
|
36
|
-
# @param
|
36
|
+
# @param cert [String] optional. Contents of the PEM encoded certificate.
|
37
|
+
# @param options [Hash] optional. Options for GCMPusher. Currently supports:
|
38
|
+
# * open_timeout [Integer]: Number of seconds to wait for the connection to open. Defaults to 30.
|
39
|
+
# * read_timeout [Integer]: Number of seconds to wait for one block to be read. Defaults to 30.
|
37
40
|
# @return [Array]. The response of post
|
38
41
|
# (http://msdn.microsoft.com/pt-br/library/windows/apps/ff941099)
|
39
|
-
def self.post(n, cert = nil)
|
42
|
+
def self.post(n, cert = nil, options = {})
|
40
43
|
headers = build_headers(n.data[:type], n.data[:delay])
|
41
44
|
body = n.as_mpns_xml
|
42
45
|
responses = []
|
43
46
|
n.each_device do |url|
|
44
47
|
http = Net::HTTP.new url.host, url.port
|
48
|
+
http.open_timeout = options.fetch(:open_timeout, 30)
|
49
|
+
http.read_timeout = options.fetch(:read_timeout, 30)
|
45
50
|
if cert && url.scheme == 'https'
|
46
51
|
http.use_ssl = true
|
47
52
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
@@ -9,9 +9,13 @@ module RubyPushNotifications
|
|
9
9
|
# Initializes the MPNSPusher
|
10
10
|
#
|
11
11
|
# @param certificate [String]. The PEM encoded MPNS certificate.
|
12
|
+
# @param options [Hash] optional. Options for GCMPusher. Currently supports:
|
13
|
+
# * open_timeout [Integer]: Number of seconds to wait for the connection to open. Defaults to 30.
|
14
|
+
# * read_timeout [Integer]: Number of seconds to wait for one block to be read. Defaults to 30.
|
12
15
|
# (http://msdn.microsoft.com/pt-br/library/windows/apps/ff941099)
|
13
|
-
def initialize(certificate = nil)
|
16
|
+
def initialize(certificate = nil, options = {})
|
14
17
|
@certificate = certificate
|
18
|
+
@options = options
|
15
19
|
end
|
16
20
|
|
17
21
|
# Actually pushes the given notifications.
|
@@ -21,7 +25,7 @@ module RubyPushNotifications
|
|
21
25
|
# @param notifications [Array]. Array of MPNSNotification to send.
|
22
26
|
def push(notifications)
|
23
27
|
notifications.each do |notif|
|
24
|
-
notif.results = MPNSConnection.post notif, @certificate
|
28
|
+
notif.results = MPNSConnection.post notif, @certificate, @options
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = 'https://github.com/calonso/ruby-push-notifications'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
|
-
spec.required_ruby_version = '>=
|
16
|
+
spec.required_ruby_version = '>= 2.0.0'
|
17
17
|
|
18
18
|
spec.files = `git ls-files -z`.split("\x0")
|
19
19
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
@@ -4,17 +4,17 @@ module RubyPushNotifications
|
|
4
4
|
describe APNSConnection do
|
5
5
|
|
6
6
|
let(:cert) { File.read 'spec/support/dummy.pem' }
|
7
|
-
let(:tcp_socket) { instance_double(
|
7
|
+
let(:tcp_socket) { instance_double(Socket).as_null_object }
|
8
8
|
let(:ssl_socket) { instance_double(OpenSSL::SSL::SSLSocket).as_null_object }
|
9
9
|
|
10
10
|
describe '::open' do
|
11
11
|
before do
|
12
|
-
allow(
|
12
|
+
allow(Socket).to receive(:tcp).with('gateway.sandbox.push.apple.com', 2195, nil, nil, { connect_timeout: 30 }).and_return tcp_socket
|
13
13
|
allow(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, an_instance_of(OpenSSL::SSL::SSLContext)).and_return ssl_socket
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'creates the connection' do
|
17
|
-
expect(
|
17
|
+
expect(Socket).to receive(:tcp).with('gateway.sandbox.push.apple.com', 2195, nil, nil, { connect_timeout: 30 }).and_return tcp_socket
|
18
18
|
expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, an_instance_of(OpenSSL::SSL::SSLContext)).and_return ssl_socket
|
19
19
|
APNSConnection.open cert, true
|
20
20
|
end
|
@@ -9,7 +9,7 @@ module RubyPushNotifications
|
|
9
9
|
let(:data) { { a: 1 } }
|
10
10
|
|
11
11
|
before do
|
12
|
-
allow(APNSConnection).to receive(:open).with(certificate, sandbox, nil).and_return connection
|
12
|
+
allow(APNSConnection).to receive(:open).with(certificate, sandbox, nil, {}).and_return connection
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '#push' do
|
@@ -93,7 +93,7 @@ module RubyPushNotifications
|
|
93
93
|
let(:connection2) { instance_double(APNSConnection).as_null_object }
|
94
94
|
|
95
95
|
before do
|
96
|
-
allow(APNSConnection).to receive(:open).with(certificate, sandbox, nil).and_return connection, connection2
|
96
|
+
allow(APNSConnection).to receive(:open).with(certificate, sandbox, nil, {}).and_return connection, connection2
|
97
97
|
end
|
98
98
|
|
99
99
|
context 'failing first' do
|
@@ -197,10 +197,10 @@ module RubyPushNotifications
|
|
197
197
|
allow(connection).to receive(:read).with(6).and_return [8, PROCESSING_ERROR_STATUS_CODE, 0].pack('ccN')
|
198
198
|
allow(connection2).to receive(:read).with(6).and_return [8, MISSING_DEVICE_TOKEN_STATUS_CODE, 2].pack('ccN')
|
199
199
|
allow(connection3).to receive(:read).with(6).and_return [8, INVALID_TOPIC_SIZE_STATUS_CODE, 9].pack('ccN')
|
200
|
-
allow(APNSConnection).to receive(:open).with(certificate, sandbox, nil).and_return connection, connection2, connection3, connection4
|
200
|
+
allow(APNSConnection).to receive(:open).with(certificate, sandbox, nil, {}).and_return connection, connection2, connection3, connection4
|
201
201
|
end
|
202
202
|
|
203
|
-
it '
|
203
|
+
it 'reopens the connection' do
|
204
204
|
(0..2).each do |i|
|
205
205
|
expect(connection).to receive(:write).with(apns_binary(data, tokens[i], i)).once
|
206
206
|
end
|
@@ -249,7 +249,7 @@ module RubyPushNotifications
|
|
249
249
|
allow(connection).to receive(:read).with(6).and_return [8, PROCESSING_ERROR_STATUS_CODE, 0].pack('ccN')
|
250
250
|
allow(connection2).to receive(:read).with(6).and_return [8, MISSING_DEVICE_TOKEN_STATUS_CODE, 2].pack('ccN')
|
251
251
|
allow(connection3).to receive(:read).with(6).and_return [8, INVALID_TOPIC_SIZE_STATUS_CODE, 9].pack('ccN')
|
252
|
-
allow(APNSConnection).to receive(:open).with(certificate, sandbox, nil).and_return connection, connection2, connection3, connection4
|
252
|
+
allow(APNSConnection).to receive(:open).with(certificate, sandbox, nil, {}).and_return connection, connection2, connection3, connection4
|
253
253
|
end
|
254
254
|
|
255
255
|
it 'repones the connection' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-push-notifications
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Alonso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: builder
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- ".rspec"
|
107
107
|
- ".ruby-style.yml"
|
108
108
|
- ".travis.yml"
|
109
|
+
- CHANGELOG.md
|
109
110
|
- Gemfile
|
110
111
|
- Gemfile.lock
|
111
112
|
- LICENSE
|
@@ -165,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
166
|
requirements:
|
166
167
|
- - ">="
|
167
168
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
169
|
+
version: 2.0.0
|
169
170
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
171
|
requirements:
|
171
172
|
- - ">="
|
@@ -195,4 +196,3 @@ test_files:
|
|
195
196
|
- spec/support/dummy.pem
|
196
197
|
- spec/support/factory_girl.rb
|
197
198
|
- spec/support/results_shared_examples.rb
|
198
|
-
has_rdoc:
|