22require "multi_json"
33require "base64"
44
5- require_relative "./client/decision"
6- require_relative "./error"
7-
85module Sift
96
107 # Represents the payload returned from a call through the track API
@@ -94,17 +91,36 @@ class Client
9491 API_ENDPOINT = ENV [ "SIFT_RUBY_API_URL" ] || 'https://api.siftscience.com'
9592 API3_ENDPOINT = ENV [ "SIFT_RUBY_API3_URL" ] || 'https://api3.siftscience.com'
9693
94+ # Maintain backward compatibility for users who may rely on HTTParty methods
9795 include HTTParty
9896 base_uri API_ENDPOINT
9997
10098 attr_reader :api_key , :account_id
10199
102- def self . build_auth_header ( api_key )
103- { "Authorization" => "Basic #{ Base64 . encode64 ( api_key ) } " }
104- end
100+ class << self
101+ def build_auth_header ( api_key )
102+ { "Authorization" => "Basic #{ Base64 . strict_encode64 ( api_key + ":" ) } " }
103+ end
104+
105+ def user_agent
106+ "sift-ruby/#{ VERSION } "
107+ end
108+
109+ # Factory methods for internal API executors that inherit from the current class context.
110+ # This ensures that subclasses of Client propagate their HTTParty configuration
111+ # to these internal clients.
105112
106- def self . user_agent
107- "sift-ruby/#{ VERSION } "
113+ def api_client
114+ @api_client ||= Class . new ( self ) do
115+ base_uri API_ENDPOINT
116+ end
117+ end
118+
119+ def api3_client
120+ @api3_client ||= Class . new ( self ) do
121+ base_uri API3_ENDPOINT
122+ end
123+ end
108124 end
109125
110126 # Constructor
@@ -256,7 +272,7 @@ def track(event, properties = {}, opts = {})
256272 }
257273 options . merge! ( :timeout => timeout ) unless timeout . nil?
258274
259- response = self . class . post ( path , options )
275+ response = self . class . api_client . post ( path , options )
260276 Response . new ( response . body , response . code , response . response )
261277 end
262278
@@ -319,7 +335,7 @@ def score(user_id, opts = {})
319335 }
320336 options . merge! ( :timeout => timeout ) unless timeout . nil?
321337
322- response = self . class . get ( Sift . score_api_path ( user_id , version ) , options )
338+ response = self . class . api_client . get ( Sift . score_api_path ( user_id , version ) , options )
323339 Response . new ( response . body , response . code , response . response )
324340 end
325341
@@ -364,6 +380,7 @@ def get_user_score(user_id, opts = {})
364380 abuse_types = opts [ :abuse_types ]
365381 api_key = opts [ :api_key ] || @api_key
366382 timeout = opts [ :timeout ] || @timeout
383+ version = opts [ :version ] || @version
367384 include_score_percentiles = opts [ :include_score_percentiles ]
368385
369386 raise ( "user_id must be a non-empty string" ) if ( !user_id . is_a? String ) || user_id . to_s . empty?
@@ -382,7 +399,7 @@ def get_user_score(user_id, opts = {})
382399 }
383400 options . merge! ( :timeout => timeout ) unless timeout . nil?
384401
385- response = self . class . get ( Sift . user_score_api_path ( user_id , @ version) , options )
402+ response = self . class . api_client . get ( Sift . user_score_api_path ( user_id , version ) , options )
386403 Response . new ( response . body , response . code , response . response )
387404 end
388405
@@ -420,6 +437,7 @@ def rescore_user(user_id, opts = {})
420437 abuse_types = opts [ :abuse_types ]
421438 api_key = opts [ :api_key ] || @api_key
422439 timeout = opts [ :timeout ] || @timeout
440+ version = opts [ :version ] || @version
423441
424442 raise ( "user_id must be a non-empty string" ) if ( !user_id . is_a? String ) || user_id . to_s . empty?
425443 raise ( "Bad api_key parameter" ) if api_key . empty?
@@ -434,7 +452,7 @@ def rescore_user(user_id, opts = {})
434452 }
435453 options . merge! ( :timeout => timeout ) unless timeout . nil?
436454
437- response = self . class . post ( Sift . user_score_api_path ( user_id , @ version) , options )
455+ response = self . class . api_client . post ( Sift . user_score_api_path ( user_id , version ) , options )
438456 Response . new ( response . body , response . code , response . response )
439457 end
440458
@@ -532,7 +550,7 @@ def unlabel(user_id, opts = {})
532550 }
533551 options . merge! ( :timeout => timeout ) unless timeout . nil?
534552
535- response = self . class . delete ( Sift . users_label_api_path ( user_id , version ) , options )
553+ response = self . class . api_client . delete ( Sift . users_label_api_path ( user_id , version ) , options )
536554 Response . new ( response . body , response . code , response . response )
537555 end
538556
@@ -569,8 +587,7 @@ def get_workflow_status(run_id, opts = {})
569587 }
570588 options . merge! ( :timeout => timeout ) unless timeout . nil?
571589
572- uri = API3_ENDPOINT + Sift . workflow_status_path ( account_id , run_id )
573- response = self . class . get ( uri , options )
590+ response = self . class . api3_client . get ( Sift . workflow_status_path ( account_id , run_id ) , options )
574591 Response . new ( response . body , response . code , response . response )
575592 end
576593
@@ -607,8 +624,7 @@ def get_user_decisions(user_id, opts = {})
607624 }
608625 options . merge! ( :timeout => timeout ) unless timeout . nil?
609626
610- uri = API3_ENDPOINT + Sift . user_decisions_api_path ( account_id , user_id )
611- response = self . class . get ( uri , options )
627+ response = self . class . api3_client . get ( Sift . user_decisions_api_path ( account_id , user_id ) , options )
612628 Response . new ( response . body , response . code , response . response )
613629 end
614630
@@ -645,8 +661,7 @@ def get_order_decisions(order_id, opts = {})
645661 }
646662 options . merge! ( :timeout => timeout ) unless timeout . nil?
647663
648- uri = API3_ENDPOINT + Sift . order_decisions_api_path ( account_id , order_id )
649- response = self . class . get ( uri , options )
664+ response = self . class . api3_client . get ( Sift . order_decisions_api_path ( account_id , order_id ) , options )
650665 Response . new ( response . body , response . code , response . response )
651666 end
652667
@@ -685,8 +700,7 @@ def get_session_decisions(user_id, session_id, opts = {})
685700 }
686701 options . merge! ( :timeout => timeout ) unless timeout . nil?
687702
688- uri = API3_ENDPOINT + Sift . session_decisions_api_path ( account_id , user_id , session_id )
689- response = self . class . get ( uri , options )
703+ response = self . class . api3_client . get ( Sift . session_decisions_api_path ( account_id , user_id , session_id ) , options )
690704 Response . new ( response . body , response . code , response . response )
691705 end
692706
@@ -725,8 +739,7 @@ def get_content_decisions(user_id, content_id, opts = {})
725739 }
726740 options . merge! ( :timeout => timeout ) unless timeout . nil?
727741
728- uri = API3_ENDPOINT + Sift . content_decisions_api_path ( account_id , user_id , content_id )
729- response = self . class . get ( uri , options )
742+ response = self . class . api3_client . get ( Sift . content_decisions_api_path ( account_id , user_id , content_id ) , options )
730743 Response . new ( response . body , response . code , response . response )
731744 end
732745
@@ -748,7 +761,7 @@ def apply_decision!(configs = {})
748761
749762 def build_default_headers_post ( api_key )
750763 {
751- "Authorization" => "Basic #{ Base64 . encode64 ( api_key +":" ) } " ,
764+ "Authorization" => "Basic #{ Base64 . strict_encode64 ( api_key +":" ) } " ,
752765 "User-Agent" => "SiftScience/v#{ @version } sift-ruby/#{ VERSION } " ,
753766 "Content-Type" => "application/json"
754767 }
@@ -768,7 +781,7 @@ def verification_send(properties = {}, opts = {})
768781 :headers => build_default_headers_post ( api_key )
769782 }
770783 options . merge! ( :timeout => timeout ) unless timeout . nil?
771- response = self . class . post ( Sift . verification_api_send_path ( @ version) , options )
784+ response = self . class . api_client . post ( Sift . verification_api_send_path ( version ) , options )
772785 Response . new ( response . body , response . code , response . response )
773786 end
774787
@@ -787,7 +800,7 @@ def verification_resend(properties = {}, opts = {})
787800 }
788801 options . merge! ( :timeout => timeout ) unless timeout . nil?
789802
790- response = self . class . post ( Sift . verification_api_resend_path ( @ version) , options )
803+ response = self . class . api_client . post ( Sift . verification_api_resend_path ( version ) , options )
791804 Response . new ( response . body , response . code , response . response )
792805 end
793806
@@ -806,7 +819,7 @@ def verification_check(properties = {}, opts = {})
806819 }
807820 options . merge! ( :timeout => timeout ) unless timeout . nil?
808821
809- response = self . class . post ( Sift . verification_api_check_path ( @ version) , options )
822+ response = self . class . api_client . post ( Sift . verification_api_check_path ( version ) , options )
810823 Response . new ( response . body , response . code , response . response )
811824 end
812825
@@ -831,7 +844,7 @@ def create_psp_merchant_profile(properties = {}, opts = {})
831844 :basic_auth => { :username => api_key , :password => "" }
832845 }
833846 options . merge! ( :timeout => timeout ) unless timeout . nil?
834- response = self . class . post ( API_ENDPOINT + Sift . psp_merchant_api_path ( account_id ) , options )
847+ response = self . class . api_client . post ( Sift . psp_merchant_api_path ( account_id ) , options )
835848 Response . new ( response . body , response . code , response . response )
836849 end
837850
@@ -858,7 +871,7 @@ def update_psp_merchant_profile(merchant_id, properties = {}, opts = {})
858871 :basic_auth => { :username => api_key , :password => "" }
859872 }
860873 options . merge! ( :timeout => timeout ) unless timeout . nil?
861- response = self . class . put ( API_ENDPOINT + Sift . psp_merchant_id_api_path ( account_id , merchant_id ) , options )
874+ response = self . class . api_client . put ( Sift . psp_merchant_id_api_path ( account_id , merchant_id ) , options )
862875 Response . new ( response . body , response . code , response . response )
863876 end
864877
@@ -882,7 +895,7 @@ def get_a_psp_merchant_profile(merchant_id, opts = {})
882895 :basic_auth => { :username => api_key , :password => "" }
883896 }
884897 options . merge! ( :timeout => timeout ) unless timeout . nil?
885- response = self . class . get ( API_ENDPOINT + Sift . psp_merchant_id_api_path ( account_id , merchant_id ) , options )
898+ response = self . class . api_client . get ( Sift . psp_merchant_id_api_path ( account_id , merchant_id ) , options )
886899 Response . new ( response . body , response . code , response . response )
887900 end
888901
@@ -911,7 +924,7 @@ def get_psp_merchant_profiles(batch_size = nil, batch_token = nil, opts = {})
911924 :query => query
912925 }
913926 options . merge! ( :timeout => timeout ) unless timeout . nil?
914- response = self . class . get ( API_ENDPOINT + Sift . psp_merchant_api_path ( account_id ) , options )
927+ response = self . class . api_client . get ( Sift . psp_merchant_api_path ( account_id ) , options )
915928 Response . new ( response . body , response . code , response . response )
916929 end
917930
@@ -926,7 +939,7 @@ def handle_response(response)
926939 end
927940
928941 def decision_instance
929- @decision_instance ||= Decision . new ( api_key , account_id )
942+ @decision_instance ||= Decision . new ( api_key , account_id , self . class )
930943 end
931944
932945 def delete_nils ( properties )
@@ -943,4 +956,8 @@ def delete_nils(properties)
943956 end
944957 end
945958 end
959+
960+ require_relative "./client/decision"
961+ require_relative "./error"
962+
946963end
0 commit comments