@ceki/n8n-nodes-ceki 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/README.md +119 -0
- package/dist/credentials/CekiApi.credentials.d.ts +11 -0
- package/dist/credentials/CekiApi.credentials.js +27 -0
- package/dist/credentials/CekiApi.credentials.js.map +1 -0
- package/dist/nodes/BrowserCeki/BrowserCeki.node.d.ts +9 -0
- package/dist/nodes/BrowserCeki/BrowserCeki.node.js +383 -0
- package/dist/nodes/BrowserCeki/BrowserCeki.node.js.map +1 -0
- package/dist/nodes/BrowserCeki/ceki.png +0 -0
- package/dist/nodes/CekiContract/CekiContract.node.d.ts +5 -0
- package/dist/nodes/CekiContract/CekiContract.node.js +249 -0
- package/dist/nodes/CekiContract/CekiContract.node.js.map +1 -0
- package/dist/nodes/CekiContract/ceki.png +0 -0
- package/dist/nodes/recipes/CekiCaptchaScrape/CekiCaptchaScrape.node.d.ts +13 -0
- package/dist/nodes/recipes/CekiCaptchaScrape/CekiCaptchaScrape.node.js +234 -0
- package/dist/nodes/recipes/CekiCaptchaScrape/CekiCaptchaScrape.node.js.map +1 -0
- package/dist/nodes/recipes/CekiCaptchaScrape/ceki.png +0 -0
- package/dist/nodes/recipes/CekiScreenshotGeo/CekiScreenshotGeo.node.d.ts +9 -0
- package/dist/nodes/recipes/CekiScreenshotGeo/CekiScreenshotGeo.node.js +78 -0
- package/dist/nodes/recipes/CekiScreenshotGeo/CekiScreenshotGeo.node.js.map +1 -0
- package/dist/nodes/recipes/CekiScreenshotGeo/ceki.png +0 -0
- package/dist/nodes/recipes/ceki.png +0 -0
- package/package.json +58 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CekiContract = void 0;
|
|
4
|
+
const sdk_1 = require("@ceki/sdk");
|
|
5
|
+
/**
|
|
6
|
+
* Ceki Contract — operation node for the Ceki contract system (tasks/events).
|
|
7
|
+
* Powered by ContractClient from @ceki/sdk (create/propose/comment/progress/call-human/...).
|
|
8
|
+
* Uses the same cekiApi credential (token ag_...) as Browser Ceki.
|
|
9
|
+
*
|
|
10
|
+
* Statuses (KalEvent.status_id): 100 Backlog · 200 Hand · 222 Hand-done ·
|
|
11
|
+
* 300 QA · 350 QA-done · 499 Reviewer. benefitable = the executor
|
|
12
|
+
* (a string of the form "agent:<id>" or "user:<id>").
|
|
13
|
+
*/
|
|
14
|
+
const STATUS_OPTIONS = [
|
|
15
|
+
{ name: '100 · Backlog', value: 100 },
|
|
16
|
+
{ name: '200 · Hand (assigned)', value: 200 },
|
|
17
|
+
{ name: '222 · Hand done', value: 222 },
|
|
18
|
+
{ name: '300 · QA', value: 300 },
|
|
19
|
+
{ name: '350 · QA done', value: 350 },
|
|
20
|
+
{ name: '499 · Reviewer', value: 499 },
|
|
21
|
+
];
|
|
22
|
+
class CekiContract {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.description = {
|
|
25
|
+
displayName: 'Ceki Contract',
|
|
26
|
+
name: 'cekiContract',
|
|
27
|
+
icon: 'file:ceki.png',
|
|
28
|
+
group: ['transform'],
|
|
29
|
+
version: 1,
|
|
30
|
+
subtitle: '={{ "Contract: " + $operation }}',
|
|
31
|
+
description: 'Work with Ceki contract tasks: list, create, assign, update status, comment, report progress, escalate to a human, and poll',
|
|
32
|
+
defaults: { name: 'Ceki Contract' },
|
|
33
|
+
inputs: ['main'],
|
|
34
|
+
outputs: ['main'],
|
|
35
|
+
credentials: [{ name: 'cekiApi', required: true }],
|
|
36
|
+
properties: [
|
|
37
|
+
{
|
|
38
|
+
displayName: 'Operation',
|
|
39
|
+
name: 'operation',
|
|
40
|
+
type: 'options',
|
|
41
|
+
default: 'myEvents',
|
|
42
|
+
options: [
|
|
43
|
+
{ name: 'List My Contracts', value: 'listContracts' },
|
|
44
|
+
{ name: 'List Tasks in Contract', value: 'listTasks' },
|
|
45
|
+
{ name: 'Get Task', value: 'getTask' },
|
|
46
|
+
{ name: 'My Assigned Events', value: 'myEvents' },
|
|
47
|
+
{ name: 'Create Task', value: 'createTask' },
|
|
48
|
+
{ name: 'Assign Executor', value: 'assign' },
|
|
49
|
+
{ name: 'Update Status', value: 'setStatus' },
|
|
50
|
+
{ name: 'Comment', value: 'comment' },
|
|
51
|
+
{ name: 'Progress Report', value: 'progress' },
|
|
52
|
+
{ name: 'Call Human', value: 'callHuman' },
|
|
53
|
+
{ name: 'Poll Notifications', value: 'poll' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
// --- contractId / eventId ---
|
|
57
|
+
{
|
|
58
|
+
displayName: 'Contract ID',
|
|
59
|
+
name: 'contractId',
|
|
60
|
+
type: 'number',
|
|
61
|
+
default: 0,
|
|
62
|
+
description: 'ceki contract id',
|
|
63
|
+
displayOptions: { show: { operation: ['listTasks', 'createTask'] } },
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
displayName: 'Event ID',
|
|
67
|
+
name: 'eventId',
|
|
68
|
+
type: 'number',
|
|
69
|
+
default: 0,
|
|
70
|
+
description: 'Task / event id (KalEvent)',
|
|
71
|
+
displayOptions: {
|
|
72
|
+
show: { operation: ['getTask', 'assign', 'setStatus', 'comment', 'progress', 'callHuman'] },
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
// --- createTask fields ---
|
|
76
|
+
{
|
|
77
|
+
displayName: 'Label',
|
|
78
|
+
name: 'label',
|
|
79
|
+
type: 'string',
|
|
80
|
+
default: '',
|
|
81
|
+
required: true,
|
|
82
|
+
displayOptions: { show: { operation: ['createTask'] } },
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
displayName: 'Description',
|
|
86
|
+
name: 'description',
|
|
87
|
+
type: 'string',
|
|
88
|
+
typeOptions: { rows: 4 },
|
|
89
|
+
default: '',
|
|
90
|
+
displayOptions: { show: { operation: ['createTask', 'comment'] } },
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
displayName: 'Executor (benefitable)',
|
|
94
|
+
name: 'benefitableType',
|
|
95
|
+
type: 'options',
|
|
96
|
+
default: 'agent',
|
|
97
|
+
options: [
|
|
98
|
+
{ name: 'Agent', value: 'agent' },
|
|
99
|
+
{ name: 'User (human)', value: 'user' },
|
|
100
|
+
],
|
|
101
|
+
displayOptions: { show: { operation: ['createTask', 'assign'] } },
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
displayName: 'Executor ID',
|
|
105
|
+
name: 'benefitableValue',
|
|
106
|
+
type: 'number',
|
|
107
|
+
default: 0,
|
|
108
|
+
description: 'Agent ID or user ID of the executor',
|
|
109
|
+
displayOptions: { show: { operation: ['createTask', 'assign'] } },
|
|
110
|
+
},
|
|
111
|
+
// --- status ---
|
|
112
|
+
{
|
|
113
|
+
displayName: 'Status',
|
|
114
|
+
name: 'status',
|
|
115
|
+
type: 'options',
|
|
116
|
+
options: STATUS_OPTIONS,
|
|
117
|
+
default: 200,
|
|
118
|
+
displayOptions: { show: { operation: ['createTask', 'setStatus', 'progress'] } },
|
|
119
|
+
},
|
|
120
|
+
// --- progress desc ---
|
|
121
|
+
{
|
|
122
|
+
displayName: 'Progress Description',
|
|
123
|
+
name: 'progressDesc',
|
|
124
|
+
type: 'string',
|
|
125
|
+
typeOptions: { rows: 4 },
|
|
126
|
+
default: '',
|
|
127
|
+
required: true,
|
|
128
|
+
description: 'Body of the progress comment (does not overwrite the task spec)',
|
|
129
|
+
displayOptions: { show: { operation: ['progress'] } },
|
|
130
|
+
},
|
|
131
|
+
// --- call human (escalate) ---
|
|
132
|
+
{
|
|
133
|
+
displayName: 'Call Kind',
|
|
134
|
+
name: 'callKind',
|
|
135
|
+
type: 'options',
|
|
136
|
+
default: 'review',
|
|
137
|
+
options: [
|
|
138
|
+
{ name: 'Input (need clarification)', value: 'input' },
|
|
139
|
+
{ name: 'Review (done, take a look)', value: 'review' },
|
|
140
|
+
{ name: 'Stuck (blocked)', value: 'stuck' },
|
|
141
|
+
],
|
|
142
|
+
description: 'Type of escalation to a human (the call-human action)',
|
|
143
|
+
displayOptions: { show: { operation: ['callHuman'] } },
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
displayName: 'Message',
|
|
147
|
+
name: 'callDesc',
|
|
148
|
+
type: 'string',
|
|
149
|
+
typeOptions: { rows: 4 },
|
|
150
|
+
default: '',
|
|
151
|
+
required: true,
|
|
152
|
+
description: 'What to tell the human — context, question, or what was done',
|
|
153
|
+
displayOptions: { show: { operation: ['callHuman'] } },
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async execute() {
|
|
159
|
+
const items = this.getInputData();
|
|
160
|
+
const out = [];
|
|
161
|
+
const creds = await this.getCredentials('cekiApi');
|
|
162
|
+
const client = new sdk_1.ContractClient({ token: creds.token });
|
|
163
|
+
for (let i = 0; i < items.length; i++) {
|
|
164
|
+
const op = this.getNodeParameter('operation', i);
|
|
165
|
+
let result;
|
|
166
|
+
switch (op) {
|
|
167
|
+
case 'listContracts':
|
|
168
|
+
result = await client.listContracts();
|
|
169
|
+
break;
|
|
170
|
+
case 'listTasks': {
|
|
171
|
+
const contractId = this.getNodeParameter('contractId', i);
|
|
172
|
+
result = await client.tasks(contractId);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case 'getTask': {
|
|
176
|
+
const eventId = this.getNodeParameter('eventId', i);
|
|
177
|
+
result = await client.task(eventId);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case 'myEvents':
|
|
181
|
+
result = await client.myEvents();
|
|
182
|
+
break;
|
|
183
|
+
case 'createTask': {
|
|
184
|
+
const contractId = this.getNodeParameter('contractId', i);
|
|
185
|
+
const label = this.getNodeParameter('label', i);
|
|
186
|
+
const description = this.getNodeParameter('description', i) || '';
|
|
187
|
+
const status = this.getNodeParameter('status', i);
|
|
188
|
+
const bType = this.getNodeParameter('benefitableType', i);
|
|
189
|
+
const bValue = this.getNodeParameter('benefitableValue', i);
|
|
190
|
+
result = await client.create(contractId, {
|
|
191
|
+
label,
|
|
192
|
+
description: description || undefined,
|
|
193
|
+
status,
|
|
194
|
+
benefitable: bValue ? `${bType}:${bValue}` : undefined,
|
|
195
|
+
});
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
case 'assign': {
|
|
199
|
+
const eventId = this.getNodeParameter('eventId', i);
|
|
200
|
+
const bType = this.getNodeParameter('benefitableType', i);
|
|
201
|
+
const bValue = this.getNodeParameter('benefitableValue', i);
|
|
202
|
+
if (!bValue)
|
|
203
|
+
throw new Error('Executor ID is required for Assign');
|
|
204
|
+
result = await client.propose(eventId, { benefitable: `${bType}:${bValue}` });
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
case 'setStatus': {
|
|
208
|
+
const eventId = this.getNodeParameter('eventId', i);
|
|
209
|
+
const status = this.getNodeParameter('status', i);
|
|
210
|
+
result = await client.propose(eventId, { status });
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case 'comment': {
|
|
214
|
+
const eventId = this.getNodeParameter('eventId', i);
|
|
215
|
+
const description = this.getNodeParameter('description', i) || '';
|
|
216
|
+
if (!description)
|
|
217
|
+
throw new Error('Comment text is required');
|
|
218
|
+
result = await client.comment(eventId, { description });
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
case 'progress': {
|
|
222
|
+
const eventId = this.getNodeParameter('eventId', i);
|
|
223
|
+
const status = this.getNodeParameter('status', i);
|
|
224
|
+
const desc = this.getNodeParameter('progressDesc', i);
|
|
225
|
+
result = await client.progress(eventId, { status, desc });
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
case 'callHuman': {
|
|
229
|
+
const eventId = this.getNodeParameter('eventId', i);
|
|
230
|
+
const kind = this.getNodeParameter('callKind', i);
|
|
231
|
+
const desc = this.getNodeParameter('callDesc', i);
|
|
232
|
+
if (!desc)
|
|
233
|
+
throw new Error('Message is required for Call Human');
|
|
234
|
+
result = await client.callHuman(eventId, kind, desc);
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case 'poll':
|
|
238
|
+
result = await client.poll();
|
|
239
|
+
break;
|
|
240
|
+
default:
|
|
241
|
+
throw new Error(`Unknown operation: ${op}`);
|
|
242
|
+
}
|
|
243
|
+
out.push({ json: { op, result: result } });
|
|
244
|
+
}
|
|
245
|
+
return [out];
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
exports.CekiContract = CekiContract;
|
|
249
|
+
//# sourceMappingURL=CekiContract.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CekiContract.node.js","sourceRoot":"","sources":["../../../nodes/CekiContract/CekiContract.node.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeType, INodeTypeDescription, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
/**
|
|
3
|
+
* Recipe: Captcha-protected Scrape.
|
|
4
|
+
* Rent a human browser → open a URL → (optional) wait for a selector →
|
|
5
|
+
* request a human to solve the captcha (requestCaptcha) → snapshot/HTML → release.
|
|
6
|
+
*
|
|
7
|
+
* This is Ceki's signature use case: anti-bot sites load thanks to the real fingerprint,
|
|
8
|
+
* and the captcha is solved by a real person (provider/solver).
|
|
9
|
+
*/
|
|
10
|
+
export declare class CekiCaptchaScrape implements INodeType {
|
|
11
|
+
description: INodeTypeDescription;
|
|
12
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CekiCaptchaScrape = void 0;
|
|
4
|
+
const sdk_1 = require("@ceki/sdk");
|
|
5
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
6
|
+
/**
|
|
7
|
+
* Wait for a selector to appear in the DOM via Runtime.evaluate.
|
|
8
|
+
* The main-mode allowlist permits Runtime.evaluate (also used by paste/copy).
|
|
9
|
+
*/
|
|
10
|
+
async function waitForSelector(browser, selector, timeoutMs, intervalMs = 500) {
|
|
11
|
+
const expr = `!!document.querySelector(${JSON.stringify(selector)})`;
|
|
12
|
+
const deadline = Date.now() + timeoutMs;
|
|
13
|
+
let lastErr = null;
|
|
14
|
+
while (Date.now() < deadline) {
|
|
15
|
+
try {
|
|
16
|
+
const res = (await browser.send({
|
|
17
|
+
method: 'Runtime.evaluate',
|
|
18
|
+
params: { expression: expr, returnByValue: true },
|
|
19
|
+
}));
|
|
20
|
+
if (res?.result?.value === true)
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
lastErr = e;
|
|
25
|
+
}
|
|
26
|
+
await sleep(intervalMs);
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`waitForSelector("${selector}") timed out after ${timeoutMs}ms${lastErr ? `: ${lastErr.message}` : ''}`);
|
|
29
|
+
}
|
|
30
|
+
/** Extract the outerHTML of the first element matching the selector (or the whole <body>). */
|
|
31
|
+
async function extractHtml(browser, selector) {
|
|
32
|
+
const expr = selector.trim() === '' || selector === 'body'
|
|
33
|
+
? `document.body ? document.body.outerHTML : ''`
|
|
34
|
+
: `(function(){ var el = document.querySelector(${JSON.stringify(selector)}); return el ? el.outerHTML : ''; })()`;
|
|
35
|
+
const res = (await browser.send({
|
|
36
|
+
method: 'Runtime.evaluate',
|
|
37
|
+
params: { expression: expr, returnByValue: true },
|
|
38
|
+
}));
|
|
39
|
+
return res?.result?.value ?? '';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Recipe: Captcha-protected Scrape.
|
|
43
|
+
* Rent a human browser → open a URL → (optional) wait for a selector →
|
|
44
|
+
* request a human to solve the captcha (requestCaptcha) → snapshot/HTML → release.
|
|
45
|
+
*
|
|
46
|
+
* This is Ceki's signature use case: anti-bot sites load thanks to the real fingerprint,
|
|
47
|
+
* and the captcha is solved by a real person (provider/solver).
|
|
48
|
+
*/
|
|
49
|
+
class CekiCaptchaScrape {
|
|
50
|
+
constructor() {
|
|
51
|
+
this.description = {
|
|
52
|
+
displayName: 'Browser Ceki: Captcha-protected Scrape',
|
|
53
|
+
name: 'cekiCaptchaScrape',
|
|
54
|
+
description: 'Rent a human browser, wait, solve captcha via a human, snapshot/HTML, release',
|
|
55
|
+
icon: 'file:ceki.png',
|
|
56
|
+
group: ['transform'],
|
|
57
|
+
version: 1,
|
|
58
|
+
subtitle: '=rent in {{ $geo }} → captcha → snapshot',
|
|
59
|
+
defaults: { name: 'Browser Ceki: Captcha-protected Scrape' },
|
|
60
|
+
inputs: ['main'],
|
|
61
|
+
outputs: ['main'],
|
|
62
|
+
credentials: [{ name: 'cekiApi', required: true }],
|
|
63
|
+
properties: [
|
|
64
|
+
{
|
|
65
|
+
displayName: 'URL',
|
|
66
|
+
name: 'url',
|
|
67
|
+
type: 'string',
|
|
68
|
+
default: 'https://example.com',
|
|
69
|
+
required: true,
|
|
70
|
+
description: 'Page protected by anti-bot / captcha',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
displayName: 'Geo',
|
|
74
|
+
name: 'geo',
|
|
75
|
+
type: 'string',
|
|
76
|
+
default: 'RU',
|
|
77
|
+
placeholder: 'RU, EE, US…',
|
|
78
|
+
},
|
|
79
|
+
{ displayName: 'Max $/min', name: 'maxPrice', type: 'number', typeOptions: { numberPrecision: 4 }, default: 0.02 },
|
|
80
|
+
{
|
|
81
|
+
displayName: 'Wait for Selector',
|
|
82
|
+
name: 'waitSelector',
|
|
83
|
+
type: 'string',
|
|
84
|
+
default: '',
|
|
85
|
+
placeholder: 'CSS selector (optional)',
|
|
86
|
+
description: 'Wait until this selector appears in the DOM before requesting captcha',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
displayName: 'Wait Timeout (ms)',
|
|
90
|
+
name: 'waitTimeout',
|
|
91
|
+
type: 'number',
|
|
92
|
+
default: 30000,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
displayName: 'Request Captcha',
|
|
96
|
+
name: 'requestCaptcha',
|
|
97
|
+
type: 'boolean',
|
|
98
|
+
default: true,
|
|
99
|
+
description: 'Ask a human to solve the captcha via requestCaptcha',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
displayName: 'Auto-accept Solved Work',
|
|
103
|
+
name: 'autoAccept',
|
|
104
|
+
type: 'boolean',
|
|
105
|
+
default: true,
|
|
106
|
+
description: 'Automatically accept (pay) the solver when captcha is solved',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
displayName: 'Acceptance Timeout (ms)',
|
|
110
|
+
name: 'acceptanceTimeout',
|
|
111
|
+
type: 'number',
|
|
112
|
+
default: 60000,
|
|
113
|
+
description: 'Time to wait for a human to pick up the captcha task',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
displayName: 'Completion Timeout (ms)',
|
|
117
|
+
name: 'completionTimeout',
|
|
118
|
+
type: 'number',
|
|
119
|
+
default: 180000,
|
|
120
|
+
description: 'Time to wait for the human to solve after pickup',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
displayName: 'Extract HTML',
|
|
124
|
+
name: 'extractHtml',
|
|
125
|
+
type: 'boolean',
|
|
126
|
+
default: true,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
displayName: 'HTML Selector',
|
|
130
|
+
name: 'htmlSelector',
|
|
131
|
+
type: 'string',
|
|
132
|
+
default: 'body',
|
|
133
|
+
placeholder: 'CSS selector or "body"',
|
|
134
|
+
description: 'outerHTML of this selector is returned as `html`',
|
|
135
|
+
displayOptions: { show: { extractHtml: [true] } },
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
displayName: 'Full Page Screenshot',
|
|
139
|
+
name: 'fullPage',
|
|
140
|
+
type: 'boolean',
|
|
141
|
+
default: false,
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
async execute() {
|
|
147
|
+
const items = this.getInputData();
|
|
148
|
+
const out = [];
|
|
149
|
+
const creds = await this.getCredentials('cekiApi');
|
|
150
|
+
for (let i = 0; i < items.length; i++) {
|
|
151
|
+
const url = this.getNodeParameter('url', i);
|
|
152
|
+
const geo = this.getNodeParameter('geo', i);
|
|
153
|
+
const maxPrice = this.getNodeParameter('maxPrice', i);
|
|
154
|
+
const waitSelector = this.getNodeParameter('waitSelector', i) || '';
|
|
155
|
+
const waitTimeout = this.getNodeParameter('waitTimeout', i);
|
|
156
|
+
const wantCaptcha = this.getNodeParameter('requestCaptcha', i);
|
|
157
|
+
const autoAccept = this.getNodeParameter('autoAccept', i);
|
|
158
|
+
const acceptanceTimeout = this.getNodeParameter('acceptanceTimeout', i);
|
|
159
|
+
const completionTimeout = this.getNodeParameter('completionTimeout', i);
|
|
160
|
+
const extractHtmlFlag = this.getNodeParameter('extractHtml', i);
|
|
161
|
+
const htmlSelector = this.getNodeParameter('htmlSelector', i) || 'body';
|
|
162
|
+
const fullPage = this.getNodeParameter('fullPage', i);
|
|
163
|
+
const client = await (0, sdk_1.connect)(creds.token);
|
|
164
|
+
let browser;
|
|
165
|
+
let scheduleId = 0;
|
|
166
|
+
let captchaSolved = null;
|
|
167
|
+
try {
|
|
168
|
+
const list = await client.search({ geo: geo || undefined, max_price_per_min: maxPrice });
|
|
169
|
+
if (!list.length)
|
|
170
|
+
throw new Error(`No browsers in geo ${geo || '*'}`);
|
|
171
|
+
scheduleId = list[0].schedule_id;
|
|
172
|
+
browser = await client.rent(scheduleId);
|
|
173
|
+
await browser.navigate(url);
|
|
174
|
+
if (waitSelector) {
|
|
175
|
+
await waitForSelector(browser, waitSelector, waitTimeout);
|
|
176
|
+
}
|
|
177
|
+
if (wantCaptcha) {
|
|
178
|
+
const result = (await browser.requestCaptcha({
|
|
179
|
+
acceptanceTimeout,
|
|
180
|
+
completionTimeout,
|
|
181
|
+
autoAccept,
|
|
182
|
+
}));
|
|
183
|
+
captchaSolved = result.solved;
|
|
184
|
+
if (!result.solved) {
|
|
185
|
+
// not solved — reject the solver (don't pay) and throw
|
|
186
|
+
await result.rejectWork(result.cancelReason ?? 'not solved');
|
|
187
|
+
throw new Error(`Captcha not solved: ${result.cancelReason ?? 'unknown'}`);
|
|
188
|
+
}
|
|
189
|
+
// autoAccept=true — the SDK already accepted; otherwise confirm payment manually
|
|
190
|
+
if (!autoAccept)
|
|
191
|
+
await result.acceptWork();
|
|
192
|
+
}
|
|
193
|
+
// after the captcha the page usually reloads — wait for the selector/stabilization again
|
|
194
|
+
if (waitSelector) {
|
|
195
|
+
try {
|
|
196
|
+
await waitForSelector(browser, waitSelector, waitTimeout);
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
/* non-critical — capture what's there */
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const shot = (await browser.screenshot({ format: 'base64', fullPage }));
|
|
203
|
+
const data = shot.data ?? shot.toString('base64');
|
|
204
|
+
const binary = await this.helpers.prepareBinaryData(Buffer.from(data, 'base64'), 'captcha-scrape.png', 'image/png');
|
|
205
|
+
const json = {
|
|
206
|
+
url,
|
|
207
|
+
geo,
|
|
208
|
+
schedule_id: scheduleId,
|
|
209
|
+
captcha_requested: wantCaptcha,
|
|
210
|
+
captcha_solved: captchaSolved,
|
|
211
|
+
};
|
|
212
|
+
if (extractHtmlFlag) {
|
|
213
|
+
json.html = await extractHtml(browser, htmlSelector);
|
|
214
|
+
}
|
|
215
|
+
out.push({ json: json, binary: { data: binary } });
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
if (browser) {
|
|
219
|
+
try {
|
|
220
|
+
await browser.close();
|
|
221
|
+
}
|
|
222
|
+
catch { /* ignore */ }
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
await client.close();
|
|
226
|
+
}
|
|
227
|
+
catch { /* ignore */ }
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return [out];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.CekiCaptchaScrape = CekiCaptchaScrape;
|
|
234
|
+
//# sourceMappingURL=CekiCaptchaScrape.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CekiCaptchaScrape.node.js","sourceRoot":"","sources":["../../../../nodes/recipes/CekiCaptchaScrape/CekiCaptchaScrape.node.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeType, INodeTypeDescription, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
/**
|
|
3
|
+
* Recipe: Screenshot in Geo.
|
|
4
|
+
* One call — rent a browser in the requested geo, open a URL, take a screenshot, release.
|
|
5
|
+
*/
|
|
6
|
+
export declare class CekiScreenshotGeo implements INodeType {
|
|
7
|
+
description: INodeTypeDescription;
|
|
8
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CekiScreenshotGeo = void 0;
|
|
4
|
+
const sdk_1 = require("@ceki/sdk");
|
|
5
|
+
/**
|
|
6
|
+
* Recipe: Screenshot in Geo.
|
|
7
|
+
* One call — rent a browser in the requested geo, open a URL, take a screenshot, release.
|
|
8
|
+
*/
|
|
9
|
+
class CekiScreenshotGeo {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.description = {
|
|
12
|
+
displayName: 'Browser Ceki: Screenshot in Geo',
|
|
13
|
+
name: 'cekiScreenshotGeo',
|
|
14
|
+
description: 'Rent a browser in a given geo, screenshot a page, release',
|
|
15
|
+
icon: 'file:ceki.png',
|
|
16
|
+
group: ['transform'],
|
|
17
|
+
version: 1,
|
|
18
|
+
subtitle: '=rent in {{ $geo }} → screenshot → release',
|
|
19
|
+
defaults: { name: 'Browser Ceki: Screenshot in Geo' },
|
|
20
|
+
inputs: ['main'],
|
|
21
|
+
outputs: ['main'],
|
|
22
|
+
credentials: [{ name: 'cekiApi', required: true }],
|
|
23
|
+
properties: [
|
|
24
|
+
{
|
|
25
|
+
displayName: 'URL',
|
|
26
|
+
name: 'url',
|
|
27
|
+
type: 'string',
|
|
28
|
+
default: 'https://ifconfig.me',
|
|
29
|
+
required: true,
|
|
30
|
+
},
|
|
31
|
+
{ displayName: 'Geo', name: 'geo', type: 'string', default: 'RU', placeholder: 'RU, EE, US…' },
|
|
32
|
+
{ displayName: 'Full page', name: 'fullPage', type: 'boolean', default: false },
|
|
33
|
+
{ displayName: 'Max $/min', name: 'maxPrice', type: 'number', default: 0.02 },
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async execute() {
|
|
38
|
+
const items = this.getInputData();
|
|
39
|
+
const out = [];
|
|
40
|
+
const creds = await this.getCredentials('cekiApi');
|
|
41
|
+
for (let i = 0; i < items.length; i++) {
|
|
42
|
+
const url = this.getNodeParameter('url', i);
|
|
43
|
+
const geo = this.getNodeParameter('geo', i);
|
|
44
|
+
const fullPage = this.getNodeParameter('fullPage', i);
|
|
45
|
+
const maxPrice = this.getNodeParameter('maxPrice', i);
|
|
46
|
+
const client = await (0, sdk_1.connect)(creds.token);
|
|
47
|
+
let browser;
|
|
48
|
+
try {
|
|
49
|
+
const list = await client.search({ geo, max_price_per_min: maxPrice });
|
|
50
|
+
if (!list.length)
|
|
51
|
+
throw new Error(`No browsers in geo ${geo}`);
|
|
52
|
+
browser = await client.rent(list[0].schedule_id);
|
|
53
|
+
await browser.navigate(url);
|
|
54
|
+
const shot = (await browser.screenshot({ format: 'base64', fullPage }));
|
|
55
|
+
const binary = await this.helpers.prepareBinaryData(Buffer.from(shot.data, 'base64'), 'screenshot.png', 'image/png');
|
|
56
|
+
out.push({
|
|
57
|
+
json: { url, geo, schedule_id: list[0].schedule_id },
|
|
58
|
+
binary: { data: binary },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
if (browser) {
|
|
63
|
+
try {
|
|
64
|
+
await browser.close();
|
|
65
|
+
}
|
|
66
|
+
catch { }
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
await client.close();
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return [out];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.CekiScreenshotGeo = CekiScreenshotGeo;
|
|
78
|
+
//# sourceMappingURL=CekiScreenshotGeo.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CekiScreenshotGeo.node.js","sourceRoot":"","sources":["../../../../nodes/recipes/CekiScreenshotGeo/CekiScreenshotGeo.node.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
Binary file
|