sift 1.1.6.2 → 4.5.0

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.
Files changed (45) hide show
  1. checksums.yaml +5 -13
  2. data/.circleci/config.yml +105 -0
  3. data/.github/pull_request_template.md +12 -0
  4. data/.github/workflows/publishing_sift_ruby.yml +38 -0
  5. data/.gitignore +1 -0
  6. data/.jenkins/Jenkinsfile +103 -0
  7. data/HISTORY +104 -0
  8. data/README.md +351 -0
  9. data/examples/psp_merchant_management_apis.rb +105 -0
  10. data/examples/validation_apis.rb +47 -0
  11. data/lib/sift/client/decision/apply_to.rb +129 -0
  12. data/lib/sift/client/decision.rb +66 -0
  13. data/lib/sift/client.rb +845 -112
  14. data/lib/sift/error.rb +13 -0
  15. data/lib/sift/router.rb +41 -0
  16. data/lib/sift/utils/hash_getter.rb +15 -0
  17. data/lib/sift/validate/decision.rb +65 -0
  18. data/lib/sift/validate/primitive.rb +43 -0
  19. data/lib/sift/version.rb +2 -2
  20. data/lib/sift.rb +85 -11
  21. data/sift.gemspec +5 -3
  22. data/spec/fixtures/fake_responses.rb +16 -0
  23. data/spec/spec_helper.rb +1 -1
  24. data/spec/unit/client/decision/apply_to_spec.rb +262 -0
  25. data/spec/unit/client/decision_spec.rb +83 -0
  26. data/spec/unit/client_203_spec.rb +193 -0
  27. data/spec/unit/client_205_spec.rb +117 -0
  28. data/spec/unit/client_label_spec.rb +68 -11
  29. data/spec/unit/client_psp_merchant_spec.rb +133 -0
  30. data/spec/unit/client_spec.rb +556 -79
  31. data/spec/unit/client_validationapi_spec.rb +91 -0
  32. data/spec/unit/router_spec.rb +37 -0
  33. data/spec/unit/validate/decision_spec.rb +85 -0
  34. data/spec/unit/validate/primitive_spec.rb +73 -0
  35. data/test_integration_app/decisions_api/test_decisions_api.rb +31 -0
  36. data/test_integration_app/events_api/test_events_api.rb +843 -0
  37. data/test_integration_app/globals.rb +2 -0
  38. data/test_integration_app/main.rb +67 -0
  39. data/test_integration_app/psp_merchants_api/test_psp_merchant_api.rb +44 -0
  40. data/test_integration_app/score_api/test_score_api.rb +11 -0
  41. data/test_integration_app/verification_api/test_verification_api.rb +32 -0
  42. metadata +85 -28
  43. data/.travis.yml +0 -13
  44. data/README.rdoc +0 -85
  45. data/spec/unit/sift_spec.rb +0 -6
data/README.md ADDED
@@ -0,0 +1,351 @@
1
+ # sift-ruby
2
+
3
+ The official Ruby bindings for the latest version (v205) of the [Sift API](https://sift.com/developers/docs/java/apis-overview).
4
+
5
+ ## Requirements
6
+
7
+ * Ruby 2.0.0 or above.
8
+
9
+
10
+ ## Installation
11
+
12
+ If you want to build the gem from source:
13
+
14
+ ```
15
+ $ gem build sift.gemspec
16
+ ```
17
+
18
+ Alternatively, you can install the gem from rubygems.org:
19
+
20
+ ```
21
+ gem install sift
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ### Creating a Client:
27
+
28
+ ```ruby
29
+ require "sift"
30
+
31
+ Sift.api_key = '<your_api_key_here>'
32
+ Sift.account_id = '<your_account_id_here>'
33
+ client = Sift::Client.new()
34
+
35
+ ##### OR
36
+
37
+ client = Sift::Client.new(api_key: '<your_api_key_here>', account_id: '<your_account_id_here>')
38
+
39
+ ```
40
+
41
+ ### Sending an event
42
+ Send event to Sift.
43
+ To learn more about the Events API visit our [developer docs](https://developers.sift.com/docs/ruby/events-api/overview).
44
+
45
+
46
+ **Optional Params**
47
+ - `return_score`: `:true` or `:false`
48
+ - `return_action`: `:true` or `:false`
49
+ - `return_workflow_status`: `:true` or `:false`
50
+ - `return_route_info`: `:true` or `:false`
51
+ - `force_workflow_run`: `:true` or `:false`
52
+ - `include_score_percentiles`: `:true` or `:false`
53
+ - `warnings`: `:true` or `:false`
54
+ - `abuse_types`: `["payment_abuse", "content_abuse", "content_abuse", "account_abuse", "legacy", "account_takeover"]`
55
+
56
+ **Example:**
57
+ ```ruby
58
+ event = "$transaction"
59
+
60
+ user_id = "23056" # User ID's may only contain a-z, A-Z, 0-9, =, ., -, _, +, @, :, &, ^, %, !, $
61
+
62
+ properties = {
63
+ "$user_id" => user_id,
64
+ "$user_email" => "buyer@gmail.com",
65
+ "$seller_user_id" => "2371",
66
+ "seller_user_email" => "seller@gmail.com",
67
+ "$transaction_id" => "573050",
68
+ "$payment_method" => {
69
+ "$payment_type" => "$credit_card",
70
+ "$payment_gateway" => "$braintree",
71
+ "$card_bin" => "542486",
72
+ "$card_last4" => "4444"
73
+ },
74
+ "$currency_code" => "USD",
75
+ "$amount" => 15230000,
76
+ }
77
+
78
+ response = client.track(event, properties)
79
+
80
+ response.ok? # returns true or false
81
+ response.body # API response body
82
+ response.http_status_code # HTTP response code, 200 is ok.
83
+ response.api_status # status field in the return body, Link to Error Codes
84
+ response.api_error_message # Error message associated with status Error Code
85
+
86
+ # Request a score for the user with user_id 23056
87
+ response = client.score(user_id)
88
+ ```
89
+
90
+ ## Decisions
91
+
92
+ To learn more about the decisions endpoint visit our [developer docs](https://sift.com/developers/docs/ruby/decisions-api/get-decisions).
93
+
94
+ ### List of Configured Decisions
95
+
96
+ Get a list of your decisions.
97
+
98
+ **Optional Params**
99
+ - `entity_type`: `:user` or `:order` or `:session` or `:content`
100
+ - `abuse_types`: `["payment_abuse", "content_abuse", "content_abuse",
101
+ "account_abuse", "legacy", "account_takeover"]`
102
+
103
+ **Returns**
104
+
105
+ A `Response` object
106
+
107
+ **Example:**
108
+ ```ruby
109
+ # fetch a list of all your decisions
110
+ response = client.decisions({
111
+ entity_type: :user,
112
+ abuse_types: ["payment_abuse", "content_abuse"]
113
+ })
114
+
115
+ # Check that response is okay.
116
+ unless response.ok?
117
+ raise "Unable to fetch decisions #{response.api_error_message} " +
118
+ "#{response.api_error_description}"
119
+ end
120
+
121
+ # find a decisions with the id "block_bad_user"
122
+ user_decision = response.body["data"].find do |decision|
123
+ decision["id"] == "block_bad_user"
124
+ end
125
+
126
+ # Get the next page
127
+
128
+ if response.body["has_more"]
129
+ client.decisions(response.body)
130
+ end
131
+ ```
132
+
133
+
134
+ ### Apply a decision
135
+
136
+ Applies a decision to an entity. Visit our [developer docs](http://sift.com/developers/docs/ruby/decisions-api/apply-decision) for more information.
137
+
138
+ **Required Params:**
139
+ - `decision_id`, `source`, `user_id`
140
+
141
+ **Other Params**
142
+ - `order_id`: when applying a decision to an order, you must pass in the `order_id`
143
+ - `session_id`: when applying a decision to a session, you must pass in the `session_id`
144
+ - `analyst`: when `source` is set to `manual_review`, this field *is required*
145
+
146
+ **Returns**
147
+ `Response` object.
148
+
149
+ **Examples:**
150
+ ```ruby
151
+ # apply decision to a user
152
+ response = client.apply_decision({
153
+ decision_id: "block_bad_user",
154
+ source: "manual_review",
155
+ analyst: "bob@your_company.com",
156
+ user_id: "john@example.com"
157
+ })
158
+
159
+ # apply decision to "john@example.com"'s order
160
+ response = client.apply_decision({
161
+ decision_id: "block_bad_order",
162
+ source: "manual_review",
163
+ analyst: "bob@your_company.com",
164
+ user_id: "john@example.com",
165
+ order_id: "ORDER_1234"
166
+ })
167
+
168
+ # apply decision to "john@example.com"'s session
169
+ response = client.apply_decision({
170
+ decision_id: "block_bad_session",
171
+ source: "manual_review",
172
+ analyst: "bob@your_company.com",
173
+ user_id: "john@example.com",
174
+ session_id: "SESSION_ID_1234"
175
+ })
176
+
177
+ # apply decision to "john@example.com"'s content
178
+ response = client.apply_decision({
179
+ decision_id: "block_bad_session",
180
+ source: "manual_review",
181
+ analyst: "bob@your_company.com",
182
+ user_id: "john@example.com",
183
+ content_id: "CONTENT_ID_1234"
184
+ })
185
+
186
+
187
+ # Make sure you handle the response after applying a decision:
188
+
189
+ if response.ok?
190
+ # do stuff
191
+ else
192
+ # Error message
193
+ response.api_error_message
194
+
195
+ # Summary of the error
196
+ response.api_error_description
197
+
198
+ # hash of errors:
199
+ # key: field in question
200
+ # value: description of the issue
201
+ response.api_error_issues
202
+ end
203
+ ```
204
+
205
+ ## Sending a Label
206
+
207
+ ```ruby
208
+ # Label the user with user_id 23056 as Bad with all optional fields
209
+ response = client.label(user_id, {
210
+ "$is_bad" => true,
211
+ "$abuse_type" => "payment_abuse",
212
+ "$description" => "Chargeback issued",
213
+ "$source" => "Manual Review",
214
+ "$analyst" => "analyst.name@your_domain.com"
215
+ })
216
+
217
+ # Get the status of a workflow run
218
+ response = client.get_workflow_status('my_run_id')
219
+
220
+ # Get the latest decisions for a user
221
+ response = client.get_user_decisions('example_user_id')
222
+
223
+ # Get the latest decisions for an order
224
+ response = client.get_order_decisions('example_order_id')
225
+
226
+ # Get the latest decisions for a session
227
+ response = client.get_session_decisions('example_user_id', 'example_session_id')
228
+
229
+ # Get the latest decisions for an content
230
+ response = client.get_content_decisions('example_user_id', 'example_order_id')
231
+ ```
232
+
233
+ ## PSP Merchant Management API
234
+
235
+ To learn more about the decisions endpoint visit our [developer docs](https://sift.com/developers/docs/ruby/psp-merchant-management-api).
236
+
237
+ ```ruby
238
+ # On-board a PSP merchant summary to Sift Platform.
239
+ # Sample psp_merchant_profile
240
+ properties = {
241
+ "id": "merchant_id_01000",
242
+ "name": "Wonderful Payments Inc.",
243
+ "description": "Wonderful Payments payment provider.",
244
+ "address": {
245
+ "name": "Alany",
246
+ "address_1": "Big Payment blvd, 22",
247
+ "address_2": "apt, 8",
248
+ "city": "New Orleans",
249
+ "region": "NA",
250
+ "country": "US",
251
+ "zipcode": "76830",
252
+ "phone": "0394888320"
253
+ },
254
+ "category": "1002",
255
+ "service_level": "Platinum",
256
+ "status": "active",
257
+ "risk_profile": {
258
+ "level": "low",
259
+ "score": 10
260
+ }
261
+ }
262
+ response = client.create_psp_merchant_profile(properties)
263
+
264
+ # Update a merchant summary to reflect changes in the status or service level or address etc.
265
+ properties = {
266
+ "id": "merchant_id_01000",
267
+ "name": "Wonderful Payments Inc.",
268
+ "description": "Wonderful Payments payment provider.",
269
+ "address": {
270
+ "name": "Alany",
271
+ "address_1": "Big Payment blvd, 22",
272
+ "address_2": "apt, 8",
273
+ "city": "New Orleans",
274
+ "region": "NA",
275
+ "country": "US",
276
+ "zipcode": "76830",
277
+ "phone": "0394888320"
278
+ },
279
+ "category": "1002",
280
+ "service_level": "Platinum",
281
+ "status": "active",
282
+ "risk_profile": {
283
+ "level": "low",
284
+ "score": 10
285
+ }
286
+ }
287
+ response = client.update_psp_merchant_profile('merchant_id', properties)
288
+
289
+ # Get the existing PSP merchant summaries.
290
+ response = client.get_a_psp_merchant_profile('merchant_id')
291
+
292
+ # Get all PSP merchant summaries
293
+ response = client.get_psp_merchant_profiles()
294
+
295
+ # Get PSP merchant summaries paginated
296
+ response = client.get_psp_merchant_profiles('batch_size', 'batch_token')
297
+ ```
298
+
299
+ ## Response Object
300
+
301
+ All requests to our apis will return a `Response` instance.
302
+
303
+ ### Public Methods:
304
+ - `ok?` returns `true` when the response is a `200`-`299`, `false` if it isn't
305
+ - `body` returns a hash representation of the json body returned.
306
+ - `api_error_message` returns a string describing the api error code.
307
+ - `api_error_description` a summary of the error that occured.
308
+ - `api_error_issues` a hash describing the items the error occured. The `key` is the item and the `value` is the description of the error.
309
+
310
+
311
+ ## Building
312
+
313
+ Building and publishing the gem is captured by the following steps:
314
+
315
+ ```ruby
316
+ $ gem build sift.gemspec
317
+ $ gem push sift-<current version>.gem
318
+
319
+ $ bundle
320
+ $ rake -T
321
+ $ rake build
322
+ $ rake install
323
+ $ rake release
324
+ ```
325
+
326
+
327
+ ## Testing
328
+
329
+ To run the various tests use the rake command as follows:
330
+
331
+ ```ruby
332
+ $ rake spec
333
+ ```
334
+
335
+ ## Integration testing app
336
+
337
+ For testing the app with real calls it is possible to run the integration testing app,
338
+ it makes calls to almost all our public endpoints to make sure the library integrates
339
+ well. At the moment, the app is run on every merge to master
340
+
341
+ #### How to run it locally
342
+
343
+ 1. Add env variable `ACCOUNT_ID` with the valid account id
344
+ 2. Add env variable `API_KEY` with the valid Api Key associated from the account
345
+ 3. Run the following under the project root folder
346
+ ```
347
+ # Install the budle locally
348
+ bundle check || bundle install
349
+ # Run the app
350
+ bundle exec ruby test_integration_app/main.rb
351
+ ```
@@ -0,0 +1,105 @@
1
+ require 'rubygems'
2
+ require 'sift'
3
+ require 'multi_json'
4
+
5
+ class MyLogger
6
+ def warn(e)
7
+ puts "[WARN] " + e.to_s
8
+ end
9
+
10
+ def error(e)
11
+ puts "[ERROR] " + e.to_s
12
+ end
13
+
14
+ def fatal(e)
15
+ puts "[FATAL] " + e.to_s
16
+ end
17
+
18
+ def info(e)
19
+ puts "[INFO] " + e.to_s
20
+ end
21
+ end
22
+
23
+ def handle_response(response)
24
+ if response.nil?
25
+ puts 'Error: there was an HTTP error calling through the API'
26
+ else
27
+ puts 'Successfully sent request; was ok? : ' + response.ok?.to_s
28
+ puts 'API error message : ' + response.api_error_message.to_s
29
+ puts 'API status code : ' + response.api_status.to_s
30
+ puts 'HTTP status code : ' + response.http_status_code.to_s
31
+ puts 'original request : ' + response.original_request.to_s
32
+ puts 'response body : ' + response.body.to_s
33
+ end
34
+ end
35
+
36
+ Sift.logger = MyLogger.new
37
+
38
+ $api_key = 'put-valid-api-key'
39
+ $account_id = 'put-valid-account-id'
40
+
41
+ def post_merchant_properties
42
+ # Sample psp_merchant_profile
43
+ {
44
+ "id": "merchant_id_01004",
45
+ "name": "Wonderful Payments Inc.",
46
+ "description": "Wonderful Payments payment provider.",
47
+ "address": {
48
+ "name": "Alany",
49
+ "address_1": "Big Payment blvd, 22",
50
+ "address_2": "apt, 8",
51
+ "city": "New Orleans",
52
+ "region": "NA",
53
+ "country": "US",
54
+ "zipcode": "76830",
55
+ "phone": "0394888320"
56
+ },
57
+ "category": "1002",
58
+ "service_level": "Platinum",
59
+ "status": "active",
60
+ "risk_profile": {
61
+ "level": "low",
62
+ "score": 10
63
+ }
64
+ }
65
+ end
66
+
67
+ def put_merchant_properties
68
+ # Sample update psp_merchant_profile
69
+ {
70
+ "id": "merchant_id_01004",
71
+ "name": "Wonderful Payments Inc. update",
72
+ "description": "Wonderful Payments payment provider. update",
73
+ "address": {
74
+ "name": "Alany",
75
+ "address_1": "Big Payment blvd, 22",
76
+ "address_2": "apt, 8",
77
+ "city": "New Orleans",
78
+ "region": "NA",
79
+ "country": "US",
80
+ "zipcode": "76830",
81
+ "phone": "0394888320"
82
+ },
83
+ "category": "1002",
84
+ "service_level": "Platinum",
85
+ "status": "active",
86
+ "risk_profile": {
87
+ "level": "low",
88
+ "score": 10
89
+ }
90
+ }
91
+ end
92
+
93
+ # handle_response Sift::Client.new(:api_key => $api_key, :account_id => $account_id).create_psp_merchant_profile(post_merchant_properties)
94
+
95
+ # handle_response Sift::Client.new(:api_key => $api_key, :account_id => $account_id).update_psp_merchant_profile("merchant_id_01004", put_merchant_properties)
96
+
97
+ # handle_response Sift::Client.new(:api_key => $api_key, :account_id => $account_id).get_a_psp_merchant_profile("merchant_id_01004")
98
+
99
+ # handle_response Sift::Client.new(:api_key => $api_key, :account_id => $account_id).get_psp_merchant_profiles()
100
+
101
+ # handle_response Sift::Client.new(:api_key => $api_key, :account_id => $account_id).get_psp_merchant_profiles(2)
102
+
103
+ handle_response Sift::Client.new(:api_key => $api_key, :account_id => $account_id).get_psp_merchant_profiles(5, "next_ref")
104
+
105
+ puts "request completed"
@@ -0,0 +1,47 @@
1
+ require "sift"
2
+ require 'multi_json'
3
+
4
+ #$api_key = "put-a-valid-apikey"
5
+ #$user_id = "put-a-valid-userid"
6
+
7
+ def valid_send_properties
8
+ {
9
+ :$user_id => $user_id,
10
+ :$send_to => $user_id,
11
+ :$verification_type => '$email',
12
+ :$brand_name => 'all',
13
+ :$language => 'en',
14
+ :$event => {
15
+ :$session_id => 'gigtleqddo84l8cm15qe4il',
16
+ :$verified_event => '$login',
17
+ :$reason => '$automated_rule',
18
+ :$ip => '192.168.1.1',
19
+ :$browser => {
20
+ :$user_agent => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
21
+ }
22
+ }
23
+ }
24
+ end
25
+
26
+ def valid_resend_properties
27
+ {
28
+ :$user_id => $user_id,
29
+ :$verified_event => '$login'
30
+ }
31
+ end
32
+
33
+ def valid_check_properties
34
+ {
35
+ :$user_id => $user_id,
36
+ :$code => '668316'
37
+ }
38
+ end
39
+
40
+ #response = Sift::Client.new(:api_key => $api_key,:user_id => $user_id,:version=>1.1).verification_send(valid_send_properties)
41
+
42
+ #response = Sift::Client.new(:api_key => $api_key,:user_id => $user_id,:version=>1.1).verification_resend(valid_resend_properties)
43
+ response = Sift::Client.new(:api_key => $api_key,:user_id => $user_id,:version=>1.1).verification_check(valid_check_properties)
44
+
45
+ p response
46
+
47
+ puts "completed"
@@ -0,0 +1,129 @@
1
+ require "multi_json"
2
+
3
+ require_relative "../../validate/decision"
4
+ require_relative "../../client"
5
+ require_relative "../../router"
6
+ require_relative "../../utils/hash_getter"
7
+
8
+ module Sift
9
+ class Client
10
+ class Decision
11
+ class ApplyTo
12
+ PROPERTIES = %w{
13
+ source
14
+ analyst
15
+ description
16
+ order_id
17
+ session_id
18
+ content_id
19
+ user_id
20
+ account_id
21
+ time
22
+ }
23
+
24
+ attr_reader :decision_id, :configs, :getter, :api_key
25
+
26
+ PROPERTIES.each do |attribute|
27
+ class_eval %{
28
+ def #{attribute}
29
+ getter.get(:#{attribute})
30
+ end
31
+ }
32
+ end
33
+
34
+ def initialize(api_key, decision_id, configs)
35
+ @api_key = api_key
36
+ @decision_id = decision_id
37
+ @configs = configs
38
+ @getter = Utils::HashGetter.new(configs)
39
+ end
40
+
41
+ def run
42
+ if errors.empty?
43
+ send_request
44
+ else
45
+ Response.new(
46
+ MultiJson.dump({
47
+ status: 55,
48
+ error_message: errors.join(", ")
49
+ }),
50
+ 400,
51
+ nil
52
+ )
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def send_request
59
+ Router.post(path, {
60
+ body: request_body,
61
+ headers: headers
62
+ })
63
+ end
64
+
65
+ def request_body
66
+ {
67
+ source: source,
68
+ description: description,
69
+ analyst: analyst,
70
+ decision_id: decision_id,
71
+ time: time
72
+ }
73
+ end
74
+
75
+ def errors
76
+ validator = Validate::Decision.new(configs)
77
+
78
+ if applying_to_order?
79
+ validator.valid_order?
80
+ elsif applying_to_session?
81
+ validator.valid_session?
82
+ else
83
+ validator.valid_user?
84
+ end
85
+
86
+ validator.error_messages
87
+ end
88
+
89
+ def applying_to_order?
90
+ configs.has_key?("order_id") || configs.has_key?(:order_id)
91
+ end
92
+
93
+ def applying_to_session?
94
+ configs.has_key?("session_id") || configs.has_key?(:session_id)
95
+ end
96
+
97
+ def applying_to_content?
98
+ configs.has_key?("content_id") || configs.has_key?(:content_id)
99
+ end
100
+
101
+ def path
102
+ if applying_to_order?
103
+ "#{user_path}/orders/#{CGI.escape(order_id)}/decisions"
104
+ elsif applying_to_session?
105
+ "#{user_path}/sessions/#{CGI.escape(session_id)}/decisions"
106
+ elsif applying_to_content?
107
+ "#{user_path}/content/#{CGI.escape(content_id)}/decisions"
108
+ else
109
+ "#{user_path}/decisions"
110
+ end
111
+ end
112
+
113
+ def user_path
114
+ "#{base_path}/users/#{CGI.escape(user_id)}"
115
+ end
116
+
117
+ def base_path
118
+ "#{Client::API3_ENDPOINT}/v3/accounts/#{account_id}"
119
+ end
120
+
121
+ def headers
122
+ {
123
+ "Content-type" => "application/json"
124
+ }.merge(Client.build_auth_header(api_key))
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,66 @@
1
+ require "cgi"
2
+
3
+ require_relative "../router"
4
+ require_relative "../validate/decision"
5
+ require_relative "../utils/hash_getter"
6
+ require_relative "./decision/apply_to"
7
+
8
+ module Sift
9
+ class Client
10
+ class Decision
11
+ FILTER_PARAMS = %w{ limit entity_type abuse_types from }
12
+
13
+ attr_reader :account_id, :api_key
14
+
15
+ def initialize(api_key, account_id)
16
+ @account_id = account_id
17
+ @api_key = api_key
18
+ end
19
+
20
+ def list(options = {})
21
+ getter = Utils::HashGetter.new(options)
22
+
23
+ if path = getter.get(:next_ref)
24
+ request_next_page(path)
25
+ else
26
+ Router.get(index_path, {
27
+ query: build_query(getter),
28
+ headers: auth_header
29
+ })
30
+ end
31
+ end
32
+
33
+ def build_query(getter)
34
+ FILTER_PARAMS.inject({}) do |result, filter|
35
+ if value = getter.get(filter)
36
+ result[filter] = value.is_a?(Array) ? value.join(",") : value
37
+ end
38
+
39
+ result
40
+ end
41
+ end
42
+
43
+ def apply_to(configs = {})
44
+ getter = Utils::HashGetter.new(configs)
45
+ configs[:account_id] = account_id
46
+
47
+ ApplyTo.new(api_key, getter.get(:decision_id), configs).run
48
+ end
49
+
50
+ def index_path
51
+ "#{Client::API3_ENDPOINT}/v3/accounts/#{account_id}/decisions"
52
+ end
53
+
54
+ private
55
+
56
+ def request_next_page(path)
57
+ Router.get(path, headers: auth_header)
58
+ end
59
+
60
+ def auth_header
61
+ Client.build_auth_header(api_key)
62
+ end
63
+ end
64
+ end
65
+ end
66
+