n8n-nodes-octopus-scraping 0.1.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/LICENSE.md +19 -0
- package/README.md +262 -0
- package/dist/credentials/BrowserRunApi.credentials.d.ts +10 -0
- package/dist/credentials/BrowserRunApi.credentials.js +53 -0
- package/dist/credentials/BrowserRunApi.credentials.js.map +1 -0
- package/dist/credentials/browser-run-dark.svg +6 -0
- package/dist/credentials/browser-run-light.svg +6 -0
- package/dist/credentials/octopus-dark.svg +27 -0
- package/dist/credentials/octopus-light.svg +27 -0
- package/dist/icons/github.dark.svg +3 -0
- package/dist/icons/github.svg +3 -0
- package/dist/nodes/BrowserRun/BrowserRun.node.d.ts +5 -0
- package/dist/nodes/BrowserRun/BrowserRun.node.js +706 -0
- package/dist/nodes/BrowserRun/BrowserRun.node.js.map +1 -0
- package/dist/nodes/BrowserRun/browser-run.svg +6 -0
- package/dist/nodes/BrowserRun/octopus.svg +29 -0
- package/dist/package.json +58 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,706 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserRun = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
class BrowserRun {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Octopus Scraping',
|
|
9
|
+
name: 'browserRun',
|
|
10
|
+
icon: 'file:octopus.svg',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
subtitle: '={{$parameter.action}}',
|
|
14
|
+
description: 'Interact with Octopus Scraping Worker for web scraping, screenshots, PDFs, and browser automation',
|
|
15
|
+
defaults: {
|
|
16
|
+
name: 'Octopus Scraping',
|
|
17
|
+
},
|
|
18
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
19
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
20
|
+
usableAsTool: true,
|
|
21
|
+
credentials: [
|
|
22
|
+
{
|
|
23
|
+
name: 'browserRunApi',
|
|
24
|
+
required: true,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
properties: [
|
|
28
|
+
{
|
|
29
|
+
displayName: 'Action',
|
|
30
|
+
name: 'action',
|
|
31
|
+
type: 'options',
|
|
32
|
+
noDataExpression: true,
|
|
33
|
+
options: [
|
|
34
|
+
{ name: 'Batch', value: 'batch' },
|
|
35
|
+
{ name: 'Click', value: 'click' },
|
|
36
|
+
{ name: 'Cookies', value: 'cookies' },
|
|
37
|
+
{ name: 'Crawl', value: 'crawl' },
|
|
38
|
+
{ name: 'Evaluate JavaScript', value: 'evaluate' },
|
|
39
|
+
{ name: 'Extract Links', value: 'links' },
|
|
40
|
+
{ name: 'Health Check', value: 'health' },
|
|
41
|
+
{ name: 'JSON Extraction (AI)', value: 'json' },
|
|
42
|
+
{ name: 'Markdown', value: 'markdown' },
|
|
43
|
+
{ name: 'PDF', value: 'pdf' },
|
|
44
|
+
{ name: 'Run Custom Steps', value: 'run' },
|
|
45
|
+
{ name: 'Scrape (HTML)', value: 'scrape' },
|
|
46
|
+
{ name: 'Screenshot', value: 'screenshot' },
|
|
47
|
+
{ name: 'SEO Analysis', value: 'seo' },
|
|
48
|
+
{ name: 'Snapshot (Accessibility Tree)', value: 'snapshot' },
|
|
49
|
+
],
|
|
50
|
+
default: 'screenshot',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
displayName: 'URL',
|
|
54
|
+
name: 'url',
|
|
55
|
+
type: 'string',
|
|
56
|
+
default: '',
|
|
57
|
+
required: true,
|
|
58
|
+
placeholder: 'https://example.com',
|
|
59
|
+
displayOptions: {
|
|
60
|
+
show: {
|
|
61
|
+
action: ['screenshot', 'pdf', 'scrape', 'markdown', 'snapshot', 'links', 'json', 'crawl', 'seo', 'click', 'cookies', 'evaluate'],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
displayName: 'Full Page',
|
|
67
|
+
name: 'fullPage',
|
|
68
|
+
type: 'boolean',
|
|
69
|
+
default: true,
|
|
70
|
+
description: 'Whether to capture the full page or just the viewport',
|
|
71
|
+
displayOptions: {
|
|
72
|
+
show: {
|
|
73
|
+
action: ['screenshot'],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
displayName: 'Format',
|
|
79
|
+
name: 'format',
|
|
80
|
+
type: 'options',
|
|
81
|
+
options: [
|
|
82
|
+
{ name: 'JPEG', value: 'jpeg' },
|
|
83
|
+
{ name: 'PNG', value: 'png' },
|
|
84
|
+
],
|
|
85
|
+
default: 'png',
|
|
86
|
+
displayOptions: {
|
|
87
|
+
show: {
|
|
88
|
+
action: ['screenshot'],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
displayName: 'Viewport Width',
|
|
94
|
+
name: 'viewportWidth',
|
|
95
|
+
type: 'number',
|
|
96
|
+
default: 1920,
|
|
97
|
+
description: 'Viewport width in pixels',
|
|
98
|
+
displayOptions: {
|
|
99
|
+
show: {
|
|
100
|
+
action: ['screenshot', 'pdf'],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
displayName: 'Viewport Height',
|
|
106
|
+
name: 'viewportHeight',
|
|
107
|
+
type: 'number',
|
|
108
|
+
default: 1080,
|
|
109
|
+
description: 'Viewport height in pixels',
|
|
110
|
+
displayOptions: {
|
|
111
|
+
show: {
|
|
112
|
+
action: ['screenshot', 'pdf'],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
displayName: 'Clip Region',
|
|
118
|
+
name: 'clipRegion',
|
|
119
|
+
type: 'collection',
|
|
120
|
+
placeholder: 'Add Clip Region',
|
|
121
|
+
default: {},
|
|
122
|
+
displayOptions: {
|
|
123
|
+
show: {
|
|
124
|
+
action: ['screenshot'],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
options: [
|
|
128
|
+
{ displayName: 'X', name: 'x', type: 'number', default: 0 },
|
|
129
|
+
{ displayName: 'Y', name: 'y', type: 'number', default: 0 },
|
|
130
|
+
{ displayName: 'Width', name: 'width', type: 'number', default: 800 },
|
|
131
|
+
{ displayName: 'Height', name: 'height', type: 'number', default: 600 },
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
displayName: 'Page Format',
|
|
136
|
+
name: 'pageFormat',
|
|
137
|
+
type: 'options',
|
|
138
|
+
options: [
|
|
139
|
+
{ name: 'A4', value: 'A4' },
|
|
140
|
+
{ name: 'Legal', value: 'Legal' },
|
|
141
|
+
{ name: 'Letter', value: 'Letter' },
|
|
142
|
+
{ name: 'Tabloid', value: 'Tabloid' },
|
|
143
|
+
],
|
|
144
|
+
default: 'A4',
|
|
145
|
+
displayOptions: {
|
|
146
|
+
show: {
|
|
147
|
+
action: ['pdf'],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
displayName: 'Landscape',
|
|
153
|
+
name: 'landscape',
|
|
154
|
+
type: 'boolean',
|
|
155
|
+
default: false,
|
|
156
|
+
description: 'Whether to use landscape orientation',
|
|
157
|
+
displayOptions: {
|
|
158
|
+
show: {
|
|
159
|
+
action: ['pdf'],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
displayName: 'Margin',
|
|
165
|
+
name: 'margin',
|
|
166
|
+
type: 'collection',
|
|
167
|
+
placeholder: 'Add Margin',
|
|
168
|
+
default: {},
|
|
169
|
+
displayOptions: {
|
|
170
|
+
show: {
|
|
171
|
+
action: ['pdf'],
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
options: [
|
|
175
|
+
{ displayName: 'Top', name: 'top', type: 'string', default: '1cm' },
|
|
176
|
+
{ displayName: 'Bottom', name: 'bottom', type: 'string', default: '1cm' },
|
|
177
|
+
{ displayName: 'Left', name: 'left', type: 'string', default: '1cm' },
|
|
178
|
+
{ displayName: 'Right', name: 'right', type: 'string', default: '1cm' },
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
displayName: 'Selectors',
|
|
183
|
+
name: 'selectors',
|
|
184
|
+
type: 'json',
|
|
185
|
+
default: '{}',
|
|
186
|
+
description: 'CSS selectors to extract elements (JSON object)',
|
|
187
|
+
displayOptions: {
|
|
188
|
+
show: {
|
|
189
|
+
action: ['scrape'],
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
displayName: 'Wait Until',
|
|
195
|
+
name: 'waitUntil',
|
|
196
|
+
type: 'options',
|
|
197
|
+
options: [
|
|
198
|
+
{ name: 'DOM Content Loaded', value: 'domcontentloaded' },
|
|
199
|
+
{ name: 'Load', value: 'load' },
|
|
200
|
+
{ name: 'Network Idle 0', value: 'networkidle0' },
|
|
201
|
+
{ name: 'Network Idle 2', value: 'networkidle2' },
|
|
202
|
+
],
|
|
203
|
+
default: 'load',
|
|
204
|
+
description: 'When to consider the page loaded',
|
|
205
|
+
displayOptions: {
|
|
206
|
+
show: {
|
|
207
|
+
action: ['scrape', 'markdown', 'snapshot', 'links', 'json'],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
displayName: 'Wait For Selector',
|
|
213
|
+
name: 'waitForSelector',
|
|
214
|
+
type: 'string',
|
|
215
|
+
default: '',
|
|
216
|
+
description: 'CSS selector to wait for before scraping',
|
|
217
|
+
displayOptions: {
|
|
218
|
+
show: {
|
|
219
|
+
action: ['scrape', 'markdown'],
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
displayName: 'Prompt',
|
|
225
|
+
name: 'prompt',
|
|
226
|
+
type: 'string',
|
|
227
|
+
default: '',
|
|
228
|
+
description: 'Natural language prompt for AI extraction',
|
|
229
|
+
displayOptions: {
|
|
230
|
+
show: {
|
|
231
|
+
action: ['json'],
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
displayName: 'Schema',
|
|
237
|
+
name: 'schema',
|
|
238
|
+
type: 'json',
|
|
239
|
+
default: '{}',
|
|
240
|
+
description: 'JSON schema for structured extraction',
|
|
241
|
+
displayOptions: {
|
|
242
|
+
show: {
|
|
243
|
+
action: ['json'],
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
displayName: 'Max Depth',
|
|
249
|
+
name: 'maxDepth',
|
|
250
|
+
type: 'number',
|
|
251
|
+
default: 2,
|
|
252
|
+
description: 'Maximum crawl depth',
|
|
253
|
+
displayOptions: {
|
|
254
|
+
show: {
|
|
255
|
+
action: ['crawl'],
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
displayName: 'Max Pages',
|
|
261
|
+
name: 'maxPages',
|
|
262
|
+
type: 'number',
|
|
263
|
+
default: 10,
|
|
264
|
+
description: 'Maximum number of pages to crawl',
|
|
265
|
+
displayOptions: {
|
|
266
|
+
show: {
|
|
267
|
+
action: ['crawl'],
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
displayName: 'Include Pattern',
|
|
273
|
+
name: 'includePattern',
|
|
274
|
+
type: 'string',
|
|
275
|
+
default: '',
|
|
276
|
+
description: 'URL pattern to include (e.g., /blog/)',
|
|
277
|
+
displayOptions: {
|
|
278
|
+
show: {
|
|
279
|
+
action: ['crawl'],
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
displayName: 'Exclude Pattern',
|
|
285
|
+
name: 'excludePattern',
|
|
286
|
+
type: 'string',
|
|
287
|
+
default: '',
|
|
288
|
+
description: 'URL pattern to exclude (e.g., /tag/)',
|
|
289
|
+
displayOptions: {
|
|
290
|
+
show: {
|
|
291
|
+
action: ['crawl'],
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
displayName: 'Selector',
|
|
297
|
+
name: 'selector',
|
|
298
|
+
type: 'string',
|
|
299
|
+
default: '',
|
|
300
|
+
description: 'CSS selector for the element to click',
|
|
301
|
+
displayOptions: {
|
|
302
|
+
show: {
|
|
303
|
+
action: ['click'],
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
displayName: 'Wait After Click (MS)',
|
|
309
|
+
name: 'waitFor',
|
|
310
|
+
type: 'number',
|
|
311
|
+
default: 2000,
|
|
312
|
+
description: 'Time to wait after clicking in milliseconds',
|
|
313
|
+
displayOptions: {
|
|
314
|
+
show: {
|
|
315
|
+
action: ['click'],
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
displayName: 'Take Screenshot',
|
|
321
|
+
name: 'takeScreenshot',
|
|
322
|
+
type: 'boolean',
|
|
323
|
+
default: false,
|
|
324
|
+
description: 'Whether to take a screenshot after clicking',
|
|
325
|
+
displayOptions: {
|
|
326
|
+
show: {
|
|
327
|
+
action: ['click'],
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
displayName: 'Operation',
|
|
333
|
+
name: 'cookieOperation',
|
|
334
|
+
type: 'options',
|
|
335
|
+
options: [
|
|
336
|
+
{ name: 'Get', value: 'get' },
|
|
337
|
+
],
|
|
338
|
+
default: 'get',
|
|
339
|
+
displayOptions: {
|
|
340
|
+
show: {
|
|
341
|
+
action: ['cookies'],
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
displayName: 'JavaScript',
|
|
347
|
+
name: 'script',
|
|
348
|
+
type: 'string',
|
|
349
|
+
default: '() => document.title',
|
|
350
|
+
description: 'JavaScript function to execute in page context',
|
|
351
|
+
displayOptions: {
|
|
352
|
+
show: {
|
|
353
|
+
action: ['evaluate'],
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
displayName: 'Wait Before (MS)',
|
|
359
|
+
name: 'waitBefore',
|
|
360
|
+
type: 'number',
|
|
361
|
+
default: 0,
|
|
362
|
+
description: 'Time to wait before executing script',
|
|
363
|
+
displayOptions: {
|
|
364
|
+
show: {
|
|
365
|
+
action: ['evaluate'],
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
displayName: 'URLs',
|
|
371
|
+
name: 'urls',
|
|
372
|
+
type: 'string',
|
|
373
|
+
default: '',
|
|
374
|
+
description: 'Comma-separated list of URLs to process',
|
|
375
|
+
displayOptions: {
|
|
376
|
+
show: {
|
|
377
|
+
action: ['batch'],
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
displayName: 'Batch Action',
|
|
383
|
+
name: 'batchAction',
|
|
384
|
+
type: 'options',
|
|
385
|
+
options: [
|
|
386
|
+
{ name: 'Markdown', value: 'markdown' },
|
|
387
|
+
{ name: 'Scrape', value: 'scrape' },
|
|
388
|
+
{ name: 'Screenshot', value: 'screenshot' },
|
|
389
|
+
],
|
|
390
|
+
default: 'scrape',
|
|
391
|
+
displayOptions: {
|
|
392
|
+
show: {
|
|
393
|
+
action: ['batch'],
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
displayName: 'Parallel',
|
|
399
|
+
name: 'parallel',
|
|
400
|
+
type: 'boolean',
|
|
401
|
+
default: false,
|
|
402
|
+
description: 'Whether to process URLs in parallel',
|
|
403
|
+
displayOptions: {
|
|
404
|
+
show: {
|
|
405
|
+
action: ['batch'],
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
displayName: 'Steps',
|
|
411
|
+
name: 'steps',
|
|
412
|
+
type: 'json',
|
|
413
|
+
default: '[]',
|
|
414
|
+
description: 'Array of browser automation steps (JSON)',
|
|
415
|
+
displayOptions: {
|
|
416
|
+
show: {
|
|
417
|
+
action: ['run'],
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
displayName: 'Timeout (Ms)',
|
|
423
|
+
name: 'timeout',
|
|
424
|
+
type: 'number',
|
|
425
|
+
default: 30000,
|
|
426
|
+
description: 'Maximum execution time in milliseconds',
|
|
427
|
+
displayOptions: {
|
|
428
|
+
show: {
|
|
429
|
+
action: ['run', 'crawl', 'batch'],
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
displayName: 'Return Binary Data',
|
|
435
|
+
name: 'returnBinary',
|
|
436
|
+
type: 'boolean',
|
|
437
|
+
default: false,
|
|
438
|
+
description: 'Whether to return binary data (for screenshot/PDF) instead of base64 string',
|
|
439
|
+
displayOptions: {
|
|
440
|
+
show: {
|
|
441
|
+
action: ['screenshot', 'pdf'],
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
displayName: 'Binary Property',
|
|
447
|
+
name: 'binaryProperty',
|
|
448
|
+
type: 'string',
|
|
449
|
+
default: 'data',
|
|
450
|
+
description: 'Name of the binary property to save the file',
|
|
451
|
+
displayOptions: {
|
|
452
|
+
show: {
|
|
453
|
+
action: ['screenshot', 'pdf'],
|
|
454
|
+
returnBinary: [true],
|
|
455
|
+
},
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
],
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
async execute() {
|
|
462
|
+
const items = this.getInputData();
|
|
463
|
+
const returnData = [];
|
|
464
|
+
const credentials = await this.getCredentials('browserRunApi');
|
|
465
|
+
const workerUrl = credentials.workerUrl;
|
|
466
|
+
const apiKey = credentials.apiKey;
|
|
467
|
+
for (let i = 0; i < items.length; i++) {
|
|
468
|
+
try {
|
|
469
|
+
const action = this.getNodeParameter('action', i);
|
|
470
|
+
const body = { action };
|
|
471
|
+
switch (action) {
|
|
472
|
+
case 'health':
|
|
473
|
+
break;
|
|
474
|
+
case 'screenshot': {
|
|
475
|
+
const url = this.getNodeParameter('url', i);
|
|
476
|
+
body.url = url;
|
|
477
|
+
body.fullPage = this.getNodeParameter('fullPage', i);
|
|
478
|
+
body.format = this.getNodeParameter('format', i);
|
|
479
|
+
const viewportWidth = this.getNodeParameter('viewportWidth', i);
|
|
480
|
+
const viewportHeight = this.getNodeParameter('viewportHeight', i);
|
|
481
|
+
if (viewportWidth || viewportHeight) {
|
|
482
|
+
body.viewport = { width: viewportWidth, height: viewportHeight };
|
|
483
|
+
}
|
|
484
|
+
const clipRegion = this.getNodeParameter('clipRegion', i);
|
|
485
|
+
if (Object.keys(clipRegion).length > 0) {
|
|
486
|
+
body.clip = clipRegion;
|
|
487
|
+
}
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
case 'pdf': {
|
|
491
|
+
const url = this.getNodeParameter('url', i);
|
|
492
|
+
body.url = url;
|
|
493
|
+
body.format = this.getNodeParameter('pageFormat', i);
|
|
494
|
+
body.landscape = this.getNodeParameter('landscape', i);
|
|
495
|
+
const margin = this.getNodeParameter('margin', i);
|
|
496
|
+
if (Object.keys(margin).length > 0) {
|
|
497
|
+
body.margin = margin;
|
|
498
|
+
}
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
case 'scrape': {
|
|
502
|
+
const url = this.getNodeParameter('url', i);
|
|
503
|
+
body.url = url;
|
|
504
|
+
const selectors = this.getNodeParameter('selectors', i);
|
|
505
|
+
if (selectors && selectors !== '{}') {
|
|
506
|
+
body.selectors = JSON.parse(selectors);
|
|
507
|
+
}
|
|
508
|
+
const waitUntil = this.getNodeParameter('waitUntil', i);
|
|
509
|
+
if (waitUntil !== 'load') {
|
|
510
|
+
body.waitUntil = waitUntil;
|
|
511
|
+
}
|
|
512
|
+
const waitForSelector = this.getNodeParameter('waitForSelector', i);
|
|
513
|
+
if (waitForSelector) {
|
|
514
|
+
body.waitForSelector = waitForSelector;
|
|
515
|
+
}
|
|
516
|
+
break;
|
|
517
|
+
}
|
|
518
|
+
case 'markdown': {
|
|
519
|
+
const url = this.getNodeParameter('url', i);
|
|
520
|
+
body.url = url;
|
|
521
|
+
const waitUntil = this.getNodeParameter('waitUntil', i);
|
|
522
|
+
if (waitUntil !== 'load') {
|
|
523
|
+
body.waitUntil = waitUntil;
|
|
524
|
+
}
|
|
525
|
+
const waitForSelector = this.getNodeParameter('waitForSelector', i);
|
|
526
|
+
if (waitForSelector) {
|
|
527
|
+
body.waitForSelector = waitForSelector;
|
|
528
|
+
}
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
case 'snapshot': {
|
|
532
|
+
const url = this.getNodeParameter('url', i);
|
|
533
|
+
body.url = url;
|
|
534
|
+
const waitUntil = this.getNodeParameter('waitUntil', i);
|
|
535
|
+
if (waitUntil !== 'load') {
|
|
536
|
+
body.waitUntil = waitUntil;
|
|
537
|
+
}
|
|
538
|
+
break;
|
|
539
|
+
}
|
|
540
|
+
case 'links': {
|
|
541
|
+
const url = this.getNodeParameter('url', i);
|
|
542
|
+
body.url = url;
|
|
543
|
+
const waitUntil = this.getNodeParameter('waitUntil', i);
|
|
544
|
+
if (waitUntil !== 'load') {
|
|
545
|
+
body.waitUntil = waitUntil;
|
|
546
|
+
}
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
case 'json': {
|
|
550
|
+
const url = this.getNodeParameter('url', i);
|
|
551
|
+
body.url = url;
|
|
552
|
+
const prompt = this.getNodeParameter('prompt', i);
|
|
553
|
+
if (prompt) {
|
|
554
|
+
body.prompt = prompt;
|
|
555
|
+
}
|
|
556
|
+
const schema = this.getNodeParameter('schema', i);
|
|
557
|
+
if (schema && schema !== '{}') {
|
|
558
|
+
body.schema = JSON.parse(schema);
|
|
559
|
+
}
|
|
560
|
+
const waitUntil = this.getNodeParameter('waitUntil', i);
|
|
561
|
+
if (waitUntil !== 'load') {
|
|
562
|
+
body.waitUntil = waitUntil;
|
|
563
|
+
}
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
case 'crawl': {
|
|
567
|
+
const url = this.getNodeParameter('url', i);
|
|
568
|
+
body.url = url;
|
|
569
|
+
body.maxDepth = this.getNodeParameter('maxDepth', i);
|
|
570
|
+
body.maxPages = this.getNodeParameter('maxPages', i);
|
|
571
|
+
body.timeout = this.getNodeParameter('timeout', i);
|
|
572
|
+
const includePattern = this.getNodeParameter('includePattern', i);
|
|
573
|
+
if (includePattern) {
|
|
574
|
+
body.includePattern = includePattern;
|
|
575
|
+
}
|
|
576
|
+
const excludePattern = this.getNodeParameter('excludePattern', i);
|
|
577
|
+
if (excludePattern) {
|
|
578
|
+
body.excludePattern = excludePattern;
|
|
579
|
+
}
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
case 'run': {
|
|
583
|
+
const steps = this.getNodeParameter('steps', i);
|
|
584
|
+
body.steps = JSON.parse(steps);
|
|
585
|
+
body.timeout = this.getNodeParameter('timeout', i);
|
|
586
|
+
break;
|
|
587
|
+
}
|
|
588
|
+
case 'seo': {
|
|
589
|
+
const url = this.getNodeParameter('url', i);
|
|
590
|
+
body.url = url;
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
case 'click': {
|
|
594
|
+
const url = this.getNodeParameter('url', i);
|
|
595
|
+
body.url = url;
|
|
596
|
+
body.selector = this.getNodeParameter('selector', i);
|
|
597
|
+
body.waitFor = this.getNodeParameter('waitFor', i);
|
|
598
|
+
body.screenshot = this.getNodeParameter('takeScreenshot', i);
|
|
599
|
+
break;
|
|
600
|
+
}
|
|
601
|
+
case 'cookies': {
|
|
602
|
+
const url = this.getNodeParameter('url', i);
|
|
603
|
+
body.url = url;
|
|
604
|
+
body.operation = this.getNodeParameter('cookieOperation', i);
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
case 'evaluate': {
|
|
608
|
+
const url = this.getNodeParameter('url', i);
|
|
609
|
+
body.url = url;
|
|
610
|
+
body.script = this.getNodeParameter('script', i);
|
|
611
|
+
const waitBefore = this.getNodeParameter('waitBefore', i);
|
|
612
|
+
if (waitBefore > 0) {
|
|
613
|
+
body.waitFor = waitBefore;
|
|
614
|
+
}
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
case 'batch': {
|
|
618
|
+
const urls = this.getNodeParameter('urls', i);
|
|
619
|
+
body.urls = urls.split(',').map((u) => u.trim());
|
|
620
|
+
body.batchAction = this.getNodeParameter('batchAction', i);
|
|
621
|
+
body.parallel = this.getNodeParameter('parallel', i);
|
|
622
|
+
body.timeout = this.getNodeParameter('timeout', i);
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
default:
|
|
626
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown action: ${action}`, { itemIndex: i });
|
|
627
|
+
}
|
|
628
|
+
const headers = {
|
|
629
|
+
'Content-Type': 'application/json',
|
|
630
|
+
};
|
|
631
|
+
if (apiKey) {
|
|
632
|
+
headers['x-api-key'] = apiKey;
|
|
633
|
+
}
|
|
634
|
+
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'generic', {
|
|
635
|
+
method: 'POST',
|
|
636
|
+
url: workerUrl,
|
|
637
|
+
headers,
|
|
638
|
+
body,
|
|
639
|
+
json: true,
|
|
640
|
+
timeout: body.timeout || 60000,
|
|
641
|
+
});
|
|
642
|
+
if ((action === 'screenshot' || action === 'pdf') && response.success && response.result) {
|
|
643
|
+
const returnBinary = this.getNodeParameter('returnBinary', i);
|
|
644
|
+
if (returnBinary) {
|
|
645
|
+
const binaryProperty = this.getNodeParameter('binaryProperty', i);
|
|
646
|
+
const buffer = Buffer.from(response.result, 'base64');
|
|
647
|
+
const mimeType = action === 'screenshot'
|
|
648
|
+
? (body.format === 'jpeg' ? 'image/jpeg' : 'image/png')
|
|
649
|
+
: 'application/pdf';
|
|
650
|
+
const fileName = action === 'screenshot'
|
|
651
|
+
? `screenshot.${body.format || 'png'}`
|
|
652
|
+
: 'page.pdf';
|
|
653
|
+
const binaryData = await this.helpers.prepareBinaryData(buffer, fileName, mimeType);
|
|
654
|
+
returnData.push({
|
|
655
|
+
json: { success: true, fileName, mimeType },
|
|
656
|
+
binary: { [binaryProperty]: binaryData },
|
|
657
|
+
pairedItem: { item: i },
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
else {
|
|
661
|
+
returnData.push({
|
|
662
|
+
json: response,
|
|
663
|
+
pairedItem: { item: i },
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
returnData.push({
|
|
669
|
+
json: response,
|
|
670
|
+
pairedItem: { item: i },
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
catch (error) {
|
|
675
|
+
const errorObj = error;
|
|
676
|
+
const errorDetails = error;
|
|
677
|
+
if (this.continueOnFail()) {
|
|
678
|
+
returnData.push({
|
|
679
|
+
json: {
|
|
680
|
+
success: false,
|
|
681
|
+
error: errorObj.message || 'Unknown error',
|
|
682
|
+
},
|
|
683
|
+
pairedItem: { item: i },
|
|
684
|
+
});
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
if (errorDetails.statusCode === 401) {
|
|
688
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid API Key - Please check your API key in the credentials section', { itemIndex: i });
|
|
689
|
+
}
|
|
690
|
+
if (errorDetails.statusCode === 429) {
|
|
691
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Rate limit exceeded - Please wait before making more requests', { itemIndex: i });
|
|
692
|
+
}
|
|
693
|
+
if (errorDetails.code === 'MISSING_ACTION') {
|
|
694
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Missing required field: action', { itemIndex: i });
|
|
695
|
+
}
|
|
696
|
+
if (errorDetails.code === 'INVALID_URL') {
|
|
697
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid URL: ${errorObj.message}`, { itemIndex: i });
|
|
698
|
+
}
|
|
699
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorObj.message || 'Request failed', { itemIndex: i });
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return [returnData];
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
exports.BrowserRun = BrowserRun;
|
|
706
|
+
//# sourceMappingURL=BrowserRun.node.js.map
|