pushradar 1.0.2 → 1.8.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.
data/lib/PushRadar.rb CHANGED
@@ -1,391 +1,384 @@
1
- require 'PushRadar/version'
2
- require 'PushRadar/Targeting'
3
- require 'PushRadar/APIClient'
4
- require 'json'
5
-
6
- module PushRadar
7
-
8
- # A realtime push notifications API service for the web, featuring advanced targeting
9
- class Radar
10
-
11
- # ------------------------------
12
- # Initialisation & configuration
13
- # ------------------------------
14
-
15
- # Creates a new instance of PushRadar with the specified API secret
16
- def initialize(api_secret)
17
-
18
- # Initialize data
19
- @data = {}
20
-
21
- # Reset the targeting options
22
- reset_targeting
23
-
24
- # Check that the API secret is a string
25
- unless api_secret.is_a?(String)
26
- raise 'The API secret must be a string value.'
27
- end
28
-
29
- # Trim the API secret
30
- api_secret.strip!
31
-
32
- # If we are running unit tests, set the unit test mode flag and skip the PushRadar API client initialisation
33
- if api_secret == 'test-secret'
34
- @is_unit_test_mode = true
35
- return
36
- else
37
- @is_unit_test_mode = false
38
- end
39
-
40
- # Check that the API secret starts with sk_
41
- unless api_secret.start_with?('sk_')
42
- raise 'API secret invalid. You can view your PushRadar API secret at https://dashboard.pushradar.com/api'
43
- end
44
-
45
- # Make a new instance of a PushRadar API client with the specified API secret
46
- @api_client = APIClient.new(api_secret)
47
-
48
- end
49
-
50
- # ------------------------------
51
- # Browser targeting
52
- # ------------------------------
53
-
54
- # Targets the notification to clients currently using the given browser
55
- def target_browser(browser)
56
-
57
- # Add the browser to the list of target browsers
58
- @targeting.target_browser browser
59
-
60
- # Allow method chaining
61
- self
62
-
63
- end
64
-
65
- # Targets the notification to clients currently using any of the given browsers
66
- def target_browsers(*browsers)
67
-
68
- # Target each browser
69
- browsers.each {|x|
70
- target_browser x
71
- }
72
-
73
- # Allow method chaining
74
- self
75
-
76
- end
77
-
78
- # ------------------------------
79
- # Country targeting
80
- # ------------------------------
81
-
82
- # Targets the notification to clients currently located in the given country
83
- def target_country(country_code)
84
-
85
- # Add the country to the list of target countries
86
- @targeting.target_country country_code
87
-
88
- # Allow method chaining
89
- self
90
-
91
- end
92
-
93
- # Targets the notification to clients currently located in any of the given countries
94
- def target_countries(*country_codes)
95
-
96
- # Target each country
97
- country_codes.each {|x|
98
- target_country x
99
- }
100
-
101
- # Allow method chaining
102
- self
103
-
104
- end
105
-
106
- # ------------------------------
107
- # Continent targeting
108
- # ------------------------------
109
-
110
- # Targets the notification to clients currently located in Asia
111
- def target_asia
112
-
113
- # Target the continent
114
- @targeting.target_continent('AS')
115
-
116
- # Allow method chaining
117
- self
118
-
119
- end
120
-
121
- # Targets the notification to clients currently located in Africa
122
- def target_africa
123
-
124
- # Target the continent
125
- @targeting.target_continent('AF')
126
-
127
- # Allow method chaining
128
- self
129
-
130
- end
131
-
132
- # Targets the notification to clients currently located in Antarctica
133
- def target_antarctica
134
-
135
- # Target the continent
136
- @targeting.target_continent('AN')
137
-
138
- # Allow method chaining
139
- self
140
-
141
- end
142
-
143
- # Targets the notification to clients currently located in Europe
144
- def target_europe
145
-
146
- # Target the continent
147
- @targeting.target_continent('EU')
148
-
149
- # Allow method chaining
150
- self
151
-
152
- end
153
-
154
- # Targets the notification to clients currently located in North America
155
- def target_north_america
156
-
157
- # Target the continent
158
- @targeting.target_continent('NA')
159
-
160
- # Allow method chaining
161
- self
162
-
163
- end
164
-
165
- # Targets the notification to clients currently located in South America
166
- def target_south_america
167
-
168
- # Target the continent
169
- @targeting.target_continent('SA')
170
-
171
- # Allow method chaining
172
- self
173
-
174
- end
175
-
176
- # Targets the notification to clients currently located in Oceania
177
- def target_oceania
178
-
179
- # Target the continent
180
- @targeting.target_continent('OC')
181
-
182
- # Allow method chaining
183
- self
184
-
185
- end
186
-
187
- # ------------------------------
188
- # IP address targeting
189
- # ------------------------------
190
-
191
- # Targets the notification to clients with the given IP address
192
- def target_ip(ip_address)
193
-
194
- # Add the IP address to the list of target IP addresses
195
- @targeting.target_ip ip_address
196
-
197
- # Allow method chaining
198
- self
199
-
200
- end
201
-
202
- # Targets the notification to clients with any of the given IP addresses
203
- def target_ips(*ip_addresses)
204
-
205
- # Target each IP address
206
- ip_addresses.each {|x|
207
- target_ip x
208
- }
209
-
210
- # Allow method chaining
211
- self
212
-
213
- end
214
-
215
- # ------------------------------
216
- # Action targeting
217
- # ------------------------------
218
-
219
- # Targets the notification to clients who have taken the given action
220
- def target_action(action_identifier)
221
-
222
- # Add the action to the list of target actions
223
- @targeting.target_action action_identifier
224
-
225
- # Allow method chaining
226
- self
227
-
228
- end
229
-
230
- # Targets the notification to clients who have taken any of the given actions
231
- def target_actions(*action_identifiers)
232
-
233
- # Target each action
234
- action_identifiers.each {|x|
235
- target_action x
236
- }
237
-
238
- # Allow method chaining
239
- self
240
-
241
- end
242
-
243
- # Targets the notification to clients who have not taken the given action
244
- def target_not_action(action_identifier)
245
-
246
- # Add the action to the list of target "not" actions
247
- @targeting.target_not_action action_identifier
248
-
249
- # Allow method chaining
250
- self
251
-
252
- end
253
-
254
- # Targets the notification to clients who have not taken any of the given actions
255
- def target_not_actions(*action_identifiers)
256
-
257
- # Target each action
258
- action_identifiers.each {|x|
259
- target_not_action x
260
- }
261
-
262
- # Allow method chaining
263
- self
264
-
265
- end
266
-
267
- # ------------------------------
268
- # User targeting
269
- # ------------------------------
270
-
271
- # Targets the notification to a specific user (identified by their user ID)
272
- def target_user(user_id)
273
-
274
- # Target the user
275
- @targeting.target_user user_id
276
-
277
- # Allow method chaining
278
- self
279
-
280
- end
281
-
282
- # Targets the notification to specific users (identified by their user IDs)
283
- def target_users(*user_ids)
284
-
285
- # Target the user IDs
286
- user_ids.each {|x|
287
- target_user x
288
- }
289
-
290
- # Allow method chaining
291
- self
292
-
293
- end
294
-
295
- # ------------------------------
296
- # Adding data
297
- # ------------------------------
298
-
299
- # Adds a data item to the list of data items
300
- def add_data_item(key, value)
301
-
302
- # Make sure the key is not empty
303
- if key == ''
304
- raise 'The key provided cannot be empty.'
305
- end
306
-
307
- # Add the data item
308
- unless @data.keys.include?(key)
309
- @data[key] = value
310
- end
311
-
312
- # Allow method chaining
313
- self
314
-
315
- end
316
-
317
- # Adds multiple data items to the list of data items
318
- def add_data_items(data = {})
319
-
320
- # Add the data items
321
- data.keys.each {|x|
322
- add_data_item x, data[x]
323
- }
324
-
325
- # Allow method chaining
326
- self
327
-
328
- end
329
-
330
- # ------------------------------
331
- # Broadcast method
332
- # ------------------------------
333
-
334
- # Broadcasts data on the channel specified
335
- def broadcast(channel, data = {})
336
-
337
- # If we are running unit tests, throw an exception
338
- if @is_unit_test_mode
339
- raise 'Unit testing of the broadcast() method is not supported.'
340
- end
341
-
342
- # Trim the channel name
343
- channel.strip!
344
-
345
- # Check whether data has been provided
346
- if data.length == 0 && @data.length == 0
347
- raise 'There is no data to broadcast.'
348
- end
349
-
350
- # Check whether the channel name contains spaces
351
- if channel.include? ' '
352
- raise "The channel name cannot contain spaces. By convention, channel names are alphanumerical and lowercase, with optional dashes (e.g. 'test-channel')."
353
- end
354
-
355
- # Use the stored data if the data parameter is empty
356
- if data.length == 0
357
- data = @data
358
- end
359
-
360
- # Initialize the hash of data to send to the server
361
- data_to_send = {
362
- channel: channel,
363
- notification: data.to_json,
364
- target_user_ids: @targeting.instance_variable_get('@target_user_ids').to_json,
365
- target_actions: @targeting.instance_variable_get('@target_actions').to_json,
366
- target_not_actions: @targeting.instance_variable_get('@target_not_actions').to_json,
367
- target_continents: @targeting.instance_variable_get('@target_continents').to_json,
368
- target_countries: @targeting.instance_variable_get('@target_countries').to_json,
369
- target_ips: @targeting.instance_variable_get('@target_ips').to_json,
370
- target_browsers: @targeting.instance_variable_get('@target_browsers').to_json
371
- }
372
-
373
- # Broadcast the notification
374
- @api_client.post('/broadcast', data_to_send)
375
-
376
- # Reset the targeting options
377
- reset_targeting
378
-
379
- end
380
-
381
- # Resets the targeting options
382
- def reset_targeting
383
- @targeting = Targeting.new
384
- end
385
-
386
- # Set which methods are private
387
- private :reset_targeting
388
-
389
- end
390
-
1
+ require 'PushRadar/version'
2
+ require 'PushRadar/Targeting'
3
+ require 'PushRadar/APIClient'
4
+ require 'json'
5
+ require 'digest/md5'
6
+
7
+ module PushRadar
8
+
9
+ # A realtime push notifications API service for the web, featuring advanced targeting
10
+ class Radar
11
+
12
+ # Creates a new instance of PushRadar with the specified API secret
13
+ def initialize(api_secret)
14
+
15
+ # Initialize data
16
+ @data = {}
17
+
18
+ # Reset the targeting options
19
+ reset_targeting
20
+
21
+ # Check that the API secret is a string
22
+ unless api_secret.is_a?(String)
23
+ raise 'The API secret must be a string value.'
24
+ end
25
+
26
+ # Trim the API secret
27
+ api_secret.strip!
28
+
29
+ # If we are running unit tests, set the unit test mode flag and skip the PushRadar API client initialisation
30
+ if api_secret == 'test-secret'
31
+ @is_unit_test_mode = true
32
+ return
33
+ else
34
+ @is_unit_test_mode = false
35
+ end
36
+
37
+ # Check that the API secret starts with sk_
38
+ unless api_secret.start_with?('sk_')
39
+ raise 'API secret invalid. You can view your PushRadar API secret at https://dashboard.pushradar.com/api'
40
+ end
41
+
42
+ # Make a new instance of a PushRadar API client with the specified API secret
43
+ @api_client = APIClient.new(api_secret)
44
+
45
+ end
46
+
47
+ # Targets the notification to clients currently using the given browser
48
+ def target_browser(browser)
49
+
50
+ # Add the browser to the list of target browsers
51
+ @targeting.target_browser browser
52
+
53
+ # Allow method chaining
54
+ self
55
+
56
+ end
57
+
58
+ # Targets the notification to clients currently using any of the given browsers
59
+ def target_browsers(*browsers)
60
+
61
+ # Target each browser
62
+ browsers.each {|x|
63
+ target_browser x
64
+ }
65
+
66
+ # Allow method chaining
67
+ self
68
+
69
+ end
70
+
71
+ # Targets the notification to clients currently located in the given country
72
+ def target_country(country_code)
73
+
74
+ # Add the country to the list of target countries
75
+ @targeting.target_country country_code
76
+
77
+ # Allow method chaining
78
+ self
79
+
80
+ end
81
+
82
+ # Targets the notification to clients currently located in any of the given countries
83
+ def target_countries(*country_codes)
84
+
85
+ # Target each country
86
+ country_codes.each {|x|
87
+ target_country x
88
+ }
89
+
90
+ # Allow method chaining
91
+ self
92
+
93
+ end
94
+
95
+ # Targets the notification to clients currently located in Asia
96
+ def target_asia
97
+
98
+ # Target the continent
99
+ @targeting.target_continent('AS')
100
+
101
+ # Allow method chaining
102
+ self
103
+
104
+ end
105
+
106
+ # Targets the notification to clients currently located in Africa
107
+ def target_africa
108
+
109
+ # Target the continent
110
+ @targeting.target_continent('AF')
111
+
112
+ # Allow method chaining
113
+ self
114
+
115
+ end
116
+
117
+ # Targets the notification to clients currently located in Antarctica
118
+ def target_antarctica
119
+
120
+ # Target the continent
121
+ @targeting.target_continent('AN')
122
+
123
+ # Allow method chaining
124
+ self
125
+
126
+ end
127
+
128
+ # Targets the notification to clients currently located in Europe
129
+ def target_europe
130
+
131
+ # Target the continent
132
+ @targeting.target_continent('EU')
133
+
134
+ # Allow method chaining
135
+ self
136
+
137
+ end
138
+
139
+ # Targets the notification to clients currently located in North America
140
+ def target_north_america
141
+
142
+ # Target the continent
143
+ @targeting.target_continent('NA')
144
+
145
+ # Allow method chaining
146
+ self
147
+
148
+ end
149
+
150
+ # Targets the notification to clients currently located in South America
151
+ def target_south_america
152
+
153
+ # Target the continent
154
+ @targeting.target_continent('SA')
155
+
156
+ # Allow method chaining
157
+ self
158
+
159
+ end
160
+
161
+ # Targets the notification to clients currently located in Oceania
162
+ def target_oceania
163
+
164
+ # Target the continent
165
+ @targeting.target_continent('OC')
166
+
167
+ # Allow method chaining
168
+ self
169
+
170
+ end
171
+
172
+ # Targets the notification to clients with the given IP address
173
+ def target_ip(ip_address)
174
+
175
+ # Add the IP address to the list of target IP addresses
176
+ @targeting.target_ip ip_address
177
+
178
+ # Allow method chaining
179
+ self
180
+
181
+ end
182
+
183
+ # Targets the notification to clients with any of the given IP addresses
184
+ def target_ips(*ip_addresses)
185
+
186
+ # Target each IP address
187
+ ip_addresses.each {|x|
188
+ target_ip x
189
+ }
190
+
191
+ # Allow method chaining
192
+ self
193
+
194
+ end
195
+
196
+ # Targets the notification to clients who have taken the given action
197
+ def target_action(action)
198
+
199
+ # Add the action to the list of target actions
200
+ @targeting.target_action action
201
+
202
+ # Allow method chaining
203
+ self
204
+
205
+ end
206
+
207
+ # Targets the notification to clients who have taken any of the given actions
208
+ def target_actions(*actions)
209
+
210
+ # Target each action
211
+ actions.each {|x|
212
+ target_action x
213
+ }
214
+
215
+ # Allow method chaining
216
+ self
217
+
218
+ end
219
+
220
+ # Targets the notification to clients who have not taken the given action
221
+ def target_not_action(action)
222
+
223
+ # Add the action to the list of target "not" actions
224
+ @targeting.target_not_action action
225
+
226
+ # Allow method chaining
227
+ self
228
+
229
+ end
230
+
231
+ # Targets the notification to clients who have not taken any of the given actions
232
+ def target_not_actions(*actions)
233
+
234
+ # Target each action
235
+ actions.each {|x|
236
+ target_not_action x
237
+ }
238
+
239
+ # Allow method chaining
240
+ self
241
+
242
+ end
243
+
244
+ # Targets the notification to a specific user (identified by their user ID)
245
+ def target_user(user_id)
246
+
247
+ # Target the user
248
+ @targeting.target_user user_id
249
+
250
+ # Allow method chaining
251
+ self
252
+
253
+ end
254
+
255
+ # Targets the notification to specific users (identified by their user IDs)
256
+ def target_users(*user_ids)
257
+
258
+ # Target the user IDs
259
+ user_ids.each {|x|
260
+ target_user x
261
+ }
262
+
263
+ # Allow method chaining
264
+ self
265
+
266
+ end
267
+
268
+ # Adds a data item to the list of data items
269
+ def add_data_item(key, value)
270
+
271
+ # Make sure the key is not empty
272
+ if key == ''
273
+ raise 'The key provided cannot be empty.'
274
+ end
275
+
276
+ # Add the data item
277
+ unless @data.keys.include?(key)
278
+ @data[key] = value
279
+ end
280
+
281
+ # Allow method chaining
282
+ self
283
+
284
+ end
285
+
286
+ # Adds multiple data items to the list of data items
287
+ def add_data_items(data = {})
288
+
289
+ # Add the data items
290
+ data.keys.each {|x|
291
+ add_data_item x, data[x]
292
+ }
293
+
294
+ # Allow method chaining
295
+ self
296
+
297
+ end
298
+
299
+ # Broadcasts data on the channel specified
300
+ def broadcast(channel, data = {})
301
+
302
+ # If we are running unit tests, throw an exception
303
+ if @is_unit_test_mode
304
+ raise 'Unit testing of the broadcast() method is not supported.'
305
+ end
306
+
307
+ # Trim the channel name
308
+ channel.strip!
309
+
310
+ # Check whether data has been provided
311
+ if data.length == 0 && @data.length == 0
312
+ raise 'There is no data to broadcast.'
313
+ end
314
+
315
+ # Check whether the channel name contains spaces
316
+ if channel.include? ' '
317
+ raise "The channel name cannot contain spaces. By convention, channel names are alphanumerical and lowercase, with optional dashes (e.g. 'test-channel')."
318
+ end
319
+
320
+ # Use the stored data if the data parameter is empty
321
+ if data.length == 0
322
+ data = @data
323
+ else
324
+ data.keys.each {|x|
325
+ @data[x] = data[x]
326
+ }
327
+ data = @data
328
+ end
329
+
330
+ # Initialize the hash of data to send to the server
331
+ data_to_send = {
332
+ notification: {
333
+ channel: channel,
334
+ data: data,
335
+ userIDs: @targeting.instance_variable_get('@target_user_ids'),
336
+ actions: @targeting.instance_variable_get('@target_actions'),
337
+ notActions: @targeting.instance_variable_get('@target_not_actions'),
338
+ continents: @targeting.instance_variable_get('@target_continents'),
339
+ ipAddresses: @targeting.instance_variable_get('@target_countries'),
340
+ countries: @targeting.instance_variable_get('@target_ips'),
341
+ browsers: @targeting.instance_variable_get('@target_browsers'),
342
+ }.to_json
343
+ }
344
+
345
+ # Broadcast the notification
346
+ @api_client.post('/broadcast', data_to_send)
347
+
348
+ # Reset the targeting options
349
+ reset_targeting
350
+
351
+ end
352
+
353
+ def channel_auth(channel)
354
+
355
+ # Trim the channel name
356
+ channel.strip!
357
+
358
+ unless (channel.start_with? "private-") || (channel.start_with? "presence-")
359
+ raise "Channel authentication can only be used with private or presence channels."
360
+ end
361
+
362
+ # Generate the channel authentication token
363
+ channel_auth_token = "channel_auth_token_" + Digest::MD5.hexdigest(channel) + "." + (0...8).map { (65 + rand(26)).chr }.join
364
+
365
+ # Broadcast the notification
366
+ @api_client.post('/channel-auth', {
367
+ authToken: channel_auth_token
368
+ })
369
+
370
+ channel_auth_token
371
+
372
+ end
373
+
374
+ # Resets the targeting options
375
+ def reset_targeting
376
+ @targeting = Targeting.new
377
+ end
378
+
379
+ # Set which methods are private
380
+ private :reset_targeting
381
+
382
+ end
383
+
391
384
  end