Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.15.3] - 2026-06-30

### Added

- Google Shopping barcode offers: `client.google.shopping.offers({ barcode, gl?, hl? })` calls `GET /v1/google/shopping/offers`, resolving a product by barcode (GTIN-8/UPC-A/EAN-13/GTIN-14) and returning its multi-seller Google Shopping offers. New `ShoppingOffersParams` type. Costs 14 credits; returns 422 for an invalid/checksum-failing barcode and 404 when the barcode can't be resolved.

## [0.13.1] - 2026-06-13

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The official Node.js/TypeScript client library for the [ScrapeBadger](https://sc
- **Resilient Retries** - Exponential backoff with colored console warnings
- **Typed Exceptions** - Distinct error classes for every failure scenario
- **37+ Twitter endpoints** - Tweets, users, lists, communities, trends, geo, real-time streams
- **19 Google product APIs** - Search (with optional deferred AI Overview follow-up), Maps, News, Hotels, Trends (incl. topic autocomplete), Jobs, Shopping (+ merchant URL enrichment), Patents, Scholar (search + profiles + author + author citation + cite formats), Images, Videos, Finance, AI Mode, Lens, **Local Pack**, **Shorts**, **Flights**, Products
- **19 Google product APIs** - Search (with optional deferred AI Overview follow-up), Maps, News, Hotels, Trends (incl. topic autocomplete), Jobs, Shopping (+ merchant URL enrichment, barcode offers), Patents, Scholar (search + profiles + author + author citation + cite formats), Images, Videos, Finance, AI Mode, Lens, **Local Pack**, **Shorts**, **Flights**, Products
- **Vinted scraping** - Search items, item details, user profiles, brands, colors, markets
- **Web scraping** - Anti-bot bypass, JS rendering, and AI data extraction

Expand Down
17 changes: 16 additions & 1 deletion docs/google.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,18 @@ console.log("Merchant URL:", enriched.merchant_url);

// Get detailed product information + seller list
const detail = await client.google.shopping.product({ product_id: first.product_id });

// Resolve a product by barcode (GTIN-8/UPC-A/EAN-13/GTIN-14) and return
// its multi-seller Google Shopping offers. 422 for an invalid/checksum-
// failing barcode, 404 when the barcode can't be resolved.
const byBarcode = await client.google.shopping.offers({
barcode: "0190198001751",
gl: "us",
});
console.log(byBarcode.product_title, byBarcode.resolved_query);
for (const o of byBarcode.offers as any[]) {
console.log(`${o.source} — ${o.price.extracted}`);
}
```

### Patents
Expand Down Expand Up @@ -271,7 +283,7 @@ const product = await client.google.products.detail({ product_id: "1234567890" }
| `client.google.hotels` | Hotels: search, details |
| `client.google.trends` | Trends: interest, regions, related, trending |
| `client.google.jobs` | Job listings search |
| `client.google.shopping` | Shopping: search, product, click enrichment |
| `client.google.shopping` | Shopping: search, product, click enrichment, barcode offers |
| `client.google.patents` | Patents: search, detail |
| `client.google.scholar` | Academic paper search |
| `client.google.autocomplete` | Search suggestion lookup |
Expand Down Expand Up @@ -305,6 +317,7 @@ const product = await client.google.products.detail({ product_id: "1234567890" }
| `shopping` | `search(params)` | Product search |
| `shopping` | `product(params)` | Product detail + sellers |
| `shopping` | `click(params)` | Merchant URL enrichment |
| `shopping` | `offers(params)` | Barcode → multi-seller offers |
| `patents` | `search(params)` | Patent search |
| `patents` | `detail(params)` | Patent document |
| `scholar` | `search(params)` | Academic papers |
Expand Down Expand Up @@ -343,6 +356,7 @@ import type {
ShoppingSearchParams,
ShoppingProductParams,
ShoppingClickParams,
ShoppingOffersParams,
PatentsSearchParams,
PatentsDetailParams,
ScholarSearchParams,
Expand Down Expand Up @@ -411,6 +425,7 @@ import type {
| `search`, `images`, `videos`, `maps/search`, `shopping/search`, `jobs/search`, `scholar/search`, `patents/search`, `finance/quote`, `trends/*` (except trending) | **2** |
| `maps/place`, `maps/reviews`, `patents/detail`, `ai-mode/search`, `lens/search`, `hotels/search`, `products/detail` | **3** |
| `hotels/details`, `shopping/product` | **5** |
| `shopping/offers` | **14** |
| `news/*`, `autocomplete`, `trends/trending`, `maps/photos`, `maps/posts`, `shopping/product/click` | **1** |
| Failed requests | **0** |

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "scrapebadger",
"version": "0.15.2",
"version": "0.15.3",
"description": "Official Node.js SDK for ScrapeBadger - Async web scraping APIs for Twitter, Google, Vinted, Reddit, and more",
"type": "module",
"main": "./dist/index.js",
Expand Down
1 change: 1 addition & 0 deletions src/google/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export type {
ScholarProfilesParams,
ScholarSearchParams,
ShoppingClickParams,
ShoppingOffersParams,
ShoppingProductParams,
ShoppingSearchParams,
ShortsSearchParams,
Expand Down
12 changes: 12 additions & 0 deletions src/google/shopping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { BaseClient } from "../internal/client.js";
import type {
GoogleResponse,
ShoppingClickParams,
ShoppingOffersParams,
ShoppingProductParams,
ShoppingSearchParams,
} from "./types.js";
Expand Down Expand Up @@ -58,4 +59,15 @@ export class ShoppingClient {
params: { ...params },
});
}

/**
* Resolve a product by `barcode` (GTIN-8/UPC-A/EAN-13/GTIN-14) and return
* its multi-seller Google Shopping offers. Throws on a 422 (invalid or
* checksum-failing barcode) or 404 (barcode not resolvable to a product).
*/
async offers(params: ShoppingOffersParams): Promise<GoogleResponse> {
return this.client.request<GoogleResponse>("/v1/google/shopping/offers", {
params: { ...params },
});
}
}
29 changes: 17 additions & 12 deletions src/google/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,7 @@ export interface NewsSearchParams {
* back to a plain `string` when you know the topic code out-of-band.
*/
export type NewsTopic =
| "WORLD"
| "BUSINESS"
| "TECHNOLOGY"
| "ENTERTAINMENT"
| "SPORTS"
| "SCIENCE"
| "HEALTH";
"WORLD" | "BUSINESS" | "TECHNOLOGY" | "ENTERTAINMENT" | "SPORTS" | "SCIENCE" | "HEALTH";

export interface NewsTopicsParams {
// Accept the canonical codes as a `NewsTopic` union, but also allow any
Expand Down Expand Up @@ -233,11 +227,7 @@ export interface TrendsTrendingNowParams {
}

export type TrendsDataType =
| "TIMESERIES"
| "GEO_MAP"
| "GEO_MAP_0"
| "RELATED_TOPICS"
| "RELATED_QUERIES";
"TIMESERIES" | "GEO_MAP" | "GEO_MAP_0" | "RELATED_TOPICS" | "RELATED_QUERIES";

export interface TrendsSearchParams {
/** Search term(s). Comma-separated (max 5) for TIMESERIES / GEO_MAP. */
Expand Down Expand Up @@ -349,6 +339,21 @@ export interface ShoppingClickParams {
product_id?: string;
}

/**
* Params for `/v1/google/shopping/offers` — resolve a product by barcode
* (GTIN-8/UPC-A/EAN-13/GTIN-14) and return its multi-seller Google
* Shopping offers. Returns 422 for an invalid/checksum-failing barcode and
* 404 when the barcode can't be resolved to a product.
*/
export interface ShoppingOffersParams {
/** Product barcode: a GTIN-8, UPC-A, EAN-13, or GTIN-14. */
barcode: string;
/** ISO-3166 alpha-2 country code (e.g. `us`). */
gl?: string;
/** UI/results language (e.g. `en`). Defaults to `en`. */
hl?: string;
}

// ===== Patents =====

/**
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export type {
ScholarProfilesParams,
ScholarSearchParams,
ShoppingClickParams,
ShoppingOffersParams,
ShoppingProductParams,
ShoppingSearchParams,
ShortsSearchParams,
Expand Down
19 changes: 16 additions & 3 deletions tests/google.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ describe("MapsClient", () => {

it("place throws when no identifier is supplied", async () => {
const client = makeClient();
await expect(client.google.maps.place({})).rejects.toThrow(
"place_id or data_id"
);
await expect(client.google.maps.place({})).rejects.toThrow("place_id or data_id");
});

it("reviews forwards all params", async () => {
Expand Down Expand Up @@ -318,6 +316,21 @@ describe("ShoppingClient", () => {
expect(url.searchParams.get("product_id")).toBe("pid123");
expect(response.merchant_url).toBe("https://www.razer.com/x");
});

it("offers resolves a barcode via /shopping/offers", async () => {
mockFetch({ barcode: "0190198001751", offers: [] });
const client = makeClient();
const response = await client.google.shopping.offers({
barcode: "0190198001751",
gl: "us",
hl: "en",
});
const url = capturedUrl();
expect(url.pathname).toBe("/v1/google/shopping/offers");
expect(url.searchParams.get("barcode")).toBe("0190198001751");
expect(url.searchParams.get("gl")).toBe("us");
expect(response.barcode).toBe("0190198001751");
});
});

// ---------------------------------------------------------------------------
Expand Down
Loading