sift 2.2.1 → 3.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
2
  SHA1:
3
- metadata.gz: e4c2e3042d8ff485909a45e093bfe1f1145e8f28
4
- data.tar.gz: 57c0c4e3bb6cfdfe26cb5907717581d4ba8d3e25
3
+ metadata.gz: cbaf2000cc0d9083f104b38c5e04ca271cc2cd9c
4
+ data.tar.gz: c90f468af4bdfdf91a04b22faaa0ec7eb637fd29
5
5
  SHA512:
6
- metadata.gz: 8f81535b358bab94f1156197e54612f3e8c81210dbbe38a45e68309eb3327bfc9c6ac164921fcece99059577ded9b6431f65caae9016513c00dfb512e4e76d3a
7
- data.tar.gz: 063f7691c9f6f99f241db47f837135dd0e32fcb1d65d5c35aea1aece78effb4fa6fdfbdb97d758d2b9d6fb8905837f030bfd7b56b5c1ab942f7787bb1ef73a9f
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 "bob@example.com"'s order
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 "bob@example.com"'s session
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
@@ -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
@@ -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 204.
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 must be a non-empty string") if !@api_key.is_a?(String) || @api_key.empty?
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
@@ -20,6 +20,12 @@ module Sift
20
20
  validate_key(:non_empty_string, :user_id, :session_id)
21
21
  end
22
22
  end
23
+
24
+ def valid_content?
25
+ run do
26
+ validate_key(:non_empty_string, :user_id, :content_id)
27
+ end
28
+ end
23
29
 
24
30
  def valid_user?
25
31
  run do
@@ -1,4 +1,4 @@
1
1
  module Sift
2
- VERSION = "2.2.1"
3
- API_VERSION = "204"
2
+ VERSION = "3.0.0"
3
+ API_VERSION = "205"
4
4
  end
@@ -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/v204/users/frodo_baggins/labels")
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/v204/users/frodo_baggins/labels?api_key=foobar&abuse_type=payment_abuse")
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"
@@ -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/v204/events").
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/v204/events").
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/v204/events")
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/v204/score/247019/?api_key=foobar")
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/v204/score/247019/?api_key=overridden")
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/v204/events?return_score=true")
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/v204/events?return_action=true")
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/v204/events?return_workflow_status=true&abuse_types=legacy,payment_abuse")
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: 2.2.1
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-02-15 00:00:00.000000000 Z
13
+ date: 2018-04-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec