Class: ShopsavvyDataApi::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/shopsavvy_data_api/client.rb

Overview

Official Ruby client for ShopSavvy Data API

Provides access to product data, pricing information, and price history across thousands of retailers and millions of products.

Examples:

Basic usage

client = ShopsavvyDataApi::Client.new(api_key: "ss_live_your_api_key_here")
product = client.get_product_details("012345678901")
puts product.data[0].title

Using configuration

config = ShopsavvyDataApi::Configuration.new(
  api_key: "ss_live_your_api_key_here",
  timeout: 60
)
client = ShopsavvyDataApi::Client.new(config)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = nil, api_key: nil, base_url: nil, timeout: nil) ⇒ Client

Initialize a new client

Parameters:

  • config (Configuration, Hash) (defaults to: nil)

    Configuration object or hash with :api_key

  • api_key (String) (defaults to: nil)

    API key (alternative to config parameter)

  • base_url (String) (defaults to: nil)

    Base URL for API (default: api.shopsavvy.com/v1)

  • timeout (Integer) (defaults to: nil)

    Request timeout in seconds (default: 30)



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/shopsavvy_data_api/client.rb', line 33

def initialize(config = nil, api_key: nil, base_url: nil, timeout: nil)
  @config = if config.is_a?(Configuration)
              config
            elsif config.is_a?(Hash)
              Configuration.new(**config)
            elsif api_key
              Configuration.new(
                api_key: api_key,
                base_url: base_url || "https://api.shopsavvy.com/v1",
                timeout: timeout || 30
              )
            else
              raise ConfigurationError, "Either config or api_key must be provided"
            end

  @connection = build_connection
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



25
26
27
# File 'lib/shopsavvy_data_api/client.rb', line 25

def config
  @config
end

Instance Method Details

#batch_lookup(identifiers, include: nil) ⇒ Object

Look up multiple products at once (sync for <=20, async for >20)

Parameters:

  • identifiers (Array<String>)

    Product identifiers (max 100)

  • include (Array<String>) (defaults to: nil)

    Optional extras: [“offers”], [“reviews”]



277
278
279
280
281
# File 'lib/shopsavvy_data_api/client.rb', line 277

def batch_lookup(identifiers, include: nil)
  body = { identifiers: identifiers }
  body[:include] = include if include
  make_request(:post, "products/batch", body: body)
end

#create_webhook(url, events:) ⇒ Object



288
289
290
# File 'lib/shopsavvy_data_api/client.rb', line 288

def create_webhook(url, events:)
  make_request(:post, "webhooks", body: { url: url, events: events })
end

#delete_webhook(webhook_id) ⇒ Object



300
301
302
# File 'lib/shopsavvy_data_api/client.rb', line 300

def delete_webhook(webhook_id)
  make_request(:delete, "webhooks/#{webhook_id}")
end

#get_batch_status(batch_id) ⇒ Object

Poll for async batch job results



284
285
286
# File 'lib/shopsavvy_data_api/client.rb', line 284

def get_batch_status(batch_id)
  make_request(:get, "batch/#{batch_id}")
end

#get_current_offers(identifier, retailer: nil, format: nil) ⇒ APIResponse<Array<ProductWithOffers>>

Get current offers for a product

Examples:

result = client.get_current_offers("012345678901")
result.data.each do |product|
  puts "Product: #{product.title}"
  product.offers.each { |offer| puts "  #{offer.retailer}: $#{offer.price}" }
end

Parameters:

  • identifier (String)

    Product identifier

  • retailer (String, nil) (defaults to: nil)

    Optional retailer to filter by

  • format (String, nil) (defaults to: nil)

    Response format (‘json’ or ‘csv’)

Returns:



117
118
119
120
121
122
123
124
# File 'lib/shopsavvy_data_api/client.rb', line 117

def get_current_offers(identifier, retailer: nil, format: nil)
  params = { ids: identifier }
  params[:retailer] = retailer if retailer
  params[:format] = format if format

  response = make_request(:get, "products/offers", params: params)
  APIResponse.new(response, data_class: ProductWithOffers)
end

#get_current_offers_batch(identifiers, retailer: nil, format: nil) ⇒ APIResponse<Array<ProductWithOffers>>

Get current offers for multiple products

Parameters:

  • identifiers (Array<String>)

    Array of product identifiers

  • retailer (String, nil) (defaults to: nil)

    Optional retailer to filter by

  • format (String, nil) (defaults to: nil)

    Response format (‘json’ or ‘csv’)

Returns:



132
133
134
135
136
137
138
139
# File 'lib/shopsavvy_data_api/client.rb', line 132

def get_current_offers_batch(identifiers, retailer: nil, format: nil)
  params = { ids: identifiers.join(",") }
  params[:retailer] = retailer if retailer
  params[:format] = format if format

  response = make_request(:get, "products/offers", params: params)
  APIResponse.new(response, data_class: ProductWithOffers)
end

#get_deals(sort: "hot", limit: 25, offset: 0, **options) ⇒ Hash

Browse current shopping deals

Parameters:

  • sort (String) (defaults to: "hot")

    Sort algorithm: hot, new, top-hour, top-day, top-week

  • limit (Integer) (defaults to: 25)

    Results per page (1-100)

  • offset (Integer) (defaults to: 0)

    Pagination offset

  • options (Hash)

    Additional filters (category, retailer, tag, min_price, max_price, grade)

Returns:

  • (Hash)

    Deals response with deals array and pagination



262
263
264
265
# File 'lib/shopsavvy_data_api/client.rb', line 262

def get_deals(sort: "hot", limit: 25, offset: 0, **options)
  params = { sort: sort, limit: limit, offset: offset }.merge(options).compact
  make_request(:get, "deals", params: params)
end

#get_price_history(identifier, start_date, end_date, retailer: nil, format: nil) ⇒ APIResponse<Array<OfferWithHistory>>

Get price history for a product

Examples:

history = client.get_price_history("012345678901", "2024-01-01", "2024-01-31")
history.data.each do |offer|
  puts "#{offer.retailer}: #{offer.price_history.length} price points"
end

Parameters:

  • identifier (String)

    Product identifier

  • start_date (String)

    Start date (YYYY-MM-DD format)

  • end_date (String)

    End date (YYYY-MM-DD format)

  • retailer (String, nil) (defaults to: nil)

    Optional retailer to filter by

  • format (String, nil) (defaults to: nil)

    Response format (‘json’ or ‘csv’)

Returns:



155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/shopsavvy_data_api/client.rb', line 155

def get_price_history(identifier, start_date, end_date, retailer: nil, format: nil)
  params = {
    ids: identifier,
    start_date: start_date,
    end_date: end_date
  }
  params[:retailer] = retailer if retailer
  params[:format] = format if format

  response = make_request(:get, "products/offers/history", params: params)
  APIResponse.new(response, data_class: OfferWithHistory)
end

#get_product_details(identifier, format: nil) ⇒ APIResponse<Array<ProductDetails>>

Look up product details by identifier

Examples:

product = client.get_product_details("012345678901")
puts product.data[0].title

Parameters:

  • identifier (String)

    Product identifier (barcode, ASIN, URL, model number, or ShopSavvy product ID)

  • format (String, nil) (defaults to: nil)

    Response format (‘json’ or ‘csv’)

Returns:



79
80
81
82
83
84
85
# File 'lib/shopsavvy_data_api/client.rb', line 79

def get_product_details(identifier, format: nil)
  params = { ids: identifier }
  params[:format] = format if format

  response = make_request(:get, "products", params: params)
  APIResponse.new(response, data_class: ProductDetails)
end

#get_product_details_batch(identifiers, format: nil) ⇒ APIResponse<Array<ProductDetails>>

Look up details for multiple products

Examples:

products = client.get_product_details_batch(["012345678901", "B08N5WRWNW"])
products.data.each { |product| puts product.title }

Parameters:

  • identifiers (Array<String>)

    Array of product identifiers

  • format (String, nil) (defaults to: nil)

    Response format (‘json’ or ‘csv’)

Returns:



96
97
98
99
100
101
102
# File 'lib/shopsavvy_data_api/client.rb', line 96

def get_product_details_batch(identifiers, format: nil)
  params = { ids: identifiers.join(",") }
  params[:format] = format if format

  response = make_request(:get, "products", params: params)
  APIResponse.new(response, data_class: ProductDetails)
end

#get_product_review(identifier) ⇒ Hash

Get TLDR review for a product (pros, cons, scores)

Parameters:

  • identifier (String)

    Product identifier (barcode, ASIN, URL, model number)

Returns:

  • (Hash)

    Review response with review data or null



270
271
272
# File 'lib/shopsavvy_data_api/client.rb', line 270

def get_product_review(identifier)
  make_request(:get, "products/reviews", params: { id: identifier })
end

#get_scheduled_productsAPIResponse<Array<ScheduledProduct>>

Get all scheduled products

Examples:

scheduled = client.get_scheduled_products
puts "Monitoring #{scheduled.data.length} products"

Returns:



213
214
215
216
# File 'lib/shopsavvy_data_api/client.rb', line 213

def get_scheduled_products
  response = make_request(:get, "products/scheduled")
  APIResponse.new(response, data_class: ScheduledProduct)
end

#get_usageAPIResponse<UsageInfo>

Get API usage information

Examples:

usage = client.get_usage
puts "Credits remaining: #{usage.data.credits_remaining}"

Returns:



251
252
253
254
# File 'lib/shopsavvy_data_api/client.rb', line 251

def get_usage
  response = make_request(:get, "usage")
  APIResponse.new(response, data_class: UsageInfo)
end

#list_webhooksObject



292
293
294
# File 'lib/shopsavvy_data_api/client.rb', line 292

def list_webhooks
  make_request(:get, "webhooks")
end

#remove_product_from_schedule(identifier) ⇒ APIResponse<Hash>

Remove product from monitoring schedule

Examples:

result = client.remove_product_from_schedule("012345678901")
puts "Removed: #{result.data['removed']}"

Parameters:

  • identifier (String)

    Product identifier to remove

Returns:



226
227
228
229
230
231
# File 'lib/shopsavvy_data_api/client.rb', line 226

def remove_product_from_schedule(identifier)
  body = { identifier: identifier }

  response = make_request(:delete, "products/schedule", body: body)
  APIResponse.new(response)
end

#remove_products_from_schedule(identifiers) ⇒ APIResponse<Array<Hash>>

Remove multiple products from monitoring schedule

Parameters:

  • identifiers (Array<String>)

    Array of product identifiers to remove

Returns:

  • (APIResponse<Array<Hash>>)

    Removal confirmation for all products



237
238
239
240
241
242
# File 'lib/shopsavvy_data_api/client.rb', line 237

def remove_products_from_schedule(identifiers)
  body = { identifiers: identifiers.join(",") }

  response = make_request(:delete, "products/schedule", body: body)
  APIResponse.new(response)
end

#schedule_product_monitoring(identifier, frequency, retailer: nil) ⇒ APIResponse<Hash>

Schedule product monitoring

Examples:

result = client.schedule_product_monitoring("012345678901", "daily")
puts "Scheduled: #{result.data['scheduled']}"

Parameters:

  • identifier (String)

    Product identifier

  • frequency (String)

    How often to refresh (‘hourly’, ‘daily’, ‘weekly’)

  • retailer (String, nil) (defaults to: nil)

    Optional retailer to monitor

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/shopsavvy_data_api/client.rb', line 178

def schedule_product_monitoring(identifier, frequency, retailer: nil)
  body = {
    identifier: identifier,
    frequency: frequency
  }
  body[:retailer] = retailer if retailer

  response = make_request(:post, "products/schedule", body: body)
  APIResponse.new(response)
end

#schedule_product_monitoring_batch(identifiers, frequency, retailer: nil) ⇒ APIResponse<Array<Hash>>

Schedule monitoring for multiple products

Parameters:

  • identifiers (Array<String>)

    Array of product identifiers

  • frequency (String)

    How often to refresh (‘hourly’, ‘daily’, ‘weekly’)

  • retailer (String, nil) (defaults to: nil)

    Optional retailer to monitor

Returns:

  • (APIResponse<Array<Hash>>)

    Scheduling confirmation for all products



195
196
197
198
199
200
201
202
203
204
# File 'lib/shopsavvy_data_api/client.rb', line 195

def schedule_product_monitoring_batch(identifiers, frequency, retailer: nil)
  body = {
    identifiers: identifiers.join(","),
    frequency: frequency
  }
  body[:retailer] = retailer if retailer

  response = make_request(:post, "products/schedule", body: body)
  APIResponse.new(response)
end

#search_products(query, limit: nil, offset: nil) ⇒ ProductSearchResult

Search for products by keyword

Examples:

results = client.search_products("iphone 15 pro", limit: 10)
results.data.each { |product| puts product.title }

Parameters:

  • query (String)

    Search query or keyword (e.g., “iphone 15 pro”, “samsung tv”)

  • limit (Integer) (defaults to: nil)

    Maximum number of results (default: 20)

  • offset (Integer) (defaults to: nil)

    Pagination offset (default: 0)

Returns:



61
62
63
64
65
66
67
68
# File 'lib/shopsavvy_data_api/client.rb', line 61

def search_products(query, limit: nil, offset: nil)
  params = { q: query }
  params[:limit] = limit if limit
  params[:offset] = offset if offset

  response = make_request(:get, "products/search", params: params)
  ProductSearchResult.new(response)
end

#test_webhook(webhook_id) ⇒ Object



296
297
298
# File 'lib/shopsavvy_data_api/client.rb', line 296

def test_webhook(webhook_id)
  make_request(:post, "webhooks/#{webhook_id}/test")
end