sift 2.2.1 → 3.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 +4 -4
- data/HISTORY +6 -0
- data/README.md +15 -2
- data/lib/sift.rb +5 -0
- data/lib/sift/client.rb +43 -2
- data/lib/sift/client/decision/apply_to.rb +7 -0
- data/lib/sift/validate/decision.rb +6 -0
- data/lib/sift/version.rb +2 -2
- data/spec/unit/client_label_spec.rb +2 -2
- data/spec/unit/client_spec.rb +22 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbaf2000cc0d9083f104b38c5e04ca271cc2cd9c
|
4
|
+
data.tar.gz: c90f468af4bdfdf91a04b22faaa0ec7eb637fd29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb51191b838c93928607ef420f8ffd5588bf1de49f3e2f5e6ade15b9ce3e9d4a8d4b043b62605716cd452f261f4d39a48aacc33938d8a97c0c41a18ebc243482
|
7
|
+
data.tar.gz: 57fcde0d67394bacc175815dc12c60edf25782f75baad7174acc8bcded6d1d63a277aad4df2c1d7bceab2bcadbb7f520c772cad3c7be5c57c267dcff049ca059
|
data/HISTORY
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
=== 3.0.0.0 2018-03-05
|
2
|
+
* adds support for v205 of Sift Science's APIs
|
3
|
+
* v205 APIs are now called by default -- this is an incompatible change
|
4
|
+
(use :version => 204 to call the previous API version)
|
5
|
+
* Add content level decisions in Apply Decisions APIs.
|
6
|
+
|
1
7
|
=== 2.2.1.0 2018-02-12
|
2
8
|
* Add session level decisions in Apply Decisions APIs.
|
3
9
|
|
data/README.md
CHANGED
@@ -140,7 +140,7 @@ response = client.apply_decision({
|
|
140
140
|
user_id: "john@example.com"
|
141
141
|
})
|
142
142
|
|
143
|
-
# apply decision to "
|
143
|
+
# apply decision to "john@example.com"'s order
|
144
144
|
response = client.apply_decision({
|
145
145
|
decision_id: "block_bad_order",
|
146
146
|
source: "manual_review",
|
@@ -149,7 +149,7 @@ response = client.apply_decision({
|
|
149
149
|
order_id: "ORDER_1234"
|
150
150
|
})
|
151
151
|
|
152
|
-
# apply decision to "
|
152
|
+
# apply decision to "john@example.com"'s session
|
153
153
|
response = client.apply_decision({
|
154
154
|
decision_id: "block_bad_session",
|
155
155
|
source: "manual_review",
|
@@ -158,6 +158,16 @@ response = client.apply_decision({
|
|
158
158
|
session_id: "SESSION_ID_1234"
|
159
159
|
})
|
160
160
|
|
161
|
+
# apply decision to "john@example.com"'s content
|
162
|
+
response = client.apply_decision({
|
163
|
+
decision_id: "block_bad_session",
|
164
|
+
source: "manual_review",
|
165
|
+
analyst: "bob@your_company.com",
|
166
|
+
user_id: "john@example.com",
|
167
|
+
content_id: "CONTENT_ID_1234"
|
168
|
+
})
|
169
|
+
|
170
|
+
|
161
171
|
# Make sure you handle the response after applying a decision:
|
162
172
|
|
163
173
|
if response.ok?
|
@@ -196,6 +206,9 @@ response = client.get_user_decisions('example_user_id')
|
|
196
206
|
|
197
207
|
# Get the latest decisions for an order
|
198
208
|
response = client.get_order_decisions('example_order_id')
|
209
|
+
|
210
|
+
# Get the latest decisions for an content
|
211
|
+
response = client.get_content_decisions('example_user_id', 'example_order_id')
|
199
212
|
```
|
200
213
|
|
201
214
|
## Response Object
|
data/lib/sift.rb
CHANGED
@@ -33,6 +33,11 @@ module Sift
|
|
33
33
|
"/v3/accounts/#{account_id}/orders/#{order_id}/decisions"
|
34
34
|
end
|
35
35
|
|
36
|
+
# Returns the path for Content Decisions API
|
37
|
+
def self.content_decisions_api_path(account_id, user_id, content_id)
|
38
|
+
"/v3/accounts/#{account_id}/users/#{user_id}/content/#{content_id}/decisions"
|
39
|
+
end
|
40
|
+
|
36
41
|
# Module-scoped public API key
|
37
42
|
class << self
|
38
43
|
attr_accessor :api_key
|
data/lib/sift/client.rb
CHANGED
@@ -118,7 +118,7 @@ module Sift
|
|
118
118
|
#
|
119
119
|
# :version::
|
120
120
|
# The version of the Events API, Score API, and Labels API to call.
|
121
|
-
# By default, version
|
121
|
+
# By default, version 205.
|
122
122
|
#
|
123
123
|
# :path::
|
124
124
|
# The URL path to use for Events API path. By default, the
|
@@ -132,7 +132,7 @@ module Sift
|
|
132
132
|
@timeout = opts[:timeout] || 2 # 2-second timeout by default
|
133
133
|
@path = opts[:path] || Sift.rest_api_path(@version)
|
134
134
|
|
135
|
-
raise("api_key
|
135
|
+
raise("api_key") if !@api_key.is_a?(String) || @api_key.empty?
|
136
136
|
raise("path must be a non-empty string") if !@path.is_a?(String) || @path.empty?
|
137
137
|
end
|
138
138
|
|
@@ -504,6 +504,47 @@ module Sift
|
|
504
504
|
Response.new(response.body, response.code, response.response)
|
505
505
|
end
|
506
506
|
|
507
|
+
|
508
|
+
# Gets the decision status of a piece of content.
|
509
|
+
#
|
510
|
+
# See https://siftscience.com/developers/docs/ruby/decisions-api/decision-status .
|
511
|
+
#
|
512
|
+
# ==== Parameters
|
513
|
+
#
|
514
|
+
# user_id::
|
515
|
+
# The ID of the owner of the content.
|
516
|
+
#
|
517
|
+
# content_id::
|
518
|
+
# The ID of a piece of content.
|
519
|
+
#
|
520
|
+
# opts (optional)::
|
521
|
+
# A Hash of optional parameters for this request --
|
522
|
+
#
|
523
|
+
# :account_id::
|
524
|
+
# Overrides the API key for this call.
|
525
|
+
#
|
526
|
+
# :api_key::
|
527
|
+
# Overrides the API key for this call.
|
528
|
+
#
|
529
|
+
# :timeout::
|
530
|
+
# Overrides the timeout (in seconds) for this call.
|
531
|
+
#
|
532
|
+
def get_content_decisions(user_id, content_id, opts = {})
|
533
|
+
account_id = opts[:account_id] || @account_id
|
534
|
+
api_key = opts[:api_key] || @api_key
|
535
|
+
timeout = opts[:timeout] || @timeout
|
536
|
+
|
537
|
+
options = {
|
538
|
+
:headers => { "User-Agent" => user_agent },
|
539
|
+
:basic_auth => { :username => api_key, :password => "" }
|
540
|
+
}
|
541
|
+
options.merge!(:timeout => timeout) unless timeout.nil?
|
542
|
+
|
543
|
+
uri = API3_ENDPOINT + Sift.content_decisions_api_path(account_id, user_id, content_id)
|
544
|
+
response = self.class.get(uri, options)
|
545
|
+
Response.new(response.body, response.code, response.response)
|
546
|
+
end
|
547
|
+
|
507
548
|
def decisions(opts = {})
|
508
549
|
decision_instance.list(opts)
|
509
550
|
end
|
@@ -15,6 +15,7 @@ module Sift
|
|
15
15
|
description
|
16
16
|
order_id
|
17
17
|
session_id
|
18
|
+
content_id
|
18
19
|
user_id
|
19
20
|
account_id
|
20
21
|
time
|
@@ -93,11 +94,17 @@ module Sift
|
|
93
94
|
configs.has_key?("session_id") || configs.has_key?(:session_id)
|
94
95
|
end
|
95
96
|
|
97
|
+
def applying_to_content?
|
98
|
+
configs.has_key?("content_id") || configs.has_key?(:content_id)
|
99
|
+
end
|
100
|
+
|
96
101
|
def path
|
97
102
|
if applying_to_order?
|
98
103
|
"#{user_path}/orders/#{CGI.escape(order_id)}/decisions"
|
99
104
|
elsif applying_to_session?
|
100
105
|
"#{user_path}/sessions/#{CGI.escape(session_id)}/decisions"
|
106
|
+
elsif applying_to_content?
|
107
|
+
"#{user_path}/content/#{CGI.escape(content_id)}/decisions"
|
101
108
|
else
|
102
109
|
"#{user_path}/decisions"
|
103
110
|
end
|
data/lib/sift/version.rb
CHANGED
@@ -25,7 +25,7 @@ describe Sift::Client do
|
|
25
25
|
response_json = { :status => 0, :error_message => "OK" }
|
26
26
|
user_id = "frodo_baggins"
|
27
27
|
|
28
|
-
stub_request(:post, "https://api.siftscience.com/
|
28
|
+
stub_request(:post, "https://api.siftscience.com/v205/users/frodo_baggins/labels")
|
29
29
|
.with(:body => ('{"$abuse_type":"content_abuse","$is_bad":true,"$description":"Listed a fake item","$type":"$label","$api_key":"foobar"}'))
|
30
30
|
.to_return(:body => MultiJson.dump(response_json), :status => 200,
|
31
31
|
:headers => {"content-type"=>"application/json; charset=UTF-8",
|
@@ -45,7 +45,7 @@ describe Sift::Client do
|
|
45
45
|
user_id = "frodo_baggins"
|
46
46
|
|
47
47
|
stub_request(:delete,
|
48
|
-
"https://api.siftscience.com/
|
48
|
+
"https://api.siftscience.com/v205/users/frodo_baggins/labels?api_key=foobar&abuse_type=payment_abuse")
|
49
49
|
.to_return(:status => 204)
|
50
50
|
|
51
51
|
api_key = "foobar"
|
data/spec/unit/client_spec.rb
CHANGED
@@ -169,7 +169,7 @@ describe Sift::Client do
|
|
169
169
|
it "Successfuly handles an event and returns OK" do
|
170
170
|
response_json = { :status => 0, :error_message => "OK" }
|
171
171
|
|
172
|
-
stub_request(:post, "https://api.siftscience.com/
|
172
|
+
stub_request(:post, "https://api.siftscience.com/v205/events").
|
173
173
|
with { |request|
|
174
174
|
parsed_body = JSON.parse(request.body)
|
175
175
|
expect(parsed_body).to include("$buyer_user_id" => "123456")
|
@@ -190,7 +190,7 @@ describe Sift::Client do
|
|
190
190
|
|
191
191
|
it "Successfully submits event with overridden key" do
|
192
192
|
response_json = { :status => 0, :error_message => "OK"}
|
193
|
-
stub_request(:post, "https://api.siftscience.com/
|
193
|
+
stub_request(:post, "https://api.siftscience.com/v205/events").
|
194
194
|
with { | request|
|
195
195
|
parsed_body = JSON.parse(request.body)
|
196
196
|
expect(parsed_body).to include("$buyer_user_id" => "123456")
|
@@ -212,7 +212,7 @@ describe Sift::Client do
|
|
212
212
|
it "Successfully scrubs nils" do
|
213
213
|
response_json = { :status => 0, :error_message => "OK" }
|
214
214
|
|
215
|
-
stub_request(:post, "https://api.siftscience.com/
|
215
|
+
stub_request(:post, "https://api.siftscience.com/v205/events")
|
216
216
|
.with { |request|
|
217
217
|
parsed_body = JSON.parse(request.body)
|
218
218
|
expect(parsed_body).not_to include("fake_property")
|
@@ -241,7 +241,7 @@ describe Sift::Client do
|
|
241
241
|
api_key = "foobar"
|
242
242
|
response_json = score_response_json
|
243
243
|
|
244
|
-
stub_request(:get, "https://api.siftscience.com/
|
244
|
+
stub_request(:get, "https://api.siftscience.com/v205/score/247019/?api_key=foobar")
|
245
245
|
.to_return(:status => 200, :body => MultiJson.dump(response_json),
|
246
246
|
:headers => {"content-type"=>"application/json; charset=UTF-8",
|
247
247
|
"content-length"=> "74"})
|
@@ -259,7 +259,7 @@ describe Sift::Client do
|
|
259
259
|
api_key = "foobar"
|
260
260
|
response_json = score_response_json
|
261
261
|
|
262
|
-
stub_request(:get, "https://api.siftscience.com/
|
262
|
+
stub_request(:get, "https://api.siftscience.com/v205/score/247019/?api_key=overridden")
|
263
263
|
.to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})
|
264
264
|
|
265
265
|
response = Sift::Client.new(:api_key => api_key)
|
@@ -280,7 +280,7 @@ describe Sift::Client do
|
|
280
280
|
:score_response => score_response_json
|
281
281
|
}
|
282
282
|
|
283
|
-
stub_request(:post, "https://api.siftscience.com/
|
283
|
+
stub_request(:post, "https://api.siftscience.com/v205/events?return_score=true")
|
284
284
|
.to_return(:status => 200, :body => MultiJson.dump(response_json),
|
285
285
|
:headers => {"content-type"=>"application/json; charset=UTF-8",
|
286
286
|
"content-length"=> "74"})
|
@@ -304,7 +304,7 @@ describe Sift::Client do
|
|
304
304
|
:score_response => action_response_json
|
305
305
|
}
|
306
306
|
|
307
|
-
stub_request(:post, "https://api.siftscience.com/
|
307
|
+
stub_request(:post, "https://api.siftscience.com/v205/events?return_action=true")
|
308
308
|
.to_return(:status => 200, :body => MultiJson.dump(response_json),
|
309
309
|
:headers => {"content-type"=>"application/json; charset=UTF-8",
|
310
310
|
"content-length"=> "74"})
|
@@ -332,7 +332,7 @@ describe Sift::Client do
|
|
332
332
|
}
|
333
333
|
|
334
334
|
stub_request(:post,
|
335
|
-
"https://api.siftscience.com/
|
335
|
+
"https://api.siftscience.com/v205/events?return_workflow_status=true&abuse_types=legacy,payment_abuse")
|
336
336
|
.to_return(:status => 200, :body => MultiJson.dump(response_json),
|
337
337
|
:headers => {"content-type"=>"application/json; charset=UTF-8",
|
338
338
|
"content-length"=> "74"})
|
@@ -390,4 +390,18 @@ describe Sift::Client do
|
|
390
390
|
expect(response.body["decisions"]["payment_abuse"]["decision"]["id"]).to eq("decision7")
|
391
391
|
end
|
392
392
|
|
393
|
+
|
394
|
+
it "Successfully make an content decisions request" do
|
395
|
+
response_text = '{"decisions":{"content_abuse":{"decision":{"id":"decision7"},"time":1468599638005,"webhook_succeeded":false}}}'
|
396
|
+
|
397
|
+
stub_request(:get, "https://foobar:@api3.siftscience.com/v3/accounts/ACCT/users/USER/content/example_content/decisions")
|
398
|
+
.to_return(:status => 200, :body => response_text, :headers => {})
|
399
|
+
|
400
|
+
client = Sift::Client.new(:api_key => "foobar", :account_id => "ACCT")
|
401
|
+
response = client.get_content_decisions("USER", "example_content", :timeout => 3)
|
402
|
+
|
403
|
+
expect(response.ok?).to eq(true)
|
404
|
+
expect(response.body["decisions"]["content_abuse"]["decision"]["id"]).to eq("decision7")
|
405
|
+
end
|
406
|
+
|
393
407
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sift
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Sadaghiani
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2018-
|
13
|
+
date: 2018-04-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|