customerio 2.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 142c5aa6d5043fbf69018fc678fc335552c46d65
4
- data.tar.gz: 15c5da49d590ac52cbc500d24e9a31b243937092
2
+ SHA256:
3
+ metadata.gz: d874bed91dc92bf20913befe45a204319cfeb6bf82dde6ef7d59bffe76b68f01
4
+ data.tar.gz: b9d3af66629b47eda01b0f403a50b10f6f5ea7e6680f37505f3b116cce3cae34
5
5
  SHA512:
6
- metadata.gz: c612f66e9ba819f88f04659b7ea243d98c4c57e6f6733bee94ca71e85dcd7d2d5b4ecd8458623d4ad3cafa857587e47b17e74977dee302fccb2a3c879d5a53db
7
- data.tar.gz: db90752181238ad8626b2a723ae1f74230abbc6a458f39802ee25b21ac2933c653bddf2138b261e7e65b8ecb17d341d7a8234093497421a8c0b30dc811a9c0b2
6
+ metadata.gz: 29ff3dfd708c6485110d013508ec19b93544c3fd89c0a5d65b101e65b9ae0c3d325aab2b8d0b5fe9b9c8b828b1db02ea682aa8a06d6fa6b00ef5b31a0bb64dcb
7
+ data.tar.gz: 0a8c4eed08c825b5653e8f9630cafda556e958fb405fb73767e0a8f25645b8b3948daa07c5ca17e19b0799abd549cc27a8fc64ada0d5070c4d4a58a78ed80c90
@@ -0,0 +1,30 @@
1
+ name: ruby_ci
2
+
3
+ on: [push,pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ strategy:
8
+ matrix:
9
+ ruby: ['2.5', '2.6', '2.7']
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - name: set up ruby
14
+ uses: actions/setup-ruby@v1
15
+ with:
16
+ ruby-version: ${{ matrix.ruby }}
17
+ - name: install bundle
18
+ run: |
19
+ sudo apt-get -yqq install libpq-dev
20
+ gem install bundler
21
+ - name: Cache dependencies
22
+ uses: actions/cache@v2
23
+ with:
24
+ path: vendor/bundle
25
+ key: customerio-${{ matrix.ruby }}-${{ hashFiles('customerio.gemspec') }}
26
+ restore-keys: |
27
+ customerio-${{ matrix.ruby }}-
28
+ - name: Install dependencies
29
+ run: bundle install --path vendor/bundle
30
+ - run: bundle exec rspec
data/CHANGELOG.markdown CHANGED
@@ -1,48 +1,101 @@
1
- ## Customerio 2.1.0 - May 22, 2018 ##
1
+ ## Customerio 4.0.0 - July 6, 2021
2
+ ### Removed
3
+ - The `anonymous_track` method.
4
+
5
+ ### Added
6
+ - The `track_anonymous` method replaces `anonymous_track`. This method requires an `anonymous_id` parameter and will no longer trigger campaigns. If you previously used anonymous events to trigger campaigns, you can still do so [directly through the API](https://customer.io/docs/api/#operation/trackAnonymous). We now refer to anonymous events that trigger campaigns as ["invite events"](https://customer.io/docs/anonymous-events/#anonymous-or-invite).
7
+
8
+ ## Customerio 3.1.0 - March 25, 2021
9
+ ### Added
10
+ - Support for EU region
11
+
12
+ ### Removed
13
+ ### Changed
14
+ - `Customerio::Client` and `CustomerIO::APIClient` have a new parameter `region` that can be set to either `Customerio::Regions::EU` or `Customerio::Regions::US` (defaults to `Customerio::Regions::US`)
15
+
16
+ ## Customerio 3.0.0 - Dec 2, 2020
17
+
18
+ ### Added
19
+ - Support for the Transactional API
20
+
21
+ ### Removed
22
+ - `add_to_segment` and `remove_from_segment` methods
23
+ - Support for non-JSON data
24
+
25
+ ### Changed
26
+ - IDs in the URLs are now escaped.
27
+ - Improved validations for data that's passed in.
28
+ - Earlier, if you passed in an event name without a customer ID to the `track` method, we would create an anonymous event. That is now removed. To create an anonymous event, use the `anonymous_track` method.
29
+
30
+
31
+ ## Customerio 3.0.0 - Dec 2, 2020
32
+
33
+ ### Added
34
+ - Support for the Transactional API
35
+
36
+ ### Removed
37
+ - `add_to_segment` and `remove_from_segment` methods
38
+ - Support for non-JSON data
39
+
40
+ ### Changed
41
+ - IDs in the URLs are now escaped.
42
+ - Improved validations for data that's passed in.
43
+ - Earlier, if you passed in an event name without a customer ID to the `track` method, we would create an anonymous event. That is now removed. To create an anonymous event, use the `anonymous_track` method.
44
+
45
+ ## Customerio 2.2.1 - Mar 23, 2020
46
+
47
+ - Add license to gemspec [#55](https://github.com/customerio/customerio-ruby/pull/55)
48
+ - Bubble up error message [#51](https://github.com/customerio/customerio-ruby/pull/51)
49
+
50
+ ## Customerio 2.2.0 - Oct 18, 2018
51
+
52
+ Add support for manual segments [#52](https://github.com/customerio/customerio-ruby/pull/52)
53
+
54
+ ## Customerio 2.1.0 - May 22, 2018
2
55
 
3
56
  Added support for the suppress / unsuppress methods [#49](https://github.com/customerio/customerio-ruby/pull/49)
4
57
 
5
- ## Customerio 2.0.0 - Apr 10, 2018 ##
58
+ ## Customerio 2.0.0 - Apr 10, 2018
6
59
 
7
60
  With this release we have dropped the support for ruby 1.8.7.
8
61
 
9
- * Support new add and remove device endpoints for push notifications [#47](https://github.com/customerio/customerio-ruby/pull/47)
62
+ - Support new add and remove device endpoints for push notifications [#47](https://github.com/customerio/customerio-ruby/pull/47)
10
63
 
11
- ## Customerio 1.0.0 - Mar 15, 2016 ##
64
+ ## Customerio 1.0.0 - Mar 15, 2016
12
65
 
13
66
  There is a slight breaking change in this release. If you are depending on the HTTP response object included in the InvalidResponse exception (introduced in 0.6.1), note that it is now a `Net::HTTPBadRequest`.
14
67
 
15
- * Remove HTTParty dependency, use Net::HTTP instead. [#42](https://github.com/customerio/customerio-ruby/pull/42)
68
+ - Remove HTTParty dependency, use Net::HTTP instead. [#42](https://github.com/customerio/customerio-ruby/pull/42)
16
69
 
17
- * Update test suite to use webmock, to increase confidence that we're not changing our HTTP requests [#41](https://github.com/customerio/customerio-ruby/pull/41)
70
+ - Update test suite to use webmock, to increase confidence that we're not changing our HTTP requests [#41](https://github.com/customerio/customerio-ruby/pull/41)
18
71
 
19
- ## Customerio 0.7.0 - Mar 2, 2016 ##
72
+ ## Customerio 0.7.0 - Mar 2, 2016
20
73
 
21
- * Add new method for tracking anonymous events: `anonymous_track`. See README for more details. Many thanks to @sdawson for this contribution! [#36](https://github.com/customerio/customerio-ruby/pull/36)
74
+ - Add new method for tracking anonymous events: `anonymous_track`. See README for more details. Many thanks to @sdawson for this contribution! [#36](https://github.com/customerio/customerio-ruby/pull/36)
22
75
 
23
- * Use JSON encoding by default. [#37](https://github.com/customerio/customerio-ruby/pull/37)
76
+ - Use JSON encoding by default. [#37](https://github.com/customerio/customerio-ruby/pull/37)
24
77
 
25
- If you want to stick with form-encoding for your integration, you must add `:json => false` to your Customerio::Client initializer. Like this:
78
+ If you want to stick with form-encoding for your integration, you must add `:json => false` to your Customerio::Client initializer. Like this:
26
79
 
27
- ```ruby
28
- customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", :json => false)
29
- ```
80
+ ```ruby
81
+ customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", :json => false)
82
+ ```
30
83
 
31
- ## Customerio 0.6.1 - Oct 8, 2015 ##
84
+ ## Customerio 0.6.1 - Oct 8, 2015
32
85
 
33
- * Include HTTP response as an attribute on the InvalidResponse exception to help with debugging failed API requests. For example:
86
+ - Include HTTP response as an attribute on the InvalidResponse exception to help with debugging failed API requests. For example:
34
87
 
35
- ```ruby
36
- begin
37
- $customerio.track(1, 'event', { :test => 'testing' })
38
- rescue => e
39
- puts e.message
40
- puts e.response.status
41
- puts e.response.body
42
- end
43
- ```
88
+ ```ruby
89
+ begin
90
+ $customerio.track(1, 'event', { :test => 'testing' })
91
+ rescue => e
92
+ puts e.message
93
+ puts e.response.status
94
+ puts e.response.body
95
+ end
96
+ ```
44
97
 
45
- ## Customerio 0.6.0 - Oct 6, 2015 ##
98
+ ## Customerio 0.6.0 - Oct 6, 2015
46
99
 
47
100
  Deprecation warning: we are going to switch to JSON encoding by default for the next release. The current default is form-encoding. This will probably not affect you, unless you rely on how form-encoding arrays work.
48
101
 
@@ -54,46 +107,46 @@ customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", :json
54
107
 
55
108
  Other fixes and improvements, with many thanks to the community contributors:
56
109
 
57
- * Added HTTP timeout of 10 seconds (@stayhero)
58
- * Added JSON support for events (@kemper)
59
- * Convert attribute keys to symbols (@joshnabbott)
110
+ - Added HTTP timeout of 10 seconds (@stayhero)
111
+ - Added JSON support for events (@kemper)
112
+ - Convert attribute keys to symbols (@joshnabbott)
60
113
 
61
- ## Customerio 0.5.0 - Mar 28, 2014 ##
114
+ ## Customerio 0.5.0 - Mar 28, 2014
62
115
 
63
- * Added flag to send body encoded as JSON, rather than the default form encoding.
116
+ - Added flag to send body encoded as JSON, rather than the default form encoding.
64
117
 
65
- ## Customerio 0.5.0 - Apr 8, 2013 ##
118
+ ## Customerio 0.5.0 - Apr 8, 2013
66
119
 
67
- * Removed deprecated methods around using a customer object. All calls simply take a hash of attributes now.
68
- * Added ability to set a timestamp on a tracked event. Useful for backfilling past events.
120
+ - Removed deprecated methods around using a customer object. All calls simply take a hash of attributes now.
121
+ - Added ability to set a timestamp on a tracked event. Useful for backfilling past events.
69
122
 
70
- ## Customerio 0.4.1 - Feb 18, 2013 ##
123
+ ## Customerio 0.4.1 - Feb 18, 2013
71
124
 
72
- * Bug fixes related to the 4.0 change.
125
+ - Bug fixes related to the 4.0 change.
73
126
 
74
- ## Customerio 0.4.0 - Feb 18, 2013 ##
127
+ ## Customerio 0.4.0 - Feb 18, 2013
75
128
 
76
- * Added support for deleting customers.
129
+ - Added support for deleting customers.
77
130
 
78
- ## Customerio 0.3.0 - Dec 28, 2012 ##
131
+ ## Customerio 0.3.0 - Dec 28, 2012
79
132
 
80
- * Now raise an error if an API call doesn't respond with a 200 response code
81
- * Removed dependency on ActiveSupport
133
+ - Now raise an error if an API call doesn't respond with a 200 response code
134
+ - Removed dependency on ActiveSupport
82
135
 
83
- ## Customerio 0.2.0 - Nov 21, 2012 ##
136
+ ## Customerio 0.2.0 - Nov 21, 2012
84
137
 
85
- * Allow raw hashes to be passed into `identify` and `track` methods rather than a customer object.
86
- * Passing a customer object has been depreciated.
87
- * Customizing ids with `Customerio::Client.id` block is deprecated.
138
+ - Allow raw hashes to be passed into `identify` and `track` methods rather than a customer object.
139
+ - Passing a customer object has been depreciated.
140
+ - Customizing ids with `Customerio::Client.id` block is deprecated.
88
141
 
89
- ## Customerio 0.1.0 - Nov 15, 2012 ##
142
+ ## Customerio 0.1.0 - Nov 15, 2012
90
143
 
91
- * Allow tracking of anonymous events.
144
+ - Allow tracking of anonymous events.
92
145
 
93
- ## Customerio 0.0.3 - Nov 5, 2012 ##
146
+ ## Customerio 0.0.3 - Nov 5, 2012
94
147
 
95
- * Bump httparty dependency to the latest version.
148
+ - Bump httparty dependency to the latest version.
96
149
 
97
- ## Customerio 0.0.2 - May 22, 2012 ##
150
+ ## Customerio 0.0.2 - May 22, 2012
98
151
 
99
- * First release.
152
+ - First release.
data/README.md CHANGED
@@ -42,20 +42,15 @@ You'll be able to integrate **fully** with [Customer.io](http://customer.io) wit
42
42
 
43
43
  ### Setup
44
44
 
45
- Create an instance of the client with your [customer.io](http://customer.io) credentials
46
- which can be found on the [customer.io integration screen](https://fly.customer.io/account/customerio_integration).
45
+ Create an instance of the client with your [Customer.io credentials](https://fly.customer.io/settings/api_credentials).
47
46
 
48
47
  If you're using Rails, create an initializer `config/initializers/customerio.rb`:
49
48
 
50
49
  ```ruby
51
- $customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY")
50
+ $customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", region: Customerio::Regions::US)
52
51
  ```
53
52
 
54
- If you'd like to send complex data to associate to a user as json, pass a json option:
55
-
56
- ```ruby
57
- customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", :json => true)
58
- ```
53
+ `region` is optional and takes one of two values—`US` or `EU`. If you do not specify your region, we assume that your account is based in the US (`US`). If your account is based in the EU and you do not provide the correct region (`EU`), we'll route requests to our EU data centers accordingly, however this may cause data to be logged in the US.
59
54
 
60
55
  ### Identify logged in customers
61
56
 
@@ -127,7 +122,7 @@ encourage your customers to perform an action.
127
122
  $customerio.track(5, "purchase", :type => "socks", :price => "13.99")
128
123
  ```
129
124
 
130
- **Note:** If you'd like to track events which occurred in the past, you can include a `timestamp` attribute
125
+ **Note:** If you want to track events which occurred in the past, you can include a `timestamp` attribute
131
126
  (in seconds since the epoch), and we'll use that as the date the event occurred.
132
127
 
133
128
  ```ruby
@@ -136,10 +131,18 @@ $customerio.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp
136
131
 
137
132
  ### Tracking anonymous events
138
133
 
139
- You can also send anonymous events, for situations where you don't yet have a customer record but still want to trigger a campaign:
134
+ You can also send anonymous events, for situations where you don't yet have a customer record yet. An anonymous event requires an `anonymous_id` representing the unknown person and an event `name`. When you identify a person, you can set their `anonymous_id` attribute. If [event merging](https://customer.io/docs/anonymous-events/#turn-on-merging) is turned on in your workspace, and the attribute matches the `anonymous_id` in one or more events that were logged within the last 30 days, we associate those events with the person.
135
+
136
+ Anonymous events cannot trigger campaigns by themselves. To trigger a campaign, the anonymous event must be associated with a person within 72 hours of the `track_anonymous` request.
140
137
 
141
138
  ```ruby
142
- $customerio.anonymous_track("help_enquiry", :recipient => 'user@example.com')
139
+ # Arguments
140
+ # anonymous_id (required) - the id representing the unknown person.
141
+ # name (required) - the name of the event you want to track.
142
+ # attributes (optional) - any related information you want to attach to the
143
+ # event.
144
+
145
+ $customerio.track_anonymous(anonymous_id, "product_view", :type => "socks" )
143
146
  ```
144
147
 
145
148
  Use the `recipient` attribute to specify the email address to send the messages to. [See our documentation on how to use anonymous events for more details](https://learn.customer.io/recipes/invite-emails.html).
@@ -167,6 +170,69 @@ Deleting a device token will remove it from the associated customer to stop furt
167
170
  $customerio.delete_device(5, "my_device_token")
168
171
  ```
169
172
 
173
+ ### Suppress a user
174
+
175
+ Deletes the customer with the provided id if it exists and suppresses all future events and identifies for for that customer.
176
+
177
+ ```ruby
178
+ $customerio.suppress(5)
179
+ ```
180
+
181
+ ### Unsuppress a user
182
+
183
+ Start tracking events and identifies again for a previously suppressed customer. Note when a user is suppressed thier history is deleted and unsupressing them wil not recover that history.
184
+
185
+ ```ruby
186
+ $customerio.unsuppress(5)
187
+ ```
188
+
189
+ ### Send Transactional Messages
190
+
191
+ To use the Customer.io [Transactional API](https://customer.io/docs/transactional-api), create an instance of the API client using an [app key](https://customer.io/docs/managing-credentials#app-api-keys).
192
+
193
+ Create a new `SendEmailRequest` object containing:
194
+
195
+ * `transactional_message_id`: the ID of the transactional message you want to send, or the `body`, `from`, and `subject` of a new message.
196
+ * `to`: the email address of your recipients
197
+ * an `identifiers` object containing the `id` of your recipient. If the `id` does not exist, Customer.io creates it.
198
+ * a `message_data` object containing properties that you want reference in your message using liquid.
199
+ * You can also send attachments with your message. Use `attach` to encode attachments.
200
+
201
+ Use `send_email` referencing your request to send a transactional message. [Learn more about transactional messages and `SendEmailRequest` properties](https://customer.io/docs/transactional-api).
202
+
203
+
204
+ ```ruby
205
+ require "customerio"
206
+
207
+ client = Customerio::APIClient.new("your API key", region: Customerio::Regions::US)
208
+
209
+ request = Customerio::SendEmailRequest.new(
210
+ to: "person@example.com",
211
+ transactional_message_id: "3",
212
+ message_data: {
213
+ name: "Person",
214
+ items: {
215
+ name: "shoes",
216
+ price: "59.99",
217
+ },
218
+ products: [],
219
+ },
220
+ identifiers: {
221
+ id: "2",
222
+ },
223
+ )
224
+
225
+ file = File.open('<file-path>', 'r')
226
+ request.attach("filename", file.read)
227
+
228
+ begin
229
+ response = client.send_email(request)
230
+ puts response
231
+ rescue Customerio::InvalidResponse => e
232
+ puts e.code, e.message
233
+ end
234
+ ```
235
+
170
236
  ## Contributing
171
237
 
172
238
  1. Fork it
data/customerio.gemspec CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |gem|
7
7
  gem.description = "A ruby client for the Customer.io event API."
8
8
  gem.summary = "A ruby client for the Customer.io event API."
9
9
  gem.homepage = "http://customer.io"
10
+ gem.license = "MIT"
10
11
 
11
12
  gem.files = `git ls-files`.split($\)
12
13
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -16,10 +17,10 @@ Gem::Specification.new do |gem|
16
17
  gem.version = Customerio::VERSION
17
18
 
18
19
  gem.add_dependency('multi_json', "~> 1.0")
20
+ gem.add_dependency('addressable', '~> 2.7.0')
19
21
 
20
22
  gem.add_development_dependency('rake', '~> 10.5')
21
23
  gem.add_development_dependency('rspec', '3.3.0')
22
- gem.add_development_dependency('webmock', '1.24.2')
23
- gem.add_development_dependency('addressable', '~> 2.3.6')
24
+ gem.add_development_dependency('webmock', '3.6.0')
24
25
  gem.add_development_dependency('json')
25
26
  end
data/lib/customerio.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  require "customerio/version"
2
2
 
3
3
  module Customerio
4
+ require "customerio/regions"
5
+ require "customerio/base_client"
4
6
  require "customerio/client"
7
+ require "customerio/requests/send_email_request"
8
+ require "customerio/api"
5
9
  require "customerio/param_encoder"
6
10
  end
@@ -0,0 +1,35 @@
1
+ require 'net/http'
2
+ require 'multi_json'
3
+
4
+ module Customerio
5
+ class APIClient
6
+ def initialize(app_key, options = {})
7
+ options[:region] = Customerio::Regions::US if options[:region].nil?
8
+ raise "region must be an instance of Customerio::Regions::Region" unless options[:region].is_a?(Customerio::Regions::Region)
9
+
10
+ options[:url] = options[:region].api_url if options[:url].nil? || options[:url].empty?
11
+ @client = Customerio::BaseClient.new({ app_key: app_key }, options)
12
+ end
13
+
14
+ def send_email(req)
15
+ raise "request must be an instance of Customerio::SendEmailRequest" unless req.is_a?(Customerio::SendEmailRequest)
16
+ response = @client.request(:post, send_email_path, req.message)
17
+
18
+ case response
19
+ when Net::HTTPSuccess then
20
+ JSON.parse(response.body)
21
+ when Net::HTTPBadRequest then
22
+ json = JSON.parse(response.body)
23
+ raise Customerio::InvalidResponse.new(response.code, json['meta']['error'], response)
24
+ else
25
+ raise InvalidResponse.new(response.code, response.body)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def send_email_path
32
+ "/v1/send/email"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,87 @@
1
+ require 'net/http'
2
+ require 'multi_json'
3
+
4
+ module Customerio
5
+ DEFAULT_TIMEOUT = 10
6
+
7
+ class InvalidRequest < RuntimeError; end
8
+ class InvalidResponse < RuntimeError
9
+ attr_reader :code, :response
10
+
11
+ def initialize(code, body, response=nil)
12
+ @message = body
13
+ @code = code
14
+ @response = response
15
+
16
+ super(@message)
17
+ end
18
+ end
19
+
20
+ class BaseClient
21
+ def initialize(auth, options = {})
22
+ @auth = auth
23
+ @timeout = options[:timeout] || DEFAULT_TIMEOUT
24
+ @base_uri = options[:url]
25
+ end
26
+
27
+ def request(method, path, body = nil, headers = {})
28
+ execute(method, path, body, headers)
29
+ end
30
+
31
+ def request_and_verify_response(method, path, body = nil, headers = {})
32
+ verify_response(request(method, path, body, headers))
33
+ end
34
+
35
+ private
36
+
37
+ def execute(method, path, body = nil, headers = {})
38
+ uri = URI.join(@base_uri, path)
39
+
40
+ session = Net::HTTP.new(uri.host, uri.port)
41
+ session.use_ssl = (uri.scheme == 'https')
42
+ session.open_timeout = @timeout
43
+ session.read_timeout = @timeout
44
+
45
+ req = request_class(method).new(uri.path)
46
+
47
+ if @auth.has_key?(:site_id) && @auth.has_key?(:api_key)
48
+ req.initialize_http_header(headers)
49
+ req.basic_auth @auth[:site_id], @auth[:api_key]
50
+ else
51
+ headers['Authorization'] = "Bearer #{@auth[:app_key]}"
52
+ req.initialize_http_header(headers)
53
+ end
54
+
55
+ if !body.nil?
56
+ req.add_field('Content-Type', 'application/json')
57
+ req.body = MultiJson.dump(body)
58
+ end
59
+
60
+ session.start do |http|
61
+ http.request(req)
62
+ end
63
+ end
64
+
65
+ def request_class(method)
66
+ case method
67
+ when :post
68
+ Net::HTTP::Post
69
+ when :put
70
+ Net::HTTP::Put
71
+ when :delete
72
+ Net::HTTP::Delete
73
+ else
74
+ raise InvalidRequest.new("Invalid request method #{method.inspect}")
75
+ end
76
+ end
77
+
78
+ def verify_response(response)
79
+ case response
80
+ when Net::HTTPSuccess then
81
+ response
82
+ else
83
+ raise InvalidResponse.new(response.code, response.body, response)
84
+ end
85
+ end
86
+ end
87
+ end