notify_user 0.0.28 → 0.0.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -0
- data/app/mailers/notify_user/notification_mailer.rb +6 -2
- data/app/models/notify_user/apn_connection.rb +41 -0
- data/app/models/notify_user/apns.rb +18 -27
- data/app/models/notify_user/base_notification.rb +42 -64
- data/app/models/notify_user/houston.rb +98 -0
- data/app/models/notify_user/urban_airship.rb +33 -0
- data/lib/generators/notify_user/install/templates/initializer.rb +13 -0
- data/lib/notify_user.rb +16 -0
- data/lib/notify_user/channels/apns/apns_channel.rb +15 -12
- data/lib/notify_user/version.rb +1 -1
- data/spec/dummy/rails-3.2.17/Gemfile +38 -0
- data/spec/dummy/rails-3.2.17/README.rdoc +261 -0
- data/spec/dummy/rails-3.2.17/Rakefile +7 -0
- data/spec/dummy/rails-3.2.17/app/assets/images/rails.png +0 -0
- data/spec/dummy/rails-3.2.17/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/rails-3.2.17/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/rails-3.2.17/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/rails-3.2.17/app/controllers/notify_user/notifications_controller.rb +9 -0
- data/spec/dummy/rails-3.2.17/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/rails-3.2.17/app/models/user.rb +3 -0
- data/spec/dummy/rails-3.2.17/app/notifications/new_post_notification.rb +11 -0
- data/spec/dummy/rails-3.2.17/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/rails-3.2.17/app/views/notify_user/layouts/action_mailer.html.erb +39 -0
- data/spec/dummy/rails-3.2.17/app/views/notify_user/new_post_notification/action_mailer/notification.html.erb +1 -0
- data/spec/dummy/rails-3.2.17/app/views/notify_user/new_post_notification/mobile_sdk/notification.html.erb +1 -0
- data/spec/dummy/rails-3.2.17/config.ru +4 -0
- data/spec/dummy/rails-3.2.17/config/application.rb +62 -0
- data/spec/dummy/rails-3.2.17/config/boot.rb +6 -0
- data/spec/dummy/rails-3.2.17/config/database.yml +24 -0
- data/spec/dummy/rails-3.2.17/config/environment.rb +5 -0
- data/spec/dummy/rails-3.2.17/config/environments/development.rb +37 -0
- data/spec/dummy/rails-3.2.17/config/environments/production.rb +67 -0
- data/spec/dummy/rails-3.2.17/config/environments/test.rb +37 -0
- data/spec/dummy/rails-3.2.17/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/rails-3.2.17/config/initializers/inflections.rb +15 -0
- data/spec/dummy/rails-3.2.17/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/rails-3.2.17/config/initializers/notify_user.rb +14 -0
- data/spec/dummy/rails-3.2.17/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/rails-3.2.17/config/initializers/session_store.rb +8 -0
- data/spec/dummy/rails-3.2.17/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/rails-3.2.17/config/locales/en.yml +5 -0
- data/spec/dummy/rails-3.2.17/config/routes.rb +58 -0
- data/spec/dummy/rails-3.2.17/db/migrate/20150106040852_create_users.rb +9 -0
- data/spec/dummy/rails-3.2.17/db/migrate/20150106040854857857604000_create_notify_user_notifications.rb +13 -0
- data/spec/dummy/rails-3.2.17/db/migrate/20150106040854860860323000_create_notify_user_unsubscribes.rb +10 -0
- data/spec/dummy/rails-3.2.17/db/migrate/20150106040854862862248000_create_notify_user_user_hashes.rb +12 -0
- data/spec/dummy/rails-3.2.17/db/schema.rb +50 -0
- data/spec/dummy/rails-3.2.17/db/seeds.rb +7 -0
- data/spec/dummy/rails-3.2.17/doc/README_FOR_APP +2 -0
- data/spec/dummy/rails-3.2.17/log/test.log +933 -0
- data/spec/dummy/rails-3.2.17/public/404.html +26 -0
- data/spec/dummy/rails-3.2.17/public/422.html +26 -0
- data/spec/dummy/rails-3.2.17/public/500.html +25 -0
- data/spec/dummy/rails-3.2.17/public/favicon.ico +0 -0
- data/spec/dummy/rails-3.2.17/public/index.html +241 -0
- data/spec/dummy/rails-3.2.17/public/robots.txt +5 -0
- data/spec/dummy/rails-3.2.17/script/rails +6 -0
- data/spec/dummy/rails-3.2.17/test/fixtures/users.yml +7 -0
- data/spec/dummy/rails-3.2.17/test/performance/browsing_test.rb +12 -0
- data/spec/dummy/rails-3.2.17/test/test_helper.rb +13 -0
- data/spec/dummy/rails-3.2.17/test/unit/user_test.rb +7 -0
- data/spec/dummy/rails-4.0.4/log/test.log +38719 -0
- data/spec/models/notify_user/houston_spec.rb +33 -0
- data/spec/models/notify_user/notification_spec.rb +62 -96
- metadata +151 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a577a48ef571d2031ff5df80e68446265b7c4f1
|
4
|
+
data.tar.gz: 007bc887cd900949443af637df989638d61b46ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e8be63dd0b8d2fa14de7ccbfbe7a927b521b3d086ff9ef344116b48170c6e68e37d9bfae0fbe95d01061d9f698c5e88fb06f6d1543ce9e2a0b2ecefb8777058
|
7
|
+
data.tar.gz: 0e98eb7957dd725d95d8750429cd06bf38f01a4d558adcdbcab02265768124b8cfe93028b581de64e551e2c13c9dedde4772f1f19bce19c0e04f8ec662fbfd12
|
data/README.md
CHANGED
@@ -22,6 +22,15 @@ Then send:
|
|
22
22
|
```
|
23
23
|
NotifyUser.send_notification('new_my_property').to(user).with("listing_address" => "123 Main St").notify
|
24
24
|
```
|
25
|
+
Dynamic email titles use %{tags} that correspond to your params hash (Will throw an exception if key is missing)
|
26
|
+
```
|
27
|
+
channel :action_mailer,
|
28
|
+
subject: "%{name} sent you a message",
|
29
|
+
aggregate: {
|
30
|
+
subject: "%{name} sent you %{count} messages"
|
31
|
+
}
|
32
|
+
```
|
33
|
+
|
25
34
|
|
26
35
|
To enable APNS add this line to your app/notification/notification_type.rb
|
27
36
|
```
|
@@ -8,7 +8,7 @@ module NotifyUser
|
|
8
8
|
@notification = notification
|
9
9
|
|
10
10
|
mail to: notification.target.email,
|
11
|
-
subject: options[:subject],
|
11
|
+
subject: subject(notification, options[:subject]),
|
12
12
|
template_name: "notification",
|
13
13
|
template_path: "notify_user/action_mailer",
|
14
14
|
from: NotifyUser.mailer_sender
|
@@ -21,10 +21,14 @@ module NotifyUser
|
|
21
21
|
mail to: @notifications.first.target.email,
|
22
22
|
template_name: "aggregate_notification",
|
23
23
|
template_path: ["notify_user/#{notifications.first.class.name.underscore}/action_mailer", "notify_user/action_mailer"],
|
24
|
-
subject: options[:aggregate][:subject],
|
24
|
+
subject: subject(@notification, options[:aggregate][:subject]),
|
25
25
|
from: NotifyUser.mailer_sender
|
26
26
|
end
|
27
27
|
|
28
|
+
def subject(notification, subject)
|
29
|
+
subject % notification.params.symbolize_keys
|
30
|
+
end
|
31
|
+
|
28
32
|
protected
|
29
33
|
end
|
30
34
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module NotifyUser
|
2
|
+
class APNConnection
|
3
|
+
|
4
|
+
attr_accessor :connection
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
setup
|
8
|
+
end
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@uri, @certificate = if Rails.env.production? || apn_environment == :production
|
12
|
+
[
|
13
|
+
::Houston::APPLE_PRODUCTION_GATEWAY_URI,
|
14
|
+
File.read("#{Rails.root}/config/keys/production_push.pem")
|
15
|
+
]
|
16
|
+
else
|
17
|
+
[
|
18
|
+
::Houston::APPLE_DEVELOPMENT_GATEWAY_URI,
|
19
|
+
File.read("#{Rails.root}/config/keys/development_push.pem")
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
@connection = ::Houston::Connection.new(@uri, @certificate, nil)
|
24
|
+
@connection.open
|
25
|
+
end
|
26
|
+
|
27
|
+
def write(data)
|
28
|
+
raise "Connection is closed" unless @connection.open?
|
29
|
+
@connection.write(data)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def apn_environment
|
35
|
+
return nil unless ENV['APN_ENVIRONMENT']
|
36
|
+
|
37
|
+
ENV['APN_ENVIRONMENT'].downcase.to_sym
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -1,37 +1,28 @@
|
|
1
1
|
module NotifyUser
|
2
2
|
class Apns
|
3
|
-
SYMBOL_NAMES_SIZE = 10
|
3
|
+
SYMBOL_NAMES_SIZE = 10
|
4
4
|
PAYLOAD_LIMIT = 255
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
def initialize(notification, options)
|
7
|
+
@notification = notification
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
# Sends push notification:
|
12
|
+
def push
|
13
|
+
raise "Base APNS class should not be used."
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
13
17
|
|
14
|
-
|
18
|
+
# Calculates the bytes already used:
|
19
|
+
def used_space
|
20
|
+
used_space = SYMBOL_NAMES_SIZE + @notification.id.size + @notification.created_at.to_time.to_i.size +
|
21
|
+
@notification.type.size
|
15
22
|
|
16
|
-
|
17
|
-
:alias => notification.target_id,
|
18
|
-
:aps => {alert: notification.mobile_message(space_allowance), badge: notification.count_for_target},
|
19
|
-
:n_data => {
|
20
|
-
'#' => notification.id,
|
21
|
-
t: notification.created_at.to_time.to_i,
|
22
|
-
'?' => notification.type
|
23
|
-
}
|
24
|
-
}
|
25
|
-
payload[:n_data]['!'] = notification.params[:action_id] if notification.params[:action_id]
|
23
|
+
used_space += @notification.params[:action_id].size if @notification.params[:action_id]
|
26
24
|
|
27
|
-
|
28
|
-
if response.success?
|
29
|
-
Rails.logger.info "Push notification sent successfully."
|
30
|
-
return true
|
31
|
-
else
|
32
|
-
Rails.logger.info "Push notification failed."
|
33
|
-
return false
|
34
|
-
end
|
25
|
+
used_space
|
35
26
|
end
|
36
27
|
end
|
37
28
|
end
|
@@ -7,6 +7,9 @@ module NotifyUser
|
|
7
7
|
include ActionView::Helpers::TextHelper
|
8
8
|
include AASM
|
9
9
|
|
10
|
+
after_commit :deliver!, on: :create
|
11
|
+
after_commit :deliver, on: :create
|
12
|
+
|
10
13
|
if ActiveRecord::VERSION::MAJOR < 4
|
11
14
|
attr_accessible :params, :target, :type, :state
|
12
15
|
end
|
@@ -32,6 +35,9 @@ module NotifyUser
|
|
32
35
|
# Created, not sent yet. Possibly waiting for aggregation.
|
33
36
|
state :pending, initial: true
|
34
37
|
|
38
|
+
# Delivers without aggregation
|
39
|
+
state :pending_no_aggregation
|
40
|
+
|
35
41
|
# Email/SMS/APNS has been sent.
|
36
42
|
state :sent
|
37
43
|
|
@@ -40,7 +46,11 @@ module NotifyUser
|
|
40
46
|
|
41
47
|
# Record that we have sent message(s) to the user about this notification.
|
42
48
|
event :mark_as_sent do
|
43
|
-
transitions from: :pending, to: :sent
|
49
|
+
transitions from: [:pending, :pending_no_aggregation], to: :sent
|
50
|
+
end
|
51
|
+
|
52
|
+
event :dont_aggregate do
|
53
|
+
transitions from: :pending, to: :pending_no_aggregation
|
44
54
|
end
|
45
55
|
|
46
56
|
# Record that the user has seen this notification, usually on a page or in the app.
|
@@ -59,6 +69,7 @@ module NotifyUser
|
|
59
69
|
end
|
60
70
|
end
|
61
71
|
|
72
|
+
# returns the global unread notification count for a user
|
62
73
|
def count_for_target
|
63
74
|
NotifyUser::BaseNotification.for_target(target).where('state IN (?)', ["sent", "pending"]).count
|
64
75
|
end
|
@@ -92,30 +103,14 @@ module NotifyUser
|
|
92
103
|
end
|
93
104
|
|
94
105
|
def notify!
|
95
|
-
save
|
96
|
-
|
97
106
|
# Bang version of 'notify' ignores aggregation
|
98
|
-
|
107
|
+
dont_aggregate!
|
99
108
|
end
|
100
109
|
|
101
110
|
# Send any Emails/SMS/APNS
|
102
111
|
def notify
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
#if aggregation is false bypass aggregation completely
|
107
|
-
self.channels.each do |channel_name, options|
|
108
|
-
if(options[:aggregate_per] == false)
|
109
|
-
self.class.delay.deliver_notification_channel(self.id, channel_name)
|
110
|
-
else
|
111
|
-
if not aggregation_pending?
|
112
|
-
self.class.delay_for(options[:aggregate_per] || self.aggregate_per).notify_aggregated_channel(self.id, channel_name)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
|
112
|
+
# Sends with aggregation if enabled
|
113
|
+
save
|
119
114
|
end
|
120
115
|
|
121
116
|
def generate_unsubscribe_hash
|
@@ -172,32 +167,37 @@ module NotifyUser
|
|
172
167
|
return (self.class.pending_aggregation_with(self).where('id != ?', id).count > 0)
|
173
168
|
end
|
174
169
|
|
175
|
-
#
|
176
|
-
|
177
|
-
|
178
|
-
|
170
|
+
# Aggregates appropriately
|
171
|
+
def deliver
|
172
|
+
if pending? and not user_has_unsubscribed?
|
173
|
+
self.mark_as_sent!
|
179
174
|
|
180
|
-
|
181
|
-
|
182
|
-
|
175
|
+
# if aggregation is false bypass aggregation completely
|
176
|
+
self.channels.each do |channel_name, options|
|
177
|
+
if(options[:aggregate_per] == false)
|
178
|
+
self.class.delay.deliver_notification_channel(self.id, channel_name)
|
179
|
+
else
|
180
|
+
# only notifies channels if no pending aggreagte notifications
|
181
|
+
if not aggregation_pending?
|
182
|
+
self.class.delay_for(options[:aggregate_per] || self.aggregate_per).notify_aggregated_channel(self.id, channel_name)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
183
188
|
|
189
|
+
# Sends immediately and without aggregation
|
184
190
|
def deliver!
|
185
|
-
|
186
|
-
self.mark_as_sent
|
187
|
-
self.save
|
191
|
+
if pending_no_aggregation? and not user_has_unsubscribed?
|
192
|
+
self.mark_as_sent!
|
188
193
|
self.class.deliver_channels(self.id)
|
189
194
|
end
|
190
195
|
end
|
191
196
|
|
192
197
|
# Deliver a single notification across each channel.
|
193
198
|
def self.deliver_channels(notification_id)
|
194
|
-
notification = self.where(id: notification_id).first
|
195
|
-
return unless notification
|
196
199
|
self.channels.each do |channel_name, options|
|
197
|
-
|
198
|
-
channel = (channel_name.to_s + "_channel").camelize.constantize
|
199
|
-
channel.deliver(notification, options)
|
200
|
-
end
|
200
|
+
self.deliver_notification_channel(notification_id, channel_name)
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
@@ -215,11 +215,11 @@ module NotifyUser
|
|
215
215
|
|
216
216
|
# Deliver a single notification to a specific channel.
|
217
217
|
def self.deliver_notification_channel(notification_id, channel_name)
|
218
|
-
notification = self.
|
219
|
-
return unless notification
|
220
|
-
channel_options = channels[channel_name.to_sym]
|
218
|
+
notification = self.find(notification_id) # Raise an exception if not found.
|
221
219
|
|
220
|
+
channel_options = channels[channel_name.to_sym]
|
222
221
|
channel = (channel_name.to_s + "_channel").camelize.constantize
|
222
|
+
|
223
223
|
unless self.unsubscribed_from_channel?(notification.target, channel_name)
|
224
224
|
channel.deliver(notification, channel_options)
|
225
225
|
end
|
@@ -236,7 +236,7 @@ module NotifyUser
|
|
236
236
|
end
|
237
237
|
end
|
238
238
|
|
239
|
-
#
|
239
|
+
# Prepares a single channel for aggregation
|
240
240
|
def self.notify_aggregated_channel(notification_id, channel_name)
|
241
241
|
notification = self.find(notification_id) # Raise an exception if not found.
|
242
242
|
|
@@ -247,7 +247,6 @@ module NotifyUser
|
|
247
247
|
notifications.map(&:save)
|
248
248
|
|
249
249
|
return if notifications.empty?
|
250
|
-
|
251
250
|
if notifications.length == 1
|
252
251
|
# Despite waiting for more to aggregate, we only got one in the end.
|
253
252
|
self.deliver_notification_channel(notifications.first.id, channel_name)
|
@@ -257,27 +256,8 @@ module NotifyUser
|
|
257
256
|
end
|
258
257
|
end
|
259
258
|
|
260
|
-
def self.notify_aggregated(notification_id)
|
261
|
-
notification = self.find(notification_id) # Raise an exception if not found.
|
262
|
-
|
263
|
-
# Find any pending notifications with the same type and target, which can all be sent in one message.
|
264
|
-
notifications = self.pending_aggregation_with(notification)
|
265
|
-
|
266
|
-
notifications.map(&:mark_as_sent)
|
267
|
-
notifications.map(&:save)
|
268
|
-
|
269
|
-
return if notifications.empty?
|
270
|
-
|
271
|
-
if notifications.length == 1
|
272
|
-
# Despite waiting for more to aggregate, we only got one in the end.
|
273
|
-
self.deliver_channels(notifications.first.id)
|
274
|
-
else
|
275
|
-
# We got several notifications while waiting, send them aggregated.
|
276
|
-
self.deliver_channels_aggregated(notifications)
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
259
|
private
|
260
|
+
|
281
261
|
def unsubscribed_validation
|
282
262
|
errors.add(:target, (" has unsubscribed from this type")) if user_has_unsubscribed?
|
283
263
|
end
|
@@ -291,9 +271,7 @@ module NotifyUser
|
|
291
271
|
|
292
272
|
def self.unsubscribed_from_channel?(user, type)
|
293
273
|
#return true if user has unsubscribed
|
294
|
-
return
|
295
|
-
|
296
|
-
return false
|
274
|
+
return !NotifyUser::Unsubscribe.has_unsubscribed_from(user, type).empty?
|
297
275
|
end
|
298
276
|
|
299
277
|
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require_relative 'apn_connection'
|
2
|
+
require 'houston'
|
3
|
+
|
4
|
+
module NotifyUser
|
5
|
+
class Houston < Apns
|
6
|
+
|
7
|
+
NO_ERROR = -42
|
8
|
+
INVALID_TOKEN_ERROR = 8
|
9
|
+
APN_POOL = ConnectionPool.new(
|
10
|
+
size: NotifyUser.connection_pool_size,
|
11
|
+
timeout: NotifyUser.connection_pool_timeout) do
|
12
|
+
APNConnection.new
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :push_options
|
16
|
+
|
17
|
+
def initialize(notification, options)
|
18
|
+
super(notification, options)
|
19
|
+
|
20
|
+
@push_options = setup_options
|
21
|
+
|
22
|
+
device_method = @options[:device_method] || :devices
|
23
|
+
begin
|
24
|
+
@devices = @notification.target.send(device_method)
|
25
|
+
rescue
|
26
|
+
Rails.logger.info "Notification target, #{@notification.target.class}, does not respond to the method, #{device_method}."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def push
|
31
|
+
send_notifications
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def setup_options
|
37
|
+
space_allowance = PAYLOAD_LIMIT - used_space
|
38
|
+
|
39
|
+
push_options = {
|
40
|
+
alert: @notification.mobile_message(space_allowance),
|
41
|
+
badge: @notification.count_for_target,
|
42
|
+
category: @notification.params[:category] || @notification.type,
|
43
|
+
custom_data: @notification.params,
|
44
|
+
sound: 'default'
|
45
|
+
}
|
46
|
+
|
47
|
+
if @options[:silent]
|
48
|
+
push_options.merge!({
|
49
|
+
sound: '',
|
50
|
+
content_available: true
|
51
|
+
})
|
52
|
+
end
|
53
|
+
|
54
|
+
push_options
|
55
|
+
end
|
56
|
+
|
57
|
+
def send_notifications
|
58
|
+
APN_POOL.with do |connection|
|
59
|
+
if !connection.connection.open?
|
60
|
+
connection = APNConnection.new
|
61
|
+
end
|
62
|
+
|
63
|
+
ssl = connection.connection.ssl
|
64
|
+
error_index = NO_ERROR
|
65
|
+
|
66
|
+
@devices.each_with_index do |device, index|
|
67
|
+
notification = ::Houston::Notification.new(@push_options.dup.merge({ token: device.token, id: index }))
|
68
|
+
connection.write(notification.message)
|
69
|
+
end
|
70
|
+
|
71
|
+
read_socket, write_socket = IO.select([ssl], [], [ssl], 1)
|
72
|
+
if (read_socket && read_socket[0])
|
73
|
+
if error = connection.connection.read(6)
|
74
|
+
command, status, error_index = error.unpack("ccN")
|
75
|
+
|
76
|
+
# Remove all the devices prior to the error (we assume they were successful), and close the current connection:
|
77
|
+
if error_index != NO_ERROR
|
78
|
+
device = @devices.at(error_index)
|
79
|
+
Rails.logger.info "Error: #{status} with id: #{error_index}. Token: #{device.token}."
|
80
|
+
|
81
|
+
# If we encounter the Invalid Token error from APNS, just remove the device:
|
82
|
+
if status == ERROR_INVALID_TOKEN
|
83
|
+
Rails.logger.info "Invalid token encountered, removing device. Token: #{device.token}."
|
84
|
+
device.destroy
|
85
|
+
end
|
86
|
+
|
87
|
+
@devices.slice!(0..error_index)
|
88
|
+
connection.connection.close
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Resend all notifications after the once that produced the error:
|
94
|
+
send_notifications if error_index != NO_ERROR
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module NotifyUser
|
2
|
+
class UrbanAirship < Apns
|
3
|
+
|
4
|
+
def push
|
5
|
+
space_allowance = PAYLOAD_LIMIT - used_space
|
6
|
+
|
7
|
+
payload = {
|
8
|
+
:alias => notification.target_id,
|
9
|
+
:aps => {
|
10
|
+
:alert => notification.mobile_message(space_allowance),
|
11
|
+
:badge => notification.count_for_target
|
12
|
+
},
|
13
|
+
:n_data => {
|
14
|
+
'#' => notification.id,
|
15
|
+
:t => notification.created_at.to_time.to_i,
|
16
|
+
'?' => notification.type
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
payload[:n_data]['!'] = notification.params[:action_id] if notification.params[:action_id]
|
21
|
+
|
22
|
+
response = Urbanairship.push(payload)
|
23
|
+
if response.success?
|
24
|
+
Rails.logger.info "Push notification sent successfully."
|
25
|
+
return true
|
26
|
+
else
|
27
|
+
Rails.logger.info "Push notification failed."
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|