exponent-server-sdk 0.0.7 → 0.1.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/.rubocop.yml +3923 -0
- data/.travis.yml +10 -10
- data/README.md +72 -58
- data/Rakefile +12 -12
- data/examples/getting_started.rb +47 -0
- data/exponent-server-sdk.gemspec +3 -3
- data/lib/exponent-server-sdk.rb +315 -160
- data/lib/exponent-server-sdk/too_many_messages_error.rb +2 -0
- data/lib/exponent-server-sdk/version.rb +1 -1
- data/test/exponent-server-sdk-test.rb +680 -232
- metadata +21 -6
- data/manual_test.rb +0 -19
data/.travis.yml
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
language: ruby
|
2
|
-
cache: bundler
|
3
|
-
rvm:
|
4
|
-
- 2.6.0
|
5
|
-
- 2.5.0
|
6
|
-
- 2.4.0
|
7
|
-
- 2.3.0
|
8
|
-
before_install:
|
9
|
-
- gem update --system
|
10
|
-
- gem install bundler
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
rvm:
|
4
|
+
- 2.6.0
|
5
|
+
- 2.5.0
|
6
|
+
- 2.4.0
|
7
|
+
- 2.3.0
|
8
|
+
before_install:
|
9
|
+
- gem update --system
|
10
|
+
- gem install bundler
|
data/README.md
CHANGED
@@ -1,58 +1,72 @@
|
|
1
|
-
# Exponent Server SDK Ruby
|
2
|
-
|
3
|
-
[![
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
```ruby
|
37
|
-
client = Exponent::Push::Client.new
|
38
|
-
# client = Exponent::Push::Client.new(gzip: true) # for compressed, faster requests
|
39
|
-
|
40
|
-
messages = [{
|
41
|
-
to: "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
|
42
|
-
sound: "default",
|
43
|
-
body: "Hello world!"
|
44
|
-
}, {
|
45
|
-
to: "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
|
46
|
-
badge: 1,
|
47
|
-
body: "You've got mail"
|
48
|
-
}]
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
1
|
+
# Exponent Server SDK Ruby
|
2
|
+
|
3
|
+
[](https://travis-ci.org/expo/expo-server-sdk-ruby)
|
4
|
+
[](https://badge.fury.io/rb/exponent-server-sdk)
|
5
|
+
|
6
|
+
Use to send push notifications to Exponent Experiences from a Ruby server.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'exponent-server-sdk'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
```shell
|
19
|
+
$ bundle
|
20
|
+
```
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
```shell
|
25
|
+
$ gem install exponent-server-sdk
|
26
|
+
```
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
### Client
|
31
|
+
|
32
|
+
The push client is the preferred way. This hits the latest version of the api.
|
33
|
+
|
34
|
+
Optional arguments: `gzip: true`
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
client = Exponent::Push::Client.new
|
38
|
+
# client = Exponent::Push::Client.new(gzip: true) # for compressed, faster requests
|
39
|
+
|
40
|
+
messages = [{
|
41
|
+
to: "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
|
42
|
+
sound: "default",
|
43
|
+
body: "Hello world!"
|
44
|
+
}, {
|
45
|
+
to: "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
|
46
|
+
badge: 1,
|
47
|
+
body: "You've got mail"
|
48
|
+
}]
|
49
|
+
|
50
|
+
# @Deprecated
|
51
|
+
# client.publish(messages)
|
52
|
+
|
53
|
+
# MAX 100 messages at a time
|
54
|
+
handler = client.send_messages(messages)
|
55
|
+
|
56
|
+
# Array of all errors returned from the API
|
57
|
+
# puts handler.errors
|
58
|
+
|
59
|
+
# you probably want to delay calling this because the service might take a few moments to send
|
60
|
+
# I would recommend reading the expo documentation regarding delivery delays
|
61
|
+
client.verify_deliveries(handler.receipt_ids)
|
62
|
+
|
63
|
+
```
|
64
|
+
|
65
|
+
See the getting started example. If you clone this repo, you can also use it to test locally by entering your ExponentPushToken. Otherwise it serves as a good copy pasta example to get you going.
|
66
|
+
|
67
|
+
The complete format of the messages can be found [here.](https://docs.expo.io/versions/latest/guides/push-notifications#message-format)
|
68
|
+
|
69
|
+
## Contributing
|
70
|
+
|
71
|
+
If you have problems with the code in this repository, please file issues & bug reports. We encourage you
|
72
|
+
to submit a pull request with a solution or a failing test to reproduce your issue. Thanks!
|
data/Rakefile
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
3
|
|
4
|
-
def load_libs(
|
5
|
-
|
6
|
-
|
4
|
+
def load_libs(rake_task)
|
5
|
+
rake_task.libs << 'test'
|
6
|
+
rake_task.libs << 'lib'
|
7
7
|
end
|
8
8
|
|
9
|
-
Rake::TestTask.new(:test) do |
|
10
|
-
load_libs
|
11
|
-
|
9
|
+
Rake::TestTask.new(:test) do |rake_task|
|
10
|
+
load_libs rake_task
|
11
|
+
rake_task.test_files = FileList['test/**/*-test.rb']
|
12
12
|
end
|
13
13
|
|
14
|
-
Rake::TestTask.new(:
|
15
|
-
load_libs
|
16
|
-
|
14
|
+
Rake::TestTask.new(:getting_started) do |rake_task|
|
15
|
+
load_libs rake_task
|
16
|
+
rake_task.test_files = FileList['examples/getting_started.rb']
|
17
17
|
end
|
18
18
|
|
19
|
-
task :
|
19
|
+
task default: :test
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'exponent-server-sdk'
|
4
|
+
|
5
|
+
class Test
|
6
|
+
def initialize
|
7
|
+
# @client = Exponent::Push::Client.new
|
8
|
+
|
9
|
+
# OR use GZIP to be AWESOME
|
10
|
+
@client = Exponent::Push::Client.new(gzip: true)
|
11
|
+
end
|
12
|
+
|
13
|
+
def too_many_messages
|
14
|
+
(0..101).map { create_message }
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_message
|
18
|
+
{
|
19
|
+
# REPLACE WITH YOUR EXPONENT PUSH TOKEN LIKE:
|
20
|
+
# to: 'ExponentPushToken[g5sIEbOm2yFdzn5VdSSy9n]',
|
21
|
+
to: "ExponentPushToken[#{(0...22).map { ('a'..'z').to_a[rand(26)] }.join}]",
|
22
|
+
sound: 'default',
|
23
|
+
title: 'Hello World',
|
24
|
+
subtitle: 'This is a Push Notification',
|
25
|
+
body: 'Here\'s a little message for you...',
|
26
|
+
data: {
|
27
|
+
user_id: 1,
|
28
|
+
points: 23_434
|
29
|
+
},
|
30
|
+
ttl: 10,
|
31
|
+
expiration: 1_886_207_332,
|
32
|
+
priority: 'default',
|
33
|
+
badge: 0,
|
34
|
+
channelId: 'game'
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def test
|
39
|
+
# messages = too_many_messages
|
40
|
+
messages = [create_message]
|
41
|
+
|
42
|
+
response_handler = @client.send_messages(messages)
|
43
|
+
puts response_handler.response.response_body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Test.new.test
|
data/exponent-server-sdk.gemspec
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'exponent-server-sdk/version'
|
5
4
|
|
@@ -21,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
21
20
|
spec.add_dependency 'typhoeus'
|
22
21
|
|
23
22
|
spec.add_development_dependency 'bundler'
|
24
|
-
spec.add_development_dependency 'rake'
|
25
23
|
spec.add_development_dependency 'minitest'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rubocop'
|
26
26
|
end
|
data/lib/exponent-server-sdk.rb
CHANGED
@@ -1,160 +1,315 @@
|
|
1
|
-
require 'exponent-server-sdk/version'
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
end
|
132
|
-
|
133
|
-
def
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
1
|
+
require 'exponent-server-sdk/version'
|
2
|
+
require 'exponent-server-sdk/too_many_messages_error'
|
3
|
+
require 'typhoeus'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# Basic Usage:
|
7
|
+
#
|
8
|
+
# Create new client
|
9
|
+
# client = Exponent::Push::Client.new(**args)
|
10
|
+
#
|
11
|
+
# Send UPTO ~~100~~ messages per call,
|
12
|
+
# https://docs.expo.io/versions/latest/guides/push-notifications/#message-format
|
13
|
+
# response_handler = client.send_messages([list of formatted messages])
|
14
|
+
#
|
15
|
+
# Check the response to see if any errors were re
|
16
|
+
# response_handler.errors?
|
17
|
+
#
|
18
|
+
# To process each error, iterate over the errors array
|
19
|
+
# which contains each Error class instance
|
20
|
+
# response_handler.errors
|
21
|
+
#
|
22
|
+
# There is an array of invalid ExponentPushTokens that were found in the initial /send call
|
23
|
+
# response_handler.invalid_push_tokens['ExponentPushToken[1212121212121212]']
|
24
|
+
#
|
25
|
+
# You can use the handler to get receipt_ids
|
26
|
+
# response_handler.receipt_ids
|
27
|
+
#
|
28
|
+
# You can pass an array of receipt_ids to verify_deliveries method and
|
29
|
+
# it will populate a new ResponseHandler with any errors
|
30
|
+
# receipt_response = client.verify_deliveries(receipt_ids)
|
31
|
+
|
32
|
+
module Exponent
|
33
|
+
def self.is_exponent_push_token?(token)
|
34
|
+
token.start_with?('ExponentPushToken')
|
35
|
+
end
|
36
|
+
|
37
|
+
module Push
|
38
|
+
class Client
|
39
|
+
def initialize(**args)
|
40
|
+
@http_client = args[:http_client] || Typhoeus
|
41
|
+
@error_builder = ErrorBuilder.new
|
42
|
+
# future versions will deprecate this
|
43
|
+
@response_handler = args[:response_handler] || ResponseHandler.new
|
44
|
+
@gzip = args[:gzip] == true
|
45
|
+
end
|
46
|
+
|
47
|
+
# returns a string response with parsed success json or error
|
48
|
+
# @deprecated
|
49
|
+
def publish(messages)
|
50
|
+
warn '[DEPRECATION] `publish` is deprecated. Please use `send_messages` instead.'
|
51
|
+
@response_handler.handle(push_notifications(messages))
|
52
|
+
end
|
53
|
+
|
54
|
+
# returns response handler that provides access to errors? and other response inspection methods
|
55
|
+
def send_messages(messages, **args)
|
56
|
+
# https://docs.expo.io/versions/latest/guides/push-notifications/#message-format
|
57
|
+
raise TooManyMessagesError, 'Only 100 message objects at a time allowed.' if messages.length > 100
|
58
|
+
|
59
|
+
response = push_notifications(messages)
|
60
|
+
|
61
|
+
# each call to send_messages will return a new instance of ResponseHandler
|
62
|
+
handler = args[:response_handler] || ResponseHandler.new
|
63
|
+
handler.process_response(response)
|
64
|
+
handler
|
65
|
+
end
|
66
|
+
|
67
|
+
def verify_deliveries(receipt_ids, **args)
|
68
|
+
response = get_receipts(receipt_ids)
|
69
|
+
handler = args[:response_handler] || ResponseHandler.new
|
70
|
+
handler.process_response(response)
|
71
|
+
handler
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def push_notifications(messages)
|
77
|
+
@http_client.post(
|
78
|
+
push_url,
|
79
|
+
body: messages.to_json,
|
80
|
+
headers: headers,
|
81
|
+
accept_encoding: @gzip
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def push_url
|
86
|
+
'https://exp.host/--/api/v2/push/send'
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_receipts(receipt_ids)
|
90
|
+
@http_client.post(
|
91
|
+
receipts_url,
|
92
|
+
body: { ids: receipt_ids }.to_json,
|
93
|
+
headers: headers,
|
94
|
+
accept_encoding: @gzip
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
def receipts_url
|
99
|
+
'https://exp.host/--/api/v2/push/getReceipts'
|
100
|
+
end
|
101
|
+
|
102
|
+
def headers
|
103
|
+
headers = {
|
104
|
+
'Content-Type' => 'application/json',
|
105
|
+
'Accept' => 'application/json'
|
106
|
+
}
|
107
|
+
headers
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class ResponseHandler
|
112
|
+
attr_reader :response, :invalid_push_tokens, :receipt_ids, :errors
|
113
|
+
|
114
|
+
def initialize(error_builder = ErrorBuilder.new)
|
115
|
+
@error_builder = error_builder
|
116
|
+
@response = nil
|
117
|
+
@receipt_ids = []
|
118
|
+
@invalid_push_tokens = []
|
119
|
+
@errors = []
|
120
|
+
end
|
121
|
+
|
122
|
+
def process_response(response)
|
123
|
+
@response = response
|
124
|
+
|
125
|
+
case response.code.to_s
|
126
|
+
when /(^4|^5)/
|
127
|
+
raise @error_builder.parse_response(response)
|
128
|
+
else
|
129
|
+
sort_results
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def errors?
|
134
|
+
@errors.any?
|
135
|
+
end
|
136
|
+
|
137
|
+
# @deprecated
|
138
|
+
def handle(response)
|
139
|
+
warn '[DEPRECATION] `handle` is deprecated. Please use `process_response` instead.'
|
140
|
+
@response = response
|
141
|
+
case response.code.to_s
|
142
|
+
when /(^4|^5)/
|
143
|
+
raise build_error_from_failure
|
144
|
+
else
|
145
|
+
extract_data
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def sort_results
|
152
|
+
data = body&.fetch('data', nil) || nil
|
153
|
+
|
154
|
+
# something is definitely wrong
|
155
|
+
return if data.nil?
|
156
|
+
|
157
|
+
# Array indicates a response from the /send endpoint
|
158
|
+
# Hash indicates a response from the /getReceipts endpoint
|
159
|
+
if data.is_a? Array
|
160
|
+
data.each do |push_ticket|
|
161
|
+
receipt_id = push_ticket.fetch('id', nil)
|
162
|
+
if push_ticket.fetch('status', nil) == 'ok'
|
163
|
+
@receipt_ids.push(receipt_id) unless receipt_id.nil?
|
164
|
+
else
|
165
|
+
process_error(push_ticket)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
else
|
169
|
+
process_receipts(data)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def process_receipts(receipts)
|
174
|
+
receipts.each do |receipt_id, receipt|
|
175
|
+
@receipt_ids.push(receipt_id) unless receipt_id.nil?
|
176
|
+
process_error(receipt) unless receipt.fetch('status') == 'ok'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def process_error(push_ticket)
|
181
|
+
message = push_ticket.fetch('message')
|
182
|
+
matches = message.match(/ExponentPushToken\[(...*)\]/)
|
183
|
+
error_class = @error_builder.parse_push_ticket(push_ticket)
|
184
|
+
|
185
|
+
@invalid_push_tokens.push(matches[0]) unless matches.nil?
|
186
|
+
|
187
|
+
@errors.push(error_class) unless @errors.include?(error_class)
|
188
|
+
end
|
189
|
+
|
190
|
+
def body
|
191
|
+
# memoization FTW!
|
192
|
+
@body ||= JSON.parse(@response.body)
|
193
|
+
rescue SyntaxError
|
194
|
+
# Sometimes the server returns an empty string.
|
195
|
+
# It must be escaped before we can process it.
|
196
|
+
@body = JSON.parse(@response.body.to_json)
|
197
|
+
rescue StandardError
|
198
|
+
# Prevent nil errors in old version of ruby when using fetch
|
199
|
+
@body = {}
|
200
|
+
end
|
201
|
+
|
202
|
+
##### DEPRECATED METHODS #####
|
203
|
+
|
204
|
+
# @deprecated
|
205
|
+
def build_error_from_failure
|
206
|
+
@error_builder.build_from_erroneous(body)
|
207
|
+
end
|
208
|
+
|
209
|
+
# @deprecated
|
210
|
+
def extract_data
|
211
|
+
data = body.fetch('data')
|
212
|
+
if data.is_a? Hash
|
213
|
+
validate_status(data.fetch('status'), body)
|
214
|
+
data
|
215
|
+
elsif data.is_a? Array
|
216
|
+
data.map do |receipt|
|
217
|
+
validate_status(receipt.fetch('status'), body)
|
218
|
+
receipt
|
219
|
+
end
|
220
|
+
else
|
221
|
+
{}
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# @deprecated
|
226
|
+
def validate_status(status, response)
|
227
|
+
raise build_error_from_success(response) unless status == 'ok'
|
228
|
+
end
|
229
|
+
|
230
|
+
# @deprecated
|
231
|
+
def build_error_from_success(response)
|
232
|
+
@error_builder.build_from_successful(response)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
class ErrorBuilder
|
237
|
+
def parse_response(response)
|
238
|
+
with_error_handling(response) do
|
239
|
+
error = response.fetch('errors')
|
240
|
+
error_name = error.fetch('code')
|
241
|
+
message = error.fetch('message')
|
242
|
+
|
243
|
+
get_error_class(error_name).new(message)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def parse_push_ticket(push_ticket)
|
248
|
+
with_error_handling(push_ticket) do
|
249
|
+
message = push_ticket.fetch('message')
|
250
|
+
get_error_class(push_ticket.fetch('details').fetch('error')).new(message)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
%i[erroneous successful].each do |selector|
|
255
|
+
define_method(:"build_from_#{selector}") do |response|
|
256
|
+
with_error_handling(response) do
|
257
|
+
send "from_#{selector}_response", response
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
private
|
263
|
+
|
264
|
+
def with_error_handling(response)
|
265
|
+
yield(response)
|
266
|
+
rescue KeyError, NoMethodError
|
267
|
+
unknown_error_format(response)
|
268
|
+
end
|
269
|
+
|
270
|
+
def validate_error_name(condition)
|
271
|
+
condition ? yield : Exponent::Push::UnknownError
|
272
|
+
end
|
273
|
+
|
274
|
+
def get_error_class(error_name)
|
275
|
+
validate_error_name(Exponent::Push.error_names.include?(error_name)) do
|
276
|
+
Exponent::Push.const_get("#{error_name}Error")
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def unknown_error_format(response)
|
281
|
+
Exponent::Push::UnknownError.new("Unknown error format: #{response}")
|
282
|
+
end
|
283
|
+
|
284
|
+
##### DEPRECATED METHODS #####
|
285
|
+
|
286
|
+
# @deprecated
|
287
|
+
def from_erroneous_response(response)
|
288
|
+
error = response.fetch('errors').first
|
289
|
+
error_name = error.fetch('code')
|
290
|
+
message = error.fetch('message')
|
291
|
+
|
292
|
+
get_error_class(error_name).new(message)
|
293
|
+
end
|
294
|
+
|
295
|
+
# @deprecated
|
296
|
+
def from_successful_response(response)
|
297
|
+
delivery_result = response.fetch('data').first
|
298
|
+
message = delivery_result.fetch('message')
|
299
|
+
get_error_class(delivery_result.fetch('details').fetch('error')).new(message)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
Error = Class.new(StandardError)
|
304
|
+
|
305
|
+
def self.error_names
|
306
|
+
%w[DeviceNotRegistered MessageTooBig
|
307
|
+
MessageRateExceeded InvalidCredentials
|
308
|
+
Unknown]
|
309
|
+
end
|
310
|
+
|
311
|
+
error_names.each do |error_name|
|
312
|
+
const_set "#{error_name}Error", Class.new(Error)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|