n8n-nodes-crawlbrulee 0.2.0 → 0.3.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 +7 -4
- package/dist/nodes/Crawlbrulee/builders/map.js +2 -0
- package/dist/nodes/Crawlbrulee/builders/scrape.js +2 -0
- package/dist/nodes/Crawlbrulee/descriptions/map.js +1 -0
- package/dist/nodes/Crawlbrulee/descriptions/scrape.js +1 -0
- package/dist/nodes/Crawlbrulee/descriptions/shared.js +8 -1
- package/dist/nodes/Crawlbrulee/transport/errors.js +3 -0
- package/dist/nodes/Crawlbrulee/transport/request.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -76,6 +76,10 @@ set the node's "On Error" setting to continue and a failed item comes back as `{
|
|
|
76
76
|
|
|
77
77
|
a page the site really served is a normal item, whatever its status. a 404, 410 or 503 page comes back with its content, like any other page. it is not a node error, so "On Error" never sees it. when the status matters to your workflow, check it before you use the content — for example an **If** node on `{{ $json.page_status_code }}` is less than 400.
|
|
78
78
|
|
|
79
|
+
### zero data retention
|
|
80
|
+
|
|
81
|
+
turn on **Zero Data Retention** under **Options** of **Scrape URL**, **Scrape URL (Async)** or **Map Website** to keep the result out of the shared cache. anything stored to deliver it is kept for 24 hours, then deleted. it adds 1 credit and must be enabled for your organization. if it is not, the call fails with a clear message and costs no credits. see [zero data retention](https://crawlbrulee.com/docs/zero-data-retention).
|
|
82
|
+
|
|
79
83
|
### what a call cost
|
|
80
84
|
|
|
81
85
|
scrape, map and finished-job responses carry `response_meta.usage`, so the cost of each call is in front of you:
|
|
@@ -86,11 +90,10 @@ scrape, map and finished-job responses carry `response_meta.usage`, so the cost
|
|
|
86
90
|
| `engine_credit_cost` | the engine's base price: 1 for `http`, 3 for `browser`, 5 for `screenshot`, 0 for `cache` |
|
|
87
91
|
| `proxy_multiplier` | 1 for the Basic proxy tier, 5 for Advanced |
|
|
88
92
|
| `screenshot_slicing_credit_cost` | 1 when the screenshot was cut into slices on this call, else 0 (reusing slices from the cache costs 0). not on **Map Website** |
|
|
93
|
+
| `zero_data_retention_credit_cost` | 1 when **Zero Data Retention** added its credit to this call, else 0 |
|
|
89
94
|
| `engine`, `proxy` | the engine and the proxy tier that did the work |
|
|
90
95
|
|
|
91
|
-
`total_credit_cost` is always `engine_credit_cost × proxy_multiplier + screenshot_slicing_credit_cost
|
|
92
|
-
|
|
93
|
-
`credits` and `screenshot_slices` are still there, with the same values as `total_credit_cost` and `screenshot_slicing_credit_cost`. they are deprecated and will be removed in a future version, so read the new names in new workflows.
|
|
96
|
+
`total_credit_cost` is always `engine_credit_cost × proxy_multiplier + screenshot_slicing_credit_cost + zero_data_retention_credit_cost` (map has no slicing part). a page we don't bill, such as one the site answered with a 5xx status, has 0 in every `*_credit_cost` field. the [credits and pricing](https://crawlbrulee.com/docs/credits-and-pricing) page lists what is billed.
|
|
94
97
|
|
|
95
98
|
## the crawlbrulee Trigger
|
|
96
99
|
|
|
@@ -106,7 +109,7 @@ with the secret set, the trigger checks the HMAC-SHA256 signature on every deliv
|
|
|
106
109
|
|
|
107
110
|
## errors
|
|
108
111
|
|
|
109
|
-
the node turns api errors into messages you can act on: a rate limit says how long to wait, out of credits and concurrency limit are each named, an anti-bot block says so with no retry hint, a scrape error points you at the Advanced proxy tier and at Require JS, and a site we could not reach at all (for example it timed out, or its certificate is bad) tells you to check the url and try again later. the raw response stays on the error for the n8n error view, and every error name is in the [error reference](https://crawlbrulee.com/docs/errors).
|
|
112
|
+
the node turns api errors into messages you can act on: a rate limit says how long to wait, a Zero Data Retention request your organization cannot make yet says to turn the option off or ask us to enable it, out of credits and concurrency limit are each named, an anti-bot block says so with no retry hint, a scrape error points you at the Advanced proxy tier and at Require JS, and a site we could not reach at all (for example it timed out, or its certificate is bad) tells you to check the url and try again later. the raw response stays on the error for the n8n error view, and every error name is in the [error reference](https://crawlbrulee.com/docs/errors).
|
|
110
113
|
|
|
111
114
|
## development
|
|
112
115
|
|
|
@@ -8,6 +8,8 @@ function buildMapBody(_node, _itemIndex, p) {
|
|
|
8
8
|
const o = (_a = p.options) !== null && _a !== void 0 ? _a : {};
|
|
9
9
|
if (o.sitemapOnly === true)
|
|
10
10
|
body.sitemap_only = true;
|
|
11
|
+
if (o.zeroDataRetention === true)
|
|
12
|
+
body.zero_data_retention = true;
|
|
11
13
|
const types = {};
|
|
12
14
|
if (typeof o.internal === 'boolean')
|
|
13
15
|
types.internal = o.internal;
|
|
@@ -88,6 +88,8 @@ function buildScrapeBody(node, itemIndex, p) {
|
|
|
88
88
|
body.proxy = o.proxy;
|
|
89
89
|
if (o.requireJs === true)
|
|
90
90
|
body.require_js = true;
|
|
91
|
+
if (o.zeroDataRetention === true)
|
|
92
|
+
body.zero_data_retention = true;
|
|
91
93
|
const cleanup = {};
|
|
92
94
|
if (typeof o.removeAdsAndPopups === 'boolean')
|
|
93
95
|
cleanup.ads_and_popups = o.removeAdsAndPopups;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.localeOption = exports.countryOption = exports.cacheMaxAgeOption = exports.proxyOption = void 0;
|
|
3
|
+
exports.localeOption = exports.countryOption = exports.zeroDataRetentionOption = exports.cacheMaxAgeOption = exports.proxyOption = void 0;
|
|
4
4
|
exports.proxyOption = {
|
|
5
5
|
displayName: 'Proxy',
|
|
6
6
|
name: 'proxy',
|
|
@@ -30,6 +30,13 @@ const cacheMaxAgeOption = (defaultText) => ({
|
|
|
30
30
|
description: `Seconds, or an ISO-8601 cutoff. Cached results older than this are skipped. Default ${defaultText}.`,
|
|
31
31
|
});
|
|
32
32
|
exports.cacheMaxAgeOption = cacheMaxAgeOption;
|
|
33
|
+
exports.zeroDataRetentionOption = {
|
|
34
|
+
displayName: 'Zero Data Retention',
|
|
35
|
+
name: 'zeroDataRetention',
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
default: false,
|
|
38
|
+
description: 'Whether to keep the result out of the shared cache. Anything stored to deliver it is kept for 24 hours, then deleted. Adds 1 credit. Must be enabled for your organization.',
|
|
39
|
+
};
|
|
33
40
|
exports.countryOption = {
|
|
34
41
|
displayName: 'Country',
|
|
35
42
|
name: 'country',
|
|
@@ -5,6 +5,7 @@ exports.toNodeApiError = toNodeApiError;
|
|
|
5
5
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
6
|
const KEY_REJECTED = 'crawlbrulee rejected the API key. Check the key on the credential.';
|
|
7
7
|
const UNREACHABLE = 'crawlbrulee could not reach the target site. Check the URL. If it is right, the site may be down or slow, so try again later. This costs no credits.';
|
|
8
|
+
const ZDR_NOT_ENABLED = 'Zero data retention is not enabled for your organization. Turn the Zero Data Retention option off, or contact sales@crawlbrulee.com to have it turned on. This costs no credits.';
|
|
8
9
|
const SCRAPE_HINT = 'The Advanced proxy tier has a higher success rate; enable Require JS for JavaScript-rendered content.';
|
|
9
10
|
function isApiErrorBody(body) {
|
|
10
11
|
return (typeof body === 'object' &&
|
|
@@ -42,6 +43,8 @@ function describeApiError(status, body) {
|
|
|
42
43
|
return { message: body.message, description };
|
|
43
44
|
case 'target_unreachable':
|
|
44
45
|
return { message: UNREACHABLE, description };
|
|
46
|
+
case 'zero_data_retention_not_enabled':
|
|
47
|
+
return { message: ZDR_NOT_ENABLED, description };
|
|
45
48
|
case 'scrape_error':
|
|
46
49
|
return { message: `${body.message.replace(/[.\s]*$/, '')}. ${SCRAPE_HINT}`, description };
|
|
47
50
|
default:
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.USER_AGENT = void 0;
|
|
4
4
|
exports.crawlbruleeRequest = crawlbruleeRequest;
|
|
5
5
|
const errors_1 = require("./errors");
|
|
6
|
-
exports.USER_AGENT = 'n8n-nodes-crawlbrulee/0.
|
|
6
|
+
exports.USER_AGENT = 'n8n-nodes-crawlbrulee/0.3.0';
|
|
7
7
|
function stripTrailingSlash(url) {
|
|
8
8
|
return url.replace(/\/+$/, '');
|
|
9
9
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-crawlbrulee",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "crawlbrulee for n8n — EU-native web scraping for AI agents & developers. scrape any url to markdown, html, links, images, metadata or a screenshot, map a site's urls, and react to finished background scrapes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://crawlbrulee.com",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
]
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@crawlbrulee/sdk": "^1.
|
|
60
|
+
"@crawlbrulee/sdk": "^1.2.0",
|
|
61
61
|
"@n8n/node-cli": "0.48.6",
|
|
62
62
|
"@types/node": "^22.0.0",
|
|
63
63
|
"eslint": "9.32.0",
|