urbanairship 3.0.2 → 3.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.
data/docs/devices.rst ADDED
@@ -0,0 +1,54 @@
1
+ Retrieving Device Information
2
+ =============================
3
+
4
+ Channel Listing
5
+ ---------------
6
+
7
+ Device lists are fetched by instantiating an iterator object
8
+ using :rb:class:`ChannelList`. For more information, see:
9
+ http://docs.urbanairship.com/api/ua.html#channels
10
+
11
+ .. code-block:: ruby
12
+
13
+ require 'urbanairship'
14
+ UA = Urbanairship
15
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
16
+ channel_list = UA::ChannelList.new(client: airship)
17
+
18
+ channel_list.each do |channel|
19
+ puts(channel)
20
+ end
21
+
22
+ Channel Lookup
23
+ --------------
24
+
25
+ Device metadata is fetched for a specific channel by using
26
+ :rb:class:`ChannelInfo` with the method ``lookup(uuid: 'uuid')``.
27
+
28
+ .. code-block:: ruby
29
+
30
+ require 'urbanairship'
31
+ UA = Urbanairship
32
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
33
+ channel_client = UA::ChannelInfo.new(client: airship)
34
+ channel_info = channel_client.lookup(uuid: 'uuid')
35
+ puts(channel_info)
36
+
37
+ Feedback
38
+ --------
39
+
40
+ Feedback returns a list of dictionaries of device tokens/APIDs that the
41
+ respective push provider has told us are uninstalled since the given
42
+ timestamp. For more information, see:
43
+ http://docs.urbanairship.com/api/ua.html#feedback
44
+
45
+ .. code-block:: ruby
46
+
47
+ require 'urbanairship'
48
+ require 'time'
49
+ UA = Urbanairship
50
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
51
+ since = (Time.now.utc - (60 * 60 * 24 * 3)).iso8601
52
+ feedback = UA::Feedback.new(client: airship)
53
+ tokens = feedback.device_token(since: since)
54
+ apids = feedback.apid(since: since)
data/docs/examples.rst ADDED
@@ -0,0 +1,118 @@
1
+ Examples
2
+ ========
3
+
4
+ Common setup:
5
+
6
+ .. code-block:: ruby
7
+
8
+ require 'urbanairship'
9
+ UA = Urbanairship
10
+ airship = UA::Client.new(key: 'app_key', secret: 'master_secret')
11
+
12
+
13
+ Simple broadcast to all devices
14
+ -------------------------------
15
+
16
+ .. code-block:: ruby
17
+
18
+ push = airship.create_push
19
+ push.audience = UA.all
20
+ push.notification = UA.notification(alert: "Hello, world!")
21
+ push.device_types = UA.all
22
+ push.send_push
23
+
24
+
25
+ Complex audience with platform specifics
26
+ ---------------------------------------------
27
+
28
+ .. code-block:: ruby
29
+
30
+ push = airship.create_push
31
+ push.audience = UA.and(
32
+ UA.tag("breakingnews"),
33
+ UA.or(
34
+ UA.tag("sports"),
35
+ UA.tag("worldnews")
36
+ )
37
+ )
38
+ push.notification = UA.notification(
39
+ ios: UA.ios(
40
+ alert: "Kim Jong-Un wins U.S. Open",
41
+ badge: "+1",
42
+ extra: {"articleid" => "123456"}
43
+ ),
44
+ android: UA.android(
45
+ alert: "Breaking Android News! Glorious Leader Kim Jong-Un wins U.S. Open!",
46
+ extra: {"articleid" => "http://m.example.com/123456"}
47
+ ),
48
+ amazon: UA.amazon(
49
+ alert: 'Breaking Amazon News!',
50
+ expires_after: 60,
51
+ extra: {'articleid' => '12345'},
52
+ summary: 'This is a short message summary',
53
+ )
54
+ )
55
+ push.device_types = UA.device_types(['ios', 'android', 'amazon'])
56
+ push.send_push
57
+
58
+
59
+ Single iOS push
60
+ ---------------
61
+
62
+ .. code-block:: ruby
63
+
64
+ push = airship.create_push
65
+ push.audience = UA.ios_channel('channel-id')
66
+ push.notification = UA.notification(
67
+ ios: UA.ios(alert="Kim Jong-Un is following you on Twitter")
68
+ )
69
+ push.device_types = UA.device_types(['ios'])
70
+ push.send_push
71
+
72
+
73
+ Single iOS Rich Push with notification
74
+ --------------------------------------
75
+
76
+ .. code-block:: ruby
77
+
78
+ push = airship.create_push
79
+ push.audience = UA.ios_channel('channel-id')
80
+ push.notification = UA.notification(
81
+ ios: UA.ios(alert="Kim Jong-Un is following you on Twitter")
82
+ )
83
+ push.device_types = UA.device_types(['ios'])
84
+ push.message = UA.message(title: "New follower", body: "<h1>OMG It's Kim Jong-Un</h1>")
85
+ push.send_push
86
+
87
+
88
+ Rich Push with extra and without notification
89
+ ---------------------------------------------
90
+
91
+ .. code-block:: ruby
92
+
93
+ push = airship.create_push
94
+ push.audience = UA.all
95
+ push.device_types = UA.all
96
+ push.message = UA.message(
97
+ title: "New follower",
98
+ body: "<h1>OMG It's Kim Jong-Un</h1>",
99
+ extra: {"articleid" => "http://m.example.com/123456"}
100
+ )
101
+ push.send_push
102
+
103
+
104
+ Scheduled iOS Push
105
+ ------------------
106
+
107
+ .. code-block:: ruby
108
+
109
+ sched = airship.create_scheduled_push
110
+ sched.schedule = UA.scheduled_time(Time.now.utc + 60)
111
+
112
+ sched.push = airship.create_push
113
+ sched.push.audience = UA.ios_channel('channel-id')
114
+ sched.push.notification = UA.notification(
115
+ ios: UA.ios(alert: "Kim Jong-Un is following you on Twitter"))
116
+ sched.push.device_types = UA.device_types(['ios'])
117
+
118
+ sched.send_push
@@ -0,0 +1,17 @@
1
+ Exceptions
2
+ ==========
3
+
4
+ AirshipFailure
5
+ --------------
6
+
7
+ Raised when there is an error response from the server that is not a 401 or 403 error.
8
+
9
+ Forbidden
10
+ ---------
11
+
12
+ Raised when there is a 403 error response from the server.
13
+
14
+ Unauthorized
15
+ ------------
16
+
17
+ Raised when there is a 401 error response from the server.
data/docs/index.rst ADDED
@@ -0,0 +1,83 @@
1
+ Urban Airship Ruby Library
2
+ ==========================
3
+
4
+ ``urbanairship`` is a Ruby library for using the `Urban Airship
5
+ <http://urbanairship.com/>`_ web service API for push notifications and
6
+ rich app pages.
7
+
8
+
9
+ Installation
10
+ ------------
11
+
12
+ If you have the ``bundler`` gem (if not you can get it with ``$ gem install bundler``) add this line to your application's Gemfile::
13
+
14
+ >>> gem 'urbanairship'
15
+
16
+ And then execute::
17
+
18
+ >>> $ bundle
19
+
20
+ OR install it yourself as::
21
+
22
+ >>> gem install urbanairship
23
+
24
+
25
+ Using the library
26
+ -----------------
27
+
28
+ The library is intended to be used with the small footprint of a single
29
+ import. To get started, import the package, and create an
30
+ :rb:class:`Airship` object representing a single UA application.
31
+
32
+ Note that channels are preferred over ``device_token`` and ``apid``. See:
33
+ `documentation on channels <channels>`_.
34
+
35
+ .. code-block:: ruby
36
+
37
+ require 'urbanairship'
38
+ UA = Urbanairship
39
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
40
+ p = airship.create_push
41
+ p.audience = UA.all
42
+ p.notification = UA.notification(alert: 'Hello')
43
+ p.device_types = UA.all
44
+ p.send_push
45
+
46
+ The library uses `unirest`_ for communication with the UA API.
47
+
48
+
49
+ Development
50
+ -----------
51
+
52
+ The library source code is `available on GitHub <github>`_.
53
+
54
+ Tests can be run with rspec_:
55
+
56
+ Contents:
57
+
58
+ .. toctree::
59
+ :maxdepth: 2
60
+
61
+ push.rst
62
+ segment.rst
63
+ devices.rst
64
+ channel_uninstall.rst
65
+ tags.rst
66
+ named_user.rst
67
+ reports.rst
68
+ exceptions.rst
69
+ examples.rst
70
+
71
+
72
+ Indices and tables
73
+ ==================
74
+
75
+ * :ref:`genindex`
76
+ * :ref:`modindex`
77
+ * :ref:`search`
78
+
79
+
80
+ .. _channels: http://docs.urbanairship.com/topic-guides/channels.html
81
+ .. _unirest: http://unirest.io/ruby.html
82
+ .. _github: https://github.com/urbanairship/ruby-library
83
+ .. _rspec: https://nose.readthedocs.org/en/latest/
@@ -0,0 +1,101 @@
1
+ Named User
2
+ ==========
3
+
4
+ Named User Listing
5
+ ------------------
6
+
7
+ Named User lists are fetched by instantiating an iterator object
8
+ using :rb:class:`NamedUserList`.
9
+ For more information, see `the API documentation
10
+ <http://docs.urbanairship.com/api/ua.html#listing>`__
11
+
12
+ .. code-block:: ruby
13
+
14
+ require 'urbanairship'
15
+ UA = Urbanairship
16
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
17
+ named_user_list = UA::NamedUserList.new(client: airship)
18
+
19
+ named_user_list.each do |named_user|
20
+ puts(named_user)
21
+ end
22
+
23
+ Association
24
+ -----------
25
+
26
+ Associate a channel with a named user ID. For more information, see
27
+ `the API documentation
28
+ <http://docs.urbanairship.com/api/ua.html#association>`__
29
+
30
+ .. code-block:: ruby
31
+
32
+ require 'urbanairship'
33
+ UA = Urbanairship
34
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
35
+ named_user = UA::NamedUser.new(client: airship)
36
+ named_user.named_user_id = 'named_user'
37
+ named_user.associate(channel_id: 'channel_id', device_type: 'ios')
38
+
39
+ .. note::
40
+
41
+ You may only associate up to 20 channels to a Named User.
42
+
43
+ Disassociation
44
+ --------------
45
+
46
+ Remove a channel from the list of associated channels for a named user.
47
+ For more information, see `the API documentation
48
+ <http://docs.urbanairship.com/api/ua.html#disassociation>`__
49
+
50
+ .. code-block:: ruby
51
+
52
+ require 'urbanairship'
53
+ UA = Urbanairship
54
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
55
+ named_user = UA::NamedUser.new(client: airship)
56
+ named_user.disassociate(channel_id: 'channel_id', device_type: 'ios')
57
+
58
+ .. note::
59
+
60
+ ``named_user_id`` does not have to be set on the named_user object for this
61
+ method call since ``channel_id`` can only be associated with one named user.
62
+
63
+ Lookup
64
+ ------
65
+
66
+ Look up a single named user.
67
+ For more information, see `the API documentation
68
+ <http://docs.urbanairship.com/api/ua.html#lookup>`__
69
+
70
+ .. code-block:: ruby
71
+
72
+ require 'urbanairship'
73
+ UA = Urbanairship
74
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
75
+ named_user = UA::NamedUser.new(client: airship)
76
+ named_user.named_user_id = 'named_user'
77
+ user = named_user.lookup
78
+
79
+ Tags
80
+ ----
81
+
82
+ Add, remove, or set tags on a named user. For more information,
83
+ see `the API documentation
84
+ <http://docs.urbanairship.com/api/ua.html#tags-named-users>`__
85
+
86
+ .. code-block:: ruby
87
+
88
+ require 'urbanairship'
89
+ UA = Urbanairship
90
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
91
+ named_user_tags = UA::NamedUserTags.new(client: airship)
92
+ named_user_ids = ['named_user_id1', 'named_user_id2', 'named_user_id3']
93
+ named_user_tags.set_audience(user_ids: named_user_ids)
94
+ named_user_tags.add(group_name: 'group_name1', tags: ['tag1', 'tag2', 'tag3'])
95
+ named_user_tags.remove(group_name: 'group_name2', tags: 'tag4')
96
+ named_user_tags.send_request
97
+
98
+ .. note::
99
+
100
+ A single request may contain an add or remove field, both, or a single set
101
+ field.
data/docs/push.rst ADDED
@@ -0,0 +1,416 @@
1
+ Defining and Sending Push Notifications
2
+ =======================================
3
+
4
+ The Urban Airship Ruby Library strives to match the standard Urban
5
+ Airship JSON format for specifying push notifications. When creating a
6
+ push notification, you:
7
+
8
+ #. Select the audience
9
+ #. Define the notification payload
10
+ #. Specify device types.
11
+ #. Deliver the notification.
12
+
13
+ This example performs a broadcast with the same alert to all recipients
14
+ and device types:
15
+
16
+ .. code-block:: ruby
17
+
18
+ require 'urbanairship'
19
+
20
+ UA = Urbanairship
21
+ airship = UA::Client.new(key:'application_key', secret:'master_secret')
22
+ push = airship.create_push
23
+ push.audience = UA.all
24
+ push.notification = UA.notification(alert: 'Hello')
25
+ push.device_types = UA.all
26
+ push.send_push
27
+
28
+
29
+ Audience Selectors
30
+ ------------------
31
+
32
+ An audience should specify one or more devices. An audience can be a
33
+ device, such as a ``channel``, ``device_token`` or ``apid``; a tag,
34
+ alias, or segment; a location; or a combination. Audience selectors are
35
+ combined with ``and``, ``or``, and ``not``.
36
+
37
+
38
+ Select all to do a broadcast.
39
+
40
+ .. code-block:: ruby
41
+
42
+ push.audience = UA.all
43
+
44
+ Select a single iOS Channel:
45
+
46
+ .. code-block:: ruby
47
+
48
+ push.audience = UA.ios_channel(uuid)
49
+
50
+ Select a single Android Channel:
51
+
52
+ .. code-block:: ruby
53
+
54
+ push.audience = UA.android_channel(uuid)
55
+
56
+ Select a single Amazon Channel:
57
+
58
+ .. code-block:: ruby
59
+
60
+ push.audience = UA.amazon_channel(uuid)
61
+
62
+ Select a single iOS device token:
63
+
64
+ .. code-block:: ruby
65
+
66
+ push.audience = UA.device_token(token)
67
+
68
+ Select a single BlackBerry PIN:
69
+
70
+ .. code-block:: ruby
71
+
72
+ push.audience = UA.device_pin(pin)
73
+
74
+ Select a single Android APID:
75
+
76
+ .. code-block:: ruby
77
+
78
+ push.audience = UA.apid(uuid)
79
+
80
+ Select a single Windows 8 APID:
81
+
82
+ .. code-block:: ruby
83
+
84
+ push.audience = UA.wns(uuid)
85
+
86
+ Select a single Windows Phone 8 APID:
87
+
88
+ .. code-block:: ruby
89
+
90
+ push.audience = UA.mpns(uuid)
91
+
92
+ Select a single tag:
93
+
94
+ .. code-block:: ruby
95
+
96
+ push.audience = UA.tag(tag)
97
+
98
+ Select a single alias:
99
+
100
+ .. code-block:: ruby
101
+
102
+ push.audience = UA.alias(alias)
103
+
104
+ Select a single segment:
105
+
106
+ .. code-block:: ruby
107
+
108
+ push.audience = UA.segment(segment)
109
+
110
+ Select devices that match at least one of the given selectors:
111
+
112
+ .. code-block:: ruby
113
+
114
+ push.audience = UA.or(UA.tag('sports'), UA.tag('business'))
115
+
116
+ Select devices that match all of the given selectors:
117
+
118
+ .. code-block:: ruby
119
+
120
+ push.audience = UA.and(UA.tag('sports'), UA.tag('business'))
121
+
122
+ Select devices that do not match the given selectors:
123
+
124
+ .. code-block:: ruby
125
+
126
+ push.audience = UA.not(UA.and(UA.tag('sports'), UA.tag('business')))
127
+
128
+ Select a location expression. Location selectors are made up of either an id or
129
+ an alias and a date period specifier. Use a date specification function to
130
+ generate the time period specifier. Location aliases can be found here:
131
+ http://docs.urbanairship.com/reference/location_boundary_catalog.html
132
+
133
+ ID location example:
134
+
135
+ .. code-block:: ruby
136
+
137
+ push.audience = UA.location(
138
+ id: 'location_id',
139
+ date: UA.recent_date(days: 4)
140
+ )
141
+
142
+ Alias location example:
143
+
144
+ .. code-block:: ruby
145
+
146
+ push.audience = UA.location(
147
+ us_zip: 12345,
148
+ date: UA.recent_date(days: 4)
149
+ )
150
+
151
+ Select a recent date range for a location selector.
152
+ Valid selectors are: hours ,days, weeks, months, years
153
+
154
+ .. code-block:: ruby
155
+
156
+ recent_date(months: 6)
157
+ recent_date(weeks: 3)
158
+
159
+ Select an absolute date range for a location selector. Parameters are resolution,
160
+ start, and the_end. Resolutions is one of :hours, :days, :weeks, :months, or :years.
161
+ Start and the_end are UTC times in ISO 8601 format.
162
+
163
+ .. code-block:: ruby
164
+
165
+ absolute_date(
166
+ resolution: months,
167
+ start: '2013-01', the_end: '2013-06'
168
+ )
169
+
170
+ absolute_date(
171
+ resolution: :hours,
172
+ start: '2012-01-01 11:00',
173
+ the_end: '2012-01-01 12:00')
174
+ )
175
+
176
+ Notification Payload
177
+ --------------------
178
+
179
+ The notification payload determines what message and data is sent to a
180
+ device. At its simplest, it consists of a single string-valued
181
+ attribute, "alert", which sends a push notification consisting of a
182
+ single piece of text:
183
+
184
+ .. code-block:: ruby
185
+
186
+ push.notification = UA.notification(alert="Hello, world!")
187
+
188
+ You can override the payload with platform-specific values as well.
189
+
190
+ .. code-block:: ruby
191
+
192
+ push.notification = UA.ios(
193
+ alert: 'hello world',
194
+ badge: 123,
195
+ sound: 'sound file',
196
+ extra: { 'key' => 'value', 'key2' => 'value2' }
197
+ expiry: '2012-01-01 12:45',
198
+ category: 'category_name',
199
+ interactive: UA.interactive(
200
+ type: 'ua_share',
201
+ button_actions: {
202
+ share: { share: 'Sharing is caring!' }
203
+ }
204
+ ),
205
+ content_available: true
206
+ )
207
+
208
+ push.notification = UA.amazon(
209
+ alert: 'hello world',
210
+ consolidation_key: 'key',
211
+ expires_after: '2012-01-01 12:45',
212
+ extra: { 'key' => 'value', 'key2' => 'value2' },
213
+ title: 'title',
214
+ summary: 'summary',
215
+ interactive: UA.interactive(
216
+ type: 'ua_share',
217
+ button_actions: {
218
+ share: { share: 'Sharing is caring!' }
219
+ }
220
+ )
221
+ )
222
+
223
+ push.notification = UA.android(
224
+ alert: 'hello world',
225
+ collapse_key: 'key',
226
+ time_to_live: 123,
227
+ extra: { 'key' => 'value', 'key2' => 'value2' },
228
+ delay_while_idle: false,
229
+ interactive: UA.interactive(
230
+ type: 'ua_share',
231
+ button_actions: {
232
+ share: { share: 'Sharing is caring!' }
233
+ }
234
+ )
235
+ )
236
+
237
+ push.notification = UA.blackberry(
238
+ alert: 'hello world',
239
+ body: 'body',
240
+ content_type: 'text/plain'
241
+ )
242
+
243
+ push.notification = UA.wns_payload(
244
+ alert: 'hello world',
245
+ tile: nil,
246
+ toast: nil,
247
+ badge: nil
248
+ )
249
+
250
+ push.notification = UA.mpns_payload(
251
+ alert: 'hello world',
252
+ tile: nil,
253
+ toast: nil,
254
+ badge: nil
255
+ )
256
+
257
+ .. note::
258
+ The input for wns_payload must include exactly one of
259
+ alert, toast, tile, or badge.
260
+
261
+ The input for mpns_payload must include exactly one of
262
+ alert, toast, or tile.
263
+
264
+ Actions
265
+ -------
266
+
267
+ Urban Airship Actions provides a convenient way to automatically
268
+ perform tasks by name in response to push notifications,
269
+ Rich App Page interactions and JavaScript. More information at
270
+ http://docs.urbanairship.com/api/ua.html#actions, example:
271
+
272
+ .. code-block:: ruby
273
+
274
+ push.notification = UA.notification(
275
+ alert: 'Hello world',
276
+ actions: UA.actions(
277
+ add_tag: 'new_tag',
278
+ remove_old: 'old_tag',
279
+ share: 'Check out Urban Airship!',
280
+ open_: {
281
+ type: 'url',
282
+ content: 'http://www.urbanairship.com'
283
+ },
284
+ app_defined: {
285
+ some_app_defined_action: 'some_values'
286
+ },
287
+ ))
288
+
289
+
290
+ Interactive Notifications
291
+ -------------------------
292
+
293
+ The interactive notification payload determines the ways you can interact
294
+ with a notification. It contains two attributes: "type" (mandatory) and
295
+ "button_actions" (optional). More information at
296
+ http://docs.urbanairship.com/api/ua.html#interactive-notifications
297
+ Example:
298
+
299
+ .. code-block:: ruby
300
+
301
+ push.notification = UA.notification(
302
+ alert="Hello, world!",
303
+ interactive=UA.interactive(
304
+ type: "ua_share",
305
+ button_actions: {
306
+ share: {share: "Sharing is caring!"}
307
+ }
308
+ )
309
+ )
310
+
311
+ Button actions can also be mapped to *actions* objects as shown below:
312
+
313
+ .. code-block:: ruby
314
+
315
+ shared = ua.actions(share="Sharing is caring!")
316
+ push.notification = ua.notification(
317
+ alert="Hello, world!",
318
+ interactive=ua.interactive(
319
+ type = "ua_share",
320
+ button_actions = {
321
+ "share" : shared
322
+ }
323
+ )
324
+ )
325
+
326
+
327
+ Device Types
328
+ ------------
329
+
330
+ In addition to specifying the audience, you must specify the device
331
+ types you wish to target with a list of strings:
332
+
333
+ .. code-block:: ruby
334
+
335
+ push.device_types = UA.device_types(['ios', 'blackberry'])
336
+
337
+ or with the ``all`` shortcut.
338
+
339
+ .. code-block:: ruby
340
+
341
+ push.device_types = UA.all
342
+
343
+
344
+ Delivery
345
+ --------
346
+
347
+ Once you have set the ``audience``, ``notification``, and ``device_types``
348
+ attributes, the notification is ready for delivery.
349
+
350
+ .. code-block:: ruby
351
+
352
+ push.send_push
353
+
354
+ If the delivery is unsuccessful, an :rb:class:`AirshipFailure` exception
355
+ will be raised.
356
+
357
+
358
+ Scheduled Delivery
359
+ ------------------
360
+
361
+ Scheduled notifications build upon the Push object, and have two other
362
+ components: the scheduled time(s) and an optional name.
363
+
364
+ This example schedules the above notification for delivery in one
365
+ minute.
366
+
367
+ .. code-block:: ruby
368
+
369
+ schedule = airship.create_scheduled_push
370
+ schedule.push = push
371
+ schedule.name = "optional name for later reference"
372
+ schedule.schedule = UA.scheduled_time(Time.now.utc + 60)
373
+ response = schedule.send_push
374
+ print ("Created schedule. url: " + response.schedule_url)
375
+
376
+ If the schedule is unsuccessful, an :rb:class:`AirshipFailure`
377
+ exception will be raised.
378
+
379
+
380
+ Scheduled Delivery in Device Local Time
381
+ ---------------------------------------
382
+
383
+ Scheduled notifications build upon the Push object, and have two other
384
+ components: the scheduled time(s) and an optional name.
385
+
386
+ This example schedules the above notification for delivery in device
387
+ local time.
388
+
389
+ .. code-block:: ruby
390
+
391
+ schedule = airship.create_scheduled_push
392
+ schedule.push = push
393
+ schedule.name = "optional name for later reference"
394
+ schedule.schedule = UA.local_scheduled_time(Time.now + 60)
395
+ response = schedule.send_push
396
+ print ("Created schedule. url: " + response.schedule_url)
397
+
398
+ If the schedule is unsuccessful, an :rb:class:`AirshipFailure` exception
399
+ will be raised.
400
+
401
+
402
+ Updating or Canceling a Schedule
403
+ --------------------------------
404
+
405
+ If you have the ``schedule_url`` returned from creating a scheduled
406
+ notification, you can update or cancel it before it's sent.
407
+
408
+ .. code-block:: ruby
409
+
410
+ schedule = UA.ScheduledPush.from_url(airship, url)
411
+ # change scheduled time to tomorrow
412
+ schedule.schedule = UA.scheduled_time(Time.now.utc + (60 * 60 * 24))
413
+ schedule.update
414
+
415
+ # Cancel
416
+ schedule.cancel