sift 1.1.7.3 → 2.0.0.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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZmNiNGJmZDg2OGU5ZTEzYjNmOWJhZjAzMGNiMzZkYTE5NTVmOGFkZg==
5
- data.tar.gz: !binary |-
6
- NjJmY2FmYWQxMWEyNjFlY2MwMDdmOGZlN2ZiMWE0ODFiMGI1N2MyYg==
2
+ SHA1:
3
+ metadata.gz: 5116181929ffbab6a17941eb341a852a7c4c75c6
4
+ data.tar.gz: 4699c62cdadc3fd2f9123b929925abcf45cfb19b
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- M2FkOGQyZTM0MzdjM2FiMGVjNjU0ZDgxOTU0MjFjNjQ4NWE0NzM2ZGZkNGJi
10
- ZjhkNmZlMzA5MGRiNGU1OWM3NGI4MzFjMDZkODE5NzQ3NDkyZGQwYmVhNzIy
11
- NzI3ZmIzZjkzMzMyMWEwMTBmMzMxYTIwMjA0YTExN2UxZThhNDE=
12
- data.tar.gz: !binary |-
13
- ZGQ0Zjk1YTRmM2YyYzBhMjkzYzcxNzZkOWIxNTIxNTY2MzcyZmUyY2U3ZDRi
14
- YTk1OGExNzBlZDFjNjhlZjhlOTE4NDUzOWJjNjI0Y2MwOTFmYmEwMmY1MDI0
15
- OWU1MDQ0YzBmN2EzMmE1ZmQyMDRmNTJkNTI5Y2IzNzAwNTlmN2M=
6
+ metadata.gz: 5d228bd45520217fe3e06a0e2673e4a176b497ff83fc5f73940a6e656006b7725521597fb263d64cc133020162400562380b30aee1f29c9a3bde91ce080e03a3
7
+ data.tar.gz: bce89304cbf0eb1c963e05c9ec76248ba5e06d9c0829df983735dfaf5828288faf8e73fd3c81a53876ee39081cf3695364a929775ffdb5665caa99fc4dc6f957
@@ -3,6 +3,11 @@ script: "bundle exec rake spec"
3
3
  rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
+ - 2.1.5
7
+ - 2.2.1
8
+ before_install:
9
+ - gem install bundler
10
+ - bundle --version
6
11
  env:
7
12
  # None for now
8
13
  gemfile:
data/HISTORY CHANGED
@@ -1,5 +1,9 @@
1
- === 1.1.7.3 2015-08-18
2
- * Added support for return_action
1
+ === 2.0.0.0 2016-07-19
2
+ * adds support for v204 of Sift Science's APIs
3
+ * adds Workflow Status API, User Decisions API, Order Decisions API
4
+ * v204 APIs are now called by default -- this is an incompatible change
5
+ (use :version => 203 to call the previous API version)
6
+ * uses Hash arg for optional params in Client methods -- incompatible change
3
7
 
4
8
  === 1.1.7.2 2015-04-13
5
9
  * Fixed backwards compatibility issue
@@ -1,5 +1,6 @@
1
1
  = Sift Science Ruby bindings {<img src="https://travis-ci.org/SiftScience/sift-ruby.png?branch=master" alt="Build Status" />}[https://travis-ci.org/SiftScience/sift-ruby]
2
2
 
3
+
3
4
  == Requirements
4
5
 
5
6
  * Ruby 1.8.7 or above. (Ruby 1.8.6 might work if you load ActiveSupport.)
@@ -12,6 +13,7 @@ For development only:
12
13
  * webmock, 1.16 or greater
13
14
  * rake, any version
14
15
 
16
+
15
17
  == Installation
16
18
 
17
19
  If you want to build the gem from source:
@@ -22,16 +24,19 @@ Alternatively, you can install the gem from Rubyforge:
22
24
 
23
25
  $ gem install sift
24
26
 
27
+
25
28
  == Usage
29
+
26
30
  require "sift"
27
31
 
28
32
  Sift.api_key = '<your_api_key_here>'
33
+ Sift.account_id = '<your_account_id_here>'
29
34
  client = Sift::Client.new()
30
35
 
31
36
  # send a transaction event -- note this is blocking
32
37
  event = "$transaction"
33
38
 
34
- user_id = "23056" # User ID's may only contain a-z, A-Z, 0-9, =, ., -, _, +, @, :, &, ^, %, !, $
39
+ user_id = "23056" # User ID's may only contain a-z, A-Z, 0-9, =, ., -, _, +, @, :, &, ^, %, !, $
35
40
 
36
41
  properties = {
37
42
  "$user_id" => user_id,
@@ -50,20 +55,39 @@ Alternatively, you can install the gem from Rubyforge:
50
55
  }
51
56
 
52
57
  response = client.track(event, properties)
53
-
54
- response.ok? # returns true or false
55
-
56
- response.http_status_code # HTTP response code, 200 is ok.
57
-
58
- response.api_status # status field in the return body, Link to Error Codes
59
58
 
60
- response.api_error_message # Error message associated with status Error Code
59
+ response.ok? # returns true or false
60
+ response.body # API response body
61
+ response.http_status_code # HTTP response code, 200 is ok.
62
+ response.api_status # status field in the return body, Link to Error Codes
63
+ response.api_error_message # Error message associated with status Error Code
61
64
 
62
- # Request a score forthe user with user_id 23056
65
+
66
+ # Request a score for the user with user_id 23056
63
67
  response = client.score(user_id)
64
-
68
+
69
+
65
70
  # Label the user with user_id 23056 as Bad with all optional fields
66
- response = client.label(user_id,{ "$is_bad" => true, "$reasons" => ["$chargeback", ], "$description" => "Chargeback issued", "$source" => "Manual Review", "$analyst" => "analyst.name@your_domain.com"})
71
+ response = client.label(user_id, {
72
+ "$is_bad" => true,
73
+ "$abuse_type" => "payment_abuse",
74
+ "$description" => "Chargeback issued",
75
+ "$source" => "Manual Review",
76
+ "$analyst" => "analyst.name@your_domain.com"
77
+ })
78
+
79
+
80
+ # Get the status of a workflow run
81
+ response = client.get_workflow_status('my_run_id')
82
+
83
+
84
+ # Get the latest decisions for a user
85
+ response = client.get_user_decisions('example_user_id')
86
+
87
+
88
+ # Get the latest decisions for an order
89
+ response = client.get_order_decisions('example_order_id')
90
+
67
91
 
68
92
  == Building
69
93
 
@@ -78,6 +102,7 @@ Building and publishing the gem is captured by the following steps:
78
102
  $ rake install
79
103
  $ rake release
80
104
 
105
+
81
106
  == Testing
82
107
 
83
108
  To run the various tests use the rake command as follows:
@@ -3,21 +3,46 @@ require "sift/client"
3
3
 
4
4
  module Sift
5
5
 
6
- # Returns the path for the current API version
7
- def self.current_rest_api_path
8
- "/v#{API_VERSION}/events"
6
+ # Returns the path for the specified API version
7
+ def self.rest_api_path(version=API_VERSION)
8
+ "/v#{version}/events"
9
9
  end
10
10
 
11
- def self.current_users_label_api_path(user_id)
12
- # This API version is a minor version ahead of the /events API
13
- "/v#{API_VERSION}/users/#{URI.encode(user_id)}/labels"
11
+ # Returns the Score API path for the specified user ID and API version
12
+ def self.score_api_path(user_id, version=API_VERSION)
13
+ "/v#{version}/score/#{URI.encode(user_id)}/"
14
14
  end
15
-
16
- # Adding module scoped public API key
15
+
16
+ # Returns the users API path for the specified user ID and API version
17
+ def self.users_label_api_path(user_id, version=API_VERSION)
18
+ "/v#{version}/users/#{URI.encode(user_id)}/labels"
19
+ end
20
+
21
+ # Returns the path for the Workflow Status API
22
+ def self.workflow_status_path(account_id, run_id)
23
+ "/v3/accounts/#{account_id}/workflows/runs/#{run_id}"
24
+ end
25
+
26
+ # Returns the path for User Decisions API
27
+ def self.user_decisions_api_path(account_id, user_id)
28
+ "/v3/accounts/#{account_id}/users/#{user_id}/decisions"
29
+ end
30
+
31
+ # Returns the path for Orders Decisions API
32
+ def self.order_decisions_api_path(account_id, order_id)
33
+ "/v3/accounts/#{account_id}/orders/#{order_id}/decisions"
34
+ end
35
+
36
+ # Module-scoped public API key
17
37
  class << self
18
38
  attr_accessor :api_key
19
39
  end
20
40
 
41
+ # Module-scoped account ID
42
+ class << self
43
+ attr_accessor :account_id
44
+ end
45
+
21
46
  # Sets the Output logger to use within the client. This can be left uninitializaed
22
47
  # but is useful for debugging.
23
48
  def self.logger=(logger)
@@ -15,8 +15,9 @@ module Sift
15
15
 
16
16
  # Constructor
17
17
  #
18
- # == Parameters:
19
- # http_response
18
+ # ==== Parameters:
19
+ #
20
+ # http_response::
20
21
  # The HTTP body text returned from the API call. The body is expected to be
21
22
  # a JSON object that can be decoded into status, message and request
22
23
  # sections.
@@ -37,10 +38,11 @@ module Sift
37
38
  # Helper method returns true if and only if the response from the API call was
38
39
  # successful
39
40
  #
40
- # == Returns:
41
- # true on success; false otherwise
41
+ # ==== Returns:
42
+ #
43
+ # true on success; false otherwise
44
+ #
42
45
  def ok?
43
-
44
46
  if @http_raw_response.kind_of? Net::HTTPNoContent
45
47
  #if there is no content expected, use HTTP code
46
48
  204 == @http_status_code
@@ -51,14 +53,14 @@ module Sift
51
53
  end
52
54
 
53
55
 
54
- # DEPRECIATED
55
- # Getter method for depreciated 'json' member variable.
56
+ # DEPRECATED
57
+ # Getter method for deprecated 'json' member variable.
56
58
  def json
57
59
  @body
58
60
  end
59
61
 
60
- # DEPRECIATED
61
- # Getter method for depreciated 'original_request' member variable.
62
+ # DEPRECATED
63
+ # Getter method for deprecated 'original_request' member variable.
62
64
  def original_request
63
65
  @request
64
66
  end
@@ -67,29 +69,50 @@ module Sift
67
69
  # This class wraps accesses through the API
68
70
  #
69
71
  class Client
70
- API_ENDPOINT = "https://api.siftscience.com"
71
- API_TIMEOUT = 2
72
+ API_ENDPOINT = 'https://api.siftscience.com'
73
+ API3_ENDPOINT = 'https://api3.siftscience.com'
72
74
 
73
75
  include HTTParty
74
76
  base_uri API_ENDPOINT
75
77
 
78
+
76
79
  # Constructor
77
80
  #
78
- # == Parameters:
79
- # api_key
80
- # The Sift Science API key associated with your customer account. This parameter
81
- # cannot be nil or blank.
82
- # path
83
- # The path to the event API, e.g., "/v201/events"
81
+ # ==== Parameters:
84
82
  #
85
- def initialize(api_key = Sift.api_key, path = Sift.current_rest_api_path, timeout = API_TIMEOUT)
86
- raise("api_key must be a non-empty string") if !api_key.is_a?(String) || api_key.empty?
87
- raise("path must be a non-empty string") if !path.is_a?(String) || path.empty?
88
- @api_key = api_key
89
- @path = path
90
- @timeout = timeout
91
-
92
-
83
+ # opts (optional)::
84
+ # A Hash of optional parameters for this Client --
85
+ #
86
+ # :api_key::
87
+ # The Sift Science API key associated with your account.
88
+ # Sift.api_key is used if this parameter is not set.
89
+ #
90
+ # :account_id::
91
+ # The ID of your Sift Science account. Sift.account_id is
92
+ # used if this parameter is not set.
93
+ #
94
+ # :timeout::
95
+ # The number of seconds to wait before failing a request. By
96
+ # default this is configured to 2 seconds.
97
+ #
98
+ # :version::
99
+ # The version of the Events API, Score API, and Labels API to call.
100
+ # By default, version 204.
101
+ #
102
+ # :path::
103
+ # The URL path to use for Events API path. By default, the
104
+ # official path of the specified-version of the Events API.
105
+ #
106
+ #
107
+ def initialize(opts = {})
108
+ @api_key = opts[:api_key] || Sift.api_key
109
+ @account_id = opts[:account_id] || Sift.account_id
110
+ @version = opts[:version] || API_VERSION
111
+ @timeout = opts[:timeout] || 2 # 2-second timeout by default
112
+ @path = opts[:path] || Sift.rest_api_path(@version)
113
+
114
+ raise("api_key must be a non-empty string") if !@api_key.is_a?(String) || @api_key.empty?
115
+ raise("path must be a non-empty string") if !@path.is_a?(String) || @path.empty?
93
116
  end
94
117
 
95
118
  def api_key
@@ -97,64 +120,95 @@ module Sift
97
120
  end
98
121
 
99
122
  def user_agent
100
- "SiftScience/v#{API_VERSION} sift-ruby/#{VERSION}"
123
+ "SiftScience/v#{@version} sift-ruby/#{VERSION}"
101
124
  end
102
125
 
103
- # Tracks an event and associated properties through the Sift Science API. This call
104
- # is blocking.
126
+
127
+ # Sends an event to the Sift Science Events API.
105
128
  #
106
- # == Parameters:
107
- # event
108
- # The name of the event to send. This can be either a reserved event name, like
109
- # $transaction or $label or a custom event name (that does not start with a $).
110
- # This parameter must be specified.
129
+ # See https://siftscience.com/developers/docs/ruby/events-api .
111
130
  #
112
- # properties
113
- # A hash of name-value pairs that specify the event-specific attributes to track.
114
- # This parameter must be specified.
131
+ # ==== Parameters:
132
+ #
133
+ # event::
134
+ # The name of the event to send. This can be either a reserved
135
+ # event name, like $transaction or $label or a custom event name
136
+ # (that does not start with a $). This parameter must be
137
+ # specified.
138
+ #
139
+ # properties::
140
+ # A hash of name-value pairs that specify the event-specific
141
+ # attributes to track. This parameter must be specified.
142
+ #
143
+ # opts (optional)::
144
+ # A Hash of optional parameters for the request --
145
+ #
146
+ # :return_score::
147
+ # If true, requests that the response include a score for this
148
+ # user, computed using the submitted event. See
149
+ # https://siftscience.com/developers/docs/ruby/score-api/synchronous-scores
150
+ #
151
+ # :abuse_types::
152
+ # List of abuse types, specifying for which abuse types a
153
+ # score should be returned (if scoring was requested). By
154
+ # default, a score is returned for every abuse type to which
155
+ # you are subscribed.
115
156
  #
116
- # timeout (optional)
117
- # The number of seconds to wait before failing the request. By default this is
118
- # configured to 2 seconds (see above). This parameter is optional.
157
+ # :return_action::
158
+ # If true, requests that the response include any actions
159
+ # triggered as a result of the tracked event.
119
160
  #
120
- # path (optional)
121
- # Overrides the default API path with a different URL.
161
+ # :return_workflow_status::
162
+ # If true, requests that the response include the status of
163
+ # any workflow run as a result of the tracked event. See
164
+ # https://siftscience.com/developers/docs/ruby/workflows-api/workflow-decisions
122
165
  #
123
- # return_score (optional)
124
- # Whether the API response should include a score for this user. The score will
125
- # be calculated using the submitted event. This feature must be
126
- # enabled for your account in order to use it. Please contact
127
- # support@siftscience.com if you are interested in using this feature.
166
+ # :timeout::
167
+ # Overrides the timeout (in seconds) for this call.
128
168
  #
129
- # return_action (optional)
130
- # Whether the API response should include an action triggered for this transaction.
169
+ # :api_key::
170
+ # Overrides the API key for this call.
131
171
  #
132
- # == Returns:
133
- # In the case of an HTTP error (timeout, broken connection, etc.), this
134
- # method returns nil; otherwise, a Response object is returned and captures
135
- # the status message and status code. In general, you can ignore the returned
136
- # result, though.
172
+ # :version::
173
+ # Overrides the version of the Events API to call.
137
174
  #
138
- def track(event, properties = {}, timeout = nil, path = nil, return_score = false, api_key = @api_key, return_action = false)
139
- warn "[WARNING] api_key cannot be empty, fallback to default api_key." if api_key.to_s.empty?
140
- api_key ||= @api_key
175
+ # :path::
176
+ # Overrides the URI path for this API call.
177
+ #
178
+ # ==== Returns:
179
+ #
180
+ # In the case of a connection error (timeout, broken connection,
181
+ # etc.), this method returns nil; otherwise, a Response object is
182
+ # returned that captures the status message and status code.
183
+ #
184
+ def track(event, properties = {}, opts = {})
185
+ api_key = opts[:api_key] || @api_key
186
+ version = opts[:version] || @version
187
+ path = opts[:path] || (version && Sift.rest_api_path(version)) || @path
188
+ timeout = opts[:timeout] || @timeout
189
+ return_score = opts[:return_score]
190
+ return_action = opts[:return_action]
191
+ return_workflow_status = opts[:return_workflow_status]
192
+ abuse_types = opts[:abuse_types]
193
+
141
194
  raise("event must be a non-empty string") if (!event.is_a? String) || event.empty?
142
195
  raise("properties cannot be empty") if properties.empty?
143
- raise("Bad api_key parameter") if api_key.empty?
144
- path ||= @path
145
- timeout ||= @timeout
196
+ raise("api_key cannot be empty") if api_key.empty?
146
197
 
147
- uri = URI.parse(API_ENDPOINT)
148
- uri.query = URI.encode_www_form(URI.decode_www_form(uri.query.to_s) << ["return_score", "true"]) if return_score
149
- uri.query = URI.encode_www_form(URI.decode_www_form(uri.query.to_s) << ["return_action", "true"]) if return_action
150
- path = path + "?" + uri.query if !uri.query.to_s.empty?
198
+ query = {}
199
+ query["return_score"] = "true" if return_score
200
+ query["return_action"] = "true" if return_action
201
+ query["return_workflow_status"] = "true" if return_workflow_status
202
+ query["abuse_types"] = abuse_types.join(",") if abuse_types
151
203
 
152
204
  options = {
153
205
  :body => MultiJson.dump(delete_nils(properties).merge({"$type" => event,
154
206
  "$api_key" => api_key})),
155
- :headers => {"User-Agent" => user_agent}
207
+ :headers => {"User-Agent" => user_agent},
208
+ :query => query
156
209
  }
157
210
  options.merge!(:timeout => timeout) unless timeout.nil?
211
+
158
212
  begin
159
213
  response = self.class.post(path, options)
160
214
  Response.new(response.body, response.code, response.response)
@@ -165,91 +219,277 @@ module Sift
165
219
  end
166
220
  end
167
221
 
168
- # Retrieves a user's fraud score from the Sift Science API. This call
169
- # is blocking.
222
+
223
+ # Retrieves a user's fraud score from the Sift Science API.
170
224
  #
171
- # == Parameters:
172
- # user_id
225
+ # See https://siftscience.com/developers/docs/ruby/score-api/score-api .
226
+ #
227
+ # ==== Parameters:
228
+ #
229
+ # user_id::
173
230
  # A user's id. This id should be the same as the user_id used in
174
231
  # event calls.
175
232
  #
176
- # == Returns:
177
- # A Response object is returned and captures the status message and
178
- # status code. In general, you can ignore the returned result, though.
233
+ # opts (optional)::
234
+ # A Hash of optional parameters for the request --
235
+ #
236
+ # :abuse_types::
237
+ # List of abuse types, specifying for which abuse types a
238
+ # score should be returned. By default, a score is returned
239
+ # for every abuse type to which you are subscribed.
240
+ #
241
+ # :api_key::
242
+ # Overrides the API key for this call.
243
+ #
244
+ # :timeout::
245
+ # Overrides the timeout (in seconds) for this call.
246
+ #
247
+ # :version::
248
+ # Overrides the version of the Events API to call.
249
+ #
250
+ # ==== Returns:
179
251
  #
180
- def score(user_id, timeout = nil, api_key = @api_key)
252
+ # A Response object containing a status code, status message, and,
253
+ # if successful, the user's score(s).
254
+ #
255
+ def score(user_id, opts = {})
256
+ abuse_types = opts[:abuse_types]
257
+ api_key = opts[:api_key] || @api_key
258
+ timeout = opts[:timeout] || @timeout
259
+ version = opts[:version] || @version
181
260
 
182
261
  raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
183
262
  raise("Bad api_key parameter") if api_key.empty?
184
- timetout ||= @timeout
185
263
 
186
- options = { :headers => {"User-Agent" => user_agent} }
264
+ query = {}
265
+ query["api_key"] = api_key
266
+ query["abuse_types"] = abuse_types.join(",") if abuse_types
267
+
268
+ options = {
269
+ :headers => {"User-Agent" => user_agent},
270
+ :query => query
271
+ }
187
272
  options.merge!(:timeout => timeout) unless timeout.nil?
188
273
 
189
- response = self.class.get("/v#{API_VERSION}/score/#{user_id}/?api_key=#{api_key}", options)
274
+ response = self.class.get(Sift.score_api_path(user_id, version), options)
190
275
  Response.new(response.body, response.code, response.response)
191
-
192
276
  end
193
277
 
194
- # Labels a user as either good or bad. This call is blocking.
278
+
279
+ # Labels a user.
280
+ #
281
+ # See https://siftscience.com/developers/docs/ruby/labels-api/label-user .
195
282
  #
196
- # == Parameters:
197
- # user_id
283
+ # ==== Parameters:
284
+ #
285
+ # user_id::
198
286
  # A user's id. This id should be the same as the user_id used in
199
287
  # event calls.
200
288
  #
201
- # properties
289
+ # properties::
202
290
  # A hash of name-value pairs that specify the label attributes.
203
291
  # This parameter must be specified.
204
292
  #
205
- # timeout (optional)
206
- # The number of seconds to wait before failing the request. By default this is
207
- # configured to 2 seconds (see above). This parameter is optional.
293
+ # opts (optional)::
294
+ # A Hash of optional parameters for the request --
295
+ #
296
+ # :api_key::
297
+ # Overrides the API key for this call.
298
+ #
299
+ # :timeout::
300
+ # Overrides the timeout (in seconds) for this call.
301
+ #
302
+ # :version::
303
+ # Overrides the version of the Events API to call.
208
304
  #
209
- # == Returns:
210
- # A Response object is returned and captures the status message and
211
- # status code. In general, you can ignore the returned result, though.
305
+ # ==== Returns:
212
306
  #
213
- def label(user_id, properties = {}, timeout = nil, api_key = @api_key)
307
+ # In the case of a connection error (timeout, broken connection,
308
+ # etc.), this method returns nil; otherwise, a Response object is
309
+ # returned that captures the status message and status code.
310
+ #
311
+ def label(user_id, properties = {}, opts = {})
312
+ api_key = opts[:api_key] || @api_key
313
+ timeout = opts[:timeout] || @timeout
314
+ version = opts[:version] || @version
315
+ path = Sift.users_label_api_path(user_id, version)
214
316
 
215
317
  raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
216
318
 
217
- path = Sift.current_users_label_api_path(user_id)
218
-
219
- # No return_action logic supported when using labels.
220
- track("$label", delete_nils(properties), timeout, path, false, api_key, false)
319
+ track("$label", delete_nils(properties),
320
+ :path => path, :api_key => api_key, :timeout => timeout)
221
321
  end
222
322
 
223
- # Unlabels a user. This call is blocking.
323
+
324
+ # Unlabels a user.
224
325
  #
225
- # == Parameters:
226
- # user_id
326
+ # See https://siftscience.com/developers/docs/ruby/labels-api/unlabel-user .
327
+ #
328
+ # ==== Parameters:
329
+ #
330
+ # user_id::
227
331
  # A user's id. This id should be the same as the user_id used in
228
332
  # event calls.
229
333
  #
230
- # timeout (optional)
231
- # The number of seconds to wait before failing the request. By default this is
232
- # configured to 2 seconds (see above). This parameter is optional.
334
+ # opts (optional)::
335
+ # A Hash of optional parameters for this request --
336
+ #
337
+ # :abuse_type::
338
+ # The abuse type for which the user should be unlabeled. If
339
+ # omitted, the user is unlabeled for all abuse types.
340
+ #
341
+ # :api_key::
342
+ # Overrides the API key for this call.
343
+ #
344
+ # :timeout::
345
+ # Overrides the timeout (in seconds) for this call.
346
+ #
347
+ # :version::
348
+ # Overrides the version of the Events API to call.
349
+ #
350
+ # ==== Returns:
233
351
  #
234
- # == Returns:
235
- # A Response object is returned with only an http code of 204.
352
+ # A Response object is returned with only an http code of 204.
236
353
  #
237
- def unlabel(user_id, timeout = nil)
354
+ def unlabel(user_id, opts = {})
355
+ abuse_type = opts[:abuse_type]
356
+ api_key = opts[:api_key] || @api_key
357
+ timeout = opts[:timeout] || @timeout
358
+ version = opts[:version] || @version
238
359
 
239
360
  raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
240
- timetout ||= @timeout
241
361
 
242
- options = { :headers => {"User-Agent" => user_agent} }
362
+ query = {}
363
+ query[:api_key] = api_key
364
+ query[:abuse_type] = abuse_type if abuse_type
365
+
366
+ options = {
367
+ :headers => {},
368
+ :query => query
369
+ }
243
370
  options.merge!(:timeout => timeout) unless timeout.nil?
244
- path = Sift.current_users_label_api_path(user_id)
245
- response = self.class.delete(path + "?api_key=#{@api_key}", options)
371
+
372
+ response = self.class.delete(Sift.users_label_api_path(user_id, version), options)
246
373
  Response.new(response.body, response.code, response.response)
247
374
  end
248
375
 
376
+
377
+ # Gets the status of a workflow run.
378
+ #
379
+ # See https://siftscience.com/developers/docs/ruby/workflows-api/workflow-status .
380
+ #
381
+ # ==== Parameters
382
+ #
383
+ # run_id::
384
+ # The ID of a workflow run.
385
+ #
386
+ # opts (optional)::
387
+ # A Hash of optional parameters for this request --
388
+ #
389
+ # :account_id::
390
+ # Overrides the API key for this call.
391
+ #
392
+ # :api_key::
393
+ # Overrides the API key for this call.
394
+ #
395
+ # :timeout::
396
+ # Overrides the timeout (in seconds) for this call.
397
+ #
398
+ def get_workflow_status(run_id, opts = {})
399
+ account_id = opts[:account_id] || @account_id
400
+ api_key = opts[:api_key] || @api_key
401
+ timeout = opts[:timeout] || @timeout
402
+
403
+ options = {
404
+ :headers => { "User-Agent" => user_agent },
405
+ :basic_auth => { :username => api_key, :password => "" }
406
+ }
407
+ options.merge!(:timeout => timeout) unless timeout.nil?
408
+
409
+ uri = API3_ENDPOINT + Sift.workflow_status_path(account_id, run_id)
410
+ response = self.class.get(uri, options)
411
+ Response.new(response.body, response.code, response.response)
412
+ end
413
+
414
+
415
+ # Gets the decision status of a user.
416
+ #
417
+ # See https://siftscience.com/developers/docs/ruby/decisions-api/decision-status .
418
+ #
419
+ # ==== Parameters
420
+ #
421
+ # user_id::
422
+ # The ID of user.
423
+ #
424
+ # opts (optional)::
425
+ # A Hash of optional parameters for this request --
426
+ #
427
+ # :account_id::
428
+ # Overrides the API key for this call.
429
+ #
430
+ # :api_key::
431
+ # Overrides the API key for this call.
432
+ #
433
+ # :timeout::
434
+ # Overrides the timeout (in seconds) for this call.
435
+ #
436
+ def get_user_decisions(user_id, opts = {})
437
+ account_id = opts[:account_id] || @account_id
438
+ api_key = opts[:api_key] || @api_key
439
+ timeout = opts[:timeout] || @timeout
440
+
441
+ options = {
442
+ :headers => { "User-Agent" => user_agent },
443
+ :basic_auth => { :username => api_key, :password => "" }
444
+ }
445
+ options.merge!(:timeout => timeout) unless timeout.nil?
446
+
447
+ uri = API3_ENDPOINT + Sift.user_decisions_api_path(account_id, user_id)
448
+ response = self.class.get(uri, options)
449
+ Response.new(response.body, response.code, response.response)
450
+ end
451
+
452
+
453
+ # Gets the decision status of an order.
454
+ #
455
+ # See https://siftscience.com/developers/docs/ruby/decisions-api/decision-status .
456
+ #
457
+ # ==== Parameters
458
+ #
459
+ # order_id::
460
+ # The ID of an order.
461
+ #
462
+ # opts (optional)::
463
+ # A Hash of optional parameters for this request --
464
+ #
465
+ # :account_id::
466
+ # Overrides the API key for this call.
467
+ #
468
+ # :api_key::
469
+ # Overrides the API key for this call.
470
+ #
471
+ # :timeout::
472
+ # Overrides the timeout (in seconds) for this call.
473
+ #
474
+ def get_order_decisions(order_id, opts = {})
475
+ account_id = opts[:account_id] || @account_id
476
+ api_key = opts[:api_key] || @api_key
477
+ timeout = opts[:timeout] || @timeout
478
+
479
+ options = {
480
+ :headers => { "User-Agent" => user_agent },
481
+ :basic_auth => { :username => api_key, :password => "" }
482
+ }
483
+ options.merge!(:timeout => timeout) unless timeout.nil?
484
+
485
+ uri = API3_ENDPOINT + Sift.order_decisions_api_path(account_id, order_id)
486
+ response = self.class.get(uri, options)
487
+ Response.new(response.body, response.code, response.response)
488
+ end
489
+
490
+
249
491
  private
250
- # def add_query_parameter(query_parameter)
251
- # uri = URI.parse(API_ENDPOINT)
252
- # end
492
+
253
493
  def delete_nils(properties)
254
494
  properties.delete_if do |k, v|
255
495
  case v