urbanairship-ruby 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.markdown +397 -0
- data/Rakefile +8 -0
- data/lib/urbanairship/response.rb +33 -0
- data/lib/urbanairship.rb +200 -0
- data/spec/response_spec.rb +79 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/urbanairship_spec.rb +1088 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 634851e82146e4d7774e3d7d353650b5eb8170d3
|
4
|
+
data.tar.gz: e1ccd545450475e9250172ddb12c8aa43b74cc56
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d47927b532355e361f8ec17d16ee1f6565253952978fbefebe407ff5ffa82fd8070e56ec37f7771556774851bc1ce955366eff48a0670c5828da7c1eec5a3d3e
|
7
|
+
data.tar.gz: 349b8e0cc64ae48f5da928a51bdfc467fdc337f1e95a22996ab7158234284ae5d51f779c0a75eff5e33a7390980db382787d14def68343538fedbbaef0e87a8e
|
data/README.markdown
ADDED
@@ -0,0 +1,397 @@
|
|
1
|
+
Urbanairship is a Ruby library for interacting with the [Urban Airship API](http://urbanairship.com).
|
2
|
+
|
3
|
+
Installation
|
4
|
+
============
|
5
|
+
gem install urbanairship-ruby
|
6
|
+
|
7
|
+
Configuration
|
8
|
+
=============
|
9
|
+
```ruby
|
10
|
+
Urbanairship.application_key = 'application-key'
|
11
|
+
Urbanairship.application_secret = 'application-secret'
|
12
|
+
Urbanairship.master_secret = 'master-secret'
|
13
|
+
Urbanairship.logger = Rails.logger
|
14
|
+
Urbanairship.request_timeout = 5 # default
|
15
|
+
```
|
16
|
+
|
17
|
+
Usage
|
18
|
+
=====
|
19
|
+
|
20
|
+
Registering a device token
|
21
|
+
--------------------------
|
22
|
+
```ruby
|
23
|
+
Urbanairship.register_device('DEVICE-TOKEN')
|
24
|
+
```
|
25
|
+
You can also pass an alias, and a set of tags to device registration.
|
26
|
+
```ruby
|
27
|
+
Urbanairship.register_device('DEVICE-TOKEN',
|
28
|
+
:alias => 'user-123',
|
29
|
+
:tags => ['san-francisco-users']
|
30
|
+
)
|
31
|
+
```
|
32
|
+
|
33
|
+
Unregistering a device token
|
34
|
+
----------------------------
|
35
|
+
```ruby
|
36
|
+
Urbanairship.unregister_device('DEVICE-TOKEN')
|
37
|
+
```
|
38
|
+
|
39
|
+
Retrieving Device Info
|
40
|
+
----------------------------
|
41
|
+
```ruby
|
42
|
+
Urbanairship.device_info('DEVICE-TOKEN')
|
43
|
+
```
|
44
|
+
|
45
|
+
Sending a push notification
|
46
|
+
---------------------------
|
47
|
+
```ruby
|
48
|
+
notification = {
|
49
|
+
:audience => {
|
50
|
+
:ios_channel => "9c36e8c7-5a73-47c0-9716-99fd3d4197d5"
|
51
|
+
},
|
52
|
+
:notification => {
|
53
|
+
:alert => "Hello!"
|
54
|
+
},
|
55
|
+
:device_types => "all"
|
56
|
+
}
|
57
|
+
|
58
|
+
Urbanairship.push(notification) # =>
|
59
|
+
# {
|
60
|
+
# :ok => true,
|
61
|
+
# :operation_id => "df6a6b50-9843-0304-d5a5-743f246a4946",
|
62
|
+
# :push_ids => [
|
63
|
+
# "9d78a53b-b16a-c58f-b78d-181d5e242078",
|
64
|
+
# ]
|
65
|
+
# }
|
66
|
+
```
|
67
|
+
|
68
|
+
Batching push notification sends
|
69
|
+
--------------------------------
|
70
|
+
```ruby
|
71
|
+
notifications = [
|
72
|
+
{
|
73
|
+
:audience => {
|
74
|
+
:ios_channel => "9c36e8c7-5a73-47c0-9716-99fd3d4197d5"
|
75
|
+
},
|
76
|
+
:notification => {
|
77
|
+
:alert => "Hello!"
|
78
|
+
},
|
79
|
+
:device_types => "all"
|
80
|
+
},
|
81
|
+
{
|
82
|
+
:audience => {
|
83
|
+
:android_channel => "b8f9b663-0a3b-cf45-587a-be880946e880"
|
84
|
+
},
|
85
|
+
:notification => {
|
86
|
+
:alert => "Hello!"
|
87
|
+
},
|
88
|
+
:device_types => "all"
|
89
|
+
}
|
90
|
+
]
|
91
|
+
|
92
|
+
Urbanairship.batch_push(notifications)
|
93
|
+
```
|
94
|
+
|
95
|
+
Polling the feedback API
|
96
|
+
------------------------
|
97
|
+
The first time you attempt to send a push notification to a device that has uninstalled your app (or has opted-out of notifications), both Apple and Urban Airship will register that token in their feedback API. Urban Airship will prevent further attempted notification sends to that device, but it's a good practice to periodically poll Urban Airship's feedback API and mark those tokens as inactive in your own system as well.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
# find all device tokens deactivated in the past 24 hours
|
101
|
+
Urbanairship.feedback(24.hours.ago) # =>
|
102
|
+
# [
|
103
|
+
# {
|
104
|
+
# "marked_inactive_on"=>"2011-06-03 22:53:23",
|
105
|
+
# "alias"=>nil,
|
106
|
+
# "device_token"=>"DEVICE-TOKEN-ONE"
|
107
|
+
# },
|
108
|
+
# {
|
109
|
+
# "marked_inactive_on"=>"2011-06-03 22:53:23",
|
110
|
+
# "alias"=>nil,
|
111
|
+
# "device_token"=>"DEVICE-TOKEN-TWO"
|
112
|
+
# }
|
113
|
+
# ]
|
114
|
+
```
|
115
|
+
|
116
|
+
Schedule notifications
|
117
|
+
--------------------------------
|
118
|
+
|
119
|
+
### Listing your schedules ###
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
Urbanairship.schedules
|
123
|
+
Urbanairship.schedule('03ab5ba1-6f8d-415d-baae-5a81cc24fae2')
|
124
|
+
```
|
125
|
+
|
126
|
+
### Creating your schedules ###
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
schedule = {
|
130
|
+
:name => "Booyah Sports",
|
131
|
+
:schedule => {
|
132
|
+
:scheduled_time => "2015-08-01T18:45:00Z"
|
133
|
+
},
|
134
|
+
:push => {
|
135
|
+
:audience => {
|
136
|
+
:tag => "spoaaaarts"
|
137
|
+
},
|
138
|
+
:notification => {
|
139
|
+
:alert => "Booyah!"
|
140
|
+
},
|
141
|
+
:device_types => "all"
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
Urbanairship.create_schedule(schedule) # =>
|
146
|
+
# {
|
147
|
+
# "ok" => true,
|
148
|
+
# "operation_id" => "cd9d6390-2a12-11e5-a2b8-90e2ba2901f0",
|
149
|
+
# "schedule_urls" => [
|
150
|
+
# "https://go.urbanairship.com/api/schedules/03ab5ba1-6f8d-415d-baae-5a81cc24fae2"
|
151
|
+
# ],
|
152
|
+
# "schedule_ids" => [
|
153
|
+
# "03ab5ba1-6f8d-415d-baae-5a81cc24fae2"
|
154
|
+
# ],
|
155
|
+
# "schedules" => [
|
156
|
+
# {
|
157
|
+
# "url" => "https://go.urbanairship.com/api/schedules/03ab5ba1-6f8d-415d-baae-5a81cc24fae2",
|
158
|
+
# "schedule" => {
|
159
|
+
# "scheduled_time" => "2015-08-01T18:45:00"
|
160
|
+
# },
|
161
|
+
# "name" => "Booyah Sports",
|
162
|
+
# "push" => {
|
163
|
+
# "audience" => {
|
164
|
+
# "tag" => "spoaaaarts"
|
165
|
+
# },
|
166
|
+
# "device_types" => "all",
|
167
|
+
# "notification" => {
|
168
|
+
# "alert" => "Booyah!"
|
169
|
+
# }
|
170
|
+
# },
|
171
|
+
# "push_ids" => [
|
172
|
+
# "a74db2b6-65f0-465f-82d6-4fa25448b642"
|
173
|
+
# ]
|
174
|
+
# }
|
175
|
+
# ]
|
176
|
+
# }
|
177
|
+
```
|
178
|
+
|
179
|
+
### Modifying your schedules ###
|
180
|
+
|
181
|
+
You can modify an unsent scheduled push if you know its ID
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
schedule = {
|
185
|
+
:name => "Booyah Sports",
|
186
|
+
:schedule => {
|
187
|
+
:scheduled_time => "2015-08-01T18:45:00Z"
|
188
|
+
},
|
189
|
+
:push => {
|
190
|
+
:audience => {
|
191
|
+
:tag => "spoaaaarts"
|
192
|
+
},
|
193
|
+
:notification => {
|
194
|
+
:alert => "Booyah!"
|
195
|
+
},
|
196
|
+
:device_types => "all"
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
Urbanairship.update_schedule('03ab5ba1-6f8d-415d-baae-5a81cc24fae2', schedule)
|
201
|
+
```
|
202
|
+
|
203
|
+
|
204
|
+
### Deleting your schedules ###
|
205
|
+
|
206
|
+
If you know the alias or id of a scheduled push notification then you can delete it from Urban Airship's queue and it will not be delivered.
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
Urbanairship.delete_schedule("123456789")
|
210
|
+
Urbanairship.delete_schedule(123456789)
|
211
|
+
Urbanairship.delete_schedule(:alias => "deadbeef")
|
212
|
+
```
|
213
|
+
|
214
|
+
Segments
|
215
|
+
---------------------------
|
216
|
+
|
217
|
+
### Creating a segment ###
|
218
|
+
``` ruby
|
219
|
+
Urbanairship.create_segment({
|
220
|
+
:display_name => 'segment1',
|
221
|
+
:criteria => {:and => [{:tag => 'one'}, {:tag => 'two'}]}
|
222
|
+
}) # => {}
|
223
|
+
```
|
224
|
+
|
225
|
+
### Listing your segments ###
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
Urbanairship.segments # =>
|
229
|
+
# {
|
230
|
+
# "segments" => [
|
231
|
+
# {
|
232
|
+
# "id" => "abcd-efgh-ijkl",
|
233
|
+
# "display_name" => "segment1",
|
234
|
+
# "creation_date" => 1360950614201,
|
235
|
+
# "modification_date" => 1360950614201
|
236
|
+
# }
|
237
|
+
# ]
|
238
|
+
# }
|
239
|
+
|
240
|
+
Urbanairship.segment("abcd-efgh-ijkl") # =>
|
241
|
+
# {
|
242
|
+
# "id" => "abcd-efgh-ijkl",
|
243
|
+
# "display_name" => "segment1",
|
244
|
+
# "creation_date" => 1360950614201,
|
245
|
+
# "modification_date" => 1360950614201
|
246
|
+
# }
|
247
|
+
```
|
248
|
+
|
249
|
+
### Modifying a segment ###
|
250
|
+
Note that you must provide both the display name and criteria when updating a segment, even if you are only changing one or the other.
|
251
|
+
``` ruby
|
252
|
+
Urbanairship.update_segment('abcd-efgh-ijkl', {
|
253
|
+
:display_name => 'segment1',
|
254
|
+
:criteria => {:and => [{:tag => 'asdf'}]}
|
255
|
+
}) # => {}
|
256
|
+
```
|
257
|
+
|
258
|
+
### Deleting a segment ###
|
259
|
+
```ruby
|
260
|
+
Urbanairship.delete_segment("abcd-efgh-ijkl") # => {}
|
261
|
+
```
|
262
|
+
|
263
|
+
Getting your device tokens
|
264
|
+
-------------------------------------
|
265
|
+
```ruby
|
266
|
+
Urbanairship.device_tokens # =>
|
267
|
+
# {
|
268
|
+
# "device_tokens" => {"device_token"=>"<token>", "active"=>true, "alias"=>"<alias>", "tags"=>[]},
|
269
|
+
# "device_tokens_count" => 3,
|
270
|
+
# "active_device_tokens_count" => 1
|
271
|
+
# }
|
272
|
+
```
|
273
|
+
|
274
|
+
Getting a count of your device tokens
|
275
|
+
-------------------------------------
|
276
|
+
```ruby
|
277
|
+
Urbanairship.device_tokens_count # =>
|
278
|
+
# {
|
279
|
+
# "device_tokens_count" => 3,
|
280
|
+
# "active_device_tokens_count" => 1
|
281
|
+
# }
|
282
|
+
```
|
283
|
+
|
284
|
+
Tags
|
285
|
+
----
|
286
|
+
|
287
|
+
Urban Airship allows you to create tags and associate them with devices. Then you can easily send a notification to every device matching a certain tag with a single call to the push API.
|
288
|
+
|
289
|
+
### Creating a tag ###
|
290
|
+
|
291
|
+
Tags must be registered before you can use them.
|
292
|
+
|
293
|
+
```ruby
|
294
|
+
Urbanairship.add_tag('TAG')
|
295
|
+
```
|
296
|
+
|
297
|
+
### Listing your tags ###
|
298
|
+
|
299
|
+
```ruby
|
300
|
+
Urbanairship.tags
|
301
|
+
```
|
302
|
+
|
303
|
+
### Removing a tag ##
|
304
|
+
|
305
|
+
This will remove a tag from your set of registered tags, as well as removing that tag from any devices that are currently using it.
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
Urbanairship.remove_tag('TAG')
|
309
|
+
```
|
310
|
+
|
311
|
+
### View tags associated with device ###
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
Urbanairship.tags_for_device('DEVICE-TOKEN')
|
315
|
+
```
|
316
|
+
|
317
|
+
### Tag a device ###
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
Urbanairship.tag_device(:device_token => 'DEVICE-TOKEN', :tag => 'TAG')
|
321
|
+
```
|
322
|
+
|
323
|
+
You can also tag a device during device registration.
|
324
|
+
|
325
|
+
```ruby
|
326
|
+
Urbanairship.register_device('DEVICE-TOKEN', :tags => ['san-francisco-users'])
|
327
|
+
```
|
328
|
+
|
329
|
+
### Untag a device ###
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
Urbanairship.untag_device(:device_token => 'DEVICE-TOKEN', :tag => 'TAG')
|
333
|
+
```
|
334
|
+
|
335
|
+
### Sending a notification to all devices with a given tag ###
|
336
|
+
|
337
|
+
```ruby
|
338
|
+
notification = {
|
339
|
+
:tags => ['san-francisco-users'],
|
340
|
+
:aps => {:alert => 'Good morning San Francisco!', :badge => 1}
|
341
|
+
}
|
342
|
+
|
343
|
+
Urbanairship.push(notification)
|
344
|
+
```
|
345
|
+
|
346
|
+
Using Urbanairship with Android
|
347
|
+
-------------------------------
|
348
|
+
|
349
|
+
The Urban Airship API extends a subset of their push API to Android devices. You can read more about what is currently supported [here](https://docs.urbanairship.com/display/DOCS/Server%3A+Android+Push+API), but as of this writing, only registration, aliases, tags, broadcast, individual push, and batch push are supported.
|
350
|
+
|
351
|
+
To use this library with Android devices, you can set the `provider` configuration option to `:android`:
|
352
|
+
|
353
|
+
```ruby
|
354
|
+
Urbanairship.provider = :android
|
355
|
+
```
|
356
|
+
|
357
|
+
Alternatively, you can pass the `:provider => :android` option to device registration calls if your app uses Urbanairship to send notifications to both Android and iOS devices.
|
358
|
+
|
359
|
+
```ruby
|
360
|
+
Urbanairship.register_device("DEVICE-TOKEN", :provider => :android)
|
361
|
+
```
|
362
|
+
|
363
|
+
Note: all other supported actions use the same API endpoints as iOS, so it is not necessary to specify the provider as `:android` when calling them.
|
364
|
+
|
365
|
+
-----------------------------
|
366
|
+
|
367
|
+
Note: all public library methods will return either an array or a hash, depending on the response from the Urban Airship API. In addition, you can inspect these objects to find out if they were successful or not, and what the http response code from Urban Airship was.
|
368
|
+
|
369
|
+
```ruby
|
370
|
+
response = Urbanairship.push(payload)
|
371
|
+
response.success? # => true
|
372
|
+
response.code # => '200'
|
373
|
+
response.inspect # => "{\"scheduled_notifications\"=>[\"https://go.urbanairship.com/api/push/scheduled/123456\"]}"
|
374
|
+
```
|
375
|
+
|
376
|
+
If the call to Urban Airship times out, you'll get a response object with a '503' code.
|
377
|
+
|
378
|
+
```ruby
|
379
|
+
response = Urbanairship.feedback(1.year.ago)
|
380
|
+
response.success? # => false
|
381
|
+
response.code # => '503'
|
382
|
+
response.inspect # => "{\"error\"=>\"Request timeout\"}"
|
383
|
+
```
|
384
|
+
|
385
|
+
Instantiating an Urbanairship::Client
|
386
|
+
-------------------------------------
|
387
|
+
|
388
|
+
Anything you can do directly with the Urbanairship module, you can also do with a Client.
|
389
|
+
|
390
|
+
```ruby
|
391
|
+
client = Urbanairship::Client.new
|
392
|
+
client.application_key = 'application-key'
|
393
|
+
client.application_secret = 'application-secret'
|
394
|
+
client.register_device('DEVICE-TOKEN')
|
395
|
+
```
|
396
|
+
|
397
|
+
This can be used to use clients for different Urbanairship applications in a thread-safe manner.
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Urbanairship
|
2
|
+
module Response
|
3
|
+
module InstanceMethods
|
4
|
+
attr_accessor :ua_response, :ua_options
|
5
|
+
|
6
|
+
def code
|
7
|
+
(ua_options[:code] || ua_response.code).to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def success?
|
11
|
+
!!(code =~ /^2/)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.wrap(response, options = {})
|
16
|
+
if options[:body]
|
17
|
+
output = options[:body]
|
18
|
+
else
|
19
|
+
begin
|
20
|
+
output = JSON.parse(response.body || '{}')
|
21
|
+
rescue JSON::ParserError => e
|
22
|
+
output = {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
output.extend(Urbanairship::Response::InstanceMethods)
|
27
|
+
output.ua_response = response
|
28
|
+
output.ua_options = options
|
29
|
+
|
30
|
+
return output
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/urbanairship.rb
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/https'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
require File.join(File.dirname(__FILE__), 'urbanairship/response')
|
6
|
+
|
7
|
+
module Urbanairship
|
8
|
+
begin
|
9
|
+
require 'system_timer'
|
10
|
+
Timer = SystemTimer
|
11
|
+
rescue LoadError
|
12
|
+
require 'timeout'
|
13
|
+
Timer = Timeout
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
attr_accessor :application_key, :application_secret, :master_secret, :logger, :request_timeout, :provider
|
18
|
+
VERSION = 3
|
19
|
+
|
20
|
+
def register_device(device_token, options = {})
|
21
|
+
body = parse_register_options(options).to_json
|
22
|
+
|
23
|
+
path = device_tokens_end_point(options[:provider] || @provider)
|
24
|
+
do_request(:put, "/api/#{path}/#{device_token}", :body => body, :authenticate_with => :application_secret)
|
25
|
+
end
|
26
|
+
|
27
|
+
def unregister_device(device_token, options = {})
|
28
|
+
path = device_tokens_end_point(options[:provider] || @provider)
|
29
|
+
do_request(:delete, "/api/#{path}/#{device_token}", :authenticate_with => :application_secret)
|
30
|
+
end
|
31
|
+
|
32
|
+
def device_info(device_token, options = {})
|
33
|
+
path = device_tokens_end_point(options[:provider] || @provider)
|
34
|
+
do_request(:get, "/api/#{path}/#{device_token}", :authenticate_with => :application_secret)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Schedules API
|
38
|
+
def create_schedule(schedule)
|
39
|
+
do_request(:post, "/api/schedules/", :body => schedule.to_json, :authenticate_with => :master_secret)
|
40
|
+
end
|
41
|
+
|
42
|
+
def schedules
|
43
|
+
do_request(:get, "/api/schedules/", :authenticate_with => :master_secret)
|
44
|
+
end
|
45
|
+
|
46
|
+
def schedule(id)
|
47
|
+
do_request(:get, "/api/schedules/#{id}", :authenticate_with => :master_secret)
|
48
|
+
end
|
49
|
+
|
50
|
+
def update_schedule(id, schedule)
|
51
|
+
do_request(:put, "/api/schedules/#{id}", :body => schedule.to_json, :authenticate_with => :master_secret)
|
52
|
+
end
|
53
|
+
|
54
|
+
def delete_schedule(id)
|
55
|
+
do_request(:delete, "/api/schedules/#{id}", :authenticate_with => :master_secret)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Push API
|
59
|
+
def push(options = {})
|
60
|
+
body = parse_push_options(options.dup).to_json
|
61
|
+
do_request(:post, "/api/push/", :body => body, :authenticate_with => :master_secret)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Tags API
|
65
|
+
def tags
|
66
|
+
do_request(:get, "/api/tags/", :authenticate_with => :master_secret)
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_tag(tag)
|
70
|
+
do_request(:put, "/api/tags/#{tag}", :authenticate_with => :master_secret, :content_type => 'text/plain')
|
71
|
+
end
|
72
|
+
|
73
|
+
def remove_tag(tag)
|
74
|
+
do_request(:delete, "/api/tags/#{tag}", :authenticate_with => :master_secret)
|
75
|
+
end
|
76
|
+
|
77
|
+
def tag_device(params)
|
78
|
+
provider_field = device_tokens_end_point(params[:provider] || @provider).to_sym
|
79
|
+
do_request(:post, "/api/tags/#{params[:tag]}", :body => {provider_field => {:add => [params[:device_token]]}}.to_json, :authenticate_with => :master_secret)
|
80
|
+
end
|
81
|
+
|
82
|
+
def untag_device(params)
|
83
|
+
provider_field = device_tokens_end_point(params[:provider] || @provider).to_sym
|
84
|
+
do_request(:post, "/api/tags/#{params[:tag]}", :body => {provider_field => {:remove => [params[:device_token]]}}.to_json, :authenticate_with => :master_secret)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Device Tokens API
|
88
|
+
def tags_for_device(device_token)
|
89
|
+
do_request(:get, "/api/device_tokens/#{device_token}/tags/", :authenticate_with => :master_secret)
|
90
|
+
end
|
91
|
+
|
92
|
+
def device_tokens
|
93
|
+
do_request(:get, "/api/device_tokens/", :authenticate_with => :master_secret)
|
94
|
+
end
|
95
|
+
|
96
|
+
def device_tokens_count
|
97
|
+
do_request(:get, "/api/device_tokens/count/", :authenticate_with => :master_secret)
|
98
|
+
end
|
99
|
+
|
100
|
+
def feedback(time)
|
101
|
+
do_request(:get, "/api/device_tokens/feedback/?since=#{format_time(time)}", :authenticate_with => :master_secret)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Segments API
|
105
|
+
def segments
|
106
|
+
do_request(:get, "/api/segments", :authenticate_with => :master_secret)
|
107
|
+
end
|
108
|
+
|
109
|
+
def create_segment(segment)
|
110
|
+
do_request(:post, "/api/segments", :body => segment.to_json, :authenticate_with => :master_secret)
|
111
|
+
end
|
112
|
+
|
113
|
+
def segment(id)
|
114
|
+
do_request(:get, "/api/segments/#{id}", :authenticate_with => :master_secret)
|
115
|
+
end
|
116
|
+
|
117
|
+
def update_segment(id, segment)
|
118
|
+
do_request(:put, "/api/segments/#{id}", :body => segment.to_json, :authenticate_with => :master_secret)
|
119
|
+
end
|
120
|
+
|
121
|
+
def delete_segment(id)
|
122
|
+
do_request(:delete, "/api/segments/#{id}", :authenticate_with => :master_secret)
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def do_request(http_method, path, options = {})
|
128
|
+
verify_configuration_values(:application_key, options[:authenticate_with])
|
129
|
+
|
130
|
+
klass = Net::HTTP.const_get(http_method.to_s.capitalize)
|
131
|
+
|
132
|
+
request = klass.new(path)
|
133
|
+
request.basic_auth @application_key, instance_variable_get("@#{options[:authenticate_with]}")
|
134
|
+
request.add_field "Content-Type", options[:content_type] || "application/json"
|
135
|
+
request.body = options[:body] if options[:body]
|
136
|
+
request["Accept"] = "application/vnd.urbanairship+json; version=#{VERSION};"
|
137
|
+
|
138
|
+
Timer.timeout(request_timeout) do
|
139
|
+
start_time = Time.now
|
140
|
+
response = http_client.request(request)
|
141
|
+
log_request_and_response(request, response, Time.now - start_time)
|
142
|
+
Urbanairship::Response.wrap(response)
|
143
|
+
end
|
144
|
+
rescue Timeout::Error
|
145
|
+
unless logger.nil?
|
146
|
+
logger.error "Urbanairship request timed out after #{request_timeout} seconds: [#{http_method} #{request.path} #{request.body}]"
|
147
|
+
end
|
148
|
+
Urbanairship::Response.wrap(nil, :body => {'error' => 'Request timeout'}, :code => '503')
|
149
|
+
end
|
150
|
+
|
151
|
+
def verify_configuration_values(*symbols)
|
152
|
+
absent_values = symbols.select{|symbol| instance_variable_get("@#{symbol}").nil? }
|
153
|
+
raise("Must configure #{absent_values.join(", ")} before making this request.") unless absent_values.empty?
|
154
|
+
end
|
155
|
+
|
156
|
+
def http_client
|
157
|
+
Net::HTTP.new("go.urbanairship.com", 443).tap{|http| http.use_ssl = true}
|
158
|
+
end
|
159
|
+
|
160
|
+
def parse_register_options(hash = {})
|
161
|
+
hash[:alias] = hash[:alias].to_s unless hash[:alias].nil?
|
162
|
+
hash
|
163
|
+
end
|
164
|
+
|
165
|
+
def parse_push_options(hash = {})
|
166
|
+
hash[:aliases] = hash[:aliases].map{|a| a.to_s} unless hash[:aliases].nil?
|
167
|
+
hash
|
168
|
+
end
|
169
|
+
|
170
|
+
def log_request_and_response(request, response, time)
|
171
|
+
return if logger.nil?
|
172
|
+
|
173
|
+
time = (time * 1000).to_i
|
174
|
+
http_method = request.class.to_s.split('::')[-1]
|
175
|
+
logger.info "Urbanairship (#{time}ms): [#{http_method} #{request.path}, #{request.body}], [#{response.code}, #{response.body}]"
|
176
|
+
logger.flush if logger.respond_to?(:flush)
|
177
|
+
end
|
178
|
+
|
179
|
+
def format_time(time)
|
180
|
+
time = Time.parse(time) if time.is_a?(String)
|
181
|
+
time.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
182
|
+
end
|
183
|
+
|
184
|
+
def request_timeout
|
185
|
+
@request_timeout || 5.0
|
186
|
+
end
|
187
|
+
|
188
|
+
def device_tokens_end_point(provider)
|
189
|
+
provider == :android || provider == 'android' ? 'apids' : 'device_tokens'
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
class << self
|
194
|
+
include ClassMethods
|
195
|
+
end
|
196
|
+
|
197
|
+
class Client
|
198
|
+
include ClassMethods
|
199
|
+
end
|
200
|
+
end
|