Skip to content
This repository has been archived by the owner on Jun 20, 2021. It is now read-only.

Attach the server error response to failed notifications #67

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,34 @@ connection.write(notification.message)
connection.close
```

### Logging server errors
The notification server can respond with some error information for failed deliveries. By default, this information is logged to STDOUT.

Logger initialization can be customized:

```ruby
APN = Houston::Client.development
APN.logger = Logger.new(STDERR) # will log to STDERR

APN.logger = Rails.logger # if using houston from a rails app, will use the Rails application logger.

```

Learn more about logger initialization here http://www.ruby-doc.org/stdlib-2.0.0/libdoc/logger/rdoc/Logger.html#class-Logger-label-How+to+create+a+logger

Server error messages on `push` calls are logged at WARN level.

The error code and matching message can be accessed per notification, for instance:

```ruby
APN.push(notification)
# imagine notification failure by server error on push
if notification.apns_error
puts "Failed to send notification. Server responded '#{notification.apns_error}'. Error code was #{notification.apns_error_code}."
end
```


### Feedback Service

Apple provides a feedback service to query for unregistered device tokens, these are devices that have failed to receive a push notification and should be removed from your application. You should periodically query for and remove these devices, Apple audits providers to ensure they are removing unregistered devices. To obtain the list of unregistered device tokens:
Expand Down
11 changes: 10 additions & 1 deletion lib/houston/client.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
module Houston
require 'logger'

APPLE_PRODUCTION_GATEWAY_URI = "apn://gateway.push.apple.com:2195"
APPLE_PRODUCTION_FEEDBACK_URI = "apn://feedback.push.apple.com:2196"

APPLE_DEVELOPMENT_GATEWAY_URI = "apn://gateway.sandbox.push.apple.com:2195"
APPLE_DEVELOPMENT_FEEDBACK_URI = "apn://feedback.sandbox.push.apple.com:2196"

class Client
attr_accessor :gateway_uri, :feedback_uri, :certificate, :passphrase, :timeout
attr_accessor :gateway_uri, :feedback_uri, :certificate, :passphrase, :timeout, :logger

class << self
def development
Expand Down Expand Up @@ -72,6 +74,8 @@ def push(*notifications)

if error
command, status, index = error.unpack("ccN")
notifications[index].apns_error_code = status
logger.warn "Push failed for '#{notifications[index].inspect}'. Error was '#{notifications[index].apns_error}'."
notifications.slice!(0..index)
notifications.each(&:mark_as_unsent!)
push(*notifications)
Expand All @@ -96,5 +100,10 @@ def unregistered_devices
def devices
unregistered_devices.collect{|device| device[:token]}
end

def logger
@logger ||= Logger.new(STDOUT)
end

end
end
19 changes: 18 additions & 1 deletion lib/houston/notification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module Houston
class Notification
MAXIMUM_PAYLOAD_SIZE = 256

attr_accessor :token, :alert, :badge, :sound, :content_available, :custom_data, :id, :expiry, :priority
attr_accessor :token, :alert, :badge, :sound, :content_available, :custom_data, :id, :expiry, :priority,
:apns_error_code
attr_reader :sent_at

alias :device :token
Expand Down Expand Up @@ -59,6 +60,22 @@ def valid?
payload.to_json.bytesize <= MAXIMUM_PAYLOAD_SIZE
end

def apns_error
{
0 => nil,
1 => "Processing error",
2 => "Missing device token",
3 => "Missing topic",
4 => "Missing payload",
5 => "Invalid token size",
6 => "Invalid topic size",
7 => "Invalid payload size",
8 => "Invalid token",
10 => "Shutdown",
255 => "Unknown error"
}[@apns_error_code]
end

private

def device_token_item
Expand Down