scrapebadger 0.4.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -291
- package/dist/index.d.cts +3287 -102
- package/dist/index.d.ts +3287 -102
- package/dist/index.js +1524 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1496 -58
- package/dist/index.mjs.map +1 -1
- package/dist/twitter/index.js +1 -1
- package/dist/twitter/index.js.map +1 -1
- package/dist/twitter/index.mjs +1 -1
- package/dist/twitter/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -6,100 +6,99 @@ import 'node:events';
|
|
|
6
6
|
* TypeScript types for web scraping API responses.
|
|
7
7
|
*/
|
|
8
8
|
interface ScrapeOptions {
|
|
9
|
+
/** Output format */
|
|
10
|
+
format?: "html" | "markdown" | "text";
|
|
9
11
|
/** Whether to render JavaScript */
|
|
10
12
|
renderJs?: boolean;
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
proxyCountry?: string;
|
|
15
|
-
/** Proxy type (datacenter, residential) */
|
|
16
|
-
proxyType?: "datacenter" | "residential" | "mobile" | "isp";
|
|
17
|
-
/** Reuse an existing session */
|
|
18
|
-
sessionId?: string;
|
|
19
|
-
/** Force a specific engine */
|
|
20
|
-
engine?: string;
|
|
21
|
-
/** Maximum credit cost */
|
|
22
|
-
maxCost?: number;
|
|
23
|
-
/** Custom HTTP headers */
|
|
24
|
-
headers?: Record<string, string>;
|
|
25
|
-
/** CSS selector to wait for */
|
|
13
|
+
/** Force a specific engine (auto, browser) */
|
|
14
|
+
engine?: "auto" | "browser";
|
|
15
|
+
/** CSS selector or XPath to wait for */
|
|
26
16
|
waitFor?: string;
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
/**
|
|
17
|
+
/** Timeout in ms for waitFor selector (1000-120000) */
|
|
18
|
+
waitTimeout?: number;
|
|
19
|
+
/** Additional ms to wait after page load (0-30000) */
|
|
20
|
+
waitAfterLoad?: number;
|
|
21
|
+
/** Browser actions to perform before extracting */
|
|
30
22
|
jsScenario?: Array<Record<string, unknown>>;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
23
|
+
/** Session ID for persistent cookies/state */
|
|
24
|
+
sessionId?: string;
|
|
25
|
+
/** Max retry attempts on blocking (0-10) */
|
|
26
|
+
retryCount?: number;
|
|
27
|
+
/** Auto-retry on blocking detection */
|
|
28
|
+
retryOnBlock?: boolean;
|
|
29
|
+
/** ISO country code for proxy geo-targeting */
|
|
30
|
+
country?: string;
|
|
31
|
+
/** Custom HTTP headers */
|
|
32
|
+
customHeaders?: Record<string, string>;
|
|
33
|
+
/** Capture full-page screenshot */
|
|
34
|
+
screenshot?: boolean;
|
|
35
|
+
/** Record browser session as video (+3 credits) */
|
|
36
|
+
video?: boolean;
|
|
37
|
+
/** Attempt anti-bot bypass */
|
|
38
|
+
antiBot?: boolean;
|
|
39
|
+
/** Allow auto-escalation to stronger engines */
|
|
40
|
+
escalate?: boolean;
|
|
41
|
+
/** Maximum credits budget */
|
|
42
|
+
maxCost?: number;
|
|
43
|
+
/** Run AI extraction on content */
|
|
44
|
+
aiExtract?: boolean;
|
|
45
|
+
/** Natural language prompt for AI extraction (max 2000 chars) */
|
|
46
|
+
aiPrompt?: string;
|
|
47
|
+
/**
|
|
48
|
+
* When true, the server streams the raw body as `text/html` with
|
|
49
|
+
* metadata in `X-Scrape-*` response headers instead of JSON-wrapping
|
|
50
|
+
* the content. Saves 300–1000 ms on large (>1 MB) pages. Incompatible
|
|
51
|
+
* with `aiExtract`, `screenshot`, `video`.
|
|
52
|
+
*/
|
|
53
|
+
rawContent?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* When true, the server skips the generic blocking-page + anti-bot /
|
|
56
|
+
* CAPTCHA regex scans on the response body. Saves ~1.3 s on large
|
|
57
|
+
* responses. Only safe for origins known not to use consumer WAFs
|
|
58
|
+
* (Cloudflare, DataDome, Akamai, Kasada). Default false — keep
|
|
59
|
+
* disabled for general-purpose scraping.
|
|
60
|
+
*/
|
|
61
|
+
skipBotDetection?: boolean;
|
|
67
62
|
}
|
|
68
63
|
interface ScrapeResult {
|
|
69
|
-
|
|
70
|
-
status_code: number;
|
|
64
|
+
success: boolean;
|
|
71
65
|
url: string;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
processing_time_ms?: number;
|
|
75
|
-
anti_bot_detected: boolean;
|
|
76
|
-
anti_bot_provider?: string;
|
|
77
|
-
captcha_solved: boolean;
|
|
78
|
-
session_id?: string;
|
|
79
|
-
session_reused: boolean;
|
|
80
|
-
}
|
|
81
|
-
interface ScreenshotResult {
|
|
82
|
-
image_data: string;
|
|
66
|
+
status_code: number;
|
|
67
|
+
content: string | null;
|
|
83
68
|
format: string;
|
|
84
|
-
|
|
69
|
+
engine_used: string;
|
|
85
70
|
credits_used: number;
|
|
71
|
+
duration_ms: number;
|
|
72
|
+
retries_used: number;
|
|
73
|
+
content_length: number;
|
|
74
|
+
screenshot_url: string | null;
|
|
75
|
+
video_url: string | null;
|
|
76
|
+
headers: Record<string, string>;
|
|
77
|
+
blocking_detected: boolean;
|
|
78
|
+
blocking_details: Record<string, unknown> | null;
|
|
79
|
+
antibot_systems: Array<Record<string, unknown>>;
|
|
80
|
+
captcha_systems: Array<Record<string, unknown>>;
|
|
81
|
+
anti_bot_solved: boolean;
|
|
82
|
+
solver_used: string | null;
|
|
83
|
+
ai_extraction: Record<string, unknown> | string | unknown[] | null;
|
|
84
|
+
ai_model: string | null;
|
|
85
|
+
ai_error: string | null;
|
|
86
|
+
}
|
|
87
|
+
interface DetectOptions {
|
|
88
|
+
/** Request timeout in ms (1000-60000) */
|
|
89
|
+
timeout?: number;
|
|
90
|
+
/** ISO country code for proxy geo-targeting */
|
|
91
|
+
country?: string;
|
|
86
92
|
}
|
|
87
|
-
interface
|
|
88
|
-
data: Record<string, unknown>;
|
|
93
|
+
interface DetectResult {
|
|
89
94
|
url: string;
|
|
95
|
+
antibot_systems: Array<Record<string, unknown>>;
|
|
96
|
+
captcha_systems: Array<Record<string, unknown>>;
|
|
97
|
+
is_blocked: boolean;
|
|
98
|
+
blocking_type: string | null;
|
|
99
|
+
recommendation: string | null;
|
|
90
100
|
credits_used: number;
|
|
91
|
-
|
|
92
|
-
interface BatchResult {
|
|
93
|
-
results: ScrapeResult[];
|
|
94
|
-
total: number;
|
|
95
|
-
successful: number;
|
|
96
|
-
failed: number;
|
|
97
|
-
}
|
|
98
|
-
interface SessionInfo {
|
|
99
|
-
session_id: string;
|
|
100
|
-
domain: string;
|
|
101
|
-
reused: boolean;
|
|
102
|
-
fingerprint_id?: string;
|
|
101
|
+
duration_ms: number;
|
|
103
102
|
}
|
|
104
103
|
|
|
105
104
|
/**
|
|
@@ -114,19 +113,24 @@ interface SessionInfo {
|
|
|
114
113
|
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
115
114
|
*
|
|
116
115
|
* // Simple scrape
|
|
117
|
-
* const result = await client.web.scrape("https://
|
|
116
|
+
* const result = await client.web.scrape("https://scrapebadger.com");
|
|
118
117
|
* console.log(result.content);
|
|
119
118
|
*
|
|
120
|
-
* //
|
|
121
|
-
* const
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* const data = await client.web.extract("https://example.com", {
|
|
125
|
-
* schema: { title: "css:h1" }
|
|
119
|
+
* // Scrape with JavaScript rendering
|
|
120
|
+
* const rendered = await client.web.scrape("https://scrapebadger.com", {
|
|
121
|
+
* renderJs: true,
|
|
122
|
+
* format: "markdown",
|
|
126
123
|
* });
|
|
127
124
|
*
|
|
128
|
-
* //
|
|
129
|
-
* const
|
|
125
|
+
* // AI extraction
|
|
126
|
+
* const extracted = await client.web.extract(
|
|
127
|
+
* "https://scrapebadger.com/pricing",
|
|
128
|
+
* "Extract all pricing plans with their features"
|
|
129
|
+
* );
|
|
130
|
+
*
|
|
131
|
+
* // Detect anti-bot systems
|
|
132
|
+
* const detection = await client.web.detect("https://scrapebadger.com");
|
|
133
|
+
* console.log(detection.antibot_systems);
|
|
130
134
|
* ```
|
|
131
135
|
*/
|
|
132
136
|
declare class WebClient {
|
|
@@ -134,28 +138,3203 @@ declare class WebClient {
|
|
|
134
138
|
constructor(client: BaseClient);
|
|
135
139
|
/**
|
|
136
140
|
* Scrape a web page.
|
|
141
|
+
*
|
|
142
|
+
* @param url - The URL to scrape
|
|
143
|
+
* @param options - Scrape configuration options
|
|
144
|
+
* @returns The scrape result including content, metadata, and credit usage
|
|
137
145
|
*/
|
|
138
146
|
scrape(url: string, options?: ScrapeOptions): Promise<ScrapeResult>;
|
|
139
147
|
/**
|
|
140
|
-
*
|
|
148
|
+
* Extract structured data from a web page using AI.
|
|
149
|
+
*
|
|
150
|
+
* Convenience wrapper around {@link scrape} that enables AI extraction
|
|
151
|
+
* with the given prompt and defaults to markdown format.
|
|
152
|
+
*
|
|
153
|
+
* @param url - The URL to extract data from
|
|
154
|
+
* @param prompt - Natural language prompt describing what to extract (max 2000 chars)
|
|
155
|
+
* @param options - Additional scrape options (aiExtract and aiPrompt are set automatically)
|
|
156
|
+
* @returns The scrape result with ai_extraction populated
|
|
157
|
+
*/
|
|
158
|
+
extract(url: string, prompt: string, options?: ScrapeOptions): Promise<ScrapeResult>;
|
|
159
|
+
/**
|
|
160
|
+
* Detect anti-bot systems on a URL.
|
|
161
|
+
*
|
|
162
|
+
* @param url - The URL to analyze
|
|
163
|
+
* @param options - Detection options
|
|
164
|
+
* @returns Detection results including identified anti-bot and captcha systems
|
|
165
|
+
*/
|
|
166
|
+
detect(url: string, options?: DetectOptions): Promise<DetectResult>;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* TypeScript types for Vinted API responses.
|
|
171
|
+
*
|
|
172
|
+
* This module contains all the data types used by the Vinted API client.
|
|
173
|
+
*/
|
|
174
|
+
/**
|
|
175
|
+
* A price with amount and currency.
|
|
176
|
+
*/
|
|
177
|
+
interface VintedPrice {
|
|
178
|
+
/** Price amount as a string (e.g. "12.50") */
|
|
179
|
+
amount: string;
|
|
180
|
+
/** ISO currency code (e.g. "EUR") */
|
|
181
|
+
currency_code: string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* A photo attached to a Vinted item.
|
|
185
|
+
*/
|
|
186
|
+
interface VintedPhoto {
|
|
187
|
+
/** Unique photo identifier */
|
|
188
|
+
id: number;
|
|
189
|
+
/** Photo URL */
|
|
190
|
+
url: string;
|
|
191
|
+
/** Dominant color hex code */
|
|
192
|
+
dominant_color: string | null;
|
|
193
|
+
/** Whether this is the main/cover photo */
|
|
194
|
+
is_main: boolean;
|
|
195
|
+
/** Image width in pixels */
|
|
196
|
+
width: number | null;
|
|
197
|
+
/** Image height in pixels */
|
|
198
|
+
height: number | null;
|
|
199
|
+
/** Full resolution image URL */
|
|
200
|
+
full_size_url: string | null;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Brief user information shown on item listings.
|
|
204
|
+
*/
|
|
205
|
+
interface VintedUserSummary {
|
|
206
|
+
/** Unique user identifier */
|
|
207
|
+
id: number;
|
|
208
|
+
/** Username / login handle */
|
|
209
|
+
login: string;
|
|
210
|
+
/** Profile photo URL */
|
|
211
|
+
photo_url: string | null;
|
|
212
|
+
/** Whether the user is a business account */
|
|
213
|
+
business: boolean;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Seller summary with feedback and item stats.
|
|
217
|
+
*/
|
|
218
|
+
interface VintedSellerSummary extends VintedUserSummary {
|
|
219
|
+
/** Total number of feedback ratings */
|
|
220
|
+
feedback_count: number;
|
|
221
|
+
/** Overall feedback reputation score (0-1) */
|
|
222
|
+
feedback_reputation: number;
|
|
223
|
+
/** Number of items listed */
|
|
224
|
+
item_count: number;
|
|
225
|
+
/** Seller's location */
|
|
226
|
+
location: string | null;
|
|
227
|
+
/** Last activity timestamp (ISO format) */
|
|
228
|
+
last_seen: string | null;
|
|
229
|
+
/** Achievement badges */
|
|
230
|
+
badges: string[];
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* A Vinted item summary as returned in search results and listings.
|
|
234
|
+
*/
|
|
235
|
+
interface VintedItemSummary {
|
|
236
|
+
/** Unique item identifier */
|
|
237
|
+
id: number;
|
|
238
|
+
/** Item title */
|
|
239
|
+
title: string;
|
|
240
|
+
/** Item price */
|
|
241
|
+
price: VintedPrice;
|
|
242
|
+
/** Brand name */
|
|
243
|
+
brand_title: string;
|
|
244
|
+
/** Size label */
|
|
245
|
+
size_title: string;
|
|
246
|
+
/** Item condition status */
|
|
247
|
+
status: string;
|
|
248
|
+
/** Item URL on Vinted */
|
|
249
|
+
url: string;
|
|
250
|
+
/** Number of users who favorited this item */
|
|
251
|
+
favourite_count: number;
|
|
252
|
+
/** Number of views */
|
|
253
|
+
view_count: number;
|
|
254
|
+
/** Item owner summary */
|
|
255
|
+
user: VintedUserSummary;
|
|
256
|
+
/** Main photo */
|
|
257
|
+
photo: VintedPhoto;
|
|
258
|
+
/** All photos */
|
|
259
|
+
photos: VintedPhoto[];
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Full item detail with all metadata.
|
|
263
|
+
*/
|
|
264
|
+
interface VintedItemDetail extends VintedItemSummary {
|
|
265
|
+
/** Item description */
|
|
266
|
+
description: string;
|
|
267
|
+
/** Catalog category identifier */
|
|
268
|
+
catalog_id: number;
|
|
269
|
+
/** Primary color */
|
|
270
|
+
color1: string;
|
|
271
|
+
/** Seller details */
|
|
272
|
+
seller: VintedSellerSummary;
|
|
273
|
+
/** Category name */
|
|
274
|
+
category: string;
|
|
275
|
+
/** Upload timestamp (ISO format) */
|
|
276
|
+
upload_date: string;
|
|
277
|
+
/** Whether the item can be purchased */
|
|
278
|
+
can_buy: boolean;
|
|
279
|
+
/** Whether instant buy is enabled */
|
|
280
|
+
instant_buy: boolean;
|
|
281
|
+
/** Whether the listing is closed */
|
|
282
|
+
is_closed: boolean;
|
|
283
|
+
/** Whether the item is reserved */
|
|
284
|
+
is_reserved: boolean;
|
|
285
|
+
/** Whether the item is hidden */
|
|
286
|
+
is_hidden: boolean;
|
|
287
|
+
/** Size identifier */
|
|
288
|
+
size_id: number;
|
|
289
|
+
/** Status identifier */
|
|
290
|
+
status_id: number;
|
|
291
|
+
/** Brand identifier */
|
|
292
|
+
brand_id: number;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Full Vinted user profile.
|
|
296
|
+
*/
|
|
297
|
+
interface VintedUserProfile {
|
|
298
|
+
/** Unique user identifier */
|
|
299
|
+
id: number;
|
|
300
|
+
/** Username / login handle */
|
|
301
|
+
login: string;
|
|
302
|
+
/** Profile photo URL */
|
|
303
|
+
photo_url: string | null;
|
|
304
|
+
/** Whether the user is a business account */
|
|
305
|
+
business: boolean;
|
|
306
|
+
/** ISO country code */
|
|
307
|
+
country_code: string;
|
|
308
|
+
/** City name */
|
|
309
|
+
city: string;
|
|
310
|
+
/** Total feedback count */
|
|
311
|
+
feedback_count: number;
|
|
312
|
+
/** Overall feedback reputation (0-1) */
|
|
313
|
+
feedback_reputation: number;
|
|
314
|
+
/** Number of positive ratings */
|
|
315
|
+
positive_feedback_count: number;
|
|
316
|
+
/** Number of neutral ratings */
|
|
317
|
+
neutral_feedback_count: number;
|
|
318
|
+
/** Number of negative ratings */
|
|
319
|
+
negative_feedback_count: number;
|
|
320
|
+
/** Number of items listed */
|
|
321
|
+
item_count: number;
|
|
322
|
+
/** Number of followers */
|
|
323
|
+
followers_count: number;
|
|
324
|
+
/** Number of users this user follows */
|
|
325
|
+
following_count: number;
|
|
326
|
+
/** Whether the user is currently online */
|
|
327
|
+
is_online: boolean;
|
|
328
|
+
/** Whether the user is on holiday mode */
|
|
329
|
+
is_on_holiday: boolean;
|
|
330
|
+
/** Last login timestamp (Unix) */
|
|
331
|
+
last_loged_on_ts: string;
|
|
332
|
+
/** Full profile URL */
|
|
333
|
+
profile_url: string;
|
|
334
|
+
/** User locale */
|
|
335
|
+
locale: string;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* A Vinted brand.
|
|
339
|
+
*/
|
|
340
|
+
interface VintedBrand {
|
|
341
|
+
/** Unique brand identifier */
|
|
342
|
+
id: number;
|
|
343
|
+
/** Brand name */
|
|
344
|
+
title: string;
|
|
345
|
+
/** URL-friendly slug */
|
|
346
|
+
slug: string;
|
|
347
|
+
/** Number of items with this brand */
|
|
348
|
+
item_count: number;
|
|
349
|
+
/** Number of users who favorited this brand */
|
|
350
|
+
favourite_count: number;
|
|
351
|
+
/** Whether the brand is classified as luxury */
|
|
352
|
+
is_luxury: boolean;
|
|
353
|
+
/** Brand page URL */
|
|
354
|
+
url: string;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* A Vinted color option.
|
|
358
|
+
*/
|
|
359
|
+
interface VintedColor {
|
|
360
|
+
/** Unique color identifier */
|
|
361
|
+
id: number;
|
|
362
|
+
/** Color display name */
|
|
363
|
+
title: string;
|
|
364
|
+
/** Hex color code */
|
|
365
|
+
hex: string;
|
|
366
|
+
/** Internal color code */
|
|
367
|
+
code: string;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* A Vinted item condition status.
|
|
371
|
+
*/
|
|
372
|
+
interface VintedStatus {
|
|
373
|
+
/** Unique status identifier */
|
|
374
|
+
id: number;
|
|
375
|
+
/** Status display name */
|
|
376
|
+
title: string;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* A Vinted marketplace/country.
|
|
380
|
+
*/
|
|
381
|
+
interface VintedMarket {
|
|
382
|
+
/** Market code (e.g. "fr", "de") */
|
|
383
|
+
code: string;
|
|
384
|
+
/** Vinted domain for this market */
|
|
385
|
+
domain: string;
|
|
386
|
+
/** Country name */
|
|
387
|
+
country: string;
|
|
388
|
+
/** Currency code */
|
|
389
|
+
currency: string;
|
|
390
|
+
/** Market display name */
|
|
391
|
+
name: string;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Pagination metadata for list responses.
|
|
395
|
+
*/
|
|
396
|
+
interface VintedPagination {
|
|
397
|
+
/** Current page number */
|
|
398
|
+
current_page: number;
|
|
399
|
+
/** Total number of pages */
|
|
400
|
+
total_pages: number;
|
|
401
|
+
/** Total number of entries */
|
|
402
|
+
total_entries: number;
|
|
403
|
+
/** Items per page */
|
|
404
|
+
per_page: number;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Response from the search endpoint.
|
|
408
|
+
*/
|
|
409
|
+
interface SearchResponse {
|
|
410
|
+
/** List of matching items */
|
|
411
|
+
items: VintedItemSummary[];
|
|
412
|
+
/** Pagination metadata */
|
|
413
|
+
pagination: VintedPagination;
|
|
414
|
+
/** Market code used for this search */
|
|
415
|
+
market: string;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Response from the item detail endpoint.
|
|
419
|
+
*/
|
|
420
|
+
interface ItemDetailResponse {
|
|
421
|
+
/** Full item details */
|
|
422
|
+
item: VintedItemDetail;
|
|
423
|
+
/** Market code used */
|
|
424
|
+
market: string;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Response from the user profile endpoint.
|
|
428
|
+
*/
|
|
429
|
+
interface UserProfileResponse$1 {
|
|
430
|
+
/** Full user profile */
|
|
431
|
+
user: VintedUserProfile;
|
|
432
|
+
/** Market code used */
|
|
433
|
+
market: string;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Response from the user items endpoint.
|
|
437
|
+
*/
|
|
438
|
+
interface UserItemsResponse {
|
|
439
|
+
/** List of user's items */
|
|
440
|
+
items: VintedItemSummary[];
|
|
441
|
+
/** Pagination metadata */
|
|
442
|
+
pagination: VintedPagination;
|
|
443
|
+
/** Market code used */
|
|
444
|
+
market: string;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Response from the brands endpoint.
|
|
448
|
+
*/
|
|
449
|
+
interface BrandsResponse {
|
|
450
|
+
/** List of brands */
|
|
451
|
+
brands: VintedBrand[];
|
|
452
|
+
/** Pagination metadata (null when no pagination) */
|
|
453
|
+
pagination: VintedPagination | null;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Response from the colors endpoint.
|
|
457
|
+
*/
|
|
458
|
+
interface ColorsResponse {
|
|
459
|
+
/** List of available colors */
|
|
460
|
+
colors: VintedColor[];
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Response from the statuses endpoint.
|
|
464
|
+
*/
|
|
465
|
+
interface StatusesResponse {
|
|
466
|
+
/** List of item condition statuses */
|
|
467
|
+
statuses: VintedStatus[];
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Response from the markets endpoint.
|
|
471
|
+
*/
|
|
472
|
+
interface MarketsResponse {
|
|
473
|
+
/** List of available markets */
|
|
474
|
+
markets: VintedMarket[];
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Parameters for searching Vinted items.
|
|
478
|
+
*/
|
|
479
|
+
interface VintedSearchParams {
|
|
480
|
+
/** Search query string */
|
|
481
|
+
query: string;
|
|
482
|
+
/** Market code (default: "fr") */
|
|
483
|
+
market?: string;
|
|
484
|
+
/** Page number */
|
|
485
|
+
page?: number;
|
|
486
|
+
/** Items per page */
|
|
487
|
+
per_page?: number;
|
|
488
|
+
/** Minimum price filter */
|
|
489
|
+
price_from?: number;
|
|
490
|
+
/** Maximum price filter */
|
|
491
|
+
price_to?: number;
|
|
492
|
+
/** Comma-separated brand IDs */
|
|
493
|
+
brand_ids?: string;
|
|
494
|
+
/** Comma-separated color IDs */
|
|
495
|
+
color_ids?: string;
|
|
496
|
+
/** Comma-separated status IDs */
|
|
497
|
+
status_ids?: string;
|
|
498
|
+
/** Sort order */
|
|
499
|
+
order?: "relevance" | "newest_first" | "price_low_to_high" | "price_high_to_low";
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Vinted Search API client.
|
|
504
|
+
*
|
|
505
|
+
* Provides methods for searching Vinted item listings.
|
|
506
|
+
*/
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Client for Vinted search endpoints.
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```typescript
|
|
513
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
514
|
+
*
|
|
515
|
+
* // Basic search
|
|
516
|
+
* const results = await client.vinted.search.search({ query: "nike air max" });
|
|
517
|
+
* for (const item of results.items) {
|
|
518
|
+
* console.log(`${item.title} — ${item.price.amount} ${item.price.currency_code}`);
|
|
519
|
+
* }
|
|
520
|
+
*
|
|
521
|
+
* // Search with filters
|
|
522
|
+
* const filtered = await client.vinted.search.search({
|
|
523
|
+
* query: "adidas",
|
|
524
|
+
* market: "de",
|
|
525
|
+
* price_from: 10,
|
|
526
|
+
* price_to: 50,
|
|
527
|
+
* order: "price_low_to_high",
|
|
528
|
+
* });
|
|
529
|
+
* ```
|
|
530
|
+
*/
|
|
531
|
+
declare class SearchClient$2 {
|
|
532
|
+
private readonly client;
|
|
533
|
+
constructor(client: BaseClient);
|
|
534
|
+
/**
|
|
535
|
+
* Search for Vinted items.
|
|
536
|
+
*
|
|
537
|
+
* @param params - Search parameters including query, filters, and pagination.
|
|
538
|
+
* @returns Search results with items and pagination metadata.
|
|
539
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
540
|
+
* @throws ValidationError - If the search parameters are invalid.
|
|
541
|
+
*
|
|
542
|
+
* @example
|
|
543
|
+
* ```typescript
|
|
544
|
+
* const results = await client.vinted.search.search({
|
|
545
|
+
* query: "vintage jacket",
|
|
546
|
+
* market: "fr",
|
|
547
|
+
* page: 1,
|
|
548
|
+
* per_page: 20,
|
|
549
|
+
* order: "newest_first",
|
|
550
|
+
* });
|
|
551
|
+
* console.log(`Found ${results.pagination.total_entries} items`);
|
|
552
|
+
* ```
|
|
553
|
+
*/
|
|
554
|
+
search(params: VintedSearchParams): Promise<SearchResponse>;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Vinted Items API client.
|
|
559
|
+
*
|
|
560
|
+
* Provides methods for fetching individual Vinted item details.
|
|
561
|
+
*/
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Client for Vinted item endpoints.
|
|
565
|
+
*
|
|
566
|
+
* @example
|
|
567
|
+
* ```typescript
|
|
568
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
569
|
+
*
|
|
570
|
+
* const item = await client.vinted.items.get(123456789, { market: "fr" });
|
|
571
|
+
* console.log(`${item.item.title} — ${item.item.price.amount} ${item.item.price.currency_code}`);
|
|
572
|
+
* console.log(`Seller: ${item.item.seller.login}`);
|
|
573
|
+
* ```
|
|
574
|
+
*/
|
|
575
|
+
declare class ItemsClient {
|
|
576
|
+
private readonly client;
|
|
577
|
+
constructor(client: BaseClient);
|
|
578
|
+
/**
|
|
579
|
+
* Get a single item by ID.
|
|
580
|
+
*
|
|
581
|
+
* @param itemId - The Vinted item ID to fetch.
|
|
582
|
+
* @param options - Optional parameters.
|
|
583
|
+
* @param options.market - Market code (default: "fr").
|
|
584
|
+
* @returns The item detail response including full item data.
|
|
585
|
+
* @throws NotFoundError - If the item doesn't exist.
|
|
586
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* ```typescript
|
|
590
|
+
* const response = await client.vinted.items.get(123456789);
|
|
591
|
+
* const { item } = response;
|
|
592
|
+
* console.log(`${item.title}: ${item.description}`);
|
|
593
|
+
* console.log(`Brand: ${item.brand_title}, Size: ${item.size_title}`);
|
|
594
|
+
* console.log(`Photos: ${item.photos.length}`);
|
|
595
|
+
* ```
|
|
596
|
+
*/
|
|
597
|
+
get(itemId: number, options?: {
|
|
598
|
+
market?: string;
|
|
599
|
+
}): Promise<ItemDetailResponse>;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Vinted Users API client.
|
|
604
|
+
*
|
|
605
|
+
* Provides methods for fetching Vinted user profiles and their item listings.
|
|
606
|
+
*/
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Client for Vinted user endpoints.
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```typescript
|
|
613
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
614
|
+
*
|
|
615
|
+
* // Get user profile
|
|
616
|
+
* const profile = await client.vinted.users.getProfile(12345);
|
|
617
|
+
* console.log(`${profile.user.login} — ${profile.user.item_count} items`);
|
|
618
|
+
*
|
|
619
|
+
* // Get user's items
|
|
620
|
+
* const items = await client.vinted.users.getItems(12345);
|
|
621
|
+
* for (const item of items.items) {
|
|
622
|
+
* console.log(`${item.title} — ${item.price.amount} ${item.price.currency_code}`);
|
|
623
|
+
* }
|
|
624
|
+
* ```
|
|
625
|
+
*/
|
|
626
|
+
declare class UsersClient$1 {
|
|
627
|
+
private readonly client;
|
|
628
|
+
constructor(client: BaseClient);
|
|
629
|
+
/**
|
|
630
|
+
* Get a user's profile.
|
|
631
|
+
*
|
|
632
|
+
* @param userId - The Vinted user ID.
|
|
633
|
+
* @param options - Optional parameters.
|
|
634
|
+
* @param options.market - Market code (default: "fr").
|
|
635
|
+
* @returns The user profile response.
|
|
636
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
637
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
* ```typescript
|
|
641
|
+
* const response = await client.vinted.users.getProfile(12345);
|
|
642
|
+
* const { user } = response;
|
|
643
|
+
* console.log(`${user.login} from ${user.city}, ${user.country_code}`);
|
|
644
|
+
* console.log(`Reputation: ${user.feedback_reputation}`);
|
|
645
|
+
* console.log(`Items: ${user.item_count}, Followers: ${user.followers_count}`);
|
|
646
|
+
* ```
|
|
647
|
+
*/
|
|
648
|
+
getProfile(userId: number, options?: {
|
|
649
|
+
market?: string;
|
|
650
|
+
}): Promise<UserProfileResponse$1>;
|
|
651
|
+
/**
|
|
652
|
+
* Get items listed by a user.
|
|
653
|
+
*
|
|
654
|
+
* @param userId - The Vinted user ID.
|
|
655
|
+
* @param options - Optional parameters for pagination and market.
|
|
656
|
+
* @param options.market - Market code (default: "fr").
|
|
657
|
+
* @param options.page - Page number.
|
|
658
|
+
* @param options.per_page - Items per page.
|
|
659
|
+
* @returns The user's items with pagination metadata.
|
|
660
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
661
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* ```typescript
|
|
665
|
+
* const response = await client.vinted.users.getItems(12345, {
|
|
666
|
+
* market: "de",
|
|
667
|
+
* page: 1,
|
|
668
|
+
* per_page: 20,
|
|
669
|
+
* });
|
|
670
|
+
* console.log(`Page ${response.pagination.current_page} of ${response.pagination.total_pages}`);
|
|
671
|
+
* for (const item of response.items) {
|
|
672
|
+
* console.log(`${item.title} — ${item.price.amount} ${item.price.currency_code}`);
|
|
673
|
+
* }
|
|
674
|
+
* ```
|
|
141
675
|
*/
|
|
142
|
-
|
|
676
|
+
getItems(userId: number, options?: {
|
|
677
|
+
market?: string;
|
|
678
|
+
page?: number;
|
|
679
|
+
per_page?: number;
|
|
680
|
+
}): Promise<UserItemsResponse>;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Vinted Reference Data API client.
|
|
685
|
+
*
|
|
686
|
+
* Provides methods for fetching brands, colors, statuses, and markets.
|
|
687
|
+
*/
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Client for Vinted reference data endpoints.
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* ```typescript
|
|
694
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
695
|
+
*
|
|
696
|
+
* // Get available markets
|
|
697
|
+
* const markets = await client.vinted.reference.markets();
|
|
698
|
+
* for (const market of markets.markets) {
|
|
699
|
+
* console.log(`${market.name} (${market.code}) — ${market.currency}`);
|
|
700
|
+
* }
|
|
701
|
+
*
|
|
702
|
+
* // Search brands
|
|
703
|
+
* const brands = await client.vinted.reference.brands({ keyword: "nike" });
|
|
704
|
+
* for (const brand of brands.brands) {
|
|
705
|
+
* console.log(`${brand.title}: ${brand.item_count} items`);
|
|
706
|
+
* }
|
|
707
|
+
* ```
|
|
708
|
+
*/
|
|
709
|
+
declare class ReferenceClient {
|
|
710
|
+
private readonly client;
|
|
711
|
+
constructor(client: BaseClient);
|
|
143
712
|
/**
|
|
144
|
-
*
|
|
713
|
+
* Search for brands by keyword.
|
|
714
|
+
*
|
|
715
|
+
* @param options - Optional parameters.
|
|
716
|
+
* @param options.keyword - Brand name to search for.
|
|
717
|
+
* @param options.market - Market code (default: "fr").
|
|
718
|
+
* @param options.per_page - Number of results per page.
|
|
719
|
+
* @returns Brands matching the keyword.
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
* ```typescript
|
|
723
|
+
* const response = await client.vinted.reference.brands({
|
|
724
|
+
* keyword: "adidas",
|
|
725
|
+
* market: "de",
|
|
726
|
+
* per_page: 10,
|
|
727
|
+
* });
|
|
728
|
+
* for (const brand of response.brands) {
|
|
729
|
+
* console.log(`${brand.title} (${brand.slug}): ${brand.item_count} items`);
|
|
730
|
+
* }
|
|
731
|
+
* ```
|
|
145
732
|
*/
|
|
146
|
-
|
|
733
|
+
brands(options?: {
|
|
734
|
+
keyword?: string;
|
|
735
|
+
market?: string;
|
|
736
|
+
per_page?: number;
|
|
737
|
+
}): Promise<BrandsResponse>;
|
|
147
738
|
/**
|
|
148
|
-
*
|
|
739
|
+
* Get available colors for a market.
|
|
740
|
+
*
|
|
741
|
+
* @param options - Optional parameters.
|
|
742
|
+
* @param options.market - Market code (default: "fr").
|
|
743
|
+
* @returns List of available colors.
|
|
744
|
+
*
|
|
745
|
+
* @example
|
|
746
|
+
* ```typescript
|
|
747
|
+
* const response = await client.vinted.reference.colors({ market: "fr" });
|
|
748
|
+
* for (const color of response.colors) {
|
|
749
|
+
* console.log(`${color.title} (#${color.hex})`);
|
|
750
|
+
* }
|
|
751
|
+
* ```
|
|
149
752
|
*/
|
|
150
|
-
|
|
753
|
+
colors(options?: {
|
|
754
|
+
market?: string;
|
|
755
|
+
}): Promise<ColorsResponse>;
|
|
151
756
|
/**
|
|
152
|
-
*
|
|
757
|
+
* Get available item condition statuses for a market.
|
|
758
|
+
*
|
|
759
|
+
* @param options - Optional parameters.
|
|
760
|
+
* @param options.market - Market code (default: "fr").
|
|
761
|
+
* @returns List of item condition statuses.
|
|
762
|
+
*
|
|
763
|
+
* @example
|
|
764
|
+
* ```typescript
|
|
765
|
+
* const response = await client.vinted.reference.statuses({ market: "fr" });
|
|
766
|
+
* for (const status of response.statuses) {
|
|
767
|
+
* console.log(`${status.id}: ${status.title}`);
|
|
768
|
+
* }
|
|
769
|
+
* ```
|
|
153
770
|
*/
|
|
154
|
-
|
|
771
|
+
statuses(options?: {
|
|
772
|
+
market?: string;
|
|
773
|
+
}): Promise<StatusesResponse>;
|
|
155
774
|
/**
|
|
156
|
-
*
|
|
775
|
+
* Get all available Vinted markets.
|
|
776
|
+
*
|
|
777
|
+
* @returns List of all supported Vinted markets/countries.
|
|
778
|
+
*
|
|
779
|
+
* @example
|
|
780
|
+
* ```typescript
|
|
781
|
+
* const response = await client.vinted.reference.markets();
|
|
782
|
+
* for (const market of response.markets) {
|
|
783
|
+
* console.log(`${market.name}: ${market.domain} (${market.currency})`);
|
|
784
|
+
* }
|
|
785
|
+
* ```
|
|
157
786
|
*/
|
|
158
|
-
|
|
787
|
+
markets(): Promise<MarketsResponse>;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* Vinted API client.
|
|
792
|
+
*
|
|
793
|
+
* Provides access to all Vinted API endpoints through specialized sub-clients.
|
|
794
|
+
*/
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Vinted API client with access to all Vinted endpoints.
|
|
798
|
+
*
|
|
799
|
+
* Provides sub-clients for different resource types:
|
|
800
|
+
* - `search` - Search for items across Vinted marketplaces
|
|
801
|
+
* - `items` - Get individual item details
|
|
802
|
+
* - `users` - User profiles and their item listings
|
|
803
|
+
* - `reference` - Reference data (brands, colors, statuses, markets)
|
|
804
|
+
*
|
|
805
|
+
* @example
|
|
806
|
+
* ```typescript
|
|
807
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
808
|
+
*
|
|
809
|
+
* // Search items
|
|
810
|
+
* const results = await client.vinted.search.search({ query: "nike air max" });
|
|
811
|
+
*
|
|
812
|
+
* // Get item details
|
|
813
|
+
* const item = await client.vinted.items.get(123456789);
|
|
814
|
+
*
|
|
815
|
+
* // Get user profile
|
|
816
|
+
* const user = await client.vinted.users.getProfile(12345);
|
|
817
|
+
*
|
|
818
|
+
* // Get reference data
|
|
819
|
+
* const markets = await client.vinted.reference.markets();
|
|
820
|
+
* ```
|
|
821
|
+
*/
|
|
822
|
+
declare class VintedClient {
|
|
823
|
+
/** Client for item search operations */
|
|
824
|
+
readonly search: SearchClient$2;
|
|
825
|
+
/** Client for individual item operations */
|
|
826
|
+
readonly items: ItemsClient;
|
|
827
|
+
/** Client for user operations */
|
|
828
|
+
readonly users: UsersClient$1;
|
|
829
|
+
/** Client for reference data (brands, colors, statuses, markets) */
|
|
830
|
+
readonly reference: ReferenceClient;
|
|
831
|
+
/**
|
|
832
|
+
* Create a new Vinted client.
|
|
833
|
+
*
|
|
834
|
+
* @param client - The base HTTP client for making requests.
|
|
835
|
+
*/
|
|
836
|
+
constructor(client: BaseClient);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* TypeScript parameter types for Google Scraper API sub-clients.
|
|
841
|
+
*
|
|
842
|
+
* Response types use `Record<string, unknown>` rather than strict interfaces
|
|
843
|
+
* because the Google API returns rich nested data that mirrors the server-side
|
|
844
|
+
* Pydantic models; users can cast to their own typed shapes as needed. All
|
|
845
|
+
* parameter types are strictly typed.
|
|
846
|
+
*/
|
|
847
|
+
type GoogleResponse = Record<string, unknown>;
|
|
848
|
+
interface GoogleSearchParams {
|
|
849
|
+
q: string;
|
|
850
|
+
gl?: string;
|
|
851
|
+
hl?: string;
|
|
852
|
+
num?: number;
|
|
853
|
+
start?: number;
|
|
854
|
+
domain?: string;
|
|
855
|
+
device?: "desktop" | "mobile";
|
|
856
|
+
location?: string;
|
|
857
|
+
lr?: string;
|
|
858
|
+
tbs?: string;
|
|
859
|
+
safe?: "off" | "medium" | "high";
|
|
860
|
+
uule?: string;
|
|
861
|
+
filter?: number;
|
|
862
|
+
nfpr?: number;
|
|
863
|
+
cr?: string;
|
|
864
|
+
ludocid?: string;
|
|
865
|
+
lsig?: string;
|
|
866
|
+
kgmid?: string;
|
|
867
|
+
si?: string;
|
|
868
|
+
ibp?: string;
|
|
869
|
+
uds?: string;
|
|
870
|
+
/**
|
|
871
|
+
* When true, chase Google's deferred AI Overview `page_token` with a
|
|
872
|
+
* follow-up fetch and merge the result back into `ai_overview`. Adds
|
|
873
|
+
* ~1s when the SERP actually defers the overview. Credit cost is
|
|
874
|
+
* configured per-endpoint by admins — query `/public/pricing` for the
|
|
875
|
+
* live rate.
|
|
876
|
+
*/
|
|
877
|
+
ai_overview?: boolean;
|
|
878
|
+
}
|
|
879
|
+
interface MapsSearchParams {
|
|
880
|
+
/** Search query. Required unless `place_id` or `ludocid` is supplied. */
|
|
881
|
+
q?: string;
|
|
882
|
+
/** GPS coords as `@lat,lng,zoom` (e.g. `@40.745,-74.008,14z`). */
|
|
883
|
+
ll?: string;
|
|
884
|
+
gl?: string;
|
|
885
|
+
hl?: string;
|
|
886
|
+
start?: number;
|
|
887
|
+
/** 1-indexed page number (alternative to `start`). */
|
|
888
|
+
page?: number;
|
|
889
|
+
/** Business-type slug (e.g. `restaurant`, `hotel`). */
|
|
890
|
+
type?: string;
|
|
891
|
+
/** Raw Google Maps `pb=` override for advanced queries. */
|
|
892
|
+
data?: string;
|
|
893
|
+
/** Google Place ID (`ChIJ...`) — direct-lookup a single place. */
|
|
894
|
+
place_id?: string;
|
|
895
|
+
/** Google Location Document ID (CID) — direct-lookup by CID. */
|
|
896
|
+
ludocid?: string;
|
|
897
|
+
}
|
|
898
|
+
interface MapsPlaceParams {
|
|
899
|
+
place_id?: string;
|
|
900
|
+
data_id?: string;
|
|
901
|
+
hl?: string;
|
|
902
|
+
gl?: string;
|
|
903
|
+
}
|
|
904
|
+
interface MapsReviewsParams {
|
|
905
|
+
data_id: string;
|
|
906
|
+
sort_by?: "qualityScore" | "newestFirst" | "ratingHigh" | "ratingLow";
|
|
907
|
+
hl?: string;
|
|
908
|
+
next_page_token?: string;
|
|
909
|
+
results?: number;
|
|
910
|
+
}
|
|
911
|
+
interface MapsPhotosParams {
|
|
912
|
+
data_id: string;
|
|
913
|
+
hl?: string;
|
|
914
|
+
next_page_token?: string;
|
|
915
|
+
}
|
|
916
|
+
interface MapsPostsParams {
|
|
917
|
+
/** Google Maps data ID (`0x...:0x...`). Required unless `place_id` is set. */
|
|
918
|
+
data_id?: string;
|
|
919
|
+
/** Google Place ID — alternative to `data_id`. */
|
|
920
|
+
place_id?: string;
|
|
921
|
+
hl?: string;
|
|
922
|
+
gl?: string;
|
|
923
|
+
next_page_token?: string;
|
|
924
|
+
}
|
|
925
|
+
interface NewsSearchParams {
|
|
926
|
+
/** Free-text keyword query. Pass this OR one of the token fields below. */
|
|
927
|
+
q?: string;
|
|
928
|
+
hl?: string;
|
|
929
|
+
gl?: string;
|
|
930
|
+
max_results?: number;
|
|
931
|
+
/** Google News topic token (from a previous response's `topic_token`). */
|
|
932
|
+
topic_token?: string;
|
|
933
|
+
/** Google News publication token — scopes results to a single publisher. */
|
|
934
|
+
publication_token?: string;
|
|
935
|
+
/** Google News story token — scopes results to a single story cluster. */
|
|
936
|
+
story_token?: string;
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Canonical Google News topic codes. Any string is accepted at runtime —
|
|
940
|
+
* use `NewsTopic` for IDE autocomplete on the standard topics and fall
|
|
941
|
+
* back to a plain `string` when you know the topic code out-of-band.
|
|
942
|
+
*/
|
|
943
|
+
type NewsTopic = "WORLD" | "BUSINESS" | "TECHNOLOGY" | "ENTERTAINMENT" | "SPORTS" | "SCIENCE" | "HEALTH";
|
|
944
|
+
interface NewsTopicsParams {
|
|
945
|
+
topic: NewsTopic | (string & {});
|
|
946
|
+
hl?: string;
|
|
947
|
+
gl?: string;
|
|
948
|
+
max_results?: number;
|
|
949
|
+
}
|
|
950
|
+
interface NewsTrendingParams {
|
|
951
|
+
hl?: string;
|
|
952
|
+
gl?: string;
|
|
953
|
+
max_results?: number;
|
|
954
|
+
}
|
|
955
|
+
interface HotelsSearchParams {
|
|
956
|
+
q: string;
|
|
957
|
+
check_in: string;
|
|
958
|
+
check_out: string;
|
|
959
|
+
adults?: number;
|
|
960
|
+
currency?: string;
|
|
961
|
+
gl?: string;
|
|
962
|
+
}
|
|
963
|
+
interface HotelsDetailsParams {
|
|
964
|
+
property_token: string;
|
|
965
|
+
check_in: string;
|
|
966
|
+
check_out: string;
|
|
967
|
+
}
|
|
968
|
+
interface TrendsInterestParams {
|
|
969
|
+
/** Up to 5 comma-separated terms. */
|
|
970
|
+
q: string;
|
|
971
|
+
/** Geographic location code (empty = worldwide). */
|
|
972
|
+
geo?: string;
|
|
973
|
+
/** Time range — e.g. `now 1-H`, `today 12-m`, `all`, or `YYYY-MM-DD YYYY-MM-DD`. */
|
|
974
|
+
date?: string;
|
|
975
|
+
/** Category filter id (0 = all). */
|
|
976
|
+
category?: number;
|
|
977
|
+
/** Property filter — `""`, `images`, `news`, `froogle`, or `youtube`. */
|
|
978
|
+
gprop?: string;
|
|
979
|
+
}
|
|
980
|
+
interface TrendsRegionsParams {
|
|
981
|
+
q: string;
|
|
982
|
+
geo?: string;
|
|
983
|
+
date?: string;
|
|
984
|
+
/** Region granularity — `auto` (default), `COUNTRY`, `REGION`, `DMA`, or `CITY`. */
|
|
985
|
+
resolution?: "auto" | "COUNTRY" | "REGION" | "DMA" | "CITY";
|
|
986
|
+
}
|
|
987
|
+
interface TrendsRelatedParams {
|
|
988
|
+
q: string;
|
|
989
|
+
geo?: string;
|
|
990
|
+
date?: string;
|
|
991
|
+
}
|
|
992
|
+
interface TrendsTrendingParams {
|
|
993
|
+
/** Country code (ISO 3166 alpha-2). Defaults to `US`. */
|
|
994
|
+
geo?: string;
|
|
995
|
+
/** Language code (e.g. `en-US`). */
|
|
996
|
+
hl?: string;
|
|
997
|
+
/** Look-back window — Google supports `24` (default), `48`, `168` (= 1 week). */
|
|
998
|
+
hours?: number;
|
|
999
|
+
}
|
|
1000
|
+
type TrendsCategory = "all" | "business" | "entertainment" | "health" | "sci_tech" | "sports" | "top_stories" | "b" | "e" | "m" | "t" | "s" | "h";
|
|
1001
|
+
type TrendsTrendingStatus = "all" | "active";
|
|
1002
|
+
type TrendsTrendingSort = "relevance" | "search_volume" | "title" | "recency";
|
|
1003
|
+
interface TrendsTrendingNowParams {
|
|
1004
|
+
/** Country code (e.g. "US", "LT", "GB"). */
|
|
1005
|
+
geo?: string;
|
|
1006
|
+
/** Look-back window in hours. Common: 4, 24, 48, 168. */
|
|
1007
|
+
hours?: number;
|
|
1008
|
+
/** Category filter. */
|
|
1009
|
+
category?: TrendsCategory;
|
|
1010
|
+
/** Trend state: "all" (default) or "active" (only non-zero search volume). */
|
|
1011
|
+
status?: TrendsTrendingStatus;
|
|
1012
|
+
/** Sort order: relevance / search_volume / title / recency. */
|
|
1013
|
+
sort?: TrendsTrendingSort;
|
|
1014
|
+
/** Language code (e.g. "en-US"). */
|
|
1015
|
+
hl?: string;
|
|
1016
|
+
}
|
|
1017
|
+
type TrendsDataType = "TIMESERIES" | "GEO_MAP" | "GEO_MAP_0" | "RELATED_TOPICS" | "RELATED_QUERIES";
|
|
1018
|
+
interface TrendsSearchParams {
|
|
1019
|
+
/** Search term(s). Comma-separated (max 5) for TIMESERIES / GEO_MAP. */
|
|
1020
|
+
q: string;
|
|
1021
|
+
data_type?: TrendsDataType;
|
|
1022
|
+
geo?: string;
|
|
1023
|
+
date?: string;
|
|
1024
|
+
cat?: number;
|
|
1025
|
+
gprop?: string;
|
|
1026
|
+
region?: "COUNTRY" | "REGION" | "DMA" | "CITY";
|
|
1027
|
+
language?: string;
|
|
1028
|
+
tz?: string;
|
|
1029
|
+
}
|
|
1030
|
+
interface TrendsAutocompleteParams {
|
|
1031
|
+
/** Query prefix to resolve into Trends topics. */
|
|
1032
|
+
q: string;
|
|
1033
|
+
/** Language code (e.g. "en-US"). */
|
|
1034
|
+
hl?: string;
|
|
1035
|
+
/** Timezone offset in minutes. */
|
|
1036
|
+
tz?: string;
|
|
1037
|
+
}
|
|
1038
|
+
interface JobsSearchParams {
|
|
1039
|
+
q: string;
|
|
1040
|
+
/**
|
|
1041
|
+
* Data source.
|
|
1042
|
+
* - `"rpc"` (default, ~1-2 s): Google Careers batchexecute RPC —
|
|
1043
|
+
* structured JSON, scope = Google's own openings.
|
|
1044
|
+
* - `"serp"`: public Google Jobs SERP aggregator — 3rd-party listings
|
|
1045
|
+
* (LinkedIn, Indeed, Built In, ZipRecruiter, …).
|
|
1046
|
+
*/
|
|
1047
|
+
mode?: "rpc" | "serp";
|
|
1048
|
+
location?: string;
|
|
1049
|
+
gl?: string;
|
|
1050
|
+
/** Alias for gl. */
|
|
1051
|
+
country?: string;
|
|
1052
|
+
hl?: string;
|
|
1053
|
+
/** Alias for hl (accepts "en-US" etc). */
|
|
1054
|
+
language?: string;
|
|
1055
|
+
/** Google domain (google.com, google.co.uk, …). */
|
|
1056
|
+
domain?: string;
|
|
1057
|
+
job_type?: "FULLTIME" | "PARTTIME" | "CONTRACTOR" | "INTERN";
|
|
1058
|
+
date_posted?: "today" | "3days" | "week" | "month";
|
|
1059
|
+
/** Work arrangement — SERP mode only. */
|
|
1060
|
+
ltype?: "remote" | "hybrid" | "onsite" | "work_from_home";
|
|
1061
|
+
/** Raw Google chip filter string — SERP mode only. */
|
|
1062
|
+
chips?: string;
|
|
1063
|
+
/** Opaque Google filter token — SERP mode only. */
|
|
1064
|
+
uds?: string;
|
|
1065
|
+
/** UULE-encoded location — SERP mode only. */
|
|
1066
|
+
uule?: string;
|
|
1067
|
+
/** Search radius in miles — SERP mode only. */
|
|
1068
|
+
lrad?: string;
|
|
1069
|
+
/** Pagination token from prior response. */
|
|
1070
|
+
next_page_token?: string;
|
|
1071
|
+
}
|
|
1072
|
+
interface ShoppingSearchParams {
|
|
1073
|
+
q: string;
|
|
1074
|
+
gl?: string;
|
|
1075
|
+
hl?: string;
|
|
1076
|
+
domain?: string;
|
|
1077
|
+
/** Zero-based page index (each page ≈ 60 tiles). */
|
|
1078
|
+
page?: number;
|
|
1079
|
+
min_price?: number;
|
|
1080
|
+
max_price?: number;
|
|
1081
|
+
sort_by?: "price_low" | "price_high" | "rating" | "reviews";
|
|
1082
|
+
/** Free-shipping filter. */
|
|
1083
|
+
free_shipping?: boolean;
|
|
1084
|
+
/** On-sale filter. */
|
|
1085
|
+
on_sale?: boolean;
|
|
1086
|
+
safe?: "off" | "active";
|
|
1087
|
+
/** `1` disables auto-correction. */
|
|
1088
|
+
nfpr?: number;
|
|
1089
|
+
/** Language restrict (e.g. `lang_en`). */
|
|
1090
|
+
lr?: string;
|
|
1091
|
+
/** Raw Google tbs filter. */
|
|
1092
|
+
tbs?: string;
|
|
1093
|
+
/** Google internal shoprs helper token. */
|
|
1094
|
+
shoprs?: string;
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Params for `/v1/google/shopping/product` — Google Shopping product
|
|
1098
|
+
* detail page lookup.
|
|
1099
|
+
*/
|
|
1100
|
+
interface ShoppingProductParams {
|
|
1101
|
+
product_id: string;
|
|
1102
|
+
gl?: string;
|
|
1103
|
+
hl?: string;
|
|
1104
|
+
domain?: string;
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Params for `/v1/google/shopping/product/click` — resolve the direct
|
|
1108
|
+
* merchant URL for a Shopping product tile. Uses Google's "I'm Feeling
|
|
1109
|
+
* Lucky" redirect scoped to the card's `source` merchant via the
|
|
1110
|
+
* `site:` operator.
|
|
1111
|
+
*/
|
|
1112
|
+
interface ShoppingClickParams {
|
|
1113
|
+
title: string;
|
|
1114
|
+
source: string;
|
|
1115
|
+
q: string;
|
|
1116
|
+
product_id?: string;
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Params for `/v1/google/patents/search`. Backed by Google Patents'
|
|
1120
|
+
* `/xhr/query` JSON RPC — ~1 s regardless of filter complexity.
|
|
1121
|
+
*/
|
|
1122
|
+
interface PatentsSearchParams {
|
|
1123
|
+
/** Query string — supports Boolean logic (e.g. "quantum AND compute"). */
|
|
1124
|
+
q: string;
|
|
1125
|
+
page?: number;
|
|
1126
|
+
num?: number;
|
|
1127
|
+
sort?: "new" | "old";
|
|
1128
|
+
/** Comma-separated inventor names. */
|
|
1129
|
+
inventor?: string;
|
|
1130
|
+
/** Comma-separated assignee / company names. */
|
|
1131
|
+
assignee?: string;
|
|
1132
|
+
/** Patent-office country code (US, EP, WO, …). */
|
|
1133
|
+
country?: string;
|
|
1134
|
+
language?: "ENGLISH" | "GERMAN" | "CHINESE" | "FRENCH" | "JAPANESE" | "KOREAN" | "SPANISH";
|
|
1135
|
+
status?: "GRANT" | "APPLICATION";
|
|
1136
|
+
patent_type?: "PATENT" | "DESIGN";
|
|
1137
|
+
/** Filing/priority-date upper bound (YYYYMMDD). */
|
|
1138
|
+
before?: string;
|
|
1139
|
+
/** Filing/priority-date lower bound (YYYYMMDD). */
|
|
1140
|
+
after?: string;
|
|
1141
|
+
}
|
|
1142
|
+
interface PatentsDetailParams {
|
|
1143
|
+
/** Publication number (e.g. "US10000000B2", "EP3097156B1"). */
|
|
1144
|
+
patent_id: string;
|
|
1145
|
+
}
|
|
1146
|
+
interface ScholarSearchParams {
|
|
1147
|
+
q: string;
|
|
1148
|
+
hl?: string;
|
|
1149
|
+
as_ylo?: number;
|
|
1150
|
+
as_yhi?: number;
|
|
1151
|
+
as_sdt?: string;
|
|
1152
|
+
page?: number;
|
|
1153
|
+
num?: number;
|
|
1154
|
+
}
|
|
1155
|
+
interface ScholarProfilesParams {
|
|
1156
|
+
/** Author name query (e.g. "Geoffrey Hinton"). */
|
|
1157
|
+
mauthors: string;
|
|
1158
|
+
hl?: string;
|
|
1159
|
+
/** Next-page pagination token from a previous response. */
|
|
1160
|
+
after_author?: string;
|
|
1161
|
+
/** Previous-page pagination token. */
|
|
1162
|
+
before_author?: string;
|
|
1163
|
+
}
|
|
1164
|
+
interface ScholarAuthorParams {
|
|
1165
|
+
/** Scholar user ID (the `user` query parameter on a profile URL). */
|
|
1166
|
+
author_id: string;
|
|
1167
|
+
hl?: string;
|
|
1168
|
+
/** Articles pagination offset. */
|
|
1169
|
+
cstart?: number;
|
|
1170
|
+
/** Articles per page. */
|
|
1171
|
+
pagesize?: number;
|
|
1172
|
+
}
|
|
1173
|
+
interface ScholarAuthorCitationParams {
|
|
1174
|
+
author_id: string;
|
|
1175
|
+
hl?: string;
|
|
1176
|
+
}
|
|
1177
|
+
interface ScholarCiteParams {
|
|
1178
|
+
/** Cluster ID from a Scholar search result. */
|
|
1179
|
+
q: string;
|
|
1180
|
+
hl?: string;
|
|
1181
|
+
}
|
|
1182
|
+
interface AutocompleteParams {
|
|
1183
|
+
q: string;
|
|
1184
|
+
hl?: string;
|
|
1185
|
+
gl?: string;
|
|
1186
|
+
}
|
|
1187
|
+
interface ImagesSearchParams {
|
|
1188
|
+
q: string;
|
|
1189
|
+
gl?: string;
|
|
1190
|
+
hl?: string;
|
|
1191
|
+
/** Zero-based page index (each page ≈ 100 tiles). */
|
|
1192
|
+
page?: number;
|
|
1193
|
+
/** Max tiles to return (1-500, client-side cap). */
|
|
1194
|
+
results?: number;
|
|
1195
|
+
safe?: "off" | "active";
|
|
1196
|
+
/** Raw Google tbs filter (e.g. `qdr:d`). */
|
|
1197
|
+
tbs?: string;
|
|
1198
|
+
/** Size: `l`, `m`, `i`, `xXl`, `xxl`, `xxxl`. */
|
|
1199
|
+
imgsz?: string;
|
|
1200
|
+
/** Colour: `color`, `gray`, `transparent`, `red`, `orange`, … */
|
|
1201
|
+
imgcolor?: string;
|
|
1202
|
+
/** Type: `face`, `photo`, `clipart`, `lineart`, `animated`. */
|
|
1203
|
+
imgtype?: string;
|
|
1204
|
+
}
|
|
1205
|
+
interface VideosSearchParams {
|
|
1206
|
+
q: string;
|
|
1207
|
+
gl?: string;
|
|
1208
|
+
hl?: string;
|
|
1209
|
+
/** Zero-based page index (each page ≈ 10 tiles). */
|
|
1210
|
+
page?: number;
|
|
1211
|
+
/** Google domain (`google.com`, `google.co.uk`, …). */
|
|
1212
|
+
domain?: string;
|
|
1213
|
+
/** City-level geo-targeting. */
|
|
1214
|
+
location?: string;
|
|
1215
|
+
/** Language restrict (e.g. `lang_en`). */
|
|
1216
|
+
lr?: string;
|
|
1217
|
+
/** UULE-encoded location. */
|
|
1218
|
+
uule?: string;
|
|
1219
|
+
/** `1` disables auto-correction. */
|
|
1220
|
+
nfpr?: number;
|
|
1221
|
+
safe?: "off" | "active";
|
|
1222
|
+
/** Time/duration chip: `qdr:d/w/m`, `dur:s/m/l`. */
|
|
1223
|
+
tbs?: string;
|
|
1224
|
+
}
|
|
1225
|
+
interface FinanceQuoteParams {
|
|
1226
|
+
/** Ticker, optionally with exchange — `AAPL`, `AAPL:NASDAQ`, `BTC-USD`, `EURUSD`. */
|
|
1227
|
+
q: string;
|
|
1228
|
+
hl?: string;
|
|
1229
|
+
gl?: string;
|
|
1230
|
+
}
|
|
1231
|
+
interface AiModeSearchParams {
|
|
1232
|
+
q: string;
|
|
1233
|
+
gl?: string;
|
|
1234
|
+
hl?: string;
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Params for `/v1/google/lens/search`. Response carries `lens_results`
|
|
1238
|
+
* (Scrapingdog parity — each item has `title`, `source`,
|
|
1239
|
+
* `source_favicon`, `thumbnail`, optional `tag` price chip and
|
|
1240
|
+
* `in_stock`) plus `related_searches` chips. Legacy `results` alias
|
|
1241
|
+
* retained for backwards compat.
|
|
1242
|
+
*/
|
|
1243
|
+
interface LensSearchParams {
|
|
1244
|
+
/** Public URL of the image to search visually. */
|
|
1245
|
+
url: string;
|
|
1246
|
+
/** Optional text refinement (e.g. `"pizza"`) to bias Lens. */
|
|
1247
|
+
query?: string;
|
|
1248
|
+
/** ISO country code — Scrapingdog-parity alias for `gl`. */
|
|
1249
|
+
country?: string;
|
|
1250
|
+
/** Language code — Scrapingdog-parity alias for `hl`. */
|
|
1251
|
+
language?: string;
|
|
1252
|
+
gl?: string;
|
|
1253
|
+
hl?: string;
|
|
1254
|
+
/** Bias towards shoppable product matches. */
|
|
1255
|
+
product?: boolean;
|
|
1256
|
+
/** Include the visual-matches carousel (default: true). */
|
|
1257
|
+
visual_matches?: boolean;
|
|
1258
|
+
/** Restrict to exact-match results only. */
|
|
1259
|
+
exact_matches?: boolean;
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Params for `/v1/google/products/detail`. Backed by Google's
|
|
1263
|
+
* `/async/oapv` RPC — full product payload (title, brand, price, rating,
|
|
1264
|
+
* specs) in ~2s via warm-session curl_cffi.
|
|
1265
|
+
*/
|
|
1266
|
+
interface ProductsDetailParams {
|
|
1267
|
+
/** Google Shopping `gpcid`. Search results expose this on each tile. */
|
|
1268
|
+
product_id: string;
|
|
1269
|
+
/** Original search query — required, used to build the oapv context blob. */
|
|
1270
|
+
q: string;
|
|
1271
|
+
gl?: string;
|
|
1272
|
+
hl?: string;
|
|
1273
|
+
/** Google domain used to localise the SERP that yields oapv session tokens. */
|
|
1274
|
+
domain?: string;
|
|
1275
|
+
/** Extra IDs Google surfaces on Shopping tiles. Improves routing accuracy. */
|
|
1276
|
+
catalog_id?: string;
|
|
1277
|
+
image_docid?: string;
|
|
1278
|
+
headline_offer_docid?: string;
|
|
1279
|
+
mid?: string;
|
|
1280
|
+
/** When true, also fetches `/async/piu_ps` for the merchant offers list. */
|
|
1281
|
+
include_offers?: boolean;
|
|
1282
|
+
/** When true, also fetches `/async/toy_v` for size/colour variants. */
|
|
1283
|
+
include_variants?: boolean;
|
|
1284
|
+
/**
|
|
1285
|
+
* Only meaningful with `include_offers=true`. When true, browser-renders
|
|
1286
|
+
* the Shopping SERP so additional merchant deep URLs surface from the
|
|
1287
|
+
* rendered HTML. Adds ~5–8 s latency.
|
|
1288
|
+
*/
|
|
1289
|
+
resolve_deep_urls?: boolean;
|
|
1290
|
+
}
|
|
1291
|
+
interface ShortsSearchParams {
|
|
1292
|
+
q: string;
|
|
1293
|
+
gl?: string;
|
|
1294
|
+
hl?: string;
|
|
1295
|
+
domain?: string;
|
|
1296
|
+
/** Max tiles to return (1-60 cap). */
|
|
1297
|
+
num?: number;
|
|
1298
|
+
/** Pagination offset. */
|
|
1299
|
+
start?: number;
|
|
1300
|
+
safe?: "off" | "active";
|
|
1301
|
+
/** `1` disables auto-correction. */
|
|
1302
|
+
nfpr?: number;
|
|
1303
|
+
/** Raw Google tbs filter (e.g. `qdr:d`). */
|
|
1304
|
+
tbs?: string;
|
|
1305
|
+
}
|
|
1306
|
+
type FlightsTripType = "round_trip" | "one_way" | "multi_city";
|
|
1307
|
+
type FlightsTravelClass = "economy" | "premium_economy" | "business" | "first";
|
|
1308
|
+
type FlightsStopsFilter = "any" | "nonstop" | "one_stop" | "two_stops";
|
|
1309
|
+
interface FlightsSearchParams {
|
|
1310
|
+
/** Departure airport IATA code (e.g. "JFK") or location ID. */
|
|
1311
|
+
departure_id: string;
|
|
1312
|
+
/** Arrival airport IATA code (e.g. "LHR") or location ID. */
|
|
1313
|
+
arrival_id: string;
|
|
1314
|
+
/** Outbound date in YYYY-MM-DD format. */
|
|
1315
|
+
outbound_date: string;
|
|
1316
|
+
/** Return date (required for round_trip). */
|
|
1317
|
+
return_date?: string;
|
|
1318
|
+
trip_type?: FlightsTripType;
|
|
1319
|
+
/** Adult passengers (1-9). */
|
|
1320
|
+
adults?: number;
|
|
1321
|
+
/** Children passengers (0-8). */
|
|
1322
|
+
children?: number;
|
|
1323
|
+
/** Infants in seat (0-4). */
|
|
1324
|
+
infants_in_seat?: number;
|
|
1325
|
+
/** Infants on lap (0-4). */
|
|
1326
|
+
infants_on_lap?: number;
|
|
1327
|
+
travel_class?: FlightsTravelClass;
|
|
1328
|
+
/** ISO-4217 currency code (default "USD"). */
|
|
1329
|
+
currency?: string;
|
|
1330
|
+
gl?: string;
|
|
1331
|
+
hl?: string;
|
|
1332
|
+
stops?: FlightsStopsFilter;
|
|
1333
|
+
/** Upper price filter. */
|
|
1334
|
+
max_price?: number;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
/**
|
|
1338
|
+
* Google AI Mode API client (udm=50 generative answers).
|
|
1339
|
+
*/
|
|
1340
|
+
|
|
1341
|
+
/**
|
|
1342
|
+
* Client for Google AI Mode.
|
|
1343
|
+
*/
|
|
1344
|
+
declare class AiModeClient {
|
|
1345
|
+
private readonly client;
|
|
1346
|
+
constructor(client: BaseClient);
|
|
1347
|
+
search(params: AiModeSearchParams): Promise<GoogleResponse>;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
/**
|
|
1351
|
+
* Google Autocomplete API client.
|
|
1352
|
+
*
|
|
1353
|
+
* Returns up to 10 search suggestions. Suggestions that resolve to
|
|
1354
|
+
* Knowledge-Graph entities (companies, people, movies, stocks, local
|
|
1355
|
+
* businesses, …) additionally carry `entity_name` and `thumbnail` —
|
|
1356
|
+
* the same enrichment Google's own search-box surfaces.
|
|
1357
|
+
*/
|
|
1358
|
+
|
|
1359
|
+
/**
|
|
1360
|
+
* Client for Google Autocomplete (search suggestions).
|
|
1361
|
+
*/
|
|
1362
|
+
declare class AutocompleteClient {
|
|
1363
|
+
private readonly client;
|
|
1364
|
+
constructor(client: BaseClient);
|
|
1365
|
+
/**
|
|
1366
|
+
* Get Google autocomplete suggestions for a query.
|
|
1367
|
+
*
|
|
1368
|
+
* @example
|
|
1369
|
+
* ```typescript
|
|
1370
|
+
* const res = await client.google.autocomplete.get({ q: "apple" });
|
|
1371
|
+
* for (const s of res.suggestions) {
|
|
1372
|
+
* console.log(s.value, s.entity_name, s.thumbnail);
|
|
1373
|
+
* }
|
|
1374
|
+
* ```
|
|
1375
|
+
*/
|
|
1376
|
+
get(params: AutocompleteParams): Promise<GoogleResponse>;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
/**
|
|
1380
|
+
* Google Finance API client.
|
|
1381
|
+
*
|
|
1382
|
+
* Powered by the same `mKsvE` batchexecute RPC the Google Finance SPA
|
|
1383
|
+
* uses internally. Returns price / change / change% / previous_close /
|
|
1384
|
+
* after-hours / market hours / timezone / currency / country /
|
|
1385
|
+
* alternate exchange listings in ~1 s.
|
|
1386
|
+
*/
|
|
1387
|
+
|
|
1388
|
+
/**
|
|
1389
|
+
* Client for Google Finance quotes.
|
|
1390
|
+
*
|
|
1391
|
+
* @example
|
|
1392
|
+
* ```typescript
|
|
1393
|
+
* const quote = await client.google.finance.quote({ q: "AAPL:NASDAQ" });
|
|
1394
|
+
* console.log(quote.price, quote.currency, quote.after_hours);
|
|
1395
|
+
* ```
|
|
1396
|
+
*/
|
|
1397
|
+
declare class FinanceClient {
|
|
1398
|
+
private readonly client;
|
|
1399
|
+
constructor(client: BaseClient);
|
|
1400
|
+
quote(params: FinanceQuoteParams): Promise<GoogleResponse>;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
/**
|
|
1404
|
+
* Google Flights API client — one-way, round-trip, multi-city.
|
|
1405
|
+
*/
|
|
1406
|
+
|
|
1407
|
+
/**
|
|
1408
|
+
* Client for Google Flights search.
|
|
1409
|
+
*
|
|
1410
|
+
* Supports one-way, round-trip, and multi-city itineraries with
|
|
1411
|
+
* passenger configuration, cabin class, stops filter, and max-price.
|
|
1412
|
+
* Returns Google's Best flights recommendations plus the full Other
|
|
1413
|
+
* flights result set, with per-offer pricing, duration, stops,
|
|
1414
|
+
* layovers, carbon emissions, and price insights (low / typical /
|
|
1415
|
+
* high + typical price range) when Google shows them.
|
|
1416
|
+
*
|
|
1417
|
+
* @example
|
|
1418
|
+
* ```typescript
|
|
1419
|
+
* const flights = await client.google.flights.search({
|
|
1420
|
+
* departure_id: "JFK",
|
|
1421
|
+
* arrival_id: "LHR",
|
|
1422
|
+
* outbound_date: "2026-06-15",
|
|
1423
|
+
* return_date: "2026-06-22",
|
|
1424
|
+
* adults: 2,
|
|
1425
|
+
* });
|
|
1426
|
+
* for (const offer of flights.best_flights) {
|
|
1427
|
+
* console.log(offer.price, offer.currency, offer.total_duration_minutes);
|
|
1428
|
+
* }
|
|
1429
|
+
* if (flights.price_insights) {
|
|
1430
|
+
* console.log("Price level:", flights.price_insights.price_level);
|
|
1431
|
+
* }
|
|
1432
|
+
* ```
|
|
1433
|
+
*/
|
|
1434
|
+
declare class FlightsClient {
|
|
1435
|
+
private readonly client;
|
|
1436
|
+
constructor(client: BaseClient);
|
|
1437
|
+
/** Search Google Flights for available itineraries. */
|
|
1438
|
+
search(params: FlightsSearchParams): Promise<GoogleResponse>;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
/**
|
|
1442
|
+
* Google Hotels API client — search, property details.
|
|
1443
|
+
*/
|
|
1444
|
+
|
|
1445
|
+
/**
|
|
1446
|
+
* Client for Google Hotels endpoints.
|
|
1447
|
+
*
|
|
1448
|
+
* @example
|
|
1449
|
+
* ```typescript
|
|
1450
|
+
* const hotels = await client.google.hotels.search({
|
|
1451
|
+
* q: "Paris",
|
|
1452
|
+
* check_in: "2026-05-01",
|
|
1453
|
+
* check_out: "2026-05-05",
|
|
1454
|
+
* adults: 2,
|
|
1455
|
+
* });
|
|
1456
|
+
* ```
|
|
1457
|
+
*/
|
|
1458
|
+
declare class HotelsClient {
|
|
1459
|
+
private readonly client;
|
|
1460
|
+
constructor(client: BaseClient);
|
|
1461
|
+
search(params: HotelsSearchParams): Promise<GoogleResponse>;
|
|
1462
|
+
details(params: HotelsDetailsParams): Promise<GoogleResponse>;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
/**
|
|
1466
|
+
* Google Images API client.
|
|
1467
|
+
*
|
|
1468
|
+
* Returns up to 100 tiles per page with `title`, `source`, `link`
|
|
1469
|
+
* (referrer page), `thumbnail`, `image` (inline preview), `original`
|
|
1470
|
+
* (full-res URL), `original_width` / `original_height`,
|
|
1471
|
+
* `original_size` (e.g. `"635KB"`), plus licensability flags.
|
|
1472
|
+
*/
|
|
1473
|
+
|
|
1474
|
+
/**
|
|
1475
|
+
* Client for Google Images search.
|
|
1476
|
+
*
|
|
1477
|
+
* @example
|
|
1478
|
+
* ```typescript
|
|
1479
|
+
* const res = await client.google.images.search({
|
|
1480
|
+
* q: "golden retriever",
|
|
1481
|
+
* imgsz: "l",
|
|
1482
|
+
* imgcolor: "color",
|
|
1483
|
+
* });
|
|
1484
|
+
* for (const img of res.results) {
|
|
1485
|
+
* console.log(img.rank, img.title, img.original);
|
|
1486
|
+
* }
|
|
1487
|
+
* ```
|
|
1488
|
+
*/
|
|
1489
|
+
declare class ImagesClient {
|
|
1490
|
+
private readonly client;
|
|
1491
|
+
constructor(client: BaseClient);
|
|
1492
|
+
search(params: ImagesSearchParams): Promise<GoogleResponse>;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
/**
|
|
1496
|
+
* Google Jobs API client.
|
|
1497
|
+
*/
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* Client for Google Jobs search.
|
|
1501
|
+
*
|
|
1502
|
+
* @example
|
|
1503
|
+
* ```typescript
|
|
1504
|
+
* const jobs = await client.google.jobs.search({
|
|
1505
|
+
* q: "software engineer",
|
|
1506
|
+
* location: "San Francisco, CA",
|
|
1507
|
+
* job_type: "FULLTIME",
|
|
1508
|
+
* });
|
|
1509
|
+
* ```
|
|
1510
|
+
*/
|
|
1511
|
+
declare class JobsClient {
|
|
1512
|
+
private readonly client;
|
|
1513
|
+
constructor(client: BaseClient);
|
|
1514
|
+
search(params: JobsSearchParams): Promise<GoogleResponse>;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
/**
|
|
1518
|
+
* Google Lens API client (visual image search).
|
|
1519
|
+
*/
|
|
1520
|
+
|
|
1521
|
+
/**
|
|
1522
|
+
* Client for Google Lens visual search by image URL.
|
|
1523
|
+
*
|
|
1524
|
+
* Response carries `lens_results` (Scrapingdog-parity alias) with
|
|
1525
|
+
* `title`, `source`, `source_favicon`, `thumbnail`, optional `tag`
|
|
1526
|
+
* price chip and `in_stock`, plus `related_searches` chips. Legacy
|
|
1527
|
+
* `results` alias retained for backwards compat.
|
|
1528
|
+
*
|
|
1529
|
+
* @example
|
|
1530
|
+
* ```typescript
|
|
1531
|
+
* const out = await client.google.lens.search({
|
|
1532
|
+
* url: "https://example.com/photo.jpg",
|
|
1533
|
+
* product: true, // bias towards shoppable matches
|
|
1534
|
+
* });
|
|
1535
|
+
* for (const match of out.lens_results) {
|
|
1536
|
+
* console.log(match.title, match.tag);
|
|
1537
|
+
* }
|
|
1538
|
+
* ```
|
|
1539
|
+
*/
|
|
1540
|
+
declare class LensClient {
|
|
1541
|
+
private readonly client;
|
|
1542
|
+
constructor(client: BaseClient);
|
|
1543
|
+
search(params: LensSearchParams): Promise<GoogleResponse>;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
/**
|
|
1547
|
+
* Google Maps API client — search, place details, reviews, photos, posts.
|
|
1548
|
+
*/
|
|
1549
|
+
|
|
1550
|
+
/**
|
|
1551
|
+
* Client for Google Maps endpoints.
|
|
1552
|
+
*
|
|
1553
|
+
* @example
|
|
1554
|
+
* ```typescript
|
|
1555
|
+
* const places = await client.google.maps.search({ q: "coffee shops sf" });
|
|
1556
|
+
* const detail = await client.google.maps.place({ data_id: "0x...:0x..." });
|
|
1557
|
+
* const reviews = await client.google.maps.reviews({
|
|
1558
|
+
* data_id: "0x...:0x...",
|
|
1559
|
+
* sort_by: "newestFirst",
|
|
1560
|
+
* });
|
|
1561
|
+
* ```
|
|
1562
|
+
*/
|
|
1563
|
+
declare class MapsClient {
|
|
1564
|
+
private readonly client;
|
|
1565
|
+
constructor(client: BaseClient);
|
|
1566
|
+
/**
|
|
1567
|
+
* Search Maps for places by text query, place_id, or ludocid.
|
|
1568
|
+
*
|
|
1569
|
+
* Returns up to 20 results per page with full details (place_id,
|
|
1570
|
+
* data_id, GPS, rating, reviews, address, phone, website, extensions,
|
|
1571
|
+
* weekly hours, thumbnail) in a single call.
|
|
1572
|
+
*/
|
|
1573
|
+
search(params: MapsSearchParams): Promise<GoogleResponse>;
|
|
1574
|
+
/**
|
|
1575
|
+
* Get full place detail by `place_id` or `data_id`.
|
|
1576
|
+
*
|
|
1577
|
+
* Returns title, address, phone, website, GPS, rating, reviews_count,
|
|
1578
|
+
* rating_summary (per-star distribution), categories, extensions
|
|
1579
|
+
* (service_options, accessibility, offerings, payments), weekly
|
|
1580
|
+
* operating hours, popular_times graph, provider_id,
|
|
1581
|
+
* permanently_closed, thumbnail, and photo list.
|
|
1582
|
+
*/
|
|
1583
|
+
place(params: MapsPlaceParams): Promise<GoogleResponse>;
|
|
1584
|
+
/**
|
|
1585
|
+
* Get reviews for a place (paginated, optional topic filter).
|
|
1586
|
+
*
|
|
1587
|
+
* Pass the `next_page_token` from `response.pagination.next` for
|
|
1588
|
+
* subsequent pages, or use `topic_id` from `response.topics[].id`
|
|
1589
|
+
* to scope to a specific review topic.
|
|
1590
|
+
*/
|
|
1591
|
+
reviews(params: MapsReviewsParams): Promise<GoogleResponse>;
|
|
1592
|
+
/**
|
|
1593
|
+
* Get photos for a place with place-specific categories.
|
|
1594
|
+
*
|
|
1595
|
+
* Returns place-specific categories (Menu, Vibe, Comfort food, dish
|
|
1596
|
+
* names) and photo URLs from all CDN families. Use `category_id` to
|
|
1597
|
+
* scope to a category, or `page_size: 200` to fetch all photos in
|
|
1598
|
+
* one call (Google caps at ~120 photos per response).
|
|
1599
|
+
*/
|
|
1600
|
+
photos(params: MapsPhotosParams): Promise<GoogleResponse>;
|
|
1601
|
+
/** Get business posts (promotional updates, announcements) for a place. */
|
|
1602
|
+
posts(params: MapsPostsParams): Promise<GoogleResponse>;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
/**
|
|
1606
|
+
* Google News API client — search, topics, trending.
|
|
1607
|
+
*/
|
|
1608
|
+
|
|
1609
|
+
/**
|
|
1610
|
+
* Client for Google News endpoints.
|
|
1611
|
+
*
|
|
1612
|
+
* @example
|
|
1613
|
+
* ```typescript
|
|
1614
|
+
* const articles = await client.google.news.search({ q: "openai" });
|
|
1615
|
+
* const tech = await client.google.news.topics({ topic: "TECHNOLOGY" });
|
|
1616
|
+
* const trending = await client.google.news.trending();
|
|
1617
|
+
* ```
|
|
1618
|
+
*/
|
|
1619
|
+
declare class NewsClient {
|
|
1620
|
+
private readonly client;
|
|
1621
|
+
constructor(client: BaseClient);
|
|
1622
|
+
/**
|
|
1623
|
+
* Search Google News. One of `q`, `topic_token`, `publication_token`,
|
|
1624
|
+
* or `story_token` is required (or pass no params for the trending
|
|
1625
|
+
* home feed). Returns `menu_links`, `news_results`, `related_topics`.
|
|
1626
|
+
*/
|
|
1627
|
+
search(params?: NewsSearchParams): Promise<GoogleResponse>;
|
|
1628
|
+
topics(params: NewsTopicsParams): Promise<GoogleResponse>;
|
|
1629
|
+
trending(params?: NewsTrendingParams): Promise<GoogleResponse>;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
/**
|
|
1633
|
+
* Google Patents API client — search, detail.
|
|
1634
|
+
*/
|
|
1635
|
+
|
|
1636
|
+
/**
|
|
1637
|
+
* Client for Google Patents endpoints.
|
|
1638
|
+
*
|
|
1639
|
+
* @example
|
|
1640
|
+
* ```typescript
|
|
1641
|
+
* const results = await client.google.patents.search({
|
|
1642
|
+
* q: "distributed lock",
|
|
1643
|
+
* assignee: "Google",
|
|
1644
|
+
* });
|
|
1645
|
+
* ```
|
|
1646
|
+
*/
|
|
1647
|
+
declare class PatentsClient {
|
|
1648
|
+
private readonly client;
|
|
1649
|
+
constructor(client: BaseClient);
|
|
1650
|
+
search(params: PatentsSearchParams): Promise<GoogleResponse>;
|
|
1651
|
+
/**
|
|
1652
|
+
* Get rich patent document details by patent number.
|
|
1653
|
+
*
|
|
1654
|
+
* Response includes full abstract + every claim + complete description,
|
|
1655
|
+
* plus structured `cpc_classifications` (code + description), split
|
|
1656
|
+
* `backward_citations` / `forward_citations` (with `primary_examiner`
|
|
1657
|
+
* flag), `non_patent_citations`, `concepts` (research fields),
|
|
1658
|
+
* `legal_events` (prosecution history), `figures` (full-res URLs),
|
|
1659
|
+
* every `inventor`, and the full `assignees_original` history.
|
|
1660
|
+
*/
|
|
1661
|
+
detail(params: PatentsDetailParams): Promise<GoogleResponse>;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
/**
|
|
1665
|
+
* Google Products API client (immersive product detail).
|
|
1666
|
+
*/
|
|
1667
|
+
|
|
1668
|
+
/**
|
|
1669
|
+
* Client for Google's immersive product detail endpoint.
|
|
1670
|
+
*/
|
|
1671
|
+
declare class ProductsClient {
|
|
1672
|
+
private readonly client;
|
|
1673
|
+
constructor(client: BaseClient);
|
|
1674
|
+
detail(params: ProductsDetailParams): Promise<GoogleResponse>;
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
/**
|
|
1678
|
+
* Google Scholar API client.
|
|
1679
|
+
*/
|
|
1680
|
+
|
|
1681
|
+
/**
|
|
1682
|
+
* Client for Google Scholar — search, author profiles, citation charts,
|
|
1683
|
+
* and citation formats.
|
|
1684
|
+
*
|
|
1685
|
+
* Search results carry doc `id`, `type` badge, wrapped `inline_links`
|
|
1686
|
+
* (versions + cited_by + related), PDF `resources`, and author objects
|
|
1687
|
+
* with `author_id` for pipe-through into {@link ScholarClient.author}.
|
|
1688
|
+
* The author endpoint returns structured `interests_detailed`,
|
|
1689
|
+
* publications with per-article `citation_id` + nested `cited_by`, and
|
|
1690
|
+
* lifetime + since-year citation stats.
|
|
1691
|
+
*
|
|
1692
|
+
* @example
|
|
1693
|
+
* ```typescript
|
|
1694
|
+
* const papers = await client.google.scholar.search({
|
|
1695
|
+
* q: "transformer neural networks",
|
|
1696
|
+
* as_ylo: 2020,
|
|
1697
|
+
* });
|
|
1698
|
+
* const first = papers.scholar_results[0];
|
|
1699
|
+
* // Pipe a profiled author into the author endpoint:
|
|
1700
|
+
* if (first.authors[0].author_id) {
|
|
1701
|
+
* const profile = await client.google.scholar.author({
|
|
1702
|
+
* author_id: first.authors[0].author_id,
|
|
1703
|
+
* });
|
|
1704
|
+
* }
|
|
1705
|
+
* ```
|
|
1706
|
+
*/
|
|
1707
|
+
declare class ScholarClient {
|
|
1708
|
+
private readonly client;
|
|
1709
|
+
constructor(client: BaseClient);
|
|
1710
|
+
/**
|
|
1711
|
+
* Search Google Scholar. Returns each result with doc `id`, `type`
|
|
1712
|
+
* badge, wrapped `inline_links`, PDF `resources`, and structured
|
|
1713
|
+
* authors. Envelope includes `scholar_results` alias,
|
|
1714
|
+
* `related_searches`, and matched `profiles` cards.
|
|
1715
|
+
*/
|
|
1716
|
+
search(params: ScholarSearchParams): Promise<GoogleResponse>;
|
|
1717
|
+
/** Search Google Scholar for author profiles by name. */
|
|
1718
|
+
profiles(params: ScholarProfilesParams): Promise<GoogleResponse>;
|
|
1719
|
+
/**
|
|
1720
|
+
* Full Scholar author profile: structured `interests_detailed`,
|
|
1721
|
+
* publications (with per-article `citation_id` + nested
|
|
1722
|
+
* `cited_by{value, link, citation_id}`), stats, and co-authors.
|
|
1723
|
+
*/
|
|
1724
|
+
author(params: ScholarAuthorParams): Promise<GoogleResponse>;
|
|
1725
|
+
/** Citations-per-year chart for a Scholar author. */
|
|
1726
|
+
authorCitation(params: ScholarAuthorCitationParams): Promise<GoogleResponse>;
|
|
1727
|
+
/**
|
|
1728
|
+
* MLA / APA / Chicago / Harvard / Vancouver citation formats plus
|
|
1729
|
+
* BibTeX / RIS / EndNote / RefWorks export links for a paper.
|
|
1730
|
+
*/
|
|
1731
|
+
cite(params: ScholarCiteParams): Promise<GoogleResponse>;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
/**
|
|
1735
|
+
* Google Web Search (SERP) API client.
|
|
1736
|
+
*/
|
|
1737
|
+
|
|
1738
|
+
/**
|
|
1739
|
+
* Client for Google Web Search.
|
|
1740
|
+
*
|
|
1741
|
+
* @example
|
|
1742
|
+
* ```typescript
|
|
1743
|
+
* const serp = await client.google.search.search({ q: "python 3.13" });
|
|
1744
|
+
* for (const r of serp.organic_results as any[]) {
|
|
1745
|
+
* console.log(r.title, r.link);
|
|
1746
|
+
* }
|
|
1747
|
+
* ```
|
|
1748
|
+
*/
|
|
1749
|
+
declare class SearchClient$1 {
|
|
1750
|
+
private readonly client;
|
|
1751
|
+
constructor(client: BaseClient);
|
|
1752
|
+
/**
|
|
1753
|
+
* Search Google and get a structured SERP response with organic results,
|
|
1754
|
+
* knowledge graph, People Also Ask, related searches, AI overview, and
|
|
1755
|
+
* pagination.
|
|
1756
|
+
*/
|
|
1757
|
+
search(params: GoogleSearchParams): Promise<GoogleResponse>;
|
|
1758
|
+
/**
|
|
1759
|
+
* Lightweight Google Search — organic results + related searches only.
|
|
1760
|
+
*
|
|
1761
|
+
* ~40% faster than {@link search}. Skips ads, Knowledge Graph, AI
|
|
1762
|
+
* Overview, local pack, news, inline videos, and shopping blocks.
|
|
1763
|
+
* Credit cost is configured per-endpoint by admins — query
|
|
1764
|
+
* `/public/pricing` for the live rate.
|
|
1765
|
+
*
|
|
1766
|
+
* @example
|
|
1767
|
+
* ```typescript
|
|
1768
|
+
* const lite = await client.google.search.light({ q: "python 3.13" });
|
|
1769
|
+
* ```
|
|
1770
|
+
*/
|
|
1771
|
+
light(params: GoogleSearchParams): Promise<GoogleResponse>;
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
/**
|
|
1775
|
+
* Google Shopping API client — search and product detail.
|
|
1776
|
+
*/
|
|
1777
|
+
|
|
1778
|
+
/**
|
|
1779
|
+
* Client for Google Shopping endpoints.
|
|
1780
|
+
*
|
|
1781
|
+
* Each search tile now carries Google's native `gpcid`, `catalog_id`,
|
|
1782
|
+
* `headline_offer_docid`, `image_docid`, and `mid`, so callers can pipe a
|
|
1783
|
+
* tile directly into `client.google.products.detail()` for full specs
|
|
1784
|
+
* plus merchant offers via the fast `/async/oapv` RPC (~2s).
|
|
1785
|
+
*
|
|
1786
|
+
* @example
|
|
1787
|
+
* ```typescript
|
|
1788
|
+
* const products = await client.google.shopping.search({ q: "laptop" });
|
|
1789
|
+
* const first = (products.results as any[])[0];
|
|
1790
|
+
* const detail = await client.google.products.detail({
|
|
1791
|
+
* product_id: first.gpcid,
|
|
1792
|
+
* q: "laptop",
|
|
1793
|
+
* include_offers: true, // real merchant URLs from /async/piu_ps
|
|
1794
|
+
* });
|
|
1795
|
+
* ```
|
|
1796
|
+
*/
|
|
1797
|
+
declare class ShoppingClient {
|
|
1798
|
+
private readonly client;
|
|
1799
|
+
constructor(client: BaseClient);
|
|
1800
|
+
/** Search Google Shopping for products. */
|
|
1801
|
+
search(params: ShoppingSearchParams): Promise<GoogleResponse>;
|
|
1802
|
+
/** Fetch the Google Shopping product detail page by `product_id`. */
|
|
1803
|
+
product(params: ShoppingProductParams): Promise<GoogleResponse>;
|
|
1804
|
+
/**
|
|
1805
|
+
* Resolve the direct merchant URL for a Shopping product tile via
|
|
1806
|
+
* Google's "I'm Feeling Lucky" redirect (scoped to the card's `source`
|
|
1807
|
+
* merchant via the `site:` operator). You only pay for the call when
|
|
1808
|
+
* you actually want the merchant link — no bulk enrichment of every
|
|
1809
|
+
* tile.
|
|
1810
|
+
*/
|
|
1811
|
+
click(params: ShoppingClickParams): Promise<GoogleResponse>;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
/**
|
|
1815
|
+
* Google Shorts API client — short-form vertical video results.
|
|
1816
|
+
*/
|
|
1817
|
+
|
|
1818
|
+
/**
|
|
1819
|
+
* Client for Google Shorts search (`udm=39`).
|
|
1820
|
+
*
|
|
1821
|
+
* Returns a carousel of short-form videos — YouTube Shorts plus
|
|
1822
|
+
* TikToks, Instagram Reels, Facebook Reels, and other platforms.
|
|
1823
|
+
* Every tile carries `title`, `link`, `source` (platform),
|
|
1824
|
+
* `account_name`, `thumbnail`, `image` (inline preview),
|
|
1825
|
+
* `duration`, and `video_id` (YouTube only).
|
|
1826
|
+
*
|
|
1827
|
+
* @example
|
|
1828
|
+
* ```typescript
|
|
1829
|
+
* const shorts = await client.google.shorts.search({ q: "cooking hacks" });
|
|
1830
|
+
* for (const v of shorts.short_videos_results) {
|
|
1831
|
+
* console.log(v.rank, v.title, v.source, v.account_name);
|
|
1832
|
+
* }
|
|
1833
|
+
* ```
|
|
1834
|
+
*/
|
|
1835
|
+
declare class ShortsClient {
|
|
1836
|
+
private readonly client;
|
|
1837
|
+
constructor(client: BaseClient);
|
|
1838
|
+
search(params: ShortsSearchParams): Promise<GoogleResponse>;
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
/**
|
|
1842
|
+
* Google Trends API client — interest, regions, related, trending.
|
|
1843
|
+
*/
|
|
1844
|
+
|
|
1845
|
+
/**
|
|
1846
|
+
* Client for Google Trends endpoints.
|
|
1847
|
+
*
|
|
1848
|
+
* @example
|
|
1849
|
+
* ```typescript
|
|
1850
|
+
* const interest = await client.google.trends.interest({
|
|
1851
|
+
* q: "python,javascript",
|
|
1852
|
+
* date: "today 12-m",
|
|
1853
|
+
* });
|
|
1854
|
+
* ```
|
|
1855
|
+
*/
|
|
1856
|
+
declare class TrendsClient {
|
|
1857
|
+
private readonly client;
|
|
1858
|
+
constructor(client: BaseClient);
|
|
1859
|
+
interest(params: TrendsInterestParams): Promise<GoogleResponse>;
|
|
1860
|
+
regions(params: TrendsRegionsParams): Promise<GoogleResponse>;
|
|
1861
|
+
related(params: TrendsRelatedParams): Promise<GoogleResponse>;
|
|
1862
|
+
trending(params?: TrendsTrendingParams): Promise<GoogleResponse>;
|
|
1863
|
+
/**
|
|
1864
|
+
* Current trending searches with the full Google Trends UI filter set
|
|
1865
|
+
* — `geo`, `hours`, `category`, `status`, `sort`, `hl`.
|
|
1866
|
+
*/
|
|
1867
|
+
trendingNow(params?: TrendsTrendingNowParams): Promise<GoogleResponse>;
|
|
1868
|
+
/**
|
|
1869
|
+
* Unified Google Trends query — pick the response shape via
|
|
1870
|
+
* `data_type` (TIMESERIES | GEO_MAP | GEO_MAP_0 | RELATED_TOPICS |
|
|
1871
|
+
* RELATED_QUERIES).
|
|
1872
|
+
*/
|
|
1873
|
+
search(params: TrendsSearchParams): Promise<GoogleResponse>;
|
|
1874
|
+
/**
|
|
1875
|
+
* Return categorized Knowledge Graph topic entities (`mid`, `type`,
|
|
1876
|
+
* direct link into Trends explore) for a query prefix. Distinct from
|
|
1877
|
+
* Google Search autocomplete.
|
|
1878
|
+
*/
|
|
1879
|
+
autocomplete(params: TrendsAutocompleteParams): Promise<GoogleResponse>;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
/**
|
|
1883
|
+
* Google Videos API client.
|
|
1884
|
+
*
|
|
1885
|
+
* Returns up to 10 tiles per page with `title`, `link`
|
|
1886
|
+
* (YouTube / Vimeo / etc.), `displayed_link`, `snippet`, `thumbnail`,
|
|
1887
|
+
* `image` (inline base-64), `favicon`, `duration`, `channel`,
|
|
1888
|
+
* `source` (platform), `date`, `video_id`, and raw `extensions`.
|
|
1889
|
+
*/
|
|
1890
|
+
|
|
1891
|
+
/**
|
|
1892
|
+
* Client for Google Videos search.
|
|
1893
|
+
*
|
|
1894
|
+
* @example
|
|
1895
|
+
* ```typescript
|
|
1896
|
+
* const res = await client.google.videos.search({ q: "python tutorial" });
|
|
1897
|
+
* for (const v of res.results) {
|
|
1898
|
+
* console.log(v.rank, v.title, v.duration, v.channel);
|
|
1899
|
+
* }
|
|
1900
|
+
* ```
|
|
1901
|
+
*/
|
|
1902
|
+
declare class VideosClient {
|
|
1903
|
+
private readonly client;
|
|
1904
|
+
constructor(client: BaseClient);
|
|
1905
|
+
search(params: VideosSearchParams): Promise<GoogleResponse>;
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
/**
|
|
1909
|
+
* Google Scraper API aggregator — exposes all 16 Google product sub-clients.
|
|
1910
|
+
*/
|
|
1911
|
+
|
|
1912
|
+
/**
|
|
1913
|
+
* Google Scraper API client with access to all 19 Google product APIs.
|
|
1914
|
+
*
|
|
1915
|
+
* @example
|
|
1916
|
+
* ```typescript
|
|
1917
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
1918
|
+
*
|
|
1919
|
+
* const serp = await client.google.search.search({ q: "python 3.13" });
|
|
1920
|
+
* const places = await client.google.maps.search({ q: "coffee shops sf" });
|
|
1921
|
+
* const products = await client.google.shopping.search({ q: "laptop" });
|
|
1922
|
+
*
|
|
1923
|
+
* // Per-product merchant URL enrichment
|
|
1924
|
+
* const enriched = await client.google.shopping.click({
|
|
1925
|
+
* title: (products.results as any[])[0].title,
|
|
1926
|
+
* source: (products.results as any[])[0].source,
|
|
1927
|
+
* });
|
|
1928
|
+
* console.log(enriched.merchant_url);
|
|
1929
|
+
*
|
|
1930
|
+
* // New in v0.3: Shorts, Flights, and Scholar depth
|
|
1931
|
+
* const shorts = await client.google.shorts.search({ q: "cooking hacks" });
|
|
1932
|
+
* const flights = await client.google.flights.search({
|
|
1933
|
+
* departure_id: "JFK",
|
|
1934
|
+
* arrival_id: "LHR",
|
|
1935
|
+
* outbound_date: "2026-06-15",
|
|
1936
|
+
* return_date: "2026-06-22",
|
|
1937
|
+
* });
|
|
1938
|
+
* const profiles = await client.google.scholar.profiles({
|
|
1939
|
+
* mauthors: "Geoffrey Hinton",
|
|
1940
|
+
* });
|
|
1941
|
+
* ```
|
|
1942
|
+
*/
|
|
1943
|
+
declare class GoogleClient {
|
|
1944
|
+
/** Google Web Search (SERP) — with optional deferred AI Overview follow-up. */
|
|
1945
|
+
readonly search: SearchClient$1;
|
|
1946
|
+
/** Google Maps — places, reviews, photos, posts. */
|
|
1947
|
+
readonly maps: MapsClient;
|
|
1948
|
+
/** Google News — articles, topics, trending. */
|
|
1949
|
+
readonly news: NewsClient;
|
|
1950
|
+
/** Google Hotels — search and property details. */
|
|
1951
|
+
readonly hotels: HotelsClient;
|
|
1952
|
+
/** Google Trends — interest, regions, related, trending, topic autocomplete. */
|
|
1953
|
+
readonly trends: TrendsClient;
|
|
1954
|
+
/** Google Jobs. */
|
|
1955
|
+
readonly jobs: JobsClient;
|
|
1956
|
+
/** Google Shopping — search, details, click enrichment. */
|
|
1957
|
+
readonly shopping: ShoppingClient;
|
|
1958
|
+
/** Google Patents — search and document details. */
|
|
1959
|
+
readonly patents: PatentsClient;
|
|
1960
|
+
/** Google Scholar — search, profiles, author, author citation, cite formats. */
|
|
1961
|
+
readonly scholar: ScholarClient;
|
|
1962
|
+
/** Google Autocomplete — search suggestions. */
|
|
1963
|
+
readonly autocomplete: AutocompleteClient;
|
|
1964
|
+
/** Google Images. */
|
|
1965
|
+
readonly images: ImagesClient;
|
|
1966
|
+
/** Google Videos. */
|
|
1967
|
+
readonly videos: VideosClient;
|
|
1968
|
+
/** Google Finance — stock and index quotes. */
|
|
1969
|
+
readonly finance: FinanceClient;
|
|
1970
|
+
/** Google AI Mode — generative answer responses. */
|
|
1971
|
+
readonly aiMode: AiModeClient;
|
|
1972
|
+
/** Google Lens — visual image search. */
|
|
1973
|
+
readonly lens: LensClient;
|
|
1974
|
+
/** Google Shorts — short-form vertical video results (udm=39). */
|
|
1975
|
+
readonly shorts: ShortsClient;
|
|
1976
|
+
/** Google Flights — one-way, round-trip, and multi-city itineraries. */
|
|
1977
|
+
readonly flights: FlightsClient;
|
|
1978
|
+
/** Google Products — immersive product detail. */
|
|
1979
|
+
readonly products: ProductsClient;
|
|
1980
|
+
constructor(client: BaseClient);
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
/**
|
|
1984
|
+
* TypeScript types for Reddit API responses.
|
|
1985
|
+
*
|
|
1986
|
+
* This module contains all the data types used by the Reddit API client.
|
|
1987
|
+
*/
|
|
1988
|
+
/**
|
|
1989
|
+
* A preview image with dimensions.
|
|
1990
|
+
*/
|
|
1991
|
+
interface RedditPreviewImage {
|
|
1992
|
+
/** Image URL */
|
|
1993
|
+
url: string;
|
|
1994
|
+
/** Image width in pixels */
|
|
1995
|
+
width: number;
|
|
1996
|
+
/** Image height in pixels */
|
|
1997
|
+
height: number;
|
|
1998
|
+
}
|
|
1999
|
+
/**
|
|
2000
|
+
* Embedded media attached to a post.
|
|
2001
|
+
*/
|
|
2002
|
+
interface RedditMedia {
|
|
2003
|
+
/** Media type identifier */
|
|
2004
|
+
type: string | null;
|
|
2005
|
+
/** Direct media URL */
|
|
2006
|
+
url: string | null;
|
|
2007
|
+
/** Thumbnail URL */
|
|
2008
|
+
thumbnail_url: string | null;
|
|
2009
|
+
/** Media width in pixels */
|
|
2010
|
+
width: number | null;
|
|
2011
|
+
/** Media height in pixels */
|
|
2012
|
+
height: number | null;
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* An award given to a post or comment.
|
|
2016
|
+
*/
|
|
2017
|
+
interface RedditAward {
|
|
2018
|
+
/** Award ID */
|
|
2019
|
+
id: string | null;
|
|
2020
|
+
/** Award name */
|
|
2021
|
+
name: string;
|
|
2022
|
+
/** Number of this award given */
|
|
2023
|
+
count: number;
|
|
2024
|
+
/** Award icon URL */
|
|
2025
|
+
icon_url: string | null;
|
|
2026
|
+
}
|
|
2027
|
+
/**
|
|
2028
|
+
* A Reddit post (link or self post).
|
|
2029
|
+
*/
|
|
2030
|
+
interface RedditPost {
|
|
2031
|
+
/** Unique post identifier (without t3_ prefix) */
|
|
2032
|
+
id: string;
|
|
2033
|
+
/** Fullname with t3_ prefix */
|
|
2034
|
+
fullname: string;
|
|
2035
|
+
/** Post title */
|
|
2036
|
+
title: string;
|
|
2037
|
+
/** Self post text body */
|
|
2038
|
+
selftext: string;
|
|
2039
|
+
/** Self post text as HTML */
|
|
2040
|
+
selftext_html: string | null;
|
|
2041
|
+
/** External or self URL */
|
|
2042
|
+
url: string;
|
|
2043
|
+
/** Permalink to post on Reddit */
|
|
2044
|
+
permalink: string;
|
|
2045
|
+
/** Post domain */
|
|
2046
|
+
domain: string;
|
|
2047
|
+
/** Author username */
|
|
2048
|
+
author: string;
|
|
2049
|
+
/** Author fullname (t2_ prefixed) */
|
|
2050
|
+
author_fullname: string | null;
|
|
2051
|
+
/** Author flair text */
|
|
2052
|
+
author_flair_text: string | null;
|
|
2053
|
+
/** Author flair type (text or richtext) */
|
|
2054
|
+
author_flair_type: string | null;
|
|
2055
|
+
/** Author flair template ID */
|
|
2056
|
+
author_flair_template_id: string | null;
|
|
2057
|
+
/** Subreddit name (without r/ prefix) */
|
|
2058
|
+
subreddit: string;
|
|
2059
|
+
/** Subreddit fullname (t5_ prefixed) */
|
|
2060
|
+
subreddit_id: string | null;
|
|
2061
|
+
/** Subreddit with r/ prefix */
|
|
2062
|
+
subreddit_name_prefixed: string | null;
|
|
2063
|
+
/** Subreddit type (public, private, restricted, etc.) */
|
|
2064
|
+
subreddit_type: string | null;
|
|
2065
|
+
/** Number of subscribers in the subreddit */
|
|
2066
|
+
subreddit_subscribers: number | null;
|
|
2067
|
+
/** Post score (upvotes minus downvotes) */
|
|
2068
|
+
score: number;
|
|
2069
|
+
/** Raw upvotes */
|
|
2070
|
+
ups: number;
|
|
2071
|
+
/** Raw downvotes */
|
|
2072
|
+
downs: number;
|
|
2073
|
+
/** Upvote ratio as a decimal (e.g. 0.95) */
|
|
2074
|
+
upvote_ratio: number | null;
|
|
2075
|
+
/** Number of comments */
|
|
2076
|
+
num_comments: number;
|
|
2077
|
+
/** Number of crossposts */
|
|
2078
|
+
num_crossposts: number;
|
|
2079
|
+
/** Number of duplicate submissions */
|
|
2080
|
+
num_duplicates: number | null;
|
|
2081
|
+
/** View count (null if not available) */
|
|
2082
|
+
view_count: number | null;
|
|
2083
|
+
/** Post creation timestamp (Unix) */
|
|
2084
|
+
created_utc: number;
|
|
2085
|
+
/** Post creation time as ISO 8601 UTC string */
|
|
2086
|
+
created_at: string | null;
|
|
2087
|
+
/** Edited timestamp as float, false if not edited, or null */
|
|
2088
|
+
edited: number | boolean | null;
|
|
2089
|
+
/** Edit time as ISO 8601 UTC string (null if not edited) */
|
|
2090
|
+
edited_at: string | null;
|
|
2091
|
+
/** Whether the post is a self (text) post */
|
|
2092
|
+
is_self: boolean;
|
|
2093
|
+
/** Whether the post is a video */
|
|
2094
|
+
is_video: boolean;
|
|
2095
|
+
/** Whether the post is a gallery */
|
|
2096
|
+
is_gallery: boolean;
|
|
2097
|
+
/** Whether the post is marked NSFW */
|
|
2098
|
+
is_nsfw: boolean;
|
|
2099
|
+
/** Whether the post is marked as a spoiler */
|
|
2100
|
+
is_spoiler: boolean;
|
|
2101
|
+
/** Whether the post is locked */
|
|
2102
|
+
is_locked: boolean;
|
|
2103
|
+
/** Whether the post is stickied */
|
|
2104
|
+
is_stickied: boolean;
|
|
2105
|
+
/** Whether the post is archived */
|
|
2106
|
+
is_archived: boolean;
|
|
2107
|
+
/** Whether the post is pinned */
|
|
2108
|
+
is_pinned: boolean;
|
|
2109
|
+
/** Whether the post is original content */
|
|
2110
|
+
is_original_content: boolean;
|
|
2111
|
+
/** Whether the post is robot-indexable */
|
|
2112
|
+
is_robot_indexable: boolean;
|
|
2113
|
+
/** Whether the post is a meta post */
|
|
2114
|
+
is_meta: boolean;
|
|
2115
|
+
/** Whether the post can be crossposted */
|
|
2116
|
+
is_crosspostable: boolean;
|
|
2117
|
+
/** Whether to send reply notifications */
|
|
2118
|
+
send_replies: boolean;
|
|
2119
|
+
/** Post flair text (null if no flair) */
|
|
2120
|
+
link_flair_text: string | null;
|
|
2121
|
+
/** Post flair background color */
|
|
2122
|
+
link_flair_background_color: string | null;
|
|
2123
|
+
/** Post flair text color */
|
|
2124
|
+
link_flair_text_color: string | null;
|
|
2125
|
+
/** Post flair template ID */
|
|
2126
|
+
link_flair_template_id: string | null;
|
|
2127
|
+
/** Post flair type (text or richtext) */
|
|
2128
|
+
link_flair_type: string | null;
|
|
2129
|
+
/** Post flair CSS class */
|
|
2130
|
+
link_flair_css_class: string | null;
|
|
2131
|
+
/** Distinguished status (moderator, admin, or null) */
|
|
2132
|
+
distinguished: string | null;
|
|
2133
|
+
/** Post thumbnail URL (may be "self", "default", or "nsfw") */
|
|
2134
|
+
thumbnail: string | null;
|
|
2135
|
+
/** Thumbnail width in pixels */
|
|
2136
|
+
thumbnail_width: number | null;
|
|
2137
|
+
/** Thumbnail height in pixels */
|
|
2138
|
+
thumbnail_height: number | null;
|
|
2139
|
+
/** Post hint (image, video, link, self, etc.) */
|
|
2140
|
+
post_hint: string | null;
|
|
2141
|
+
/** Preview images */
|
|
2142
|
+
preview_images: RedditPreviewImage[];
|
|
2143
|
+
/** Embedded media metadata */
|
|
2144
|
+
media: RedditMedia | null;
|
|
2145
|
+
/** Gallery item data */
|
|
2146
|
+
gallery_data: Record<string, unknown>[] | null;
|
|
2147
|
+
/** Parent post fullname if this is a crosspost */
|
|
2148
|
+
crosspost_parent: string | null;
|
|
2149
|
+
/** Suggested sort for comments (null if default) */
|
|
2150
|
+
suggested_sort: string | null;
|
|
2151
|
+
/** Total awards received */
|
|
2152
|
+
total_awards: number;
|
|
2153
|
+
/** Award details */
|
|
2154
|
+
awards: RedditAward[];
|
|
2155
|
+
/** Number of gildings */
|
|
2156
|
+
gilded: number;
|
|
2157
|
+
/** Content categories */
|
|
2158
|
+
content_categories: string[] | null;
|
|
2159
|
+
/** Removal category (null if not removed) */
|
|
2160
|
+
removed_by_category: string | null;
|
|
2161
|
+
/** Treatment tags */
|
|
2162
|
+
treatment_tags: string[];
|
|
2163
|
+
}
|
|
2164
|
+
/**
|
|
2165
|
+
* A Reddit comment.
|
|
2166
|
+
*/
|
|
2167
|
+
interface RedditComment {
|
|
2168
|
+
/** Unique comment identifier (without t1_ prefix) */
|
|
2169
|
+
id: string;
|
|
2170
|
+
/** Fullname with t1_ prefix */
|
|
2171
|
+
fullname: string;
|
|
2172
|
+
/** Comment body text */
|
|
2173
|
+
body: string;
|
|
2174
|
+
/** Comment body as HTML */
|
|
2175
|
+
body_html: string | null;
|
|
2176
|
+
/** Author username */
|
|
2177
|
+
author: string;
|
|
2178
|
+
/** Author fullname (t2_ prefixed) */
|
|
2179
|
+
author_fullname: string | null;
|
|
2180
|
+
/** Author flair text */
|
|
2181
|
+
author_flair_text: string | null;
|
|
2182
|
+
/** Author flair type (text or richtext) */
|
|
2183
|
+
author_flair_type: string | null;
|
|
2184
|
+
/** Subreddit name (without r/ prefix) */
|
|
2185
|
+
subreddit: string;
|
|
2186
|
+
/** Subreddit fullname (t5_ prefixed) */
|
|
2187
|
+
subreddit_id: string | null;
|
|
2188
|
+
/** Subreddit with r/ prefix */
|
|
2189
|
+
subreddit_name_prefixed: string | null;
|
|
2190
|
+
/** Subreddit type (public, private, restricted, etc.) */
|
|
2191
|
+
subreddit_type: string | null;
|
|
2192
|
+
/** Post ID this comment belongs to */
|
|
2193
|
+
post_id: string | null;
|
|
2194
|
+
/** Title of the parent post */
|
|
2195
|
+
post_title: string | null;
|
|
2196
|
+
/** Parent ID (t3_ for top-level, t1_ for reply) */
|
|
2197
|
+
parent_id: string | null;
|
|
2198
|
+
/** Permalink to comment */
|
|
2199
|
+
permalink: string;
|
|
2200
|
+
/** Comment score (upvotes minus downvotes) */
|
|
2201
|
+
score: number;
|
|
2202
|
+
/** Raw upvotes */
|
|
2203
|
+
ups: number;
|
|
2204
|
+
/** Raw downvotes */
|
|
2205
|
+
downs: number;
|
|
2206
|
+
/** Controversiality score */
|
|
2207
|
+
controversiality: number;
|
|
2208
|
+
/** Depth level (0 for top-level comments) */
|
|
2209
|
+
depth: number;
|
|
2210
|
+
/** Comment creation timestamp (Unix) */
|
|
2211
|
+
created_utc: number;
|
|
2212
|
+
/** Comment creation time as ISO 8601 UTC string */
|
|
2213
|
+
created_at: string | null;
|
|
2214
|
+
/** Edited timestamp as float, false if not edited, or null */
|
|
2215
|
+
edited: number | boolean | null;
|
|
2216
|
+
/** Edit time as ISO 8601 UTC string (null if not edited) */
|
|
2217
|
+
edited_at: string | null;
|
|
2218
|
+
/** Whether the author is the post submitter */
|
|
2219
|
+
is_submitter: boolean;
|
|
2220
|
+
/** Whether the comment is stickied */
|
|
2221
|
+
is_stickied: boolean;
|
|
2222
|
+
/** Whether the comment is locked */
|
|
2223
|
+
is_locked: boolean;
|
|
2224
|
+
/** Whether the comment score is hidden */
|
|
2225
|
+
is_score_hidden: boolean;
|
|
2226
|
+
/** Whether to send reply notifications */
|
|
2227
|
+
send_replies: boolean;
|
|
2228
|
+
/** Distinguished status (moderator, admin, or null) */
|
|
2229
|
+
distinguished: string | null;
|
|
2230
|
+
/** Total awards received */
|
|
2231
|
+
total_awards: number;
|
|
2232
|
+
/** Number of gildings */
|
|
2233
|
+
gilded: number;
|
|
2234
|
+
/** Nested replies (empty array if none) */
|
|
2235
|
+
replies: RedditComment[];
|
|
2236
|
+
}
|
|
2237
|
+
/**
|
|
2238
|
+
* A Reddit subreddit.
|
|
2239
|
+
*/
|
|
2240
|
+
interface RedditSubreddit {
|
|
2241
|
+
/** Unique subreddit identifier */
|
|
2242
|
+
id: string;
|
|
2243
|
+
/** Fullname with t5_ prefix */
|
|
2244
|
+
fullname: string;
|
|
2245
|
+
/** Subreddit name (without r/ prefix) */
|
|
2246
|
+
name: string;
|
|
2247
|
+
/** Subreddit with r/ prefix */
|
|
2248
|
+
display_name_prefixed: string | null;
|
|
2249
|
+
/** Subreddit title */
|
|
2250
|
+
title: string;
|
|
2251
|
+
/** Full sidebar description (markdown) */
|
|
2252
|
+
description: string;
|
|
2253
|
+
/** Full sidebar description as HTML */
|
|
2254
|
+
description_html: string | null;
|
|
2255
|
+
/** Short public description */
|
|
2256
|
+
public_description: string;
|
|
2257
|
+
/** Short public description as HTML */
|
|
2258
|
+
public_description_html: string | null;
|
|
2259
|
+
/** Text shown when submitting a new post */
|
|
2260
|
+
submit_text: string;
|
|
2261
|
+
/** Submit text as HTML */
|
|
2262
|
+
submit_text_html: string | null;
|
|
2263
|
+
/** Header title text */
|
|
2264
|
+
header_title: string | null;
|
|
2265
|
+
/** Subreddit URL path */
|
|
2266
|
+
url: string;
|
|
2267
|
+
/** Subreddit type (public, private, restricted, etc.) */
|
|
2268
|
+
type: string;
|
|
2269
|
+
/** Allowed submission type (any, link, self) */
|
|
2270
|
+
submission_type: string | null;
|
|
2271
|
+
/** Number of subscribers */
|
|
2272
|
+
subscribers: number;
|
|
2273
|
+
/** Number of users currently online */
|
|
2274
|
+
active_users: number | null;
|
|
2275
|
+
/** Creation timestamp (Unix) */
|
|
2276
|
+
created_utc: number;
|
|
2277
|
+
/** Creation time as ISO 8601 UTC string */
|
|
2278
|
+
created_at: string | null;
|
|
2279
|
+
/** Whether the subreddit is marked NSFW */
|
|
2280
|
+
is_nsfw: boolean;
|
|
2281
|
+
/** Whether the subreddit is quarantined */
|
|
2282
|
+
is_quarantined: boolean;
|
|
2283
|
+
/** Whether the subreddit is advertiser-friendly */
|
|
2284
|
+
is_advertiser_friendly: boolean;
|
|
2285
|
+
/** Advertiser category */
|
|
2286
|
+
advertiser_category: string | null;
|
|
2287
|
+
/** Subreddit language code */
|
|
2288
|
+
language: string | null;
|
|
2289
|
+
/** Subreddit icon URL */
|
|
2290
|
+
icon_url: string | null;
|
|
2291
|
+
/** Header image URL */
|
|
2292
|
+
header_url: string | null;
|
|
2293
|
+
/** Banner image URL */
|
|
2294
|
+
banner_url: string | null;
|
|
2295
|
+
/** Banner background color (hex) */
|
|
2296
|
+
banner_background_color: string | null;
|
|
2297
|
+
/** Primary theme color (hex) */
|
|
2298
|
+
primary_color: string | null;
|
|
2299
|
+
/** Key theme color (hex) */
|
|
2300
|
+
key_color: string | null;
|
|
2301
|
+
/** Whether the wiki is enabled */
|
|
2302
|
+
wiki_enabled: boolean;
|
|
2303
|
+
/** Whether image posts are allowed */
|
|
2304
|
+
allow_images: boolean;
|
|
2305
|
+
/** Whether video posts are allowed */
|
|
2306
|
+
allow_videos: boolean;
|
|
2307
|
+
/** Whether gallery posts are allowed */
|
|
2308
|
+
allow_galleries: boolean;
|
|
2309
|
+
/** Whether polls are allowed */
|
|
2310
|
+
allow_polls: boolean;
|
|
2311
|
+
/** Whether the subreddit appears in discovery feeds */
|
|
2312
|
+
allow_discovery: boolean;
|
|
2313
|
+
/** Whether spoiler tags are enabled */
|
|
2314
|
+
spoilers_enabled: boolean;
|
|
2315
|
+
/** Whether custom emojis are enabled */
|
|
2316
|
+
emojis_enabled: boolean;
|
|
2317
|
+
/** Whether free-form reports are enabled */
|
|
2318
|
+
free_form_reports: boolean;
|
|
2319
|
+
/** Whether the subreddit accepts followers */
|
|
2320
|
+
accept_followers: boolean;
|
|
2321
|
+
/** Whether posting is restricted */
|
|
2322
|
+
restrict_posting: boolean;
|
|
2323
|
+
/** Whether link flairs are enabled */
|
|
2324
|
+
link_flair_enabled: boolean;
|
|
2325
|
+
/** Position of link flair (left, right, or null) */
|
|
2326
|
+
link_flair_position: string | null;
|
|
2327
|
+
/** Whether user flairs are enabled */
|
|
2328
|
+
user_flair_enabled: boolean;
|
|
2329
|
+
/** Position of user flair (left, right, or null) */
|
|
2330
|
+
user_flair_position: string | null;
|
|
2331
|
+
/** Minutes before comment scores are shown */
|
|
2332
|
+
comment_score_hide_mins: number;
|
|
2333
|
+
/** Whether posts are automatically archived */
|
|
2334
|
+
should_archive_posts: boolean;
|
|
2335
|
+
/** Media types allowed in comments */
|
|
2336
|
+
allowed_media_in_comments: string[];
|
|
2337
|
+
}
|
|
2338
|
+
/**
|
|
2339
|
+
* A Reddit user profile.
|
|
2340
|
+
*/
|
|
2341
|
+
interface RedditUser {
|
|
2342
|
+
/** Unique user identifier */
|
|
2343
|
+
id: string;
|
|
2344
|
+
/** Fullname with t2_ prefix */
|
|
2345
|
+
fullname: string | null;
|
|
2346
|
+
/** Username (without u/ prefix) */
|
|
2347
|
+
name: string;
|
|
2348
|
+
/** Username with u/ prefix */
|
|
2349
|
+
display_name_prefixed: string | null;
|
|
2350
|
+
/** Avatar/profile icon URL */
|
|
2351
|
+
icon_url: string | null;
|
|
2352
|
+
/** Snoovatar image URL */
|
|
2353
|
+
snoovatar_url: string | null;
|
|
2354
|
+
/** Profile banner URL */
|
|
2355
|
+
banner_url: string | null;
|
|
2356
|
+
/** Profile title/tagline */
|
|
2357
|
+
profile_title: string | null;
|
|
2358
|
+
/** Profile page URL */
|
|
2359
|
+
profile_url: string | null;
|
|
2360
|
+
/** User description / about text */
|
|
2361
|
+
description: string;
|
|
2362
|
+
/** Post karma */
|
|
2363
|
+
link_karma: number;
|
|
2364
|
+
/** Comment karma */
|
|
2365
|
+
comment_karma: number;
|
|
2366
|
+
/** Karma from received awards */
|
|
2367
|
+
awardee_karma: number;
|
|
2368
|
+
/** Karma from given awards */
|
|
2369
|
+
awarder_karma: number;
|
|
2370
|
+
/** Combined total karma */
|
|
2371
|
+
total_karma: number;
|
|
2372
|
+
/** Account creation timestamp (Unix) */
|
|
2373
|
+
created_utc: number;
|
|
2374
|
+
/** Account creation time as ISO 8601 UTC string */
|
|
2375
|
+
created_at: string | null;
|
|
2376
|
+
/** Whether the account email is verified */
|
|
2377
|
+
has_verified_email: boolean;
|
|
2378
|
+
/** Whether the account is verified */
|
|
2379
|
+
verified: boolean;
|
|
2380
|
+
/** Whether the account accepts followers */
|
|
2381
|
+
accepts_followers: boolean;
|
|
2382
|
+
/** Whether the account has subscribed to Reddit */
|
|
2383
|
+
has_subscribed: boolean;
|
|
2384
|
+
/** Whether the account is a Reddit employee */
|
|
2385
|
+
is_employee: boolean;
|
|
2386
|
+
/** Whether the account is a moderator somewhere */
|
|
2387
|
+
is_mod: boolean;
|
|
2388
|
+
/** Whether the account has Reddit Premium */
|
|
2389
|
+
is_gold: boolean;
|
|
2390
|
+
/** Whether the account is suspended */
|
|
2391
|
+
is_suspended: boolean;
|
|
2392
|
+
/** Whether the profile is NSFW */
|
|
2393
|
+
is_nsfw: boolean;
|
|
2394
|
+
/** Whether the snoovatar is shown in comments */
|
|
2395
|
+
pref_show_snoovatar: boolean;
|
|
2396
|
+
}
|
|
2397
|
+
/**
|
|
2398
|
+
* A subreddit rule.
|
|
2399
|
+
*/
|
|
2400
|
+
interface RedditRule {
|
|
2401
|
+
/** Rule priority order */
|
|
2402
|
+
priority: number;
|
|
2403
|
+
/** Short name / title of the rule */
|
|
2404
|
+
short_name: string;
|
|
2405
|
+
/** Full rule description (markdown) */
|
|
2406
|
+
description: string;
|
|
2407
|
+
/** Full rule description as HTML */
|
|
2408
|
+
description_html: string | null;
|
|
2409
|
+
/** What the rule applies to (link, comment, all) */
|
|
2410
|
+
kind: "link" | "comment" | "all" | string;
|
|
2411
|
+
/** Violation reason label */
|
|
2412
|
+
violation_reason: string | null;
|
|
2413
|
+
}
|
|
2414
|
+
/**
|
|
2415
|
+
* A subreddit wiki page.
|
|
2416
|
+
*/
|
|
2417
|
+
interface RedditWikiPage {
|
|
2418
|
+
/** Wiki page title/slug */
|
|
2419
|
+
title: string;
|
|
2420
|
+
/** Page content (markdown) */
|
|
2421
|
+
content_md: string;
|
|
2422
|
+
/** Page content as HTML */
|
|
2423
|
+
content_html: string | null;
|
|
2424
|
+
/** Author of latest revision */
|
|
2425
|
+
revision_by: string | null;
|
|
2426
|
+
/** Revision timestamp (Unix), null if unknown */
|
|
2427
|
+
revision_date: number | null;
|
|
2428
|
+
}
|
|
2429
|
+
/**
|
|
2430
|
+
* A Reddit user trophy.
|
|
2431
|
+
*/
|
|
2432
|
+
interface RedditTrophy {
|
|
2433
|
+
/** Trophy name */
|
|
2434
|
+
name: string;
|
|
2435
|
+
/** Trophy description */
|
|
2436
|
+
description: string | null;
|
|
2437
|
+
/** Trophy icon URL */
|
|
2438
|
+
icon_url: string | null;
|
|
2439
|
+
/** URL associated with the trophy */
|
|
2440
|
+
url: string | null;
|
|
2441
|
+
}
|
|
2442
|
+
/**
|
|
2443
|
+
* A subreddit moderator entry.
|
|
2444
|
+
*/
|
|
2445
|
+
interface RedditModerator {
|
|
2446
|
+
/** Moderator username */
|
|
2447
|
+
name: string;
|
|
2448
|
+
/** Moderator user ID */
|
|
2449
|
+
id: string | null;
|
|
2450
|
+
/** Moderator permissions list */
|
|
2451
|
+
mod_permissions: string[];
|
|
2452
|
+
/** Date added as moderator (Unix), null if unknown */
|
|
2453
|
+
date: number | null;
|
|
2454
|
+
}
|
|
2455
|
+
/**
|
|
2456
|
+
* Pagination metadata for list responses.
|
|
2457
|
+
*/
|
|
2458
|
+
interface RedditPagination {
|
|
2459
|
+
/** Cursor for fetching the next page (null if no more pages) */
|
|
2460
|
+
after: string | null;
|
|
2461
|
+
/** Cursor for fetching the previous page (null if on first page) */
|
|
2462
|
+
before: string | null;
|
|
2463
|
+
/** Total number of items fetched so far */
|
|
2464
|
+
count: number;
|
|
2465
|
+
/** Maximum number of items per page */
|
|
2466
|
+
limit: number;
|
|
2467
|
+
}
|
|
2468
|
+
/**
|
|
2469
|
+
* Response from the post search endpoint.
|
|
2470
|
+
*/
|
|
2471
|
+
interface SearchPostsResponse {
|
|
2472
|
+
/** List of matching posts */
|
|
2473
|
+
posts: RedditPost[];
|
|
2474
|
+
/** Pagination metadata */
|
|
2475
|
+
pagination: RedditPagination;
|
|
2476
|
+
/** Search query string */
|
|
2477
|
+
query: string;
|
|
2478
|
+
/** Sort method used */
|
|
2479
|
+
sort: string;
|
|
2480
|
+
}
|
|
2481
|
+
/**
|
|
2482
|
+
* Response from the subreddit posts endpoint.
|
|
2483
|
+
*/
|
|
2484
|
+
interface SubredditPostsResponse {
|
|
2485
|
+
/** List of posts in the subreddit */
|
|
2486
|
+
posts: RedditPost[];
|
|
2487
|
+
/** Pagination metadata */
|
|
2488
|
+
pagination: RedditPagination;
|
|
2489
|
+
/** Subreddit name */
|
|
2490
|
+
subreddit: string;
|
|
2491
|
+
/** Sort method used */
|
|
2492
|
+
sort: string;
|
|
2493
|
+
}
|
|
2494
|
+
/**
|
|
2495
|
+
* Response from the post detail endpoint.
|
|
2496
|
+
*/
|
|
2497
|
+
interface PostDetailResponse {
|
|
2498
|
+
/** Full post details */
|
|
2499
|
+
post: RedditPost;
|
|
2500
|
+
}
|
|
2501
|
+
/**
|
|
2502
|
+
* Response from the post comments endpoint.
|
|
2503
|
+
*/
|
|
2504
|
+
interface PostCommentsResponse {
|
|
2505
|
+
/** Post details */
|
|
2506
|
+
post: RedditPost;
|
|
2507
|
+
/** Top-level comments with nested replies */
|
|
2508
|
+
comments: RedditComment[];
|
|
2509
|
+
/** Pagination metadata */
|
|
2510
|
+
pagination: RedditPagination;
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* Response from the post duplicates endpoint.
|
|
2514
|
+
*/
|
|
2515
|
+
interface PostDuplicatesResponse {
|
|
2516
|
+
/** The original post */
|
|
2517
|
+
original: RedditPost;
|
|
2518
|
+
/** Cross-posts and duplicate submissions */
|
|
2519
|
+
duplicates: RedditPost[];
|
|
2520
|
+
/** Pagination metadata */
|
|
2521
|
+
pagination: RedditPagination;
|
|
2522
|
+
}
|
|
2523
|
+
/**
|
|
2524
|
+
* Response from the subreddit detail endpoint.
|
|
2525
|
+
*/
|
|
2526
|
+
interface SubredditDetailResponse {
|
|
2527
|
+
/** Full subreddit details */
|
|
2528
|
+
subreddit: RedditSubreddit;
|
|
2529
|
+
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Response from the subreddit rules endpoint.
|
|
2532
|
+
*/
|
|
2533
|
+
interface SubredditRulesResponse {
|
|
2534
|
+
/** List of subreddit rules */
|
|
2535
|
+
rules: RedditRule[];
|
|
2536
|
+
/** Subreddit name */
|
|
2537
|
+
subreddit: string;
|
|
2538
|
+
}
|
|
2539
|
+
/**
|
|
2540
|
+
* Response from the subreddit moderators endpoint.
|
|
2541
|
+
*/
|
|
2542
|
+
interface SubredditModeratorsResponse {
|
|
2543
|
+
/** List of moderators */
|
|
2544
|
+
moderators: RedditModerator[];
|
|
2545
|
+
/** Subreddit name */
|
|
2546
|
+
subreddit: string;
|
|
2547
|
+
}
|
|
2548
|
+
/**
|
|
2549
|
+
* Response from the subreddit wiki pages list endpoint.
|
|
2550
|
+
*/
|
|
2551
|
+
interface SubredditWikiPagesResponse {
|
|
2552
|
+
/** List of wiki page slugs */
|
|
2553
|
+
pages: string[];
|
|
2554
|
+
/** Subreddit name */
|
|
2555
|
+
subreddit: string;
|
|
2556
|
+
}
|
|
2557
|
+
/**
|
|
2558
|
+
* Response from the wiki page endpoint.
|
|
2559
|
+
*/
|
|
2560
|
+
interface WikiPageResponse {
|
|
2561
|
+
/** The wiki page content */
|
|
2562
|
+
page: RedditWikiPage;
|
|
2563
|
+
/** Subreddit name */
|
|
2564
|
+
subreddit: string;
|
|
2565
|
+
}
|
|
2566
|
+
/**
|
|
2567
|
+
* Response from the user profile endpoint.
|
|
2568
|
+
*/
|
|
2569
|
+
interface UserProfileResponse {
|
|
2570
|
+
/** Full user profile */
|
|
2571
|
+
user: RedditUser;
|
|
2572
|
+
}
|
|
2573
|
+
/**
|
|
2574
|
+
* Response from the user posts endpoint.
|
|
2575
|
+
*/
|
|
2576
|
+
interface UserPostsResponse {
|
|
2577
|
+
/** List of user's posts */
|
|
2578
|
+
posts: RedditPost[];
|
|
2579
|
+
/** Pagination metadata */
|
|
2580
|
+
pagination: RedditPagination;
|
|
2581
|
+
/** Username */
|
|
2582
|
+
username: string;
|
|
2583
|
+
}
|
|
2584
|
+
/**
|
|
2585
|
+
* Response from the user comments endpoint.
|
|
2586
|
+
*/
|
|
2587
|
+
interface UserCommentsResponse {
|
|
2588
|
+
/** List of user's comments */
|
|
2589
|
+
comments: RedditComment[];
|
|
2590
|
+
/** Pagination metadata */
|
|
2591
|
+
pagination: RedditPagination;
|
|
2592
|
+
/** Username */
|
|
2593
|
+
username: string;
|
|
2594
|
+
}
|
|
2595
|
+
/**
|
|
2596
|
+
* Response from the user moderated subreddits endpoint.
|
|
2597
|
+
*/
|
|
2598
|
+
interface UserModeratedResponse {
|
|
2599
|
+
/** Subreddits moderated by the user */
|
|
2600
|
+
subreddits: RedditSubreddit[];
|
|
2601
|
+
/** Username */
|
|
2602
|
+
username: string;
|
|
2603
|
+
}
|
|
2604
|
+
/**
|
|
2605
|
+
* Response from the user trophies endpoint.
|
|
2606
|
+
*/
|
|
2607
|
+
interface UserTrophiesResponse {
|
|
2608
|
+
/** List of trophies awarded to the user */
|
|
2609
|
+
trophies: RedditTrophy[];
|
|
2610
|
+
/** Username */
|
|
2611
|
+
username: string;
|
|
2612
|
+
}
|
|
2613
|
+
/**
|
|
2614
|
+
* Response from the subreddit search endpoint.
|
|
2615
|
+
*/
|
|
2616
|
+
interface SearchSubredditsResponse {
|
|
2617
|
+
/** List of matching subreddits */
|
|
2618
|
+
subreddits: RedditSubreddit[];
|
|
2619
|
+
/** Pagination metadata */
|
|
2620
|
+
pagination: RedditPagination;
|
|
2621
|
+
/** Search query string */
|
|
2622
|
+
query: string;
|
|
2623
|
+
}
|
|
2624
|
+
/**
|
|
2625
|
+
* Response from the user search endpoint.
|
|
2626
|
+
*/
|
|
2627
|
+
interface SearchUsersResponse {
|
|
2628
|
+
/** List of matching users */
|
|
2629
|
+
users: RedditUser[];
|
|
2630
|
+
/** Pagination metadata */
|
|
2631
|
+
pagination: RedditPagination;
|
|
2632
|
+
/** Search query string */
|
|
2633
|
+
query: string;
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Response from the trending posts endpoint.
|
|
2637
|
+
*/
|
|
2638
|
+
interface TrendingPostsResponse {
|
|
2639
|
+
/** List of trending posts */
|
|
2640
|
+
posts: RedditPost[];
|
|
2641
|
+
/** Pagination metadata */
|
|
2642
|
+
pagination: RedditPagination;
|
|
2643
|
+
/** Sort method used */
|
|
2644
|
+
sort: string;
|
|
2645
|
+
}
|
|
2646
|
+
/**
|
|
2647
|
+
* Response from the popular subreddits endpoint.
|
|
2648
|
+
*/
|
|
2649
|
+
interface PopularSubredditsResponse {
|
|
2650
|
+
/** List of popular subreddits */
|
|
2651
|
+
subreddits: RedditSubreddit[];
|
|
2652
|
+
/** Pagination metadata */
|
|
2653
|
+
pagination: RedditPagination;
|
|
2654
|
+
}
|
|
2655
|
+
/**
|
|
2656
|
+
* Response from the domain posts endpoint.
|
|
2657
|
+
*/
|
|
2658
|
+
interface DomainPostsResponse {
|
|
2659
|
+
/** List of posts linking to the domain */
|
|
2660
|
+
posts: RedditPost[];
|
|
2661
|
+
/** Pagination metadata */
|
|
2662
|
+
pagination: RedditPagination;
|
|
2663
|
+
/** Domain name */
|
|
2664
|
+
domain: string;
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
/**
|
|
2668
|
+
* Reddit Search API client.
|
|
2669
|
+
*
|
|
2670
|
+
* Provides methods for searching Reddit posts, subreddits, users, and domain posts.
|
|
2671
|
+
*/
|
|
2672
|
+
|
|
2673
|
+
/**
|
|
2674
|
+
* Client for Reddit search endpoints.
|
|
2675
|
+
*
|
|
2676
|
+
* @example
|
|
2677
|
+
* ```typescript
|
|
2678
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
2679
|
+
*
|
|
2680
|
+
* // Search posts
|
|
2681
|
+
* const results = await client.reddit.search.posts({ query: "typescript tips" });
|
|
2682
|
+
* for (const post of results.posts) {
|
|
2683
|
+
* console.log(`${post.title} — ${post.score} points`);
|
|
2684
|
+
* }
|
|
2685
|
+
*
|
|
2686
|
+
* // Search subreddits
|
|
2687
|
+
* const subs = await client.reddit.search.subreddits({ query: "programming" });
|
|
2688
|
+
*
|
|
2689
|
+
* // Get posts from a domain
|
|
2690
|
+
* const domainPosts = await client.reddit.search.domainPosts({ domain: "github.com" });
|
|
2691
|
+
* ```
|
|
2692
|
+
*/
|
|
2693
|
+
declare class SearchClient {
|
|
2694
|
+
private readonly client;
|
|
2695
|
+
constructor(client: BaseClient);
|
|
2696
|
+
/**
|
|
2697
|
+
* Search Reddit posts.
|
|
2698
|
+
*
|
|
2699
|
+
* @param options - Search parameters.
|
|
2700
|
+
* @param options.query - Search query string.
|
|
2701
|
+
* @param options.subreddit - Restrict search to a specific subreddit.
|
|
2702
|
+
* @param options.sort - Sort order (relevance, hot, top, new, comments).
|
|
2703
|
+
* @param options.time - Time filter (hour, day, week, month, year, all).
|
|
2704
|
+
* @param options.after - Pagination cursor for the next page.
|
|
2705
|
+
* @param options.limit - Number of results to return (max 100).
|
|
2706
|
+
* @returns Search results with posts and pagination metadata.
|
|
2707
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2708
|
+
* @throws ValidationError - If the search parameters are invalid.
|
|
2709
|
+
*
|
|
2710
|
+
* @example
|
|
2711
|
+
* ```typescript
|
|
2712
|
+
* const results = await client.reddit.search.posts({
|
|
2713
|
+
* query: "best practices",
|
|
2714
|
+
* subreddit: "programming",
|
|
2715
|
+
* sort: "top",
|
|
2716
|
+
* time: "month",
|
|
2717
|
+
* limit: 25,
|
|
2718
|
+
* });
|
|
2719
|
+
* console.log(`Found ${results.posts.length} posts`);
|
|
2720
|
+
* ```
|
|
2721
|
+
*/
|
|
2722
|
+
posts(options: {
|
|
2723
|
+
query: string;
|
|
2724
|
+
subreddit?: string;
|
|
2725
|
+
sort?: "relevance" | "hot" | "top" | "new" | "comments";
|
|
2726
|
+
time?: "hour" | "day" | "week" | "month" | "year" | "all";
|
|
2727
|
+
after?: string;
|
|
2728
|
+
limit?: number;
|
|
2729
|
+
}): Promise<SearchPostsResponse>;
|
|
2730
|
+
/**
|
|
2731
|
+
* Search Reddit subreddits.
|
|
2732
|
+
*
|
|
2733
|
+
* @param options - Search parameters.
|
|
2734
|
+
* @param options.query - Search query string.
|
|
2735
|
+
* @param options.after - Pagination cursor for the next page.
|
|
2736
|
+
* @param options.limit - Number of results to return (max 100).
|
|
2737
|
+
* @returns Matching subreddits with pagination metadata.
|
|
2738
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2739
|
+
* @throws ValidationError - If the search parameters are invalid.
|
|
2740
|
+
*
|
|
2741
|
+
* @example
|
|
2742
|
+
* ```typescript
|
|
2743
|
+
* const results = await client.reddit.search.subreddits({
|
|
2744
|
+
* query: "javascript",
|
|
2745
|
+
* limit: 10,
|
|
2746
|
+
* });
|
|
2747
|
+
* for (const sub of results.subreddits) {
|
|
2748
|
+
* console.log(`r/${sub.display_name}: ${sub.subscribers.toLocaleString()} subscribers`);
|
|
2749
|
+
* }
|
|
2750
|
+
* ```
|
|
2751
|
+
*/
|
|
2752
|
+
subreddits(options: {
|
|
2753
|
+
query: string;
|
|
2754
|
+
after?: string;
|
|
2755
|
+
limit?: number;
|
|
2756
|
+
}): Promise<SearchSubredditsResponse>;
|
|
2757
|
+
/**
|
|
2758
|
+
* Search Reddit users.
|
|
2759
|
+
*
|
|
2760
|
+
* @param options - Search parameters.
|
|
2761
|
+
* @param options.query - Search query string.
|
|
2762
|
+
* @param options.after - Pagination cursor for the next page.
|
|
2763
|
+
* @param options.limit - Number of results to return (max 100).
|
|
2764
|
+
* @returns Matching users with pagination metadata.
|
|
2765
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2766
|
+
* @throws ValidationError - If the search parameters are invalid.
|
|
2767
|
+
*
|
|
2768
|
+
* @example
|
|
2769
|
+
* ```typescript
|
|
2770
|
+
* const results = await client.reddit.search.users({
|
|
2771
|
+
* query: "john",
|
|
2772
|
+
* limit: 20,
|
|
2773
|
+
* });
|
|
2774
|
+
* for (const user of results.users) {
|
|
2775
|
+
* console.log(`u/${user.name}: ${user.total_karma.toLocaleString()} karma`);
|
|
2776
|
+
* }
|
|
2777
|
+
* ```
|
|
2778
|
+
*/
|
|
2779
|
+
users(options: {
|
|
2780
|
+
query: string;
|
|
2781
|
+
after?: string;
|
|
2782
|
+
limit?: number;
|
|
2783
|
+
}): Promise<SearchUsersResponse>;
|
|
2784
|
+
/**
|
|
2785
|
+
* Get Reddit posts linking to a specific domain.
|
|
2786
|
+
*
|
|
2787
|
+
* @param options - Request parameters.
|
|
2788
|
+
* @param options.domain - Domain name to search for (e.g. "github.com").
|
|
2789
|
+
* @param options.sort - Sort order (hot, new, top, rising).
|
|
2790
|
+
* @param options.time - Time filter for top sort (hour, day, week, month, year, all).
|
|
2791
|
+
* @param options.after - Pagination cursor for the next page.
|
|
2792
|
+
* @param options.limit - Number of results to return (max 100).
|
|
2793
|
+
* @returns Posts linking to the domain with pagination metadata.
|
|
2794
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2795
|
+
* @throws ValidationError - If the parameters are invalid.
|
|
2796
|
+
*
|
|
2797
|
+
* @example
|
|
2798
|
+
* ```typescript
|
|
2799
|
+
* const results = await client.reddit.search.domainPosts({
|
|
2800
|
+
* domain: "github.com",
|
|
2801
|
+
* sort: "top",
|
|
2802
|
+
* time: "week",
|
|
2803
|
+
* limit: 25,
|
|
2804
|
+
* });
|
|
2805
|
+
* for (const post of results.posts) {
|
|
2806
|
+
* console.log(`r/${post.subreddit}: ${post.title}`);
|
|
2807
|
+
* }
|
|
2808
|
+
* ```
|
|
2809
|
+
*/
|
|
2810
|
+
domainPosts(options: {
|
|
2811
|
+
domain: string;
|
|
2812
|
+
sort?: "hot" | "new" | "top" | "rising";
|
|
2813
|
+
time?: "hour" | "day" | "week" | "month" | "year" | "all";
|
|
2814
|
+
after?: string;
|
|
2815
|
+
limit?: number;
|
|
2816
|
+
}): Promise<DomainPostsResponse>;
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2819
|
+
/**
|
|
2820
|
+
* Reddit Posts API client.
|
|
2821
|
+
*
|
|
2822
|
+
* Provides methods for fetching trending posts, post details, comments, and duplicates.
|
|
2823
|
+
*/
|
|
2824
|
+
|
|
2825
|
+
/**
|
|
2826
|
+
* Client for Reddit post endpoints.
|
|
2827
|
+
*
|
|
2828
|
+
* @example
|
|
2829
|
+
* ```typescript
|
|
2830
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
2831
|
+
*
|
|
2832
|
+
* // Get trending posts
|
|
2833
|
+
* const trending = await client.reddit.posts.trending({ subreddit: "programming" });
|
|
2834
|
+
*
|
|
2835
|
+
* // Get post details
|
|
2836
|
+
* const post = await client.reddit.posts.get("t3_abc123");
|
|
2837
|
+
*
|
|
2838
|
+
* // Get post comments
|
|
2839
|
+
* const { comments } = await client.reddit.posts.comments("abc123", { subreddit: "programming" });
|
|
2840
|
+
* ```
|
|
2841
|
+
*/
|
|
2842
|
+
declare class PostsClient {
|
|
2843
|
+
private readonly client;
|
|
2844
|
+
constructor(client: BaseClient);
|
|
2845
|
+
/**
|
|
2846
|
+
* Get trending/hot posts from Reddit or a specific subreddit.
|
|
2847
|
+
*
|
|
2848
|
+
* @param options - Request parameters.
|
|
2849
|
+
* @param options.subreddit - Subreddit name (without r/). If omitted, returns site-wide posts.
|
|
2850
|
+
* @param options.sort - Sort order (hot, new, top, rising, controversial).
|
|
2851
|
+
* @param options.time - Time filter for top/controversial (hour, day, week, month, year, all).
|
|
2852
|
+
* @param options.after - Pagination cursor for the next page.
|
|
2853
|
+
* @param options.limit - Number of results to return (max 100).
|
|
2854
|
+
* @returns Trending posts with pagination metadata.
|
|
2855
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2856
|
+
*
|
|
2857
|
+
* @example
|
|
2858
|
+
* ```typescript
|
|
2859
|
+
* const results = await client.reddit.posts.trending({
|
|
2860
|
+
* subreddit: "worldnews",
|
|
2861
|
+
* sort: "hot",
|
|
2862
|
+
* limit: 25,
|
|
2863
|
+
* });
|
|
2864
|
+
* for (const post of results.posts) {
|
|
2865
|
+
* console.log(`${post.title} (${post.num_comments} comments)`);
|
|
2866
|
+
* }
|
|
2867
|
+
* ```
|
|
2868
|
+
*/
|
|
2869
|
+
trending(options?: {
|
|
2870
|
+
subreddit?: string;
|
|
2871
|
+
sort?: "hot" | "new" | "top" | "rising" | "controversial";
|
|
2872
|
+
time?: "hour" | "day" | "week" | "month" | "year" | "all";
|
|
2873
|
+
after?: string;
|
|
2874
|
+
limit?: number;
|
|
2875
|
+
}): Promise<TrendingPostsResponse>;
|
|
2876
|
+
/**
|
|
2877
|
+
* Get full details of a single Reddit post.
|
|
2878
|
+
*
|
|
2879
|
+
* @param postId - The Reddit post ID (e.g. "abc123" or "t3_abc123").
|
|
2880
|
+
* @param options - Optional parameters.
|
|
2881
|
+
* @param options.subreddit - Subreddit name (helps resolve the post URL).
|
|
2882
|
+
* @returns Full post details.
|
|
2883
|
+
* @throws NotFoundError - If the post doesn't exist.
|
|
2884
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2885
|
+
*
|
|
2886
|
+
* @example
|
|
2887
|
+
* ```typescript
|
|
2888
|
+
* const response = await client.reddit.posts.get("abc123", { subreddit: "programming" });
|
|
2889
|
+
* const { post } = response;
|
|
2890
|
+
* console.log(`${post.title} by u/${post.author}`);
|
|
2891
|
+
* console.log(`Score: ${post.score}, Comments: ${post.num_comments}`);
|
|
2892
|
+
* ```
|
|
2893
|
+
*/
|
|
2894
|
+
get(postId: string, options?: {
|
|
2895
|
+
subreddit?: string;
|
|
2896
|
+
}): Promise<PostDetailResponse>;
|
|
2897
|
+
/**
|
|
2898
|
+
* Get comments for a Reddit post.
|
|
2899
|
+
*
|
|
2900
|
+
* @param postId - The Reddit post ID (e.g. "abc123" or "t3_abc123").
|
|
2901
|
+
* @param options - Optional parameters.
|
|
2902
|
+
* @param options.subreddit - Subreddit name (helps resolve the post URL).
|
|
2903
|
+
* @param options.sort - Comment sort order (confidence, top, new, controversial, old, qa).
|
|
2904
|
+
* @param options.depth - Maximum comment tree depth.
|
|
2905
|
+
* @param options.limit - Number of top-level comments to return.
|
|
2906
|
+
* @returns Post details and nested comment tree.
|
|
2907
|
+
* @throws NotFoundError - If the post doesn't exist.
|
|
2908
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2909
|
+
*
|
|
2910
|
+
* @example
|
|
2911
|
+
* ```typescript
|
|
2912
|
+
* const response = await client.reddit.posts.comments("abc123", {
|
|
2913
|
+
* subreddit: "programming",
|
|
2914
|
+
* sort: "top",
|
|
2915
|
+
* limit: 50,
|
|
2916
|
+
* });
|
|
2917
|
+
* for (const comment of response.comments) {
|
|
2918
|
+
* console.log(`u/${comment.author}: ${comment.body.slice(0, 100)}`);
|
|
2919
|
+
* }
|
|
2920
|
+
* ```
|
|
2921
|
+
*/
|
|
2922
|
+
comments(postId: string, options?: {
|
|
2923
|
+
subreddit?: string;
|
|
2924
|
+
sort?: "confidence" | "top" | "new" | "controversial" | "old" | "qa";
|
|
2925
|
+
depth?: number;
|
|
2926
|
+
limit?: number;
|
|
2927
|
+
}): Promise<PostCommentsResponse>;
|
|
2928
|
+
/**
|
|
2929
|
+
* Get cross-posts and duplicate submissions of a Reddit post.
|
|
2930
|
+
*
|
|
2931
|
+
* @param postId - The Reddit post ID (e.g. "abc123" or "t3_abc123").
|
|
2932
|
+
* @param options - Optional parameters.
|
|
2933
|
+
* @param options.after - Pagination cursor for the next page.
|
|
2934
|
+
* @param options.limit - Number of results to return (max 100).
|
|
2935
|
+
* @returns The original post and its duplicate submissions.
|
|
2936
|
+
* @throws NotFoundError - If the post doesn't exist.
|
|
2937
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2938
|
+
*
|
|
2939
|
+
* @example
|
|
2940
|
+
* ```typescript
|
|
2941
|
+
* const response = await client.reddit.posts.duplicates("abc123");
|
|
2942
|
+
* console.log(`Original: ${response.post.title}`);
|
|
2943
|
+
* console.log(`Cross-posted ${response.duplicates.length} times`);
|
|
2944
|
+
* for (const dupe of response.duplicates) {
|
|
2945
|
+
* console.log(` r/${dupe.subreddit}: ${dupe.score} points`);
|
|
2946
|
+
* }
|
|
2947
|
+
* ```
|
|
2948
|
+
*/
|
|
2949
|
+
duplicates(postId: string, options?: {
|
|
2950
|
+
after?: string;
|
|
2951
|
+
limit?: number;
|
|
2952
|
+
}): Promise<PostDuplicatesResponse>;
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2955
|
+
/**
|
|
2956
|
+
* Reddit Subreddits API client.
|
|
2957
|
+
*
|
|
2958
|
+
* Provides methods for fetching subreddit details, posts, rules, moderators, and wiki pages.
|
|
2959
|
+
*/
|
|
2960
|
+
|
|
2961
|
+
/**
|
|
2962
|
+
* Client for Reddit subreddit endpoints.
|
|
2963
|
+
*
|
|
2964
|
+
* @example
|
|
2965
|
+
* ```typescript
|
|
2966
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
2967
|
+
*
|
|
2968
|
+
* // Get subreddit details
|
|
2969
|
+
* const sub = await client.reddit.subreddits.get("programming");
|
|
2970
|
+
* console.log(`r/programming: ${sub.subreddit.subscribers.toLocaleString()} subscribers`);
|
|
2971
|
+
*
|
|
2972
|
+
* // Get subreddit posts
|
|
2973
|
+
* const posts = await client.reddit.subreddits.posts("programming", { sort: "top" });
|
|
2974
|
+
*
|
|
2975
|
+
* // Get subreddit rules
|
|
2976
|
+
* const rules = await client.reddit.subreddits.rules("programming");
|
|
2977
|
+
* ```
|
|
2978
|
+
*/
|
|
2979
|
+
declare class SubredditsClient {
|
|
2980
|
+
private readonly client;
|
|
2981
|
+
constructor(client: BaseClient);
|
|
2982
|
+
/**
|
|
2983
|
+
* Get a subreddit's full details and metadata.
|
|
2984
|
+
*
|
|
2985
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
2986
|
+
* @returns Full subreddit details.
|
|
2987
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
2988
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
2989
|
+
*
|
|
2990
|
+
* @example
|
|
2991
|
+
* ```typescript
|
|
2992
|
+
* const response = await client.reddit.subreddits.get("javascript");
|
|
2993
|
+
* const { subreddit } = response;
|
|
2994
|
+
* console.log(`${subreddit.title}: ${subreddit.subscribers.toLocaleString()} members`);
|
|
2995
|
+
* console.log(`Description: ${subreddit.public_description}`);
|
|
2996
|
+
* ```
|
|
2997
|
+
*/
|
|
2998
|
+
get(subreddit: string): Promise<SubredditDetailResponse>;
|
|
2999
|
+
/**
|
|
3000
|
+
* Get posts from a subreddit.
|
|
3001
|
+
*
|
|
3002
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3003
|
+
* @param options - Optional parameters.
|
|
3004
|
+
* @param options.sort - Sort order (hot, new, top, rising, controversial).
|
|
3005
|
+
* @param options.time - Time filter for top/controversial (hour, day, week, month, year, all).
|
|
3006
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3007
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3008
|
+
* @returns Subreddit posts with pagination metadata.
|
|
3009
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3010
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3011
|
+
*
|
|
3012
|
+
* @example
|
|
3013
|
+
* ```typescript
|
|
3014
|
+
* const response = await client.reddit.subreddits.posts("typescript", {
|
|
3015
|
+
* sort: "top",
|
|
3016
|
+
* time: "week",
|
|
3017
|
+
* limit: 25,
|
|
3018
|
+
* });
|
|
3019
|
+
* for (const post of response.posts) {
|
|
3020
|
+
* console.log(`${post.title} — ${post.score} pts`);
|
|
3021
|
+
* }
|
|
3022
|
+
* ```
|
|
3023
|
+
*/
|
|
3024
|
+
posts(subreddit: string, options?: {
|
|
3025
|
+
sort?: "hot" | "new" | "top" | "rising" | "controversial";
|
|
3026
|
+
time?: "hour" | "day" | "week" | "month" | "year" | "all";
|
|
3027
|
+
after?: string;
|
|
3028
|
+
limit?: number;
|
|
3029
|
+
}): Promise<SubredditPostsResponse>;
|
|
3030
|
+
/**
|
|
3031
|
+
* Get the rules for a subreddit.
|
|
3032
|
+
*
|
|
3033
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3034
|
+
* @returns List of subreddit rules.
|
|
3035
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3036
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3037
|
+
*
|
|
3038
|
+
* @example
|
|
3039
|
+
* ```typescript
|
|
3040
|
+
* const response = await client.reddit.subreddits.rules("AskReddit");
|
|
3041
|
+
* for (const rule of response.rules) {
|
|
3042
|
+
* console.log(`${rule.priority}. ${rule.short_name}`);
|
|
3043
|
+
* console.log(` ${rule.description}`);
|
|
3044
|
+
* }
|
|
3045
|
+
* ```
|
|
3046
|
+
*/
|
|
3047
|
+
rules(subreddit: string): Promise<SubredditRulesResponse>;
|
|
3048
|
+
/**
|
|
3049
|
+
* Get the moderators of a subreddit.
|
|
3050
|
+
*
|
|
3051
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3052
|
+
* @param options - Optional parameters.
|
|
3053
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3054
|
+
* @param options.limit - Number of results to return.
|
|
3055
|
+
* @returns List of moderators with pagination metadata.
|
|
3056
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3057
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3058
|
+
*
|
|
3059
|
+
* @example
|
|
3060
|
+
* ```typescript
|
|
3061
|
+
* const response = await client.reddit.subreddits.moderators("programming");
|
|
3062
|
+
* for (const mod of response.moderators) {
|
|
3063
|
+
* console.log(`u/${mod.name}: [${mod.mod_permissions.join(", ")}]`);
|
|
3064
|
+
* }
|
|
3065
|
+
* ```
|
|
3066
|
+
*/
|
|
3067
|
+
moderators(subreddit: string, options?: {
|
|
3068
|
+
after?: string;
|
|
3069
|
+
limit?: number;
|
|
3070
|
+
}): Promise<SubredditModeratorsResponse>;
|
|
3071
|
+
/**
|
|
3072
|
+
* List all wiki pages in a subreddit.
|
|
3073
|
+
*
|
|
3074
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3075
|
+
* @returns List of wiki page slugs.
|
|
3076
|
+
* @throws NotFoundError - If the subreddit doesn't exist.
|
|
3077
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3078
|
+
*
|
|
3079
|
+
* @example
|
|
3080
|
+
* ```typescript
|
|
3081
|
+
* const response = await client.reddit.subreddits.wikiPages("rust");
|
|
3082
|
+
* for (const page of response.pages) {
|
|
3083
|
+
* console.log(`/r/rust/wiki/${page}`);
|
|
3084
|
+
* }
|
|
3085
|
+
* ```
|
|
3086
|
+
*/
|
|
3087
|
+
wikiPages(subreddit: string): Promise<SubredditWikiPagesResponse>;
|
|
3088
|
+
/**
|
|
3089
|
+
* Get the content of a specific wiki page in a subreddit.
|
|
3090
|
+
*
|
|
3091
|
+
* @param subreddit - Subreddit name (without r/ prefix).
|
|
3092
|
+
* @param page - Wiki page slug (e.g. "index", "faq").
|
|
3093
|
+
* @returns Wiki page content and metadata.
|
|
3094
|
+
* @throws NotFoundError - If the subreddit or wiki page doesn't exist.
|
|
3095
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3096
|
+
*
|
|
3097
|
+
* @example
|
|
3098
|
+
* ```typescript
|
|
3099
|
+
* const response = await client.reddit.subreddits.wikiPage("learnprogramming", "faq");
|
|
3100
|
+
* console.log(`Last edited by: u/${response.page.revision_by}`);
|
|
3101
|
+
* console.log(response.page.content_md);
|
|
3102
|
+
* ```
|
|
3103
|
+
*/
|
|
3104
|
+
wikiPage(subreddit: string, page: string): Promise<WikiPageResponse>;
|
|
3105
|
+
/**
|
|
3106
|
+
* Get the most popular subreddits on Reddit.
|
|
3107
|
+
*
|
|
3108
|
+
* @param options - Optional parameters.
|
|
3109
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3110
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3111
|
+
* @returns Popular subreddits with pagination metadata.
|
|
3112
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3113
|
+
*
|
|
3114
|
+
* @example
|
|
3115
|
+
* ```typescript
|
|
3116
|
+
* const response = await client.reddit.subreddits.popular({ limit: 20 });
|
|
3117
|
+
* for (const sub of response.subreddits) {
|
|
3118
|
+
* console.log(`r/${sub.display_name}: ${sub.subscribers.toLocaleString()} subscribers`);
|
|
3119
|
+
* }
|
|
3120
|
+
* ```
|
|
3121
|
+
*/
|
|
3122
|
+
popular(options?: {
|
|
3123
|
+
after?: string;
|
|
3124
|
+
limit?: number;
|
|
3125
|
+
}): Promise<PopularSubredditsResponse>;
|
|
3126
|
+
/**
|
|
3127
|
+
* Get newly created subreddits on Reddit.
|
|
3128
|
+
*
|
|
3129
|
+
* @param options - Optional parameters.
|
|
3130
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3131
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3132
|
+
* @returns New subreddits with pagination metadata.
|
|
3133
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3134
|
+
*
|
|
3135
|
+
* @example
|
|
3136
|
+
* ```typescript
|
|
3137
|
+
* const response = await client.reddit.subreddits.newSubreddits({ limit: 20 });
|
|
3138
|
+
* for (const sub of response.subreddits) {
|
|
3139
|
+
* console.log(`r/${sub.display_name} (created: ${new Date(sub.created_utc * 1000).toLocaleDateString()})`);
|
|
3140
|
+
* }
|
|
3141
|
+
* ```
|
|
3142
|
+
*/
|
|
3143
|
+
newSubreddits(options?: {
|
|
3144
|
+
after?: string;
|
|
3145
|
+
limit?: number;
|
|
3146
|
+
}): Promise<PopularSubredditsResponse>;
|
|
3147
|
+
}
|
|
3148
|
+
|
|
3149
|
+
/**
|
|
3150
|
+
* Reddit Users API client.
|
|
3151
|
+
*
|
|
3152
|
+
* Provides methods for fetching Reddit user profiles, posts, comments, moderated subreddits, and trophies.
|
|
3153
|
+
*/
|
|
3154
|
+
|
|
3155
|
+
/**
|
|
3156
|
+
* Client for Reddit user endpoints.
|
|
3157
|
+
*
|
|
3158
|
+
* @example
|
|
3159
|
+
* ```typescript
|
|
3160
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
3161
|
+
*
|
|
3162
|
+
* // Get user profile
|
|
3163
|
+
* const profile = await client.reddit.users.get("spez");
|
|
3164
|
+
* console.log(`u/${profile.user.name}: ${profile.user.total_karma.toLocaleString()} karma`);
|
|
3165
|
+
*
|
|
3166
|
+
* // Get user's recent posts
|
|
3167
|
+
* const posts = await client.reddit.users.posts("spez", { sort: "top", limit: 10 });
|
|
3168
|
+
*
|
|
3169
|
+
* // Get user's comments
|
|
3170
|
+
* const comments = await client.reddit.users.comments("spez", { sort: "new" });
|
|
3171
|
+
* ```
|
|
3172
|
+
*/
|
|
3173
|
+
declare class UsersClient {
|
|
3174
|
+
private readonly client;
|
|
3175
|
+
constructor(client: BaseClient);
|
|
3176
|
+
/**
|
|
3177
|
+
* Get a Reddit user's profile.
|
|
3178
|
+
*
|
|
3179
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3180
|
+
* @returns The user profile response.
|
|
3181
|
+
* @throws NotFoundError - If the user doesn't exist or is suspended.
|
|
3182
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3183
|
+
*
|
|
3184
|
+
* @example
|
|
3185
|
+
* ```typescript
|
|
3186
|
+
* const response = await client.reddit.users.get("spez");
|
|
3187
|
+
* const { user } = response;
|
|
3188
|
+
* console.log(`u/${user.name}`);
|
|
3189
|
+
* console.log(`Karma: ${user.total_karma.toLocaleString()} (${user.link_karma} post, ${user.comment_karma} comment)`);
|
|
3190
|
+
* console.log(`Account age: ${new Date(user.created_utc * 1000).toLocaleDateString()}`);
|
|
3191
|
+
* ```
|
|
3192
|
+
*/
|
|
3193
|
+
get(username: string): Promise<UserProfileResponse>;
|
|
3194
|
+
/**
|
|
3195
|
+
* Get posts submitted by a Reddit user.
|
|
3196
|
+
*
|
|
3197
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3198
|
+
* @param options - Optional parameters.
|
|
3199
|
+
* @param options.sort - Sort order (hot, new, top, controversial).
|
|
3200
|
+
* @param options.time - Time filter for top/controversial (hour, day, week, month, year, all).
|
|
3201
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3202
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3203
|
+
* @returns The user's posts with pagination metadata.
|
|
3204
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
3205
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3206
|
+
*
|
|
3207
|
+
* @example
|
|
3208
|
+
* ```typescript
|
|
3209
|
+
* const response = await client.reddit.users.posts("spez", {
|
|
3210
|
+
* sort: "top",
|
|
3211
|
+
* time: "all",
|
|
3212
|
+
* limit: 25,
|
|
3213
|
+
* });
|
|
3214
|
+
* for (const post of response.posts) {
|
|
3215
|
+
* console.log(`r/${post.subreddit}: ${post.title} (${post.score} pts)`);
|
|
3216
|
+
* }
|
|
3217
|
+
* ```
|
|
3218
|
+
*/
|
|
3219
|
+
posts(username: string, options?: {
|
|
3220
|
+
sort?: "hot" | "new" | "top" | "controversial";
|
|
3221
|
+
time?: "hour" | "day" | "week" | "month" | "year" | "all";
|
|
3222
|
+
after?: string;
|
|
3223
|
+
limit?: number;
|
|
3224
|
+
}): Promise<UserPostsResponse>;
|
|
3225
|
+
/**
|
|
3226
|
+
* Get comments made by a Reddit user.
|
|
3227
|
+
*
|
|
3228
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3229
|
+
* @param options - Optional parameters.
|
|
3230
|
+
* @param options.sort - Sort order (hot, new, top, controversial).
|
|
3231
|
+
* @param options.time - Time filter for top/controversial (hour, day, week, month, year, all).
|
|
3232
|
+
* @param options.after - Pagination cursor for the next page.
|
|
3233
|
+
* @param options.limit - Number of results to return (max 100).
|
|
3234
|
+
* @returns The user's comments with pagination metadata.
|
|
3235
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
3236
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3237
|
+
*
|
|
3238
|
+
* @example
|
|
3239
|
+
* ```typescript
|
|
3240
|
+
* const response = await client.reddit.users.comments("spez", {
|
|
3241
|
+
* sort: "new",
|
|
3242
|
+
* limit: 50,
|
|
3243
|
+
* });
|
|
3244
|
+
* for (const comment of response.comments) {
|
|
3245
|
+
* console.log(`r/${comment.subreddit}: ${comment.body.slice(0, 80)}`);
|
|
3246
|
+
* }
|
|
3247
|
+
* ```
|
|
3248
|
+
*/
|
|
3249
|
+
comments(username: string, options?: {
|
|
3250
|
+
sort?: "hot" | "new" | "top" | "controversial";
|
|
3251
|
+
time?: "hour" | "day" | "week" | "month" | "year" | "all";
|
|
3252
|
+
after?: string;
|
|
3253
|
+
limit?: number;
|
|
3254
|
+
}): Promise<UserCommentsResponse>;
|
|
3255
|
+
/**
|
|
3256
|
+
* Get subreddits moderated by a Reddit user.
|
|
3257
|
+
*
|
|
3258
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3259
|
+
* @returns Subreddits moderated by the user.
|
|
3260
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
3261
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3262
|
+
*
|
|
3263
|
+
* @example
|
|
3264
|
+
* ```typescript
|
|
3265
|
+
* const response = await client.reddit.users.moderated("spez");
|
|
3266
|
+
* for (const sub of response.subreddits) {
|
|
3267
|
+
* console.log(`r/${sub.display_name}: ${sub.subscribers.toLocaleString()} subscribers`);
|
|
3268
|
+
* }
|
|
3269
|
+
* ```
|
|
3270
|
+
*/
|
|
3271
|
+
moderated(username: string): Promise<UserModeratedResponse>;
|
|
3272
|
+
/**
|
|
3273
|
+
* Get trophies awarded to a Reddit user.
|
|
3274
|
+
*
|
|
3275
|
+
* @param username - The Reddit username (without u/ prefix).
|
|
3276
|
+
* @returns List of trophies awarded to the user.
|
|
3277
|
+
* @throws NotFoundError - If the user doesn't exist.
|
|
3278
|
+
* @throws AuthenticationError - If the API key is invalid.
|
|
3279
|
+
*
|
|
3280
|
+
* @example
|
|
3281
|
+
* ```typescript
|
|
3282
|
+
* const response = await client.reddit.users.trophies("spez");
|
|
3283
|
+
* for (const trophy of response.trophies) {
|
|
3284
|
+
* console.log(`${trophy.name}${trophy.description ? `: ${trophy.description}` : ""}`);
|
|
3285
|
+
* }
|
|
3286
|
+
* ```
|
|
3287
|
+
*/
|
|
3288
|
+
trophies(username: string): Promise<UserTrophiesResponse>;
|
|
3289
|
+
}
|
|
3290
|
+
|
|
3291
|
+
/**
|
|
3292
|
+
* Reddit API client.
|
|
3293
|
+
*
|
|
3294
|
+
* Provides access to all Reddit API endpoints through specialized sub-clients.
|
|
3295
|
+
*/
|
|
3296
|
+
|
|
3297
|
+
/**
|
|
3298
|
+
* Reddit API client with access to all Reddit endpoints.
|
|
3299
|
+
*
|
|
3300
|
+
* Provides sub-clients for different resource types:
|
|
3301
|
+
* - `search` - Search posts, subreddits, users, and domain posts
|
|
3302
|
+
* - `posts` - Trending posts, post details, comments, and cross-posts
|
|
3303
|
+
* - `subreddits` - Subreddit details, posts, rules, moderators, and wiki pages
|
|
3304
|
+
* - `users` - User profiles, posts, comments, moderated subreddits, and trophies
|
|
3305
|
+
*
|
|
3306
|
+
* @example
|
|
3307
|
+
* ```typescript
|
|
3308
|
+
* const client = new ScrapeBadger({ apiKey: "key" });
|
|
3309
|
+
*
|
|
3310
|
+
* // Search posts
|
|
3311
|
+
* const results = await client.reddit.search.posts({ query: "typescript tips" });
|
|
3312
|
+
*
|
|
3313
|
+
* // Get subreddit details
|
|
3314
|
+
* const sub = await client.reddit.subreddits.get("programming");
|
|
3315
|
+
*
|
|
3316
|
+
* // Get user profile
|
|
3317
|
+
* const user = await client.reddit.users.get("spez");
|
|
3318
|
+
*
|
|
3319
|
+
* // Get trending posts
|
|
3320
|
+
* const trending = await client.reddit.posts.trending({ sort: "hot" });
|
|
3321
|
+
* ```
|
|
3322
|
+
*/
|
|
3323
|
+
declare class RedditClient {
|
|
3324
|
+
/** Client for search operations (posts, subreddits, users, domain posts) */
|
|
3325
|
+
readonly search: SearchClient;
|
|
3326
|
+
/** Client for post operations (trending, details, comments, duplicates) */
|
|
3327
|
+
readonly posts: PostsClient;
|
|
3328
|
+
/** Client for subreddit operations (details, posts, rules, moderators, wiki) */
|
|
3329
|
+
readonly subreddits: SubredditsClient;
|
|
3330
|
+
/** Client for user operations (profile, posts, comments, moderated, trophies) */
|
|
3331
|
+
readonly users: UsersClient;
|
|
3332
|
+
/**
|
|
3333
|
+
* Create a new Reddit client.
|
|
3334
|
+
*
|
|
3335
|
+
* @param client - The base HTTP client for making requests.
|
|
3336
|
+
*/
|
|
3337
|
+
constructor(client: BaseClient);
|
|
159
3338
|
}
|
|
160
3339
|
|
|
161
3340
|
/**
|
|
@@ -202,6 +3381,12 @@ declare class ScrapeBadger {
|
|
|
202
3381
|
readonly twitter: TwitterClient;
|
|
203
3382
|
/** Web scraping API client */
|
|
204
3383
|
readonly web: WebClient;
|
|
3384
|
+
/** Vinted scraper API client */
|
|
3385
|
+
readonly vinted: VintedClient;
|
|
3386
|
+
/** Google Scraper API client — 19 Google product APIs */
|
|
3387
|
+
readonly google: GoogleClient;
|
|
3388
|
+
/** Reddit scraper API client */
|
|
3389
|
+
readonly reddit: RedditClient;
|
|
205
3390
|
/**
|
|
206
3391
|
* Create a new ScrapeBadger client.
|
|
207
3392
|
*
|
|
@@ -230,4 +3415,4 @@ declare class ScrapeBadger {
|
|
|
230
3415
|
constructor(config?: Partial<ScrapeBadgerConfig>);
|
|
231
3416
|
}
|
|
232
3417
|
|
|
233
|
-
export { type
|
|
3418
|
+
export { type AiModeSearchParams, type AutocompleteParams, type DetectOptions, type DetectResult, type DomainPostsResponse, type FinanceQuoteParams, type FlightsSearchParams, type FlightsStopsFilter, type FlightsTravelClass, type FlightsTripType, AiModeClient as GoogleAiModeClient, AutocompleteClient as GoogleAutocompleteClient, GoogleClient, FinanceClient as GoogleFinanceClient, FlightsClient as GoogleFlightsClient, HotelsClient as GoogleHotelsClient, ImagesClient as GoogleImagesClient, JobsClient as GoogleJobsClient, LensClient as GoogleLensClient, MapsClient as GoogleMapsClient, NewsClient as GoogleNewsClient, PatentsClient as GooglePatentsClient, ProductsClient as GoogleProductsClient, type GoogleResponse, ScholarClient as GoogleScholarClient, SearchClient$1 as GoogleSearchClient, type GoogleSearchParams, ShoppingClient as GoogleShoppingClient, ShortsClient as GoogleShortsClient, TrendsClient as GoogleTrendsClient, VideosClient as GoogleVideosClient, type HotelsDetailsParams, type HotelsSearchParams, type ImagesSearchParams, type JobsSearchParams, type LensSearchParams, type MapsPhotosParams, type MapsPlaceParams, type MapsPostsParams, type MapsReviewsParams, type MapsSearchParams, type NewsSearchParams, type NewsTopicsParams, type NewsTrendingParams, type PatentsDetailParams, type PatentsSearchParams, type PopularSubredditsResponse, type PostCommentsResponse, type PostDetailResponse, type PostDuplicatesResponse, type ProductsDetailParams, RedditClient, type RedditComment, type RedditModerator, type RedditPagination, type RedditPost, PostsClient as RedditPostsClient, type RedditRule, SearchClient as RedditSearchClient, type RedditSubreddit, SubredditsClient as RedditSubredditsClient, type RedditTrophy, type RedditUser, type UserProfileResponse as RedditUserProfileResponse, UsersClient as RedditUsersClient, type RedditWikiPage, type ScholarAuthorCitationParams, type ScholarAuthorParams, type ScholarCiteParams, type ScholarProfilesParams, type ScholarSearchParams, ScrapeBadger, ScrapeBadgerConfig, type ScrapeOptions, type ScrapeResult, type SearchPostsResponse, type SearchSubredditsResponse, type SearchUsersResponse, type ShoppingClickParams, type ShoppingProductParams, type ShoppingSearchParams, type ShortsSearchParams, type SubredditDetailResponse, type SubredditModeratorsResponse, type SubredditPostsResponse, type SubredditRulesResponse, type SubredditWikiPagesResponse, type TrendingPostsResponse, type TrendsAutocompleteParams, type TrendsInterestParams, type TrendsRegionsParams, type TrendsRelatedParams, type TrendsTrendingParams, TwitterClient, type UserCommentsResponse, type UserModeratedResponse, type UserPostsResponse, type UserTrophiesResponse, type VideosSearchParams, type VintedBrand, type BrandsResponse as VintedBrandsResponse, VintedClient, type VintedColor, type ColorsResponse as VintedColorsResponse, type VintedItemDetail, type ItemDetailResponse as VintedItemDetailResponse, type VintedItemSummary, ItemsClient as VintedItemsClient, type VintedMarket, type MarketsResponse as VintedMarketsResponse, type VintedPagination, type VintedPhoto, type VintedPrice, ReferenceClient as VintedReferenceClient, SearchClient$2 as VintedSearchClient, type VintedSearchParams, type SearchResponse as VintedSearchResponse, type VintedSellerSummary, type VintedStatus, type StatusesResponse as VintedStatusesResponse, type UserItemsResponse as VintedUserItemsResponse, type VintedUserProfile, type UserProfileResponse$1 as VintedUserProfileResponse, type VintedUserSummary, UsersClient$1 as VintedUsersClient, WebClient, type WikiPageResponse };
|