rpush 2.4.0-java → 2.6.0-java
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/CHANGELOG.md +27 -1
- data/README.md +18 -8
- data/lib/generators/rpush_migration_generator.rb +1 -0
- data/lib/generators/templates/rpush.rb +8 -2
- data/lib/generators/templates/rpush_2_0_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_2_6_0_updates.rb +10 -0
- data/lib/rpush/cli.rb +63 -27
- data/lib/rpush/client/active_model.rb +3 -0
- data/lib/rpush/client/active_model/apns/notification.rb +1 -1
- data/lib/rpush/client/active_model/gcm/notification.rb +1 -0
- data/lib/rpush/client/active_model/wns/app.rb +23 -0
- data/lib/rpush/client/active_model/wns/notification.rb +28 -0
- data/lib/rpush/client/active_model/wpns/notification.rb +11 -6
- data/lib/rpush/client/active_record.rb +3 -0
- data/lib/rpush/client/active_record/notification.rb +1 -1
- data/lib/rpush/client/active_record/wns/app.rb +11 -0
- data/lib/rpush/client/active_record/wns/notification.rb +11 -0
- data/lib/rpush/client/mongoid.rb +3 -0
- data/lib/rpush/client/mongoid/apns/feedback.rb +3 -0
- data/lib/rpush/client/mongoid/notification.rb +7 -0
- data/lib/rpush/client/mongoid/wns/app.rb +14 -0
- data/lib/rpush/client/mongoid/wns/notification.rb +11 -0
- data/lib/rpush/client/redis.rb +3 -0
- data/lib/rpush/client/redis/notification.rb +1 -0
- data/lib/rpush/client/redis/wns/app.rb +14 -0
- data/lib/rpush/client/redis/wns/notification.rb +11 -0
- data/lib/rpush/configuration.rb +3 -7
- data/lib/rpush/daemon.rb +9 -0
- data/lib/rpush/daemon/apns/feedback_receiver.rb +5 -0
- data/lib/rpush/daemon/app_runner.rb +4 -5
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +47 -12
- data/lib/rpush/daemon/dispatcher_loop.rb +5 -0
- data/lib/rpush/daemon/feeder.rb +11 -0
- data/lib/rpush/daemon/gcm/delivery.rb +2 -2
- data/lib/rpush/daemon/interruptible_sleep.rb +8 -3
- data/lib/rpush/daemon/loggable.rb +4 -0
- data/lib/rpush/daemon/rpc.rb +9 -0
- data/lib/rpush/daemon/rpc/client.rb +27 -0
- data/lib/rpush/daemon/rpc/server.rb +82 -0
- data/lib/rpush/daemon/signal_handler.rb +7 -0
- data/lib/rpush/daemon/store/active_record.rb +17 -3
- data/lib/rpush/daemon/store/mongoid.rb +2 -2
- data/lib/rpush/daemon/store/redis.rb +2 -2
- data/lib/rpush/daemon/tcp_connection.rb +2 -2
- data/lib/rpush/daemon/wns.rb +9 -0
- data/lib/rpush/daemon/wns/delivery.rb +204 -0
- data/lib/rpush/embed.rb +15 -13
- data/lib/rpush/logger.rb +4 -0
- data/lib/rpush/plugin.rb +1 -1
- data/lib/rpush/push.rb +2 -11
- data/lib/rpush/reflection_collection.rb +15 -17
- data/lib/rpush/reflection_public_methods.rb +6 -4
- data/lib/rpush/version.rb +1 -1
- data/spec/functional/apns_spec.rb +1 -11
- data/spec/functional/cli_spec.rb +36 -0
- data/spec/functional_spec_helper.rb +11 -1
- data/spec/spec_helper.rb +4 -3
- data/spec/support/active_record_setup.rb +3 -2
- data/spec/unit/client/active_record/apns/notification_spec.rb +1 -1
- data/spec/unit/client/active_record/gcm/notification_spec.rb +5 -0
- data/spec/unit/configuration_spec.rb +0 -7
- data/spec/unit/daemon/adm/delivery_spec.rb +2 -2
- data/spec/unit/daemon/app_runner_spec.rb +2 -3
- data/spec/unit/daemon/gcm/delivery_spec.rb +1 -1
- data/spec/unit/daemon/tcp_connection_spec.rb +1 -1
- data/spec/unit/daemon/wns/delivery_spec.rb +171 -0
- data/spec/unit/daemon/wpns/delivery_spec.rb +1 -1
- data/spec/unit/daemon_spec.rb +2 -0
- data/spec/unit/embed_spec.rb +4 -11
- data/spec/unit/logger_spec.rb +2 -2
- data/spec/unit/push_spec.rb +0 -7
- data/spec/unit_spec_helper.rb +1 -1
- metadata +20 -2
@@ -0,0 +1,27 @@
|
|
1
|
+
module Rpush
|
2
|
+
module Daemon
|
3
|
+
module Rpc
|
4
|
+
class Client
|
5
|
+
def initialize(pid)
|
6
|
+
@socket = UNIXSocket.open(Rpc.socket_path(pid))
|
7
|
+
end
|
8
|
+
|
9
|
+
def status
|
10
|
+
call(:status)
|
11
|
+
end
|
12
|
+
|
13
|
+
def close
|
14
|
+
@socket.close
|
15
|
+
rescue StandardError # rubocop:disable Lint/HandleExceptions
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def call(cmd, args = {})
|
21
|
+
@socket.puts(JSON.dump([cmd, args]))
|
22
|
+
JSON.parse(@socket.gets)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
module Rpush
|
5
|
+
module Daemon
|
6
|
+
module Rpc
|
7
|
+
class Server
|
8
|
+
include Singleton
|
9
|
+
include Loggable
|
10
|
+
include Reflectable
|
11
|
+
|
12
|
+
def self.start
|
13
|
+
instance.start
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.stop
|
17
|
+
instance.stop
|
18
|
+
end
|
19
|
+
|
20
|
+
def start
|
21
|
+
@stop = false
|
22
|
+
|
23
|
+
@thread = Thread.new(UNIXServer.open(Rpc.socket_path)) do |server|
|
24
|
+
begin
|
25
|
+
loop do
|
26
|
+
socket = server.accept
|
27
|
+
break if @stop
|
28
|
+
read_loop(socket)
|
29
|
+
end
|
30
|
+
|
31
|
+
server.close
|
32
|
+
rescue StandardError => e
|
33
|
+
log_error(e)
|
34
|
+
ensure
|
35
|
+
File.unlink(Rpc.socket_path) if File.exist?(Rpc.socket_path)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def stop
|
41
|
+
@stop = true
|
42
|
+
UNIXSocket.new(Rpc.socket_path)
|
43
|
+
@thread.join if @thread
|
44
|
+
rescue StandardError => e
|
45
|
+
log_error(e)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def read_loop(socket)
|
51
|
+
loop do
|
52
|
+
line = socket.gets
|
53
|
+
break unless line
|
54
|
+
|
55
|
+
begin
|
56
|
+
cmd, args = JSON.load(line)
|
57
|
+
log_debug("[rpc:server] #{cmd.to_sym.inspect}, args: #{args.inspect}")
|
58
|
+
response = process(cmd, args)
|
59
|
+
socket.puts(JSON.dump(response))
|
60
|
+
rescue StandardError => e
|
61
|
+
log_error(e)
|
62
|
+
reflect(:error, e)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
socket.close
|
67
|
+
end
|
68
|
+
|
69
|
+
def process(cmd, args) # rubocop:disable Lint/UnusedMethodArgument
|
70
|
+
case cmd
|
71
|
+
when 'status'
|
72
|
+
status
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def status
|
77
|
+
Rpush::Daemon::AppRunner.status
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Rpush
|
2
2
|
module Daemon
|
3
3
|
class SignalHandler
|
4
|
+
extend Loggable
|
5
|
+
|
4
6
|
class << self
|
5
7
|
attr_reader :thread
|
6
8
|
end
|
@@ -18,6 +20,11 @@ module Rpush
|
|
18
20
|
def self.stop
|
19
21
|
@write_io.puts('break') if @write_io
|
20
22
|
@thread.join if @thread
|
23
|
+
rescue StandardError => e
|
24
|
+
log_error(e)
|
25
|
+
reflect(:error, e)
|
26
|
+
ensure
|
27
|
+
@thread = nil
|
21
28
|
end
|
22
29
|
|
23
30
|
def self.start_handler(read_io)
|
@@ -11,7 +11,8 @@ module Rpush
|
|
11
11
|
DEFAULT_MARK_OPTIONS = { persist: true }
|
12
12
|
|
13
13
|
def initialize
|
14
|
-
|
14
|
+
@using_oracle = adapter_name =~ /oracle/
|
15
|
+
reopen_log unless Rpush.config.embedded
|
15
16
|
end
|
16
17
|
|
17
18
|
def reopen_log
|
@@ -31,7 +32,7 @@ module Rpush
|
|
31
32
|
Rpush::Client::ActiveRecord::Notification.transaction do
|
32
33
|
relation = ready_for_delivery
|
33
34
|
relation = relation.limit(limit)
|
34
|
-
notifications = relation
|
35
|
+
notifications = claim(relation)
|
35
36
|
mark_processing(notifications)
|
36
37
|
notifications
|
37
38
|
end
|
@@ -188,7 +189,8 @@ module Rpush
|
|
188
189
|
end
|
189
190
|
|
190
191
|
def ready_for_delivery
|
191
|
-
Rpush::Client::ActiveRecord::Notification.where('processing = ? AND delivered = ? AND failed = ? AND (deliver_after IS NULL OR deliver_after < ?)', false, false, false, Time.now)
|
192
|
+
relation = Rpush::Client::ActiveRecord::Notification.where('processing = ? AND delivered = ? AND failed = ? AND (deliver_after IS NULL OR deliver_after < ?)', false, false, false, Time.now)
|
193
|
+
@using_oracle ? relation : relation.order('created_at ASC')
|
192
194
|
end
|
193
195
|
|
194
196
|
def mark_processing(notifications)
|
@@ -201,6 +203,18 @@ module Rpush
|
|
201
203
|
end
|
202
204
|
Rpush::Client::ActiveRecord::Notification.where(id: ids).update_all(['processing = ?', true])
|
203
205
|
end
|
206
|
+
|
207
|
+
def claim(relation)
|
208
|
+
notifications = relation.lock(true).to_a
|
209
|
+
@using_oracle ? notifications.sort_by(&:created_at) : notifications
|
210
|
+
end
|
211
|
+
|
212
|
+
def adapter_name
|
213
|
+
env = (defined?(Rails) && Rails.env) ? Rails.env : 'development'
|
214
|
+
config = ::ActiveRecord::Base.configurations[env]
|
215
|
+
return '' unless config
|
216
|
+
Hash[config.map { |k, v| [k.to_sym, v] }][:adapter]
|
217
|
+
end
|
204
218
|
end
|
205
219
|
end
|
206
220
|
end
|
@@ -96,12 +96,12 @@ module Rpush
|
|
96
96
|
Rpush::Client::Mongoid::Apns::Feedback.create!(failed_at: failed_at, device_token: device_token, app: app)
|
97
97
|
end
|
98
98
|
|
99
|
-
def create_gcm_notification(attrs, data, registration_ids, deliver_after, app)
|
99
|
+
def create_gcm_notification(attrs, data, registration_ids, deliver_after, app)
|
100
100
|
notification = Rpush::Client::Mongoid::Gcm::Notification.new
|
101
101
|
create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app)
|
102
102
|
end
|
103
103
|
|
104
|
-
def create_adm_notification(attrs, data, registration_ids, deliver_after, app)
|
104
|
+
def create_adm_notification(attrs, data, registration_ids, deliver_after, app)
|
105
105
|
notification = Rpush::Client::Mongoid::Adm::Notification.new
|
106
106
|
create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app)
|
107
107
|
end
|
@@ -82,12 +82,12 @@ module Rpush
|
|
82
82
|
Rpush::Client::Redis::Apns::Feedback.create!(failed_at: failed_at, device_token: device_token, app_id: app.id)
|
83
83
|
end
|
84
84
|
|
85
|
-
def create_gcm_notification(attrs, data, registration_ids, deliver_after, app)
|
85
|
+
def create_gcm_notification(attrs, data, registration_ids, deliver_after, app)
|
86
86
|
notification = Rpush::Client::Redis::Gcm::Notification.new
|
87
87
|
create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app)
|
88
88
|
end
|
89
89
|
|
90
|
-
def create_adm_notification(attrs, data, registration_ids, deliver_after, app)
|
90
|
+
def create_adm_notification(attrs, data, registration_ids, deliver_after, app)
|
91
91
|
notification = Rpush::Client::Redis::Adm::Notification.new
|
92
92
|
create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app)
|
93
93
|
end
|
@@ -156,7 +156,7 @@ module Rpush
|
|
156
156
|
[tcp_socket, ssl_socket]
|
157
157
|
rescue *TCP_ERRORS => error
|
158
158
|
if error.message =~ /certificate revoked/i
|
159
|
-
|
159
|
+
log_error('Certificate has been revoked.')
|
160
160
|
reflect(:ssl_certificate_revoked, @app, error)
|
161
161
|
end
|
162
162
|
raise TcpConnectionError, "#{error.class.name}, #{error.message}"
|
@@ -166,7 +166,7 @@ module Rpush
|
|
166
166
|
cert = @ssl_context.cert
|
167
167
|
if certificate_expired?
|
168
168
|
log_error(certificate_msg('expired'))
|
169
|
-
|
169
|
+
raise Rpush::CertificateExpiredError.new(@app, cert.not_after)
|
170
170
|
elsif certificate_expires_soon?
|
171
171
|
log_warn(certificate_msg('will expire'))
|
172
172
|
reflect(:ssl_certificate_will_expire, @app, cert.not_after)
|
@@ -0,0 +1,204 @@
|
|
1
|
+
module Rpush
|
2
|
+
module Daemon
|
3
|
+
module Wns
|
4
|
+
# https://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx
|
5
|
+
class Delivery < Rpush::Daemon::Delivery
|
6
|
+
# Oauth2.0 token endpoint. This endpoint is used to request authorization tokens.
|
7
|
+
WPN_TOKEN_URI = URI.parse('https://login.live.com/accesstoken.srf')
|
8
|
+
|
9
|
+
# Data used to request authorization tokens.
|
10
|
+
ACCESS_TOKEN_REQUEST_DATA = { "grant_type" => "client_credentials", "scope" => "notify.windows.com" }
|
11
|
+
|
12
|
+
MAX_RETRIES = 14
|
13
|
+
|
14
|
+
FAILURE_MESSAGES = {
|
15
|
+
400 => 'One or more headers were specified incorrectly or conflict with another header.',
|
16
|
+
401 => 'The cloud service did not present a valid authentication ticket. The OAuth ticket may be invalid.',
|
17
|
+
403 => 'The cloud service is not authorized to send a notification to this URI even though they are authenticated.',
|
18
|
+
404 => 'The channel URI is not valid or is not recognized by WNS.',
|
19
|
+
405 => 'Invalid method (GET, CREATE); only POST (Windows or Windows Phone) or DELETE (Windows Phone only) is allowed.',
|
20
|
+
406 => 'The cloud service exceeded its throttle limit.',
|
21
|
+
410 => 'The channel expired.',
|
22
|
+
413 => 'The notification payload exceeds the 5000 byte size limit.',
|
23
|
+
500 => 'An internal failure caused notification delivery to fail.',
|
24
|
+
503 => 'The server is currently unavailable.'
|
25
|
+
}
|
26
|
+
|
27
|
+
def initialize(app, http, notification, batch)
|
28
|
+
@app = app
|
29
|
+
@http = http
|
30
|
+
@notification = notification
|
31
|
+
@batch = batch
|
32
|
+
end
|
33
|
+
|
34
|
+
def perform
|
35
|
+
handle_response(do_post)
|
36
|
+
rescue SocketError => error
|
37
|
+
mark_retryable(@notification, Time.now + 10.seconds, error)
|
38
|
+
raise
|
39
|
+
rescue StandardError => error
|
40
|
+
mark_failed(error)
|
41
|
+
raise
|
42
|
+
ensure
|
43
|
+
@batch.notification_processed
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def handle_response(response)
|
49
|
+
code = response.code.to_i
|
50
|
+
case code
|
51
|
+
when 200
|
52
|
+
ok(response)
|
53
|
+
when 401
|
54
|
+
unauthorized
|
55
|
+
when 404
|
56
|
+
invalid_channel(code)
|
57
|
+
when 406
|
58
|
+
not_acceptable
|
59
|
+
when 410
|
60
|
+
invalid_channel(code)
|
61
|
+
when 412
|
62
|
+
precondition_failed
|
63
|
+
when 503
|
64
|
+
service_unavailable
|
65
|
+
else
|
66
|
+
handle_failure(code)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def handle_failure(code, msg = nil)
|
71
|
+
unless msg
|
72
|
+
msg = FAILURE_MESSAGES.key?(code) ? FAILURE_MESSAGES[code] : Rpush::Daemon::HTTP_STATUS_CODES[code]
|
73
|
+
end
|
74
|
+
fail Rpush::DeliveryError.new(code, @notification.id, msg)
|
75
|
+
end
|
76
|
+
|
77
|
+
def ok(response)
|
78
|
+
status = status_from_response(response)
|
79
|
+
case status[:notification]
|
80
|
+
when ["received"]
|
81
|
+
mark_delivered
|
82
|
+
log_info("#{@notification.id} sent successfully")
|
83
|
+
when ["channelthrottled"]
|
84
|
+
mark_retryable(@notification, Time.now + (60 * 10))
|
85
|
+
log_warn("#{@notification.id} cannot be sent. The Queue is full.")
|
86
|
+
when ["dropped"]
|
87
|
+
log_error("#{@notification.id} was dropped. Headers: #{status}")
|
88
|
+
handle_failure(200, "Notification was received but suppressed by the service (#{status[:error_description]}).")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def unauthorized
|
93
|
+
@notification.app.access_token = nil
|
94
|
+
Rpush::Daemon.store.update_app(@notification.app)
|
95
|
+
if @notification.retries < MAX_RETRIES
|
96
|
+
retry_notification("Token invalid.")
|
97
|
+
else
|
98
|
+
msg = "Notification failed to be delivered in #{MAX_RETRIES} retries."
|
99
|
+
mark_failed(Rpush::DeliveryError.new(nil, @notification.id, msg))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def invalid_channel(code, msg = nil)
|
104
|
+
unless msg
|
105
|
+
msg = FAILURE_MESSAGES.key?(code) ? FAILURE_MESSAGES[code] : Rpush::Daemon::HTTP_STATUS_CODES[code]
|
106
|
+
end
|
107
|
+
reflect(:wns_invalid_channel, @notification, @notification.uri, "#{code}. #{msg}")
|
108
|
+
handle_failure(code, msg)
|
109
|
+
end
|
110
|
+
|
111
|
+
def not_acceptable
|
112
|
+
retry_notification("Per-day throttling limit reached.")
|
113
|
+
end
|
114
|
+
|
115
|
+
def precondition_failed
|
116
|
+
retry_notification("Device unreachable.")
|
117
|
+
end
|
118
|
+
|
119
|
+
def service_unavailable
|
120
|
+
mark_retryable_exponential(@notification)
|
121
|
+
log_warn("Service Unavailable. " + retry_message)
|
122
|
+
end
|
123
|
+
|
124
|
+
def retry_message
|
125
|
+
"Notification #{@notification.id} will be retried after #{@notification.deliver_after.strftime('%Y-%m-%d %H:%M:%S')} (retry #{@notification.retries})."
|
126
|
+
end
|
127
|
+
|
128
|
+
def retry_notification(reason)
|
129
|
+
deliver_after = Time.now + (60 * 60)
|
130
|
+
mark_retryable(@notification, deliver_after)
|
131
|
+
log_warn("#{reason} " + retry_message)
|
132
|
+
end
|
133
|
+
|
134
|
+
def do_post
|
135
|
+
body = notification_to_xml
|
136
|
+
uri = URI.parse(@notification.uri)
|
137
|
+
post = Net::HTTP::Post.new(uri.request_uri,
|
138
|
+
"Content-Length" => body.length.to_s,
|
139
|
+
"Content-Type" => "text/xml",
|
140
|
+
"X-WNS-Type" => "wns/toast",
|
141
|
+
"X-WNS-RequestForStatus" => "true",
|
142
|
+
"Authorization" => "Bearer #{access_token}")
|
143
|
+
post.body = body
|
144
|
+
@http.request(URI.parse(@notification.uri), post)
|
145
|
+
end
|
146
|
+
|
147
|
+
def status_from_response(response)
|
148
|
+
headers = response.to_hash.inject({}) {|h, v| h[v[0].downcase] = v[1]; h}
|
149
|
+
{
|
150
|
+
notification: headers["x-wns-status"],
|
151
|
+
device_connection: headers["x-wns-deviceconnectionstatus"],
|
152
|
+
msg_id: headers["x-wns-msg-id"],
|
153
|
+
error_description: headers["x-wns-error-description"],
|
154
|
+
debug_trace: headers["x-wns-debug-trace"]
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
def notification_to_xml
|
159
|
+
title = clean_param_string(@notification.data['title']) if @notification.data['title'].present?
|
160
|
+
body = clean_param_string(@notification.data['body']) if @notification.data['body'].present?
|
161
|
+
"<toast>
|
162
|
+
<visual version='1' lang='en-US'>
|
163
|
+
<binding template='ToastText02'>
|
164
|
+
<text id='1'>#{title}</text>
|
165
|
+
<text id='2'>#{body}</text>
|
166
|
+
</binding>
|
167
|
+
</visual>
|
168
|
+
</toast>"
|
169
|
+
end
|
170
|
+
|
171
|
+
def clean_param_string(string)
|
172
|
+
string.gsub(/&/, "&").gsub(/</, "<") \
|
173
|
+
.gsub(/>/, ">").gsub(/'/, "'").gsub(/"/, """)
|
174
|
+
end
|
175
|
+
|
176
|
+
def access_token
|
177
|
+
if @notification.app.access_token.nil? || @notification.app.access_token_expired?
|
178
|
+
post = Net::HTTP::Post.new(WPN_TOKEN_URI.path, 'Content-Type' => 'application/x-www-form-urlencoded')
|
179
|
+
post.set_form_data(ACCESS_TOKEN_REQUEST_DATA.merge('client_id' => @notification.app.client_id, 'client_secret' => @notification.app.client_secret))
|
180
|
+
|
181
|
+
handle_access_token(@http.request(WPN_TOKEN_URI, post))
|
182
|
+
end
|
183
|
+
|
184
|
+
@notification.app.access_token
|
185
|
+
end
|
186
|
+
|
187
|
+
def handle_access_token(response)
|
188
|
+
if response.code.to_i == 200
|
189
|
+
update_access_token(JSON.parse(response.body))
|
190
|
+
Rpush::Daemon.store.update_app(@notification.app)
|
191
|
+
log_info("WNS access token updated: token = #{@notification.app.access_token}, expires = #{@notification.app.access_token_expiration}")
|
192
|
+
else
|
193
|
+
log_warn("Could not retrieve access token from WNS: #{response.body}")
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def update_access_token(data)
|
198
|
+
@notification.app.access_token = data['access_token']
|
199
|
+
@notification.app.access_token_expiration = Time.now + data['expires_in'].to_i
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|