@pagecrawl/n8n-nodes-pagecrawl 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 +21 -0
- package/README.md +227 -0
- package/dist/credentials/PageCrawlApi.credentials.d.ts +9 -0
- package/dist/credentials/PageCrawlApi.credentials.js +57 -0
- package/dist/icons/pagecrawl.svg +24 -0
- package/dist/nodes/PageCrawl/PageCrawl.node.d.ts +5 -0
- package/dist/nodes/PageCrawl/PageCrawl.node.js +467 -0
- package/dist/nodes/PageCrawl/PageCrawl.node.json +22 -0
- package/dist/nodes/PageCrawl/descriptions/CheckDescription.d.ts +3 -0
- package/dist/nodes/PageCrawl/descriptions/CheckDescription.js +110 -0
- package/dist/nodes/PageCrawl/descriptions/PageDescription.d.ts +3 -0
- package/dist/nodes/PageCrawl/descriptions/PageDescription.js +657 -0
- package/dist/nodes/PageCrawl/descriptions/ScreenshotDescription.d.ts +3 -0
- package/dist/nodes/PageCrawl/descriptions/ScreenshotDescription.js +78 -0
- package/dist/nodes/PageCrawl/descriptions/WebhookDescription.d.ts +3 -0
- package/dist/nodes/PageCrawl/descriptions/WebhookDescription.js +203 -0
- package/dist/nodes/PageCrawl/pagecrawl.svg +18 -0
- package/dist/nodes/PageCrawl/types.d.ts +98 -0
- package/dist/nodes/PageCrawl/types.js +53 -0
- package/dist/nodes/PageCrawlTrigger/PageCrawlTrigger.node.d.ts +12 -0
- package/dist/nodes/PageCrawlTrigger/PageCrawlTrigger.node.js +221 -0
- package/dist/nodes/PageCrawlTrigger/PageCrawlTrigger.node.json +22 -0
- package/dist/nodes/PageCrawlTrigger/pagecrawl.svg +18 -0
- package/package.json +64 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PageCrawl = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const PageDescription_1 = require("./descriptions/PageDescription");
|
|
6
|
+
const CheckDescription_1 = require("./descriptions/CheckDescription");
|
|
7
|
+
const ScreenshotDescription_1 = require("./descriptions/ScreenshotDescription");
|
|
8
|
+
const WebhookDescription_1 = require("./descriptions/WebhookDescription");
|
|
9
|
+
class PageCrawl {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.description = {
|
|
12
|
+
displayName: 'PageCrawl',
|
|
13
|
+
name: 'pageCrawl',
|
|
14
|
+
icon: 'file:pagecrawl.svg',
|
|
15
|
+
group: ['transform'],
|
|
16
|
+
version: 1,
|
|
17
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
18
|
+
description: 'Interact with PageCrawl.io API for website monitoring',
|
|
19
|
+
defaults: {
|
|
20
|
+
name: 'PageCrawl',
|
|
21
|
+
},
|
|
22
|
+
inputs: ['main'],
|
|
23
|
+
outputs: ['main'],
|
|
24
|
+
credentials: [
|
|
25
|
+
{
|
|
26
|
+
name: 'pageCrawlApi',
|
|
27
|
+
required: true,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
requestDefaults: {
|
|
31
|
+
baseURL: '={{$credentials.baseUrl}}/api',
|
|
32
|
+
headers: {
|
|
33
|
+
Accept: 'application/json',
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
properties: [
|
|
38
|
+
{
|
|
39
|
+
displayName: 'Resource',
|
|
40
|
+
name: 'resource',
|
|
41
|
+
type: 'options',
|
|
42
|
+
noDataExpression: true,
|
|
43
|
+
options: [
|
|
44
|
+
{
|
|
45
|
+
name: 'Page',
|
|
46
|
+
value: 'page',
|
|
47
|
+
description: 'Manage tracked pages',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'Check',
|
|
51
|
+
value: 'check',
|
|
52
|
+
description: 'Access check history and diffs',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Screenshot',
|
|
56
|
+
value: 'screenshot',
|
|
57
|
+
description: 'Get page screenshots',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'Webhook',
|
|
61
|
+
value: 'webhook',
|
|
62
|
+
description: 'Manage webhooks',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
default: 'page',
|
|
66
|
+
},
|
|
67
|
+
...PageDescription_1.pageOperations,
|
|
68
|
+
...PageDescription_1.pageFields,
|
|
69
|
+
...CheckDescription_1.checkOperations,
|
|
70
|
+
...CheckDescription_1.checkFields,
|
|
71
|
+
...ScreenshotDescription_1.screenshotOperations,
|
|
72
|
+
...ScreenshotDescription_1.screenshotFields,
|
|
73
|
+
...WebhookDescription_1.webhookOperations,
|
|
74
|
+
...WebhookDescription_1.webhookFields,
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async execute() {
|
|
79
|
+
const items = this.getInputData();
|
|
80
|
+
const returnData = [];
|
|
81
|
+
const credentials = await this.getCredentials('pageCrawlApi');
|
|
82
|
+
const baseUrl = (credentials.baseUrl || 'https://pagecrawl.io').replace(/\/+$/, '');
|
|
83
|
+
for (let i = 0; i < items.length; i++) {
|
|
84
|
+
const resource = this.getNodeParameter('resource', i);
|
|
85
|
+
const operation = this.getNodeParameter('operation', i);
|
|
86
|
+
try {
|
|
87
|
+
let responseData;
|
|
88
|
+
// Handle different resources and operations
|
|
89
|
+
if (resource === 'page') {
|
|
90
|
+
if (operation === 'getAll') {
|
|
91
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
92
|
+
const options = this.getNodeParameter('options', i);
|
|
93
|
+
const endpoint = '/pages';
|
|
94
|
+
const qs = {};
|
|
95
|
+
if (options.simple) {
|
|
96
|
+
qs.simple = 1;
|
|
97
|
+
}
|
|
98
|
+
if (options.take) {
|
|
99
|
+
qs.take = options.take;
|
|
100
|
+
}
|
|
101
|
+
if (options.folder) {
|
|
102
|
+
qs.folder = options.folder;
|
|
103
|
+
}
|
|
104
|
+
if (!returnAll) {
|
|
105
|
+
qs.limit = this.getNodeParameter('limit', i);
|
|
106
|
+
}
|
|
107
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
108
|
+
method: 'GET',
|
|
109
|
+
url: `${baseUrl}/api${endpoint}`,
|
|
110
|
+
qs,
|
|
111
|
+
json: true,
|
|
112
|
+
});
|
|
113
|
+
if (!returnAll && Array.isArray(responseData)) {
|
|
114
|
+
responseData = responseData.slice(0, qs.limit);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else if (operation === 'get') {
|
|
118
|
+
const pageId = this.getNodeParameter('pageId', i);
|
|
119
|
+
const options = this.getNodeParameter('options', i);
|
|
120
|
+
const qs = {};
|
|
121
|
+
if (options.simple) {
|
|
122
|
+
qs.simple = 1;
|
|
123
|
+
}
|
|
124
|
+
if (options.take) {
|
|
125
|
+
qs.take = options.take;
|
|
126
|
+
}
|
|
127
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
128
|
+
method: 'GET',
|
|
129
|
+
url: `${baseUrl}/api/pages/${pageId}`,
|
|
130
|
+
qs,
|
|
131
|
+
json: true,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else if (operation === 'createSimple') {
|
|
135
|
+
const url = this.getNodeParameter('url', i);
|
|
136
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
137
|
+
const body = { url };
|
|
138
|
+
if (additionalFields.selector) {
|
|
139
|
+
body.selector = additionalFields.selector;
|
|
140
|
+
}
|
|
141
|
+
if (additionalFields.frequency !== undefined) {
|
|
142
|
+
body.frequency = additionalFields.frequency;
|
|
143
|
+
}
|
|
144
|
+
if (additionalFields.ignore_duplicates !== undefined) {
|
|
145
|
+
body.ignore_duplicates = additionalFields.ignore_duplicates;
|
|
146
|
+
}
|
|
147
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
148
|
+
method: 'POST',
|
|
149
|
+
url: `${baseUrl}/api/track-simple`,
|
|
150
|
+
body,
|
|
151
|
+
json: true,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
else if (operation === 'create') {
|
|
155
|
+
const url = this.getNodeParameter('url', i);
|
|
156
|
+
const name = this.getNodeParameter('name', i);
|
|
157
|
+
const frequency = this.getNodeParameter('frequency', i);
|
|
158
|
+
const elements = this.getNodeParameter('elements', i);
|
|
159
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
160
|
+
const body = {
|
|
161
|
+
url,
|
|
162
|
+
name,
|
|
163
|
+
frequency,
|
|
164
|
+
elements: elements.element || [],
|
|
165
|
+
};
|
|
166
|
+
// Add all additional fields
|
|
167
|
+
Object.assign(body, additionalFields);
|
|
168
|
+
// Convert tags from comma-separated string to array
|
|
169
|
+
if (typeof body.tags === 'string' && body.tags) {
|
|
170
|
+
body.tags = body.tags.split(',').map((tag) => tag.trim()).filter(Boolean);
|
|
171
|
+
}
|
|
172
|
+
// Remove ID fields if they're 0 (not set)
|
|
173
|
+
if (body.folder_id === 0)
|
|
174
|
+
delete body.folder_id;
|
|
175
|
+
if (body.template_id === 0)
|
|
176
|
+
delete body.template_id;
|
|
177
|
+
if (body.auth_id === 0)
|
|
178
|
+
delete body.auth_id;
|
|
179
|
+
// Parse JSON fields if they're strings
|
|
180
|
+
if (typeof body.actions === 'string') {
|
|
181
|
+
try {
|
|
182
|
+
body.actions = JSON.parse(body.actions);
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in actions field', { itemIndex: i });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (typeof body.rules === 'string') {
|
|
189
|
+
try {
|
|
190
|
+
body.rules = JSON.parse(body.rules);
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in rules field', { itemIndex: i });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (typeof body.headers === 'string') {
|
|
197
|
+
try {
|
|
198
|
+
body.headers = JSON.parse(body.headers);
|
|
199
|
+
}
|
|
200
|
+
catch (e) {
|
|
201
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in headers field', { itemIndex: i });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
205
|
+
method: 'POST',
|
|
206
|
+
url: `${baseUrl}/api/pages`,
|
|
207
|
+
body,
|
|
208
|
+
json: true,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
else if (operation === 'update') {
|
|
212
|
+
const pageId = this.getNodeParameter('pageId', i);
|
|
213
|
+
const updateFields = this.getNodeParameter('updateFields', i);
|
|
214
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
215
|
+
const body = { ...updateFields, ...additionalFields };
|
|
216
|
+
// Convert tags from comma-separated string to array
|
|
217
|
+
if (typeof body.tags === 'string' && body.tags) {
|
|
218
|
+
body.tags = body.tags.split(',').map((tag) => tag.trim()).filter(Boolean);
|
|
219
|
+
}
|
|
220
|
+
// Remove ID fields if they're 0 (not set)
|
|
221
|
+
if (body.folder_id === 0)
|
|
222
|
+
delete body.folder_id;
|
|
223
|
+
if (body.template_id === 0)
|
|
224
|
+
delete body.template_id;
|
|
225
|
+
if (body.auth_id === 0)
|
|
226
|
+
delete body.auth_id;
|
|
227
|
+
// Parse JSON fields if they're strings
|
|
228
|
+
if (typeof body.elements === 'string') {
|
|
229
|
+
try {
|
|
230
|
+
body.elements = JSON.parse(body.elements);
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in elements field', { itemIndex: i });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (typeof body.actions === 'string') {
|
|
237
|
+
try {
|
|
238
|
+
body.actions = JSON.parse(body.actions);
|
|
239
|
+
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in actions field', { itemIndex: i });
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (typeof body.rules === 'string') {
|
|
245
|
+
try {
|
|
246
|
+
body.rules = JSON.parse(body.rules);
|
|
247
|
+
}
|
|
248
|
+
catch (e) {
|
|
249
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in rules field', { itemIndex: i });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (typeof body.headers === 'string') {
|
|
253
|
+
try {
|
|
254
|
+
body.headers = JSON.parse(body.headers);
|
|
255
|
+
}
|
|
256
|
+
catch (e) {
|
|
257
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in headers field', { itemIndex: i });
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
261
|
+
method: 'PUT',
|
|
262
|
+
url: `${baseUrl}/api/pages/${pageId}`,
|
|
263
|
+
body,
|
|
264
|
+
json: true,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
else if (operation === 'delete') {
|
|
268
|
+
const pageId = this.getNodeParameter('pageId', i);
|
|
269
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
270
|
+
method: 'DELETE',
|
|
271
|
+
url: `${baseUrl}/api/pages/${pageId}`,
|
|
272
|
+
json: true,
|
|
273
|
+
});
|
|
274
|
+
responseData = { success: true, deleted: pageId };
|
|
275
|
+
}
|
|
276
|
+
else if (operation === 'runCheckNow') {
|
|
277
|
+
const pageId = this.getNodeParameter('pageId', i);
|
|
278
|
+
const options = this.getNodeParameter('runCheckOptions', i);
|
|
279
|
+
const qs = {};
|
|
280
|
+
if (options.skip_first_notification) {
|
|
281
|
+
qs.skip_first_notification = 1;
|
|
282
|
+
}
|
|
283
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
284
|
+
method: 'PUT',
|
|
285
|
+
url: `${baseUrl}/api/pages/${pageId}/check`,
|
|
286
|
+
qs,
|
|
287
|
+
json: true,
|
|
288
|
+
});
|
|
289
|
+
responseData = { success: true, message: 'Check triggered', pageId };
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
else if (resource === 'check') {
|
|
293
|
+
const pageId = this.getNodeParameter('pageId', i);
|
|
294
|
+
if (operation === 'getHistory') {
|
|
295
|
+
const options = this.getNodeParameter('options', i);
|
|
296
|
+
const qs = {};
|
|
297
|
+
if (options.simple) {
|
|
298
|
+
qs.simple = 1;
|
|
299
|
+
}
|
|
300
|
+
if (options.take) {
|
|
301
|
+
qs.take = options.take;
|
|
302
|
+
}
|
|
303
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
304
|
+
method: 'GET',
|
|
305
|
+
url: `${baseUrl}/api/pages/${pageId}/history`,
|
|
306
|
+
qs,
|
|
307
|
+
json: true,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
else if (operation === 'getDiffImage') {
|
|
311
|
+
const checkId = this.getNodeParameter('checkId', i);
|
|
312
|
+
const response = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
313
|
+
method: 'GET',
|
|
314
|
+
url: `${baseUrl}/api/pages/${pageId}/checks/${checkId}/diff.png`,
|
|
315
|
+
encoding: 'arraybuffer',
|
|
316
|
+
});
|
|
317
|
+
const binaryData = await this.helpers.prepareBinaryData(response, `diff-${pageId}-${checkId}.png`, 'image/png');
|
|
318
|
+
const executionData = this.helpers.constructExecutionMetaData([{ json: {}, binary: { data: binaryData } }], { itemData: { item: i } });
|
|
319
|
+
returnData.push(...executionData);
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
else if (operation === 'getDiffHtml') {
|
|
323
|
+
const checkId = this.getNodeParameter('checkId', i);
|
|
324
|
+
const htmlContent = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
325
|
+
method: 'GET',
|
|
326
|
+
url: `${baseUrl}/api/pages/${pageId}/checks/${checkId}/diff.html`,
|
|
327
|
+
headers: {
|
|
328
|
+
Accept: 'text/html',
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
responseData = {
|
|
332
|
+
html: htmlContent,
|
|
333
|
+
pageId,
|
|
334
|
+
checkId,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
else if (operation === 'getDiffMarkdown') {
|
|
338
|
+
const checkId = this.getNodeParameter('checkId', i);
|
|
339
|
+
const markdownContent = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
340
|
+
method: 'GET',
|
|
341
|
+
url: `${baseUrl}/api/pages/${pageId}/checks/${checkId}/diff.markdown`,
|
|
342
|
+
headers: {
|
|
343
|
+
Accept: 'text/markdown',
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
responseData = {
|
|
347
|
+
markdown: markdownContent,
|
|
348
|
+
pageId,
|
|
349
|
+
checkId,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
else if (resource === 'screenshot') {
|
|
354
|
+
const pageId = this.getNodeParameter('pageId', i);
|
|
355
|
+
let endpoint = '';
|
|
356
|
+
if (operation === 'getLatest') {
|
|
357
|
+
endpoint = `/pages/${pageId}/checks/latest/screenshot`;
|
|
358
|
+
}
|
|
359
|
+
else if (operation === 'getLatestDiff') {
|
|
360
|
+
endpoint = `/pages/${pageId}/checks/latest/diff`;
|
|
361
|
+
}
|
|
362
|
+
else if (operation === 'getCheckScreenshot') {
|
|
363
|
+
const checkId = this.getNodeParameter('checkId', i);
|
|
364
|
+
endpoint = `/pages/${pageId}/checks/${checkId}/screenshot`;
|
|
365
|
+
}
|
|
366
|
+
else if (operation === 'getCheckDiff') {
|
|
367
|
+
const checkId = this.getNodeParameter('checkId', i);
|
|
368
|
+
endpoint = `/pages/${pageId}/checks/${checkId}/diff`;
|
|
369
|
+
}
|
|
370
|
+
const response = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
371
|
+
method: 'GET',
|
|
372
|
+
url: `${baseUrl}/api${endpoint}`,
|
|
373
|
+
encoding: 'arraybuffer',
|
|
374
|
+
});
|
|
375
|
+
const binaryData = await this.helpers.prepareBinaryData(response, `screenshot-${pageId}.png`, 'image/png');
|
|
376
|
+
const executionData = this.helpers.constructExecutionMetaData([{ json: {}, binary: { data: binaryData } }], { itemData: { item: i } });
|
|
377
|
+
returnData.push(...executionData);
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
else if (resource === 'webhook') {
|
|
381
|
+
if (operation === 'getAll') {
|
|
382
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
383
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
384
|
+
method: 'GET',
|
|
385
|
+
url: `${baseUrl}/api/hooks`,
|
|
386
|
+
json: true,
|
|
387
|
+
});
|
|
388
|
+
if (!returnAll && Array.isArray(responseData)) {
|
|
389
|
+
const limit = this.getNodeParameter('limit', i);
|
|
390
|
+
responseData = responseData.slice(0, limit);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else if (operation === 'create') {
|
|
394
|
+
const target_url = this.getNodeParameter('target_url', i);
|
|
395
|
+
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
396
|
+
const body = { target_url };
|
|
397
|
+
if (additionalFields.change_id) {
|
|
398
|
+
body.change_id = additionalFields.change_id;
|
|
399
|
+
}
|
|
400
|
+
if (additionalFields.payload_fields) {
|
|
401
|
+
body.payload_fields = additionalFields.payload_fields;
|
|
402
|
+
}
|
|
403
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
404
|
+
method: 'POST',
|
|
405
|
+
url: `${baseUrl}/api/hooks`,
|
|
406
|
+
body,
|
|
407
|
+
json: true,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
else if (operation === 'update') {
|
|
411
|
+
const webhookId = this.getNodeParameter('webhookId', i);
|
|
412
|
+
const updateFields = this.getNodeParameter('updateFields', i);
|
|
413
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
414
|
+
method: 'PUT',
|
|
415
|
+
url: `${baseUrl}/api/hooks/${webhookId}`,
|
|
416
|
+
body: updateFields,
|
|
417
|
+
json: true,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
else if (operation === 'delete') {
|
|
421
|
+
const webhookId = this.getNodeParameter('webhookId', i);
|
|
422
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
423
|
+
method: 'DELETE',
|
|
424
|
+
url: `${baseUrl}/api/hooks/${webhookId}`,
|
|
425
|
+
json: true,
|
|
426
|
+
});
|
|
427
|
+
responseData = { success: true, deleted: webhookId };
|
|
428
|
+
}
|
|
429
|
+
else if (operation === 'test') {
|
|
430
|
+
const webhookId = this.getNodeParameter('webhookId', i);
|
|
431
|
+
responseData = await this.helpers.requestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
432
|
+
method: 'PUT',
|
|
433
|
+
url: `${baseUrl}/api/hooks/${webhookId}/test`,
|
|
434
|
+
json: true,
|
|
435
|
+
});
|
|
436
|
+
responseData = { success: true, message: 'Test webhook sent' };
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
const executionData = this.helpers.constructExecutionMetaData([{ json: responseData }], { itemData: { item: i } });
|
|
440
|
+
returnData.push(...executionData);
|
|
441
|
+
}
|
|
442
|
+
catch (error) {
|
|
443
|
+
if (this.continueOnFail()) {
|
|
444
|
+
// Extract detailed error message from API response if available
|
|
445
|
+
const errorMessage = error.response?.body?.message
|
|
446
|
+
|| error.response?.body?.error
|
|
447
|
+
|| error.message
|
|
448
|
+
|| 'An error occurred';
|
|
449
|
+
const statusCode = error.statusCode || error.response?.statusCode;
|
|
450
|
+
const executionData = this.helpers.constructExecutionMetaData([{
|
|
451
|
+
json: {
|
|
452
|
+
error: errorMessage,
|
|
453
|
+
statusCode,
|
|
454
|
+
resource,
|
|
455
|
+
operation,
|
|
456
|
+
},
|
|
457
|
+
}], { itemData: { item: i } });
|
|
458
|
+
returnData.push(...executionData);
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return [returnData];
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
exports.PageCrawl = PageCrawl;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-pagecrawl.PageCrawl",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": ["Marketing & Content"],
|
|
6
|
+
"resources": {
|
|
7
|
+
"credentialDocumentation": [
|
|
8
|
+
{
|
|
9
|
+
"url": "https://pagecrawl.io/docs/api"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"primaryDocumentation": [
|
|
13
|
+
{
|
|
14
|
+
"url": "https://pagecrawl.io/docs"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"alias": ["Monitor", "Track", "Website", "Change Detection", "Web Scraping"],
|
|
19
|
+
"subcategories": {
|
|
20
|
+
"Marketing & Content": ["Automation", "Analytics"]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkFields = exports.checkOperations = void 0;
|
|
4
|
+
exports.checkOperations = [
|
|
5
|
+
{
|
|
6
|
+
displayName: 'Operation',
|
|
7
|
+
name: 'operation',
|
|
8
|
+
type: 'options',
|
|
9
|
+
noDataExpression: true,
|
|
10
|
+
displayOptions: {
|
|
11
|
+
show: {
|
|
12
|
+
resource: ['check'],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
name: 'Get History',
|
|
18
|
+
value: 'getHistory',
|
|
19
|
+
description: 'Get check history for a page',
|
|
20
|
+
action: 'Get check history',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'Get Text Diff HTML',
|
|
24
|
+
value: 'getDiffHtml',
|
|
25
|
+
description: 'Get text difference as HTML',
|
|
26
|
+
action: 'Get text diff HTML',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'Get Text Diff Image',
|
|
30
|
+
value: 'getDiffImage',
|
|
31
|
+
description: 'Get text difference as image',
|
|
32
|
+
action: 'Get text diff image',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'Get Text Diff Markdown',
|
|
36
|
+
value: 'getDiffMarkdown',
|
|
37
|
+
description: 'Get text difference as Markdown',
|
|
38
|
+
action: 'Get text diff markdown',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
default: 'getHistory',
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
exports.checkFields = [
|
|
45
|
+
// ========================================
|
|
46
|
+
// check:getHistory
|
|
47
|
+
// ========================================
|
|
48
|
+
{
|
|
49
|
+
displayName: 'Page ID',
|
|
50
|
+
name: 'pageId',
|
|
51
|
+
type: 'string',
|
|
52
|
+
required: true,
|
|
53
|
+
displayOptions: {
|
|
54
|
+
show: {
|
|
55
|
+
resource: ['check'],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
default: '',
|
|
59
|
+
description: 'The ID or slug of the page',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
displayName: 'Options',
|
|
63
|
+
name: 'options',
|
|
64
|
+
type: 'collection',
|
|
65
|
+
placeholder: 'Add Option',
|
|
66
|
+
default: {},
|
|
67
|
+
displayOptions: {
|
|
68
|
+
show: {
|
|
69
|
+
resource: ['check'],
|
|
70
|
+
operation: ['getHistory'],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
options: [
|
|
74
|
+
{
|
|
75
|
+
displayName: 'Simple',
|
|
76
|
+
name: 'simple',
|
|
77
|
+
type: 'boolean',
|
|
78
|
+
default: false,
|
|
79
|
+
description: 'Whether to return simplified response',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
displayName: 'Take',
|
|
83
|
+
name: 'take',
|
|
84
|
+
type: 'number',
|
|
85
|
+
default: 0,
|
|
86
|
+
description: 'Limit number of checks retrieved',
|
|
87
|
+
typeOptions: {
|
|
88
|
+
minValue: 0,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
// ========================================
|
|
94
|
+
// check:getDiff*
|
|
95
|
+
// ========================================
|
|
96
|
+
{
|
|
97
|
+
displayName: 'Check ID',
|
|
98
|
+
name: 'checkId',
|
|
99
|
+
type: 'string',
|
|
100
|
+
required: true,
|
|
101
|
+
displayOptions: {
|
|
102
|
+
show: {
|
|
103
|
+
resource: ['check'],
|
|
104
|
+
operation: ['getDiffHtml', 'getDiffImage', 'getDiffMarkdown'],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
default: '',
|
|
108
|
+
description: 'The check ID (use "latest" for most recent)',
|
|
109
|
+
},
|
|
110
|
+
];
|