Class: Sift::Client

Inherits:
Object
  • Object
show all
Includes:
HTTParty
Defined in:
lib/sift/client.rb,
lib/sift/client/decision.rb,
lib/sift/client/decision/apply_to.rb

Overview

This class wraps accesses through the API

Defined Under Namespace

Classes: Decision

Constant Summary collapse

API_ENDPOINT =
ENV["SIFT_RUBY_API_URL"] || 'https://api.siftscience.com'
API3_ENDPOINT =
ENV["SIFT_RUBY_API3_URL"] || 'https://api3.siftscience.com'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Client

Constructor

Parameters:

opts (optional)

A Hash of optional parameters for this Client –

:api_key

The Sift Science API key associated with your account. Sift.api_key is used if this parameter is not set.

:account_id

The ID of your Sift Science account. Sift.account_id is used if this parameter is not set.

:timeout

The number of seconds to wait before failing a request. By default this is configured to 2 seconds.

:version

The version of the Events API, Score API, and Labels API to call. By default, version 205.

:path

The URL path to use for Events API path. By default, the official path of the specified-version of the Events API.



138
139
140
141
142
143
144
145
146
147
# File 'lib/sift/client.rb', line 138

def initialize(opts = {})
  @api_key = opts[:api_key] || Sift.api_key
  @account_id = opts[:account_id] || Sift.
  @version = opts[:version] || API_VERSION
  @timeout = opts[:timeout] || 2  # 2-second timeout by default
  @path = opts[:path] || Sift.rest_api_path(@version)

  raise("api_key") if !@api_key.is_a?(String) || @api_key.empty?
  raise("path must be a non-empty string") if !@path.is_a?(String) || @path.empty?
end

Instance Attribute Details

#account_idObject (readonly)

Returns the value of attribute account_id.



100
101
102
# File 'lib/sift/client.rb', line 100

def 
  @account_id
end

#api_keyObject (readonly)

Returns the value of attribute api_key.



100
101
102
# File 'lib/sift/client.rb', line 100

def api_key
  @api_key
end

Class Method Details

.build_auth_header(api_key) ⇒ Object



102
103
104
# File 'lib/sift/client.rb', line 102

def self.build_auth_header(api_key)
  { "Authorization" => "Basic #{Base64.encode64(api_key)}" }
end

.user_agentObject



106
107
108
# File 'lib/sift/client.rb', line 106

def self.user_agent
  "sift-ruby/#{VERSION}"
end

Instance Method Details

#apply_decision(configs = {}) ⇒ Object



715
716
717
# File 'lib/sift/client.rb', line 715

def apply_decision(configs = {})
  decision_instance.apply_to(configs)
end

#apply_decision!(configs = {}) ⇒ Object



719
720
721
# File 'lib/sift/client.rb', line 719

def apply_decision!(configs = {})
  handle_response(apply_decision(configs))
end

#build_default_headers_post(api_key) ⇒ Object



723
724
725
726
727
728
729
# File 'lib/sift/client.rb', line 723

def build_default_headers_post(api_key)
  {
    "Authorization" => "Basic #{Base64.encode64(api_key+":")}",
    "User-Agent" => "SiftScience/v#{@version} sift-ruby/#{VERSION}",
    "Content-Type" => "application/json"
  }
end

#decisions(opts = {}) ⇒ Object



707
708
709
# File 'lib/sift/client.rb', line 707

def decisions(opts = {})
  decision_instance.list(opts)
end

#decisions!(opts = {}) ⇒ Object



711
712
713
# File 'lib/sift/client.rb', line 711

def decisions!(opts = {})
  handle_response(decisions(opts))
end

#get_content_decisions(user_id, content_id, opts = {}) ⇒ Object

Gets the decision status of a piece of content.

See siftscience.com/developers/docs/ruby/decisions-api/decision-status .

Parameters

user_id

The ID of the owner of the content.

content_id

The ID of a piece of content.

opts (optional)

A Hash of optional parameters for this request –

:account_id

Overrides the API key for this call.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.



691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
# File 'lib/sift/client.rb', line 691

def get_content_decisions(user_id, content_id, opts = {})
   = opts[:account_id] || @account_id
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout

  options = {
    :headers => { "User-Agent" => user_agent },
    :basic_auth => { :username => api_key, :password => "" }
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  uri = API3_ENDPOINT + Sift.content_decisions_api_path(, user_id, content_id)
  response = self.class.get(uri, options)
  Response.new(response.body, response.code, response.response)
end

#get_order_decisions(order_id, opts = {}) ⇒ Object

Gets the decision status of an order.

See siftscience.com/developers/docs/ruby/decisions-api/decision-status .

Parameters

order_id

The ID of an order.

opts (optional)

A Hash of optional parameters for this request –

:account_id

Overrides the API key for this call.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.



611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
# File 'lib/sift/client.rb', line 611

def get_order_decisions(order_id, opts = {})
   = opts[:account_id] || @account_id
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout

  options = {
    :headers => { "User-Agent" => user_agent },
    :basic_auth => { :username => api_key, :password => "" }
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  uri = API3_ENDPOINT + Sift.order_decisions_api_path(, order_id)
  response = self.class.get(uri, options)
  Response.new(response.body, response.code, response.response)
end

#get_session_decisions(user_id, session_id, opts = {}) ⇒ Object

Gets the decision status of a session.

See siftscience.com/developers/docs/ruby/decisions-api/decision-status .

Parameters

user_id

The ID of the user in the session.

session_id

The ID of a session.

opts (optional)

A Hash of optional parameters for this request –

:account_id

Overrides the account id for this call.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.



651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
# File 'lib/sift/client.rb', line 651

def get_session_decisions(user_id, session_id, opts = {})
   = opts[:account_id] || @account_id
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout

  options = {
    :headers => { "User-Agent" => user_agent },
    :basic_auth => { :username => api_key, :password => "" }
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  uri = API3_ENDPOINT + Sift.session_decisions_api_path(, user_id, session_id)
  response = self.class.get(uri, options)
  Response.new(response.body, response.code, response.response)
end

#get_user_decisions(user_id, opts = {}) ⇒ Object

Gets the decision status of a user.

See siftscience.com/developers/docs/ruby/decisions-api/decision-status .

Parameters

user_id

The ID of user.

opts (optional)

A Hash of optional parameters for this request –

:account_id

Overrides the API key for this call.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.



573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
# File 'lib/sift/client.rb', line 573

def get_user_decisions(user_id, opts = {})
   = opts[:account_id] || @account_id
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout

  options = {
    :headers => { "User-Agent" => user_agent },
    :basic_auth => { :username => api_key, :password => "" }
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  uri = API3_ENDPOINT + Sift.user_decisions_api_path(, user_id)
  response = self.class.get(uri, options)
  Response.new(response.body, response.code, response.response)
end

#get_user_score(user_id, opts = {}) ⇒ Object

Fetches the latest score(s) computed for the specified user and abuse types.

As opposed to client.score() and client.rescore_user(), this *does not* compute a new score for the user; it simply fetches the latest score(s) which have computed. These scores may be arbitrarily old.

See siftscience.com/developers/docs/ruby/score-api/get-score for more details.

Parameters:

user_id

A user’s id. This id should be the same as the user_id used in event calls.

opts (optional)

A Hash of optional parameters for the request –

:abuse_types

List of abuse types, specifying for which abuse types a score should be returned. By default, a score is returned for every abuse type to which you are subscribed.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.

Returns:

A Response object containing a status code, status message, and, if successful, the user’s score(s).



341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/sift/client.rb', line 341

def get_user_score(user_id, opts = {})
  abuse_types = opts[:abuse_types]
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout

  raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
  raise("Bad api_key parameter") if api_key.empty?

  query = {}
  query["api_key"] = api_key
  query["abuse_types"] = abuse_types.join(",") if abuse_types

  options = {
    :headers => {"User-Agent" => user_agent},
    :query => query
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  response = self.class.get(Sift.user_score_api_path(user_id, @version), options)
  Response.new(response.body, response.code, response.response)
end

#get_workflow_status(run_id, opts = {}) ⇒ Object

Gets the status of a workflow run.

See siftscience.com/developers/docs/ruby/workflows-api/workflow-status .

Parameters

run_id

The ID of a workflow run.

opts (optional)

A Hash of optional parameters for this request –

:account_id

Overrides the API key for this call.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.



535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
# File 'lib/sift/client.rb', line 535

def get_workflow_status(run_id, opts = {})
   = opts[:account_id] || @account_id
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout

  options = {
    :headers => { "User-Agent" => user_agent },
    :basic_auth => { :username => api_key, :password => "" }
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  uri = API3_ENDPOINT + Sift.workflow_status_path(, run_id)
  response = self.class.get(uri, options)
  Response.new(response.body, response.code, response.response)
end

#label(user_id, properties = {}, opts = {}) ⇒ Object

Labels a user.

See siftscience.com/developers/docs/ruby/labels-api/label-user .

Parameters:

user_id

A user’s id. This id should be the same as the user_id used in event calls.

properties

A hash of name-value pairs that specify the label attributes. This parameter must be specified.

opts (optional)

A Hash of optional parameters for the request –

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.

:version

Overrides the version of the Events API to call.

Returns:

In the case of a connection error (timeout, broken connection, etc.), this method returns nil; otherwise, a Response object is returned that captures the status message and status code.



448
449
450
451
452
453
454
455
456
457
458
# File 'lib/sift/client.rb', line 448

def label(user_id, properties = {}, opts = {})
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout
  version = opts[:version] || @version
  path = Sift.users_label_api_path(user_id, version)

  raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?

  track("$label", delete_nils(properties),
        :path => path, :api_key => api_key, :timeout => timeout)
end

#rescore_user(user_id, opts = {}) ⇒ Object

Rescores the specified user for the specified abuse types and returns the resulting score(s).

See siftscience.com/developers/docs/ruby/score-api/rescore for more details.

Parameters:

user_id

A user’s id. This id should be the same as the user_id used in event calls.

opts (optional)

A Hash of optional parameters for the request –

:abuse_types

List of abuse types, specifying for which abuse types a score should be returned. By default, a score is returned for every abuse type to which you are subscribed.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.

Returns:

A Response object containing a status code, status message, and, if successful, the user’s score(s).



393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/sift/client.rb', line 393

def rescore_user(user_id, opts = {})
  abuse_types = opts[:abuse_types]
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout

  raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
  raise("Bad api_key parameter") if api_key.empty?

  query = {}
  query["api_key"] = api_key
  query["abuse_types"] = abuse_types.join(",") if abuse_types

  options = {
    :headers => {"User-Agent" => user_agent},
    :query => query
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  response = self.class.post(Sift.user_score_api_path(user_id, @version), options)
  Response.new(response.body, response.code, response.response)
end

#score(user_id, opts = {}) ⇒ Object

Retrieves a user’s fraud score from the Sift Science API.

See siftscience.com/developers/docs/ruby/score-api/score-api .

Parameters:

user_id

A user’s id. This id should be the same as the user_id used in event calls.

opts (optional)

A Hash of optional parameters for the request –

:abuse_types

List of abuse types, specifying for which abuse types a score should be returned. By default, a score is returned for every abuse type to which you are subscribed.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.

:version

Overrides the version of the Events API to call.

Returns:

A Response object containing a status code, status message, and, if successful, the user’s score(s).



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/sift/client.rb', line 284

def score(user_id, opts = {})
  abuse_types = opts[:abuse_types]
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout
  version = opts[:version] || @version

  raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
  raise("Bad api_key parameter") if api_key.empty?

  query = {}
  query["api_key"] = api_key
  query["abuse_types"] = abuse_types.join(",") if abuse_types

  options = {
    :headers => {"User-Agent" => user_agent},
    :query => query
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  response = self.class.get(Sift.score_api_path(user_id, version), options)
  Response.new(response.body, response.code, response.response)
end

#track(event, properties = {}, opts = {}) ⇒ Object

Sends an event to the Sift Science Events API.

See siftscience.com/developers/docs/ruby/events-api .

Parameters:

event

The name of the event to send. This can be either a reserved event name, like $transaction or $label or a custom event name (that does not start with a $). This parameter must be specified.

properties

A hash of name-value pairs that specify the event-specific attributes to track. This parameter must be specified.

opts (optional)

A Hash of optional parameters for the request –

:return_score

If true, requests that the response include a score for this user, computed using the submitted event. See siftscience.com/developers/docs/ruby/score-api/synchronous-scores

:abuse_types

List of abuse types, specifying for which abuse types a score should be returned (if scoring was requested). By default, a score is returned for every abuse type to which you are subscribed.

:return_action

If true, requests that the response include any actions triggered as a result of the tracked event.

:return_workflow_status

If true, requests that the response include the status of any workflow run as a result of the tracked event. See siftscience.com/developers/docs/ruby/workflows-api/workflow-decisions

:timeout

Overrides the timeout (in seconds) for this call.

:api_key

Overrides the API key for this call.

:version

Overrides the version of the Events API to call.

:path

Overrides the URI path for this API call.

Returns:

In the case of a network error (timeout, broken connection, etc.), this method propagates the exception, otherwise, a Response object is returned that captures the status message and status code.



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/sift/client.rb', line 211

def track(event, properties = {}, opts = {})
  api_key = opts[:api_key] || @api_key
  version = opts[:version] || @version
  path = opts[:path] || (version && Sift.rest_api_path(version)) || @path
  timeout = opts[:timeout] || @timeout
  return_score = opts[:return_score]
  return_action = opts[:return_action]
  return_workflow_status = opts[:return_workflow_status]
  return_route_info = opts[:return_route_info]
  force_workflow_run = opts[:force_workflow_run]
  abuse_types = opts[:abuse_types]
  include_score_percentiles = opts[:include_score_percentiles]

  raise("event must be a non-empty string") if (!event.is_a? String) || event.empty?
  raise("properties cannot be empty") if properties.empty?
  raise("api_key cannot be empty") if api_key.empty?

  query = {}
  query["return_score"] = "true" if return_score
  query["return_action"] = "true" if return_action
  query["return_workflow_status"] = "true" if return_workflow_status
  query["return_route_info"] = "true" if return_route_info
  query["force_workflow_run"] = "true" if force_workflow_run
  query["abuse_types"] = abuse_types.join(",") if abuse_types
  if include_score_percentiles == "true"
    query["fields"] =  "SCORE_PERCENTILES"
  end

  options = {
    :body => MultiJson.dump(delete_nils(properties).merge({"$type" => event,
                                                           "$api_key" => api_key})),
    :headers => {"User-Agent" => user_agent},
    :query => query
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  response = self.class.post(path, options)
  Response.new(response.body, response.code, response.response)
end

#unlabel(user_id, opts = {}) ⇒ Object

Unlabels a user.

See siftscience.com/developers/docs/ruby/labels-api/unlabel-user .

Parameters:

user_id

A user’s id. This id should be the same as the user_id used in event calls.

opts (optional)

A Hash of optional parameters for this request –

:abuse_type

The abuse type for which the user should be unlabeled. If omitted, the user is unlabeled for all abuse types.

:api_key

Overrides the API key for this call.

:timeout

Overrides the timeout (in seconds) for this call.

:version

Overrides the version of the Events API to call.

Returns:

A Response object is returned with only an http code of 204.



491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'lib/sift/client.rb', line 491

def unlabel(user_id, opts = {})
  abuse_type = opts[:abuse_type]
  api_key = opts[:api_key] || @api_key
  timeout = opts[:timeout] || @timeout
  version = opts[:version] || @version

  raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?

  query = {}
  query[:api_key] = api_key
  query[:abuse_type] = abuse_type if abuse_type

  options = {
    :headers => {},
    :query => query
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  response = self.class.delete(Sift.users_label_api_path(user_id, version), options)
  Response.new(response.body, response.code, response.response)
end

#user_agentObject



149
150
151
# File 'lib/sift/client.rb', line 149

def user_agent
  "SiftScience/v#{@version} sift-ruby/#{VERSION}"
end

#verification_check(properties = {}, opts = {}) ⇒ Object



769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
# File 'lib/sift/client.rb', line 769

def verification_check(properties = {}, opts = {})
  api_key = opts[:api_key] || @api_key
  version = opts[:version] || @version
  timeout = opts[:timeout] || @timeout

  raise("properties cannot be empty") if properties.empty?
  raise("api_key cannot be empty") if api_key.empty?


  options = {
    :body => MultiJson.dump(delete_nils(properties)),
    :headers => build_default_headers_post(api_key)
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  response = self.class.post(Sift.verification_api_check_path(@version), options)
  Response.new(response.body, response.code, response.response)
end

#verification_resend(properties = {}, opts = {}) ⇒ Object



750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
# File 'lib/sift/client.rb', line 750

def verification_resend(properties = {}, opts = {})
  api_key = opts[:api_key] || @api_key
  version = opts[:version] || @version
  timeout = opts[:timeout] || @timeout

  raise("properties cannot be empty") if properties.empty?
  raise("api_key cannot be empty") if api_key.empty?


  options = {
    :body => MultiJson.dump(delete_nils(properties)),
    :headers => build_default_headers_post(api_key)
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  response = self.class.post(Sift.verification_api_resend_path(@version), options)
  Response.new(response.body, response.code, response.response)
end

#verification_send(properties = {}, opts = {}) ⇒ Object



731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
# File 'lib/sift/client.rb', line 731

def verification_send(properties = {}, opts = {})
  api_key = opts[:api_key] || @api_key
  version = opts[:version] || @version
  timeout = opts[:timeout] || @timeout

  raise("properties cannot be empty") if properties.empty?
  raise("api_key cannot be empty") if api_key.empty?


  options = {
    :body => MultiJson.dump(delete_nils(properties)),
    :headers => build_default_headers_post(api_key)
  }
  options.merge!(:timeout => timeout) unless timeout.nil?

  response = self.class.post(Sift.verification_api_send_path(@version), options)
  Response.new(response.body, response.code, response.response)
end