ruby-push-notifications 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +3 -2
- data/examples/wns.rb +25 -0
- data/lib/ruby-push-notifications.rb +1 -0
- data/lib/ruby-push-notifications/wns.rb +6 -0
- data/lib/ruby-push-notifications/wns/wns_access.rb +82 -0
- data/lib/ruby-push-notifications/wns/wns_connection.rb +97 -0
- data/lib/ruby-push-notifications/wns/wns_notification.rb +101 -0
- data/lib/ruby-push-notifications/wns/wns_pusher.rb +32 -0
- data/lib/ruby-push-notifications/wns/wns_response.rb +83 -0
- data/lib/ruby-push-notifications/wns/wns_result.rb +208 -0
- data/ruby-push-notifications.gemspec +1 -1
- data/spec/factories.rb +3 -1
- data/spec/factories/notifications.rb +7 -0
- data/spec/ruby-push-notifications/wns/wns_access_spec.rb +76 -0
- data/spec/ruby-push-notifications/wns/wns_connection_spec.rb +53 -0
- data/spec/ruby-push-notifications/wns/wns_notification_spec.rb +177 -0
- data/spec/ruby-push-notifications/wns/wns_pusher_spec.rb +58 -0
- data/spec/ruby-push-notifications/wns/wns_response_spec.rb +65 -0
- metadata +21 -5
- data/.hound.yml +0 -2
- data/.ruby-style.yml +0 -1063
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d47dcca6cd9dfae155c566c9b2b90ba334e5e3f5
|
4
|
+
data.tar.gz: 957bc60afb47661d910e50f771c46ea108dbe7df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0c21ac5060259358f3a304934cc562e7d959b7dd3894ce8aaaf87843a49cbf3a5764e450d48f606db1469bafb6f01a423cacabf4d20300e34433f15db550190
|
7
|
+
data.tar.gz: a012744bfd5eab89450238c778786a84a6bde7df4a7ccd406d0a0fc0bb3f7b53443c8e41708d05b52621b5678b93a136a99d741e8c1a8accaf7b36413969f51b
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file.
|
|
3
3
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
4
|
|
5
5
|
## [unrealeased] - [unrealease date]
|
6
|
+
|
7
|
+
## 1.2.0 - 2017-09-20
|
8
|
+
- **Added**: Add support Windows Push Notification Services (WNS)
|
9
|
+
|
10
|
+
## 1.1.0 - 2017-03-14
|
6
11
|
- **Added**: Option (`url`) to set custom GCM endpoint (Android)
|
7
12
|
- **Added**: Option (`host`) to set custom APNS environment (iOS)
|
8
13
|
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/calonso/ruby-push-notifications.svg)](https://travis-ci.org/calonso/ruby-push-notifications) [![Dependency Status](https://gemnasium.com/calonso/ruby-push-notifications.svg)](https://gemnasium.com/calonso/ruby-push-notifications) [![Code Climate](https://codeclimate.com/github/calonso/ruby-push-notifications/badges/gpa.svg)](https://codeclimate.com/github/calonso/ruby-push-notifications) [![Test Coverage](https://codeclimate.com/github/calonso/ruby-push-notifications/badges/coverage.svg)](https://codeclimate.com/github/calonso/ruby-push-notifications) [![Gem Version](https://badge.fury.io/rb/ruby-push-notifications.svg)](http://badge.fury.io/rb/ruby-push-notifications) [![Join the chat at https://gitter.im/calonso/ruby-push-notifications](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/calonso/ruby-push-notifications?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
4
|
|
5
|
-
###iOS, Android and Windows Phone Push Notifications made easy!
|
5
|
+
### iOS, Android and Windows Phone Push Notifications made easy!
|
6
6
|
|
7
7
|
## Features
|
8
8
|
|
@@ -38,7 +38,8 @@ For completely detailed examples:
|
|
38
38
|
|
39
39
|
1. [Apple iOS example](https://github.com/calonso/ruby-push-notifications/tree/master/examples/apns.rb)
|
40
40
|
2. [Google Android example](https://github.com/calonso/ruby-push-notifications/tree/master/examples/gcm.rb)
|
41
|
-
3. [Windows Phone example](https://github.com/calonso/ruby-push-notifications/tree/master/examples/mpns.rb)
|
41
|
+
3. [Windows Phone(MPNS) example](https://github.com/calonso/ruby-push-notifications/tree/master/examples/mpns.rb)
|
42
|
+
4. [Windows Phone(WNS) example](https://github.com/calonso/ruby-push-notifications/tree/master/examples/wns.rb)
|
42
43
|
|
43
44
|
## Pending tasks
|
44
45
|
|
data/examples/wns.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
|
5
|
+
require 'ruby-push-notifications'
|
6
|
+
|
7
|
+
sid = "ms-app://...."
|
8
|
+
secret = "..."
|
9
|
+
|
10
|
+
wns_access = RubyPushNotifications::WNS::WNSAccess.new(sid, secret).get_token
|
11
|
+
access_token = wns_access.response.access_token
|
12
|
+
|
13
|
+
device_urls = ["https://hk2.notify.windows.com/?token=AwYAAACEIPGNfZtVWJMvU%2fJ67TTdLQNdFl2345SbaCP7dmkvUmy6Cv9Y7hM4UT5uA%2b3obnZlIIhQcse9Hs6RPW0MPFVjf3MugnfD8qjIHMtRKIsKENIFveN1xQ6S38m90%2fgaBsE%3d"]
|
14
|
+
|
15
|
+
notification = RubyPushNotifications::WNS::WNSNotification.new(device_urls, { type: :toast, title: 'This is a special title', message: 'this is a special message'})
|
16
|
+
# notification = RubyPushNotifications::WNS::WNSNotification.new(device_urls, { type: :tile, image: 'https://res-5.cloudinary.com/prepathon/image/fetch/w_21,h_21,c_fill,g_face/http://assets-cdn.github.com/images/icons/emoji/unicode/1f604.png?v6', message: 'this is a special message'})
|
17
|
+
# notification = RubyPushNotifications::WNS::WNSNotification.new(device_urls, { type: :badge, value: 'activity'})
|
18
|
+
|
19
|
+
pusher = RubyPushNotifications::WNS::WNSPusher.new(access_token)
|
20
|
+
|
21
|
+
pusher.push([notification])
|
22
|
+
p 'Notification sending results:'
|
23
|
+
p "Success: #{notification.success}, Failed: #{notification.failed}"
|
24
|
+
p 'Details:'
|
25
|
+
p notification.individual_results
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require 'ruby-push-notifications/wns/wns_access'
|
2
|
+
require 'ruby-push-notifications/wns/wns_connection'
|
3
|
+
require 'ruby-push-notifications/wns/wns_notification'
|
4
|
+
require 'ruby-push-notifications/wns/wns_pusher'
|
5
|
+
require 'ruby-push-notifications/wns/wns_result'
|
6
|
+
require 'ruby-push-notifications/wns/wns_response'
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/https'
|
3
|
+
require 'json'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
module RubyPushNotifications
|
7
|
+
module WNS
|
8
|
+
# This class is responsible for get access auth token for sending pushes
|
9
|
+
#
|
10
|
+
class WNSAccess
|
11
|
+
|
12
|
+
# This class is responsible for structurize response from login WNS service
|
13
|
+
#
|
14
|
+
class Response
|
15
|
+
# @return [OpenStruct]. Return structurized response
|
16
|
+
attr_reader :response
|
17
|
+
|
18
|
+
def initialize(response)
|
19
|
+
@response = structurize(response)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def structurize(response)
|
25
|
+
body = response.body.to_s.empty? ? {} : JSON.parse(response.body)
|
26
|
+
OpenStruct.new(
|
27
|
+
status_code: response.code.to_i,
|
28
|
+
status: response.message,
|
29
|
+
error: body['error'],
|
30
|
+
error_description: body['error_description'],
|
31
|
+
access_token: body['access_token'],
|
32
|
+
token_ttl: body['expires_in']
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @private Grant type for getting access token
|
38
|
+
GRANT_TYPE = 'client_credentials'.freeze
|
39
|
+
|
40
|
+
# @private Scope for getting access token
|
41
|
+
SCOPE = 'notify.windows.com'.freeze
|
42
|
+
|
43
|
+
# @private Url for getting access token
|
44
|
+
ACCESS_TOKEN_URL = 'https://login.live.com/accesstoken.srf'.freeze
|
45
|
+
|
46
|
+
# @return [String]. Sid
|
47
|
+
attr_reader :sid
|
48
|
+
|
49
|
+
# @return [String]. Secret token
|
50
|
+
attr_reader :secret
|
51
|
+
|
52
|
+
# @param type [String]. Sid
|
53
|
+
# @param type [String]. Secret
|
54
|
+
#
|
55
|
+
# You can get it on https://account.live.com/developers/applications/index
|
56
|
+
def initialize(sid, secret)
|
57
|
+
@sid = sid
|
58
|
+
@secret = secret
|
59
|
+
end
|
60
|
+
|
61
|
+
# Get access auth token for sending pushes
|
62
|
+
#
|
63
|
+
# https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-windows-push-notification-services--wns--overview
|
64
|
+
def get_token
|
65
|
+
body = {
|
66
|
+
grant_type: GRANT_TYPE,
|
67
|
+
client_id: sid,
|
68
|
+
client_secret: secret,
|
69
|
+
scope: SCOPE
|
70
|
+
}
|
71
|
+
|
72
|
+
url = URI.parse ACCESS_TOKEN_URL
|
73
|
+
http = Net::HTTP.new url.host, url.port
|
74
|
+
http.use_ssl = true
|
75
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
76
|
+
response = http.post url.request_uri, URI.encode_www_form(body)
|
77
|
+
|
78
|
+
Response.new response
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/https'
|
3
|
+
|
4
|
+
module RubyPushNotifications
|
5
|
+
module WNS
|
6
|
+
# Encapsulates a connection to the WNS service
|
7
|
+
# Responsible for final connection with the service.
|
8
|
+
#
|
9
|
+
class WNSConnection
|
10
|
+
# @private Content-Type HTTP Header type string
|
11
|
+
CONTENT_TYPE_HEADER = 'Content-Type'.freeze
|
12
|
+
|
13
|
+
# @private Content-Length HTTP Header type string
|
14
|
+
CONTENT_LENGTH_HEADER = 'Content-Length'.freeze
|
15
|
+
|
16
|
+
# @private WNS type string
|
17
|
+
X_WNS_TYPE_HEADER = 'X-WNS-Type'.freeze
|
18
|
+
|
19
|
+
# @private Authorization string
|
20
|
+
AUTHORIZATION_HEADER = 'Authorization'.freeze
|
21
|
+
|
22
|
+
# @private Request for status type boolean
|
23
|
+
REQUEST_FOR_STATUS_HEADER = 'X-WNS-RequestForStatus'.freeze
|
24
|
+
|
25
|
+
# @private Content-Type type string
|
26
|
+
CONTENT_TYPE = {
|
27
|
+
badge: 'text/xml',
|
28
|
+
toast: 'text/xml',
|
29
|
+
tile: 'text/xml',
|
30
|
+
raw: 'application/octet-stream'
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
# @private Windows Phone Target Types
|
34
|
+
WP_TARGETS = {
|
35
|
+
badge: 'wns/badge',
|
36
|
+
toast: 'wns/toast',
|
37
|
+
tile: 'wns/tile',
|
38
|
+
raw: 'wns/raw'
|
39
|
+
}.freeze
|
40
|
+
|
41
|
+
# Issues a POST request to the WNS send endpoint to
|
42
|
+
# submit the given notifications.
|
43
|
+
#
|
44
|
+
# @param notifications [WNSNotification]. The notifications object to POST
|
45
|
+
# @param access_token [String] required. Access token for send push
|
46
|
+
# @param options [Hash] optional. Options for GCMPusher. Currently supports:
|
47
|
+
# * open_timeout [Integer]: Number of seconds to wait for the connection to open. Defaults to 30.
|
48
|
+
# * read_timeout [Integer]: Number of seconds to wait for one block to be read. Defaults to 30.
|
49
|
+
# @return [Array]. The response of post
|
50
|
+
# (http://msdn.microsoft.com/pt-br/library/windows/apps/ff941099)
|
51
|
+
def self.post(notifications, access_token, options = {})
|
52
|
+
body = notifications.as_wns_xml
|
53
|
+
headers = build_headers(access_token, notifications.data[:type], body.length.to_s)
|
54
|
+
responses = []
|
55
|
+
notifications.each_device do |url|
|
56
|
+
http = Net::HTTP.new url.host, url.port
|
57
|
+
http.open_timeout = options.fetch(:open_timeout, 30)
|
58
|
+
http.read_timeout = options.fetch(:read_timeout, 30)
|
59
|
+
if url.scheme == 'https'
|
60
|
+
http.use_ssl = true
|
61
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
62
|
+
end
|
63
|
+
response = http.post url.request_uri, body, headers
|
64
|
+
responses << { device_url: url.to_s, headers: capitalize_headers(response), code: response.code.to_i }
|
65
|
+
end
|
66
|
+
WNSResponse.new responses
|
67
|
+
end
|
68
|
+
|
69
|
+
# Build Header based on type and delay
|
70
|
+
#
|
71
|
+
# @param type [String]. Access token
|
72
|
+
# @param type [Symbol]. The type of notification
|
73
|
+
# @param type [String]. Content length of body
|
74
|
+
# @return [Hash]. Correct delay based on notification type
|
75
|
+
# https://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx#send_notification_request
|
76
|
+
def self.build_headers(access_token, type, body_length)
|
77
|
+
{
|
78
|
+
CONTENT_TYPE_HEADER => CONTENT_TYPE[type],
|
79
|
+
X_WNS_TYPE_HEADER => WP_TARGETS[type],
|
80
|
+
CONTENT_LENGTH_HEADER => body_length,
|
81
|
+
AUTHORIZATION_HEADER => "Bearer #{access_token}",
|
82
|
+
REQUEST_FOR_STATUS_HEADER => 'true'
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
# Extract headers from response
|
87
|
+
# @param response [Net::HTTPResponse]. HTTP response for request
|
88
|
+
#
|
89
|
+
# @return [Hash]. Hash with headers with case-insensitive keys and capitalized string values
|
90
|
+
def self.capitalize_headers(response)
|
91
|
+
headers = {}
|
92
|
+
response.each_header { |k, v| headers[k] = v.capitalize }
|
93
|
+
headers
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
module RubyPushNotifications
|
4
|
+
module WNS
|
5
|
+
# Encapsulates a WNS Notification.
|
6
|
+
# Actually support for raw, toast, tiles notifications
|
7
|
+
# (http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202945)
|
8
|
+
#
|
9
|
+
class WNSNotification
|
10
|
+
include RubyPushNotifications::NotificationResultsManager
|
11
|
+
|
12
|
+
# @return [Hash]. Payload to send.
|
13
|
+
# Toast :title => a bold message
|
14
|
+
# :message => the small message
|
15
|
+
# :param => a string parameter that is passed to the app
|
16
|
+
# Tile :image => a new image for the tile
|
17
|
+
# :count => a number to show on the tile
|
18
|
+
# :title => the new title of the tile
|
19
|
+
# :back_image => an image for the back of the tile
|
20
|
+
# :back_title => a title on the back of the tile
|
21
|
+
# :back_content => some content (text) for the back
|
22
|
+
# Raw :message => the full Hash message body
|
23
|
+
attr_reader :data
|
24
|
+
|
25
|
+
# @return [Array]. Array with the receiver's WNS device URLs.
|
26
|
+
attr_reader :device_urls
|
27
|
+
|
28
|
+
# Initializes the notification
|
29
|
+
#
|
30
|
+
# @param [Array]. Array with the receiver's device urls.
|
31
|
+
# @param [Hash]. Payload to send.
|
32
|
+
# Toast :title => a bold message
|
33
|
+
# :message => the small message
|
34
|
+
# :param => a string parameter that is passed to the app
|
35
|
+
# Tile :image => a new image for the tile
|
36
|
+
# :count => a number to show on the tile
|
37
|
+
# :title => the new title of the tile
|
38
|
+
# :back_image => an image for the back of the tile
|
39
|
+
# :back_title => a title on the back of the tile
|
40
|
+
# :back_content => some content (text) for the back
|
41
|
+
# Raw :message => the full XML message body
|
42
|
+
def initialize(device_urls, data)
|
43
|
+
@device_urls = device_urls
|
44
|
+
@data = data
|
45
|
+
@data[:type] ||= :raw
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [String]. The WNS's XML format for the payload to send.
|
49
|
+
# (https://docs.microsoft.com/en-us/uwp/schemas/tiles/tiles-xml-schema-portal)
|
50
|
+
def as_wns_xml
|
51
|
+
xml = Builder::XmlMarkup.new
|
52
|
+
xml.instruct!
|
53
|
+
if data[:type] != :raw
|
54
|
+
case data[:type]
|
55
|
+
when :toast
|
56
|
+
xml.tag!('toast', **launch_params(data)) do
|
57
|
+
xml.tag!('visual') do
|
58
|
+
xml.tag!('binding', template: data[:template] || 'ToastText02') do
|
59
|
+
xml.tag!('text', id: 1) { xml.text!(data[:title].to_s) }
|
60
|
+
xml.tag!('text', id: 2) { xml.text!(data[:message].to_s) }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
when :tile
|
65
|
+
xml.tag!('tile') do
|
66
|
+
xml.tag!('visual') do
|
67
|
+
xml.tag!('binding', template: data[:template] || 'TileWideImageAndText01') do
|
68
|
+
xml.tag!('image', src: data[:image].to_s)
|
69
|
+
xml.tag!('text') { xml.text!(data[:message].to_s) }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
when :badge
|
74
|
+
xml.tag!('badge', value: data[:value])
|
75
|
+
end
|
76
|
+
else
|
77
|
+
xml.root { build_hash(xml, data[:message]) }
|
78
|
+
end
|
79
|
+
xml.target!
|
80
|
+
end
|
81
|
+
|
82
|
+
def each_device
|
83
|
+
@device_urls.each do |url|
|
84
|
+
yield(URI.parse url)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def build_hash(xml, options)
|
89
|
+
return unless options
|
90
|
+
options.each do |k, v|
|
91
|
+
xml.tag!(k.to_s) { v.is_a?(Hash) ? build_hash(xml, v) : xml.text!(v.to_s) }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def launch_params(data)
|
96
|
+
return {} unless data[:param]
|
97
|
+
{ launch: data[:param].to_json }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RubyPushNotifications
|
2
|
+
module WNS
|
3
|
+
|
4
|
+
# This class is responsible for sending notifications to the WNS service.
|
5
|
+
#
|
6
|
+
class WNSPusher
|
7
|
+
|
8
|
+
# Initializes the WNSPusher
|
9
|
+
#
|
10
|
+
# @param access_token [String]. WNS access token.
|
11
|
+
# @param options [Hash] optional. Options for GCMPusher. Currently supports:
|
12
|
+
# * open_timeout [Integer]: Number of seconds to wait for the connection to open. Defaults to 30.
|
13
|
+
# * read_timeout [Integer]: Number of seconds to wait for one block to be read. Defaults to 30.
|
14
|
+
# (http://msdn.microsoft.com/pt-br/library/windows/apps/ff941099)
|
15
|
+
def initialize(access_token, options = {})
|
16
|
+
@access_token = access_token
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
# Actually pushes the given notifications.
|
21
|
+
# Assigns every notification an array with the result of each
|
22
|
+
# individual notification.
|
23
|
+
#
|
24
|
+
# @param notifications [Array]. Array of WNSNotification to send.
|
25
|
+
def push(notifications)
|
26
|
+
notifications.each do |notif|
|
27
|
+
notif.results = WNSConnection.post notif, @access_token, @options
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module RubyPushNotifications
|
2
|
+
module WNS
|
3
|
+
|
4
|
+
# This class encapsulates a response received from the WNS service
|
5
|
+
# and helps parsing and understanding the received messages/codes.
|
6
|
+
#
|
7
|
+
class WNSResponse
|
8
|
+
|
9
|
+
# @return [Integer] the number of successfully sent notifications
|
10
|
+
attr_reader :success
|
11
|
+
|
12
|
+
# @return [Integer] the number of failed notifications
|
13
|
+
attr_reader :failed
|
14
|
+
|
15
|
+
# @return [Array] Array of a WNSResult for every receiver of the notification
|
16
|
+
# sent indicating the result of the operation.
|
17
|
+
attr_reader :results
|
18
|
+
alias_method :individual_results, :results
|
19
|
+
|
20
|
+
# Initializes the WNSResponse and runs response parsing
|
21
|
+
#
|
22
|
+
# @param responses [Array]. Array with device_urls and http responses
|
23
|
+
def initialize(responses)
|
24
|
+
parse_response responses
|
25
|
+
end
|
26
|
+
|
27
|
+
def ==(other)
|
28
|
+
(other.is_a?(WNSResponse) &&
|
29
|
+
success == other.success &&
|
30
|
+
failed == other.failed &&
|
31
|
+
results == other.results) || super(other)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Parses the response extracting counts for successful, failed messages.
|
37
|
+
# Also creates the results array assigning a WNSResult subclass for each
|
38
|
+
# device URL the notification was sent to.
|
39
|
+
#
|
40
|
+
# @param responses [Array]. Array of hash responses
|
41
|
+
def parse_response(responses)
|
42
|
+
@success = responses.count { |response| response[:code] == 200 }
|
43
|
+
@failed = responses.count { |response| response[:code] != 200 }
|
44
|
+
@results = responses.map do |response|
|
45
|
+
wns_result_for response[:code],
|
46
|
+
response[:device_url],
|
47
|
+
response[:headers]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Factory method that, for each WNS result object assigns a WNSResult
|
52
|
+
# subclass.
|
53
|
+
#
|
54
|
+
# @param code [Integer]. The HTTP status code received
|
55
|
+
# @param device_url [String]. The receiver's WNS device url.
|
56
|
+
# @param headers [Hash]. The HTTP headers received.
|
57
|
+
# @return [WNSResult]. Corresponding WNSResult subclass
|
58
|
+
def wns_result_for(code, device_url, headers)
|
59
|
+
case code
|
60
|
+
when 200
|
61
|
+
WNSResultOK.new device_url, headers
|
62
|
+
when 400
|
63
|
+
MalformedWNSResultError.new device_url
|
64
|
+
when 401
|
65
|
+
WNSAuthError.new device_url
|
66
|
+
when 404
|
67
|
+
WNSInvalidError.new device_url, headers
|
68
|
+
when 406
|
69
|
+
WNSLimitError.new device_url, headers
|
70
|
+
when 410
|
71
|
+
WNSExpiredError.new device_url, headers
|
72
|
+
when 412
|
73
|
+
WNSPreConditionError.new device_url, headers
|
74
|
+
when 500..599
|
75
|
+
WNSInternalError.new device_url
|
76
|
+
else
|
77
|
+
WNSResultError.new device_url
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|