Class: Api::ReviewsIo::Client

Inherits:
Object
  • Object
show all
Defined in:
app/services/api/reviews_io/client.rb

Overview

Thin HTTP client for interacting with the Reviews.io API.
rubocop:disable Metrics/ClassLength

Defined Under Namespace

Classes: Error, MissingCredentialsError

Constant Summary collapse

INVITATION_PATH =
'/invitation'
PRODUCT_RATING_BATCH_PATH =
'/product/rating-batch'
REVIEWS_PATH =
'/reviews'
MERCHANT_REVIEWS_PATH =
'/merchant/reviews'
DEFAULT_TIMEOUT =

seconds

15

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(store_id: nil, api_key: nil, base_url: nil, http: nil, logger: Rails.logger) ⇒ Client

Returns a new instance of Client.



19
20
21
22
23
24
25
26
27
# File 'app/services/api/reviews_io/client.rb', line 19

def initialize(store_id: nil, api_key: nil, base_url: nil, http: nil, logger: Rails.logger)
  @logger = logger
  @store_id = store_id || env_or_config(:store_id)
  @api_key = api_key || env_or_config(:api_key)
  @base_url = base_url || env_or_config(:api_url)
  @http = http || default_http_client

  validate_credentials!
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



17
18
19
# File 'app/services/api/reviews_io/client.rb', line 17

def api_key
  @api_key
end

#base_urlObject (readonly)

Returns the value of attribute base_url.



17
18
19
# File 'app/services/api/reviews_io/client.rb', line 17

def base_url
  @base_url
end

#httpObject (readonly)

Returns the value of attribute http.



17
18
19
# File 'app/services/api/reviews_io/client.rb', line 17

def http
  @http
end

#loggerObject (readonly)

Returns the value of attribute logger.



17
18
19
# File 'app/services/api/reviews_io/client.rb', line 17

def logger
  @logger
end

#store_idObject (readonly)

Returns the value of attribute store_id.



17
18
19
# File 'app/services/api/reviews_io/client.rb', line 17

def store_id
  @store_id
end

Instance Method Details

#fetch_product_ratings(skus) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'app/services/api/reviews_io/client.rb', line 38

def fetch_product_ratings(skus)
  normalized_skus = normalize_skus(skus)
  return {} if normalized_skus.empty?

  response = perform_rating_request(normalized_skus)
  log_debug("Reviews.io rating response: status=#{response.status}, body=#{safe_body(response)}")
  ensure_success!(response)
  parse_response(response)
rescue HTTP::Error => e
  raise Error, "Reviews.io request failed: #{e.message}"
rescue JSON::ParserError => e
  raise Error, "Reviews.io response parse failed: #{e.message}"
end

#fetch_reviews_by_email(email, options = {}) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'app/services/api/reviews_io/client.rb', line 62

def fetch_reviews_by_email(email, options = {})
  raise ArgumentError, 'Email is required' if email.blank?
  raise MissingCredentialsError, 'API key is required for email filtering' if api_key.blank?

  query = reviews_query_params(options).merge(
    store: store_id,
    email: email.strip,
    apikey: api_key
  )

  response = http.headers(rating_headers).get(reviews_url, params: query)
  log_debug("Reviews.io reviews by email response: status=#{response.status}, body=#{safe_body(response)}")
  ensure_success!(response)

  parsed = parse_response(response)
  parsed.is_a?(Hash) ? parsed : { 'data' => parsed }
rescue HTTP::Error => e
  raise Error, "Reviews.io request failed: #{e.message}"
rescue JSON::ParserError => e
  raise Error, "Reviews.io response parse failed: #{e.message}"
end

#fetch_reviews_by_tag(tag, options = {}) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'app/services/api/reviews_io/client.rb', line 84

def fetch_reviews_by_tag(tag, options = {})
  raise ArgumentError, 'Tag is required' if tag.blank?

  query = reviews_query_params(options).merge(
    store: store_id,
    tag: tag.strip,
    apikey: api_key
  )

  response = http.headers(rating_headers).get(reviews_url, params: query)
  log_debug("Reviews.io reviews by tag response: status=#{response.status}, body=#{safe_body(response)}")
  ensure_success!(response)

  parsed = parse_response(response)
  parsed.is_a?(Hash) ? parsed : { 'data' => parsed }
rescue HTTP::Error => e
  raise Error, "Reviews.io request failed: #{e.message}"
rescue JSON::ParserError => e
  raise Error, "Reviews.io response parse failed: #{e.message}"
end

#fetch_reviews_for_sku(sku, options = {}) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'app/services/api/reviews_io/client.rb', line 52

def fetch_reviews_for_sku(sku, options = {})
  normalized_sku = normalize_review_sku(sku)
  response = perform_reviews_request(normalized_sku, options)
  build_reviews_payload(response, normalized_sku)
rescue HTTP::Error => e
  raise Error, "Reviews.io request failed: #{e.message}"
rescue JSON::ParserError => e
  raise Error, "Reviews.io response parse failed: #{e.message}"
end

#queue_invitation(payload) ⇒ Object



29
30
31
32
33
34
35
36
# File 'app/services/api/reviews_io/client.rb', line 29

def queue_invitation(payload)
  response = http.headers(default_headers)
                 .post(invitation_url, json: payload)
  log_debug("Reviews.io invitation response: status=#{response.status}, body=#{safe_body(response)}")
  response
rescue HTTP::Error => e
  raise Error, "Reviews.io request failed: #{e.message}"
end