fcm-ruby-push-notifications 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/.rspec +2 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +32 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +82 -0
- data/Rakefile +12 -0
- data/examples/apns.rb +27 -0
- data/examples/gcm.rb +25 -0
- data/examples/mpns.rb +22 -0
- data/examples/wns.rb +25 -0
- data/gemfiles/Gemfile-legacy +8 -0
- data/lib/ruby-push-notifications.rb +7 -0
- data/lib/ruby-push-notifications/apns.rb +44 -0
- data/lib/ruby-push-notifications/apns/apns_connection.rb +70 -0
- data/lib/ruby-push-notifications/apns/apns_notification.rb +91 -0
- data/lib/ruby-push-notifications/apns/apns_pusher.rb +84 -0
- data/lib/ruby-push-notifications/apns/apns_results.rb +30 -0
- data/lib/ruby-push-notifications/fcm.rb +8 -0
- data/lib/ruby-push-notifications/fcm/fcm_connection.rb +60 -0
- data/lib/ruby-push-notifications/fcm/fcm_error.rb +17 -0
- data/lib/ruby-push-notifications/fcm/fcm_notification.rb +31 -0
- data/lib/ruby-push-notifications/fcm/fcm_pusher.rb +29 -0
- data/lib/ruby-push-notifications/fcm/fcm_request.rb +28 -0
- data/lib/ruby-push-notifications/fcm/fcm_response.rb +89 -0
- data/lib/ruby-push-notifications/fcm/fcm_result.rb +52 -0
- data/lib/ruby-push-notifications/gcm.rb +6 -0
- data/lib/ruby-push-notifications/gcm/gcm_connection.rb +54 -0
- data/lib/ruby-push-notifications/gcm/gcm_error.rb +17 -0
- data/lib/ruby-push-notifications/gcm/gcm_notification.rb +31 -0
- data/lib/ruby-push-notifications/gcm/gcm_pusher.rb +35 -0
- data/lib/ruby-push-notifications/gcm/gcm_response.rb +89 -0
- data/lib/ruby-push-notifications/gcm/gcm_result.rb +52 -0
- data/lib/ruby-push-notifications/mpns.rb +5 -0
- data/lib/ruby-push-notifications/mpns/mpns_connection.rb +87 -0
- data/lib/ruby-push-notifications/mpns/mpns_notification.rb +94 -0
- data/lib/ruby-push-notifications/mpns/mpns_pusher.rb +33 -0
- data/lib/ruby-push-notifications/mpns/mpns_response.rb +82 -0
- data/lib/ruby-push-notifications/mpns/mpns_result.rb +182 -0
- data/lib/ruby-push-notifications/notification_results_manager.rb +14 -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 +28 -0
- data/spec/factories.rb +17 -0
- data/spec/factories/notifications.rb +30 -0
- data/spec/ruby-push-notifications/apns/apns_connection_spec.rb +92 -0
- data/spec/ruby-push-notifications/apns/apns_notification_spec.rb +42 -0
- data/spec/ruby-push-notifications/apns/apns_pusher_spec.rb +295 -0
- data/spec/ruby-push-notifications/gcm/gcm_connection_spec.rb +46 -0
- data/spec/ruby-push-notifications/gcm/gcm_notification_spec.rb +37 -0
- data/spec/ruby-push-notifications/gcm/gcm_pusher_spec.rb +45 -0
- data/spec/ruby-push-notifications/gcm/gcm_response_spec.rb +82 -0
- data/spec/ruby-push-notifications/mpns/mpns_connection_spec.rb +46 -0
- data/spec/ruby-push-notifications/mpns/mpns_notification_spec.rb +53 -0
- data/spec/ruby-push-notifications/mpns/mpns_pusher_spec.rb +59 -0
- data/spec/ruby-push-notifications/mpns/mpns_response_spec.rb +64 -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
- data/spec/spec_helper.rb +23 -0
- data/spec/support/dummy.pem +44 -0
- data/spec/support/factory_girl.rb +5 -0
- data/spec/support/results_shared_examples.rb +31 -0
- metadata +249 -0
@@ -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
|
@@ -0,0 +1,208 @@
|
|
1
|
+
module RubyPushNotifications
|
2
|
+
module WNS
|
3
|
+
# Class that encapsulates the result of a single sent notification to a single
|
4
|
+
# Device URL
|
5
|
+
# https://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx#WNSResponseCodes
|
6
|
+
class WNSResult
|
7
|
+
# @return [String]. Receiver WNS device URL.
|
8
|
+
attr_accessor :device_url
|
9
|
+
|
10
|
+
# @private X-WNS-NotificationStatus HTTP Header string
|
11
|
+
X_NOTIFICATION_STATUS = 'x-wns-notificationstatus'
|
12
|
+
|
13
|
+
# @private X-WNS-DeviceConnectionStatus HTTP Header string
|
14
|
+
X_DEVICE_CONNECTION_STATUS = 'x-wns-deviceconnectionstatus'
|
15
|
+
|
16
|
+
# @private X-SubscriptionStatus HTTP Header string
|
17
|
+
X_STATUS = 'x-wns-status'
|
18
|
+
end
|
19
|
+
|
20
|
+
# Indicates that the notification was successfully sent to the corresponding
|
21
|
+
# device URL
|
22
|
+
class WNSResultOK < WNSResult
|
23
|
+
# @return [String]. The status of the notification received
|
24
|
+
# by the Windows Notification Service.
|
25
|
+
attr_accessor :notification_status
|
26
|
+
|
27
|
+
# @return [String]. The connection status of the device.
|
28
|
+
attr_accessor :device_connection_status
|
29
|
+
|
30
|
+
# @return [String]. Notification status.
|
31
|
+
attr_accessor :status
|
32
|
+
|
33
|
+
def initialize(device_url, headers)
|
34
|
+
@device_url = device_url
|
35
|
+
@notification_status = headers[X_NOTIFICATION_STATUS]
|
36
|
+
@device_connection_status = headers[X_DEVICE_CONNECTION_STATUS]
|
37
|
+
@status = headers[X_STATUS]
|
38
|
+
end
|
39
|
+
|
40
|
+
def ==(other)
|
41
|
+
(other.is_a?(WNSResultOK) &&
|
42
|
+
device_url == other.device_url &&
|
43
|
+
notification_status == other.notification_status &&
|
44
|
+
device_connection_status == other.device_connection_status &&
|
45
|
+
status == other.status) || super(other)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# This error occurs when the cloud service sends a notification
|
50
|
+
# request with a bad XML document or malformed notification URI.
|
51
|
+
class MalformedWNSResultError < WNSResult
|
52
|
+
def initialize(device_url)
|
53
|
+
@device_url = device_url
|
54
|
+
end
|
55
|
+
|
56
|
+
def ==(other)
|
57
|
+
(other.is_a?(MalformedWNSResultError) &&
|
58
|
+
device_url == other.device_url) || super(other)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Sending this notification is unauthorized.
|
63
|
+
class WNSAuthError < WNSResult
|
64
|
+
def initialize(device_url)
|
65
|
+
@device_url = device_url
|
66
|
+
end
|
67
|
+
|
68
|
+
def ==(other)
|
69
|
+
(other.is_a?(WNSAuthError) &&
|
70
|
+
device_url == other.device_url) || super(other)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Notification is invalid and is not present on the Push Notification Service.
|
75
|
+
class WNSInvalidError < WNSResult
|
76
|
+
# @return [String]. The status of the notification received
|
77
|
+
# by the Windows Notification Service.
|
78
|
+
attr_accessor :notification_status
|
79
|
+
|
80
|
+
# @return [String]. The connection status of the device.
|
81
|
+
attr_accessor :device_connection_status
|
82
|
+
|
83
|
+
# @return [String]. Notification status.
|
84
|
+
attr_accessor :status
|
85
|
+
|
86
|
+
def initialize(device_url, headers)
|
87
|
+
@device_url = device_url
|
88
|
+
@notification_status = headers[X_NOTIFICATION_STATUS]
|
89
|
+
@device_connection_status = headers[X_DEVICE_CONNECTION_STATUS]
|
90
|
+
@status = headers[X_STATUS]
|
91
|
+
end
|
92
|
+
|
93
|
+
def ==(other)
|
94
|
+
(other.is_a?(WNSInvalidError) &&
|
95
|
+
device_url == other.device_url &&
|
96
|
+
notification_status == other.notification_status &&
|
97
|
+
device_connection_status == other.device_connection_status &&
|
98
|
+
status == other.status) || super(other)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# This error occurs when an unauthenticated cloud service has reached
|
103
|
+
# the per-day throttling limit for a subscription,
|
104
|
+
# or when a cloud service (authenticated or unauthenticated)
|
105
|
+
# has sent too many notifications per second.
|
106
|
+
class WNSLimitError < WNSResult
|
107
|
+
# @return [String]. The status of the notification received
|
108
|
+
# by the Windows Notification Service.
|
109
|
+
attr_accessor :notification_status
|
110
|
+
|
111
|
+
# @return [String]. The connection status of the device.
|
112
|
+
attr_accessor :device_connection_status
|
113
|
+
|
114
|
+
# @return [String]. Notification status.
|
115
|
+
attr_accessor :status
|
116
|
+
|
117
|
+
def initialize(device_url, headers)
|
118
|
+
@device_url = device_url
|
119
|
+
@notification_status = headers[X_NOTIFICATION_STATUS]
|
120
|
+
@device_connection_status = headers[X_DEVICE_CONNECTION_STATUS]
|
121
|
+
@status = headers[X_STATUS]
|
122
|
+
end
|
123
|
+
|
124
|
+
def ==(other)
|
125
|
+
(other.is_a?(WNSLimitError) &&
|
126
|
+
device_url == other.device_url &&
|
127
|
+
notification_status == other.notification_status &&
|
128
|
+
device_connection_status == other.device_connection_status &&
|
129
|
+
status == other.status) || super(other)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# The device is in a disconnected state.
|
134
|
+
class WNSPreConditionError < WNSResult
|
135
|
+
# @return [String]. The status of the notification received
|
136
|
+
# by the Windows Notification Service.
|
137
|
+
attr_accessor :notification_status
|
138
|
+
|
139
|
+
# @return [String]. The connection status of the device.
|
140
|
+
attr_accessor :device_connection_status
|
141
|
+
|
142
|
+
def initialize(device_url, headers)
|
143
|
+
@device_url = device_url
|
144
|
+
@notification_status = headers[X_NOTIFICATION_STATUS]
|
145
|
+
@device_connection_status = headers[X_DEVICE_CONNECTION_STATUS]
|
146
|
+
end
|
147
|
+
|
148
|
+
def ==(other)
|
149
|
+
(other.is_a?(WNSPreConditionError) &&
|
150
|
+
device_url == other.device_url &&
|
151
|
+
notification_status == other.notification_status &&
|
152
|
+
device_connection_status == other.device_connection_status) || super(other)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# The device is in a disconnected state.
|
157
|
+
class WNSExpiredError < WNSResult
|
158
|
+
# @return [String]. The status of the notification received
|
159
|
+
# by the Windows Notification Service.
|
160
|
+
attr_accessor :notification_status
|
161
|
+
|
162
|
+
# @return [String]. The connection status of the device.
|
163
|
+
attr_accessor :device_connection_status
|
164
|
+
|
165
|
+
# @return [String]. Notification status.
|
166
|
+
attr_accessor :status
|
167
|
+
|
168
|
+
def initialize(device_url, headers)
|
169
|
+
@device_url = device_url
|
170
|
+
@notification_status = headers[X_NOTIFICATION_STATUS]
|
171
|
+
@device_connection_status = headers[X_DEVICE_CONNECTION_STATUS]
|
172
|
+
@status = 'Expired'.freeze
|
173
|
+
end
|
174
|
+
|
175
|
+
def ==(other)
|
176
|
+
(other.is_a?(WNSExpiredError) &&
|
177
|
+
device_url == other.device_url &&
|
178
|
+
notification_status == other.notification_status &&
|
179
|
+
device_connection_status == other.device_connection_status &&
|
180
|
+
status == other.status) || super(other)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# The Push Notification Service is unable to process the request.
|
185
|
+
class WNSInternalError < WNSResult
|
186
|
+
def initialize(device_url)
|
187
|
+
@device_url = device_url
|
188
|
+
end
|
189
|
+
|
190
|
+
def ==(other)
|
191
|
+
(other.is_a?(WNSInternalError) &&
|
192
|
+
device_url == other.device_url) || super(other)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Unknow Error
|
197
|
+
class WNSResultError < WNSResult
|
198
|
+
def initialize(device_url)
|
199
|
+
@device_url = device_url
|
200
|
+
end
|
201
|
+
|
202
|
+
def ==(other)
|
203
|
+
(other.is_a?(WNSResultError) &&
|
204
|
+
device_url == other.device_url) || super(other)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
Gem::Specification.new do |spec|
|
3
|
+
spec.name = "fcm-ruby-push-notifications"
|
4
|
+
spec.version = "1.2.0"
|
5
|
+
spec.authors = ['Santhu MS']
|
6
|
+
spec.email = ['santhu.ms83@gmail.com']
|
7
|
+
spec.summary = %q{iOS, Android and Windows Phone Push Notifications made easy!}
|
8
|
+
spec.description = %q{Easy to use gem to send iOS, Android and Windows Phone Push notifications}
|
9
|
+
spec.homepage = 'https://github.com/santhums/ruby-push-notifications'
|
10
|
+
spec.license = 'MIT'
|
11
|
+
|
12
|
+
spec.required_ruby_version = '>= 2.0.0'
|
13
|
+
|
14
|
+
spec.files = `git ls-files -z`.split("\x0")
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
|
19
|
+
spec.add_dependency 'builder', '~> 3.0'
|
20
|
+
spec.add_dependency 'httparty'
|
21
|
+
spec.add_dependency 'json'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.4'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.2'
|
26
|
+
spec.add_development_dependency 'factory_girl', '~> 4.0'
|
27
|
+
spec.add_development_dependency 'webmock', '~> 1.20'
|
28
|
+
end
|