@bauer-group/n8n-nodes-http-throttled-request 0.1.1 → 0.1.5
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 -21
- package/README.md +220 -272
- package/dist/nodes/HttpRequest/HttpRequestThrottled.node.d.ts.map +1 -1
- package/dist/nodes/HttpRequest/HttpRequestThrottled.node.js +32 -43
- package/dist/nodes/HttpRequest/HttpRequestThrottled.node.js.map +1 -1
- package/dist/nodes/HttpRequest/translations/de/httpRequestThrottled.json +77 -0
- package/package.json +69 -64
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) BAUER GROUP
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) BAUER GROUP
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,272 +1,220 @@
|
|
|
1
|
-
# n8n-nodes-http-throttled-request
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Automatic Rate Limit Detection
|
|
8
|
-
- **Smart Wait Time Calculation
|
|
9
|
-
- **Jitter Support
|
|
10
|
-
- **
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
npm
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
|
73
|
-
|
|
74
|
-
| **
|
|
75
|
-
| **
|
|
76
|
-
| **
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
|
86
|
-
|
|
87
|
-
| **
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
##
|
|
128
|
-
|
|
129
|
-
###
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
##
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
3. Ensure `npm run build` completed successfully
|
|
222
|
-
4. Restart n8n after installation
|
|
223
|
-
|
|
224
|
-
### Throttling not working
|
|
225
|
-
|
|
226
|
-
1. Verify "Throttling aktivieren" is enabled
|
|
227
|
-
2. Check that the API returns one of the configured HTTP codes
|
|
228
|
-
3. Review n8n execution logs for throttling messages
|
|
229
|
-
|
|
230
|
-
### Maximum retries exceeded
|
|
231
|
-
|
|
232
|
-
If you see "Maximale Anzahl Versuche erreicht":
|
|
233
|
-
1. Increase "Max. Throttle-Versuche" setting
|
|
234
|
-
2. Increase "Standard-Wartezeit" to wait longer between retries
|
|
235
|
-
3. Check if the API requires authentication or has other restrictions
|
|
236
|
-
|
|
237
|
-
## API Reference
|
|
238
|
-
|
|
239
|
-
### Throttling Module Exports
|
|
240
|
-
|
|
241
|
-
```typescript
|
|
242
|
-
// Maximum wait time cap (5 minutes)
|
|
243
|
-
export const MAX_THROTTLE_WAIT_MS = 300_000;
|
|
244
|
-
|
|
245
|
-
// Normalize headers to lowercase keys
|
|
246
|
-
export function normalizeHeaders(raw: Record<string, unknown>): Record<string, string>;
|
|
247
|
-
|
|
248
|
-
// Parse Retry-After header to milliseconds
|
|
249
|
-
export function parseRetryAfterToMs(v: string): number | null;
|
|
250
|
-
|
|
251
|
-
// Parse reset timestamp headers to wait milliseconds
|
|
252
|
-
export function parseResetToWaitMs(h: Record<string, string>): number | null;
|
|
253
|
-
|
|
254
|
-
// Compute wait time from response headers
|
|
255
|
-
export function computeWaitMs(rawHeaders: Record<string, unknown>, defaultWaitMs: number): number;
|
|
256
|
-
|
|
257
|
-
// Apply jitter to wait time
|
|
258
|
-
export function applyJitter(baseMs: number, jitterPct: number): number;
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## License
|
|
262
|
-
|
|
263
|
-
MIT
|
|
264
|
-
|
|
265
|
-
## Contributing
|
|
266
|
-
|
|
267
|
-
1. Fork the repository
|
|
268
|
-
2. Create a feature branch
|
|
269
|
-
3. Make your changes
|
|
270
|
-
4. Run tests: `npm test`
|
|
271
|
-
5. Submit a pull request
|
|
272
|
-
|
|
1
|
+
# @bauer-group/n8n-nodes-http-throttled-request
|
|
2
|
+
|
|
3
|
+
An n8n community node that adds intelligent rate-limit throttling to HTTP requests. It automatically detects rate-limit responses (HTTP 429, 503, 504) and waits the appropriate time before retrying, using information from response headers.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Automatic Rate Limit Detection** — Detects HTTP 429, 503, and 504 status codes
|
|
8
|
+
- **Smart Wait Time Calculation** — Parses `Retry-After`, `X-RateLimit-*`, and HubSpot-specific headers
|
|
9
|
+
- **Jitter Support** — Prevents thundering herd with configurable random variance
|
|
10
|
+
- **Full Authentication Support** — None, Basic Auth, Header Auth, OAuth1, OAuth2
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
### n8n Community Nodes (Recommended)
|
|
15
|
+
|
|
16
|
+
1. Open your self-hosted n8n instance
|
|
17
|
+
2. Go to **Settings** → **Community Nodes**
|
|
18
|
+
3. Enter `@bauer-group/n8n-nodes-http-throttled-request`
|
|
19
|
+
4. Click **Install**
|
|
20
|
+
|
|
21
|
+
The node appears immediately in the node panel — no restart required.
|
|
22
|
+
|
|
23
|
+
> Community Nodes are only available on self-hosted n8n instances.
|
|
24
|
+
|
|
25
|
+
### Manual Installation
|
|
26
|
+
|
|
27
|
+
For local development or environments without Community Nodes support:
|
|
28
|
+
|
|
29
|
+
1. Clone this repository
|
|
30
|
+
2. Build the package:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install
|
|
34
|
+
npm run build
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
3. Link to your n8n installation:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cd ~/.n8n/nodes
|
|
41
|
+
npm link @bauer-group/n8n-nodes-http-throttled-request
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
4. Restart n8n
|
|
45
|
+
|
|
46
|
+
### Docker
|
|
47
|
+
|
|
48
|
+
Install the community node via `N8N_COMMUNITY_PACKAGES`:
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
services:
|
|
52
|
+
n8n:
|
|
53
|
+
image: n8nio/n8n
|
|
54
|
+
environment:
|
|
55
|
+
- N8N_COMMUNITY_PACKAGES=@bauer-group/n8n-nodes-http-throttled-request
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Alternatively, mount the built package as a volume:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
services:
|
|
62
|
+
n8n:
|
|
63
|
+
image: n8nio/n8n
|
|
64
|
+
volumes:
|
|
65
|
+
- ./n8n-nodes-http-throttled-request:/home/node/.n8n/nodes/n8n-nodes-http-throttled-request
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Configuration
|
|
69
|
+
|
|
70
|
+
### Node Parameters
|
|
71
|
+
|
|
72
|
+
| Parameter | Type | Default | Description |
|
|
73
|
+
|-----------|------|---------|-------------|
|
|
74
|
+
| **Method** | Options | GET | HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) |
|
|
75
|
+
| **URL** | String | — | Target URL for the request |
|
|
76
|
+
| **Authentication** | Options | None | Authentication type (None, Basic Auth, Header Auth, OAuth1, OAuth2) |
|
|
77
|
+
| **Send Headers** | Boolean | false | Enable custom request headers |
|
|
78
|
+
| **Send Body** | Boolean | false | Enable request body |
|
|
79
|
+
| **Enable Throttling** | Boolean | true | Enable automatic rate-limit handling |
|
|
80
|
+
|
|
81
|
+
### Throttling Settings
|
|
82
|
+
|
|
83
|
+
When throttling is enabled, the following settings become available under *Throttling Settings*:
|
|
84
|
+
|
|
85
|
+
| Setting | Type | Default | Description |
|
|
86
|
+
|---------|------|---------|-------------|
|
|
87
|
+
| **HTTP Codes** | Multi-select | 429 | Status codes that trigger throttling (429, 503, 504) |
|
|
88
|
+
| **Default Wait Time (ms)** | Number | 10000 | Wait time when no response header provides guidance |
|
|
89
|
+
| **Random Jitter (±%)** | Number | 25 | Jitter percentage to prevent thundering herd |
|
|
90
|
+
| **Max Throttle Retries** | Number | 10 | Maximum retry attempts before failing |
|
|
91
|
+
|
|
92
|
+
## How It Works
|
|
93
|
+
|
|
94
|
+
When the node receives a response with a configured throttle status code, it:
|
|
95
|
+
|
|
96
|
+
1. Extracts the wait time from response headers
|
|
97
|
+
2. Applies jitter to distribute retry attempts
|
|
98
|
+
3. Waits the calculated time
|
|
99
|
+
4. Retries the request
|
|
100
|
+
5. Repeats until success or max retries reached
|
|
101
|
+
|
|
102
|
+
### Header Priority
|
|
103
|
+
|
|
104
|
+
The wait time is determined using this priority (highest first):
|
|
105
|
+
|
|
106
|
+
| Priority | Source | Example |
|
|
107
|
+
| -------- | ------ | ------- |
|
|
108
|
+
| 1 | `Retry-After` (seconds) | `Retry-After: 30` |
|
|
109
|
+
| 1 | `Retry-After` (HTTP-Date) | `Retry-After: Wed, 19 Feb 2025 12:00:00 GMT` |
|
|
110
|
+
| 2 | `X-RateLimit-Remaining: 0` + reset timestamp | `X-RateLimit-Reset: 1739966400` |
|
|
111
|
+
| 3 | Reset timestamp alone | `X-RateLimit-Reset: 1739966400` |
|
|
112
|
+
| 4 | Default fallback | Configured *Default Wait Time* |
|
|
113
|
+
|
|
114
|
+
### Supported Headers
|
|
115
|
+
|
|
116
|
+
- `Retry-After` — seconds or HTTP-Date
|
|
117
|
+
- `X-RateLimit-Reset` / `X-RateLimit-Remaining`
|
|
118
|
+
- `X-HubSpot-RateLimit-Reset` / `X-HubSpot-RateLimit-Remaining`
|
|
119
|
+
- `RateLimit-Reset` / `RateLimit-Remaining`
|
|
120
|
+
|
|
121
|
+
### Safety Limits
|
|
122
|
+
|
|
123
|
+
- **Maximum wait time**: 5 minutes (300,000 ms)
|
|
124
|
+
- **Jitter range**: 0–100%
|
|
125
|
+
- **Minimum jitter result**: 0 ms (never negative)
|
|
126
|
+
|
|
127
|
+
## Usage Examples
|
|
128
|
+
|
|
129
|
+
### Basic GET with Throttling
|
|
130
|
+
|
|
131
|
+
1. Add the **HTTP Request (Throttled)** node to your workflow
|
|
132
|
+
2. Set the URL to your API endpoint
|
|
133
|
+
3. Throttling is enabled by default — configure settings as needed
|
|
134
|
+
4. Execute the workflow
|
|
135
|
+
|
|
136
|
+
### API with Rate Limits (e.g. HubSpot, GitHub, Stripe)
|
|
137
|
+
|
|
138
|
+
1. Enable throttling with appropriate HTTP codes (429, 503)
|
|
139
|
+
2. Set a reasonable default wait time (e.g. 10,000 ms)
|
|
140
|
+
3. Configure max retries based on your workflow timeout
|
|
141
|
+
4. Add jitter (25%) to distribute retry attempts
|
|
142
|
+
|
|
143
|
+
## Development
|
|
144
|
+
|
|
145
|
+
### Build
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npm run build
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Test
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npm test
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Test with Coverage
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm test -- --coverage
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Project Structure
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
├── src/
|
|
167
|
+
│ └── nodes/
|
|
168
|
+
│ └── HttpRequest/
|
|
169
|
+
│ ├── HttpRequestThrottled.node.ts # Main node implementation
|
|
170
|
+
│ └── throttling.ts # Throttling logic
|
|
171
|
+
├── test/
|
|
172
|
+
│ └── throttling.test.ts # Unit tests
|
|
173
|
+
├── package.json
|
|
174
|
+
└── tsconfig.json
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Troubleshooting
|
|
178
|
+
|
|
179
|
+
### Node not appearing in n8n
|
|
180
|
+
|
|
181
|
+
1. Check n8n logs for loading errors
|
|
182
|
+
2. Verify the package is installed correctly (Settings → Community Nodes)
|
|
183
|
+
3. For manual installs: ensure `npm run build` completed and restart n8n
|
|
184
|
+
|
|
185
|
+
### Throttling not working
|
|
186
|
+
|
|
187
|
+
1. Verify *Enable Throttling* is enabled (default: on)
|
|
188
|
+
2. Check that the API returns one of the configured HTTP codes
|
|
189
|
+
3. Review n8n execution logs for throttling messages
|
|
190
|
+
|
|
191
|
+
### Maximum retries exceeded
|
|
192
|
+
|
|
193
|
+
If you see `Throttling: max retries (…) exceeded`:
|
|
194
|
+
|
|
195
|
+
1. Increase *Max Throttle Retries*
|
|
196
|
+
2. Increase *Default Wait Time* to wait longer between retries
|
|
197
|
+
3. Check if the API requires authentication or has other restrictions
|
|
198
|
+
|
|
199
|
+
## API Reference
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
export const MAX_THROTTLE_WAIT_MS = 300_000;
|
|
203
|
+
|
|
204
|
+
export function normalizeHeaders(raw: Record<string, unknown>): Record<string, string>;
|
|
205
|
+
export function parseRetryAfterToMs(v: string): number | null;
|
|
206
|
+
export function parseResetToWaitMs(h: Record<string, string>): number | null;
|
|
207
|
+
export function computeWaitMs(rawHeaders: Record<string, unknown>, defaultWaitMs: number): number;
|
|
208
|
+
export function applyJitter(baseMs: number, jitterPct: number): number;
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
MIT
|
|
214
|
+
|
|
215
|
+
## Contributing
|
|
216
|
+
|
|
217
|
+
1. Fork the repository
|
|
218
|
+
2. Create a feature branch
|
|
219
|
+
3. Run tests: `npm test`
|
|
220
|
+
4. Submit a pull request
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpRequestThrottled.node.d.ts","sourceRoot":"","sources":["../../../src/nodes/HttpRequest/HttpRequestThrottled.node.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"HttpRequestThrottled.node.d.ts","sourceRoot":"","sources":["../../../src/nodes/HttpRequest/HttpRequestThrottled.node.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EAKrB,MAAM,cAAc,CAAC;AAOtB,qBAAa,oBAAqB,YAAW,SAAS;IACpD,WAAW,EAAE,oBAAoB,CAoL/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAoMxE"}
|
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// nodes/HttpRequest/HttpRequestThrottled.node.ts
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.HttpRequestThrottled = void 0;
|
|
5
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
5
|
const throttling_1 = require("./throttling");
|
|
7
|
-
// ── Hilfsfunktion ─────────────────────────────────────────────────────────────
|
|
8
6
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
9
|
-
// ── Node-Klasse ───────────────────────────────────────────────────────────────
|
|
10
7
|
class HttpRequestThrottled {
|
|
11
8
|
constructor() {
|
|
12
9
|
this.description = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
displayName: "HTTP Request",
|
|
10
|
+
name: "httpRequestThrottled",
|
|
11
|
+
displayName: "HTTP Request (Throttled)",
|
|
16
12
|
icon: "fa:at",
|
|
17
13
|
group: ["output"],
|
|
18
|
-
// v2: Versioned nodes – Array erlaubt mehrere Versionen gleichzeitig
|
|
19
14
|
version: [1, 2, 3],
|
|
20
15
|
defaultVersion: 3,
|
|
21
16
|
subtitle: '={{$parameter["method"] + ": " + $parameter["url"]}}',
|
|
22
17
|
description: "Makes an HTTP request and returns the response data (with throttling support)",
|
|
23
|
-
defaults: { name: "HTTP Request", color: "#
|
|
24
|
-
// Kompatibel mit n8n v1/v2: String-Literal 'main'
|
|
18
|
+
defaults: { name: "HTTP Request (Throttled)", color: "#FF8500" },
|
|
25
19
|
inputs: ["main"],
|
|
26
20
|
outputs: ["main"],
|
|
27
21
|
credentials: [
|
|
@@ -47,7 +41,7 @@ class HttpRequestThrottled {
|
|
|
47
41
|
},
|
|
48
42
|
],
|
|
49
43
|
properties: [
|
|
50
|
-
// ──
|
|
44
|
+
// ── Core properties ──────────────────────────────────────────────────────
|
|
51
45
|
{
|
|
52
46
|
displayName: "Method",
|
|
53
47
|
name: "method",
|
|
@@ -134,29 +128,29 @@ class HttpRequestThrottled {
|
|
|
134
128
|
default: "",
|
|
135
129
|
typeOptions: { rows: 4 },
|
|
136
130
|
},
|
|
137
|
-
// ── Throttling
|
|
131
|
+
// ── Throttling ─────────────────────────────────────────────────────────────
|
|
138
132
|
{
|
|
139
|
-
displayName: "Throttling
|
|
133
|
+
displayName: "Enable Throttling",
|
|
140
134
|
name: "throttlingEnabled",
|
|
141
135
|
type: "boolean",
|
|
142
136
|
default: true,
|
|
143
|
-
description: "
|
|
137
|
+
description: "Automatically wait and retry on rate-limit responses (429 etc.) using response headers",
|
|
144
138
|
noDataExpression: true,
|
|
145
139
|
},
|
|
146
140
|
{
|
|
147
|
-
displayName: "Throttling
|
|
141
|
+
displayName: "Throttling Settings",
|
|
148
142
|
name: "throttling",
|
|
149
143
|
type: "collection",
|
|
150
|
-
placeholder: "
|
|
144
|
+
placeholder: "Add Setting",
|
|
151
145
|
default: {},
|
|
152
146
|
displayOptions: { show: { throttlingEnabled: [true] } },
|
|
153
147
|
options: [
|
|
154
148
|
{
|
|
155
|
-
displayName: "HTTP
|
|
149
|
+
displayName: "HTTP Codes",
|
|
156
150
|
name: "throttleCodes",
|
|
157
151
|
type: "multiOptions",
|
|
158
152
|
default: ["429"],
|
|
159
|
-
description: "
|
|
153
|
+
description: "HTTP status codes that trigger throttling",
|
|
160
154
|
options: [
|
|
161
155
|
{ name: "429 Too Many Requests", value: "429" },
|
|
162
156
|
{ name: "503 Service Unavailable", value: "503" },
|
|
@@ -164,25 +158,25 @@ class HttpRequestThrottled {
|
|
|
164
158
|
],
|
|
165
159
|
},
|
|
166
160
|
{
|
|
167
|
-
displayName: "
|
|
161
|
+
displayName: "Default Wait Time (ms)",
|
|
168
162
|
name: "defaultWaitMs",
|
|
169
163
|
type: "number",
|
|
170
164
|
default: 10000,
|
|
171
|
-
description: "
|
|
165
|
+
description: "Wait time in milliseconds when no response header provides guidance",
|
|
172
166
|
},
|
|
173
167
|
{
|
|
174
|
-
displayName: "
|
|
168
|
+
displayName: "Random Jitter (±%)",
|
|
175
169
|
name: "jitterPercent",
|
|
176
170
|
type: "number",
|
|
177
171
|
default: 25,
|
|
178
|
-
description: "
|
|
172
|
+
description: "Randomize wait time by ±N% to prevent thundering herd effects across parallel executions",
|
|
179
173
|
},
|
|
180
174
|
{
|
|
181
|
-
displayName: "Max
|
|
175
|
+
displayName: "Max Throttle Retries",
|
|
182
176
|
name: "maxThrottleTries",
|
|
183
177
|
type: "number",
|
|
184
178
|
default: 10,
|
|
185
|
-
description: "
|
|
179
|
+
description: "Maximum number of throttling retries before throwing an error",
|
|
186
180
|
},
|
|
187
181
|
],
|
|
188
182
|
},
|
|
@@ -201,17 +195,16 @@ class HttpRequestThrottled {
|
|
|
201
195
|
const defaultWaitMs = throttlingParams.defaultWaitMs ?? 10000;
|
|
202
196
|
const jitterPercent = throttlingParams.jitterPercent ?? 25;
|
|
203
197
|
const maxThrottleTries = Math.max(1, throttlingParams.maxThrottleTries ?? 10);
|
|
204
|
-
// ──
|
|
198
|
+
// ── Build request options ────────────────────────────────────────────────
|
|
205
199
|
const method = this.getNodeParameter("method", itemIndex, "GET");
|
|
206
200
|
const url = this.getNodeParameter("url", itemIndex);
|
|
207
201
|
const sendHeaders = this.getNodeParameter("sendHeaders", itemIndex, false);
|
|
208
202
|
const sendBody = this.getNodeParameter("sendBody", itemIndex, false);
|
|
209
|
-
// v2: IHttpRequestOptions – kein freies Objekt mehr
|
|
210
203
|
const requestOptions = {
|
|
211
204
|
method: method,
|
|
212
205
|
url,
|
|
213
|
-
returnFullResponse: true,
|
|
214
|
-
ignoreHttpStatusErrors: true, //
|
|
206
|
+
returnFullResponse: true,
|
|
207
|
+
ignoreHttpStatusErrors: true, // prevent auto-throw on 4xx/5xx so we can handle throttling
|
|
215
208
|
headers: {},
|
|
216
209
|
};
|
|
217
210
|
if (sendHeaders) {
|
|
@@ -237,16 +230,14 @@ class HttpRequestThrottled {
|
|
|
237
230
|
requestOptions.body = bodyRaw;
|
|
238
231
|
}
|
|
239
232
|
}
|
|
240
|
-
// ── Throttling
|
|
233
|
+
// ── Throttling loop ──────────────────────────────────────────────────────
|
|
241
234
|
let throttleAttempt = 0;
|
|
242
235
|
while (true) {
|
|
243
|
-
// v2: this.helpers.httpRequest statt this.helpers.request
|
|
244
|
-
// Authentifizierung über httpRequestWithAuthentication wenn nötig
|
|
245
236
|
const authentication = this.getNodeParameter("authentication", itemIndex, "none");
|
|
246
237
|
let response;
|
|
247
238
|
try {
|
|
248
239
|
if (authentication !== "none") {
|
|
249
|
-
//
|
|
240
|
+
// Map authentication option to credential name
|
|
250
241
|
const credMap = {
|
|
251
242
|
basicAuth: "httpBasicAuth",
|
|
252
243
|
headerAuth: "httpHeaderAuth",
|
|
@@ -257,33 +248,31 @@ class HttpRequestThrottled {
|
|
|
257
248
|
response = await this.helpers.httpRequestWithAuthentication(credMap[authentication] ?? authentication, requestOptions);
|
|
258
249
|
}
|
|
259
250
|
else {
|
|
260
|
-
// v2: this.helpers.httpRequest
|
|
261
251
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
262
252
|
response = await this.helpers.httpRequest(requestOptions);
|
|
263
253
|
}
|
|
264
254
|
}
|
|
265
255
|
catch (err) {
|
|
266
|
-
// Netzwerkfehler → direkt werfen, nicht throtteln
|
|
267
256
|
if (err instanceof n8n_workflow_1.NodeApiError)
|
|
268
257
|
throw err;
|
|
269
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `
|
|
258
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Network error: ${err.message}`, { itemIndex });
|
|
270
259
|
}
|
|
271
260
|
const statusStr = String(response.statusCode);
|
|
272
|
-
// ── Throttling
|
|
273
|
-
//
|
|
274
|
-
//
|
|
261
|
+
// ── Throttling branch ──────────────────────────────────────────────
|
|
262
|
+
// Uses manual sleep + continue instead of throw to avoid triggering
|
|
263
|
+
// n8n's built-in retry-on-fail mechanism.
|
|
275
264
|
if (throttlingEnabled && throttleCodes.has(statusStr)) {
|
|
276
265
|
throttleAttempt++;
|
|
277
266
|
if (throttleAttempt >= maxThrottleTries) {
|
|
278
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Throttling:
|
|
267
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Throttling: max retries (${maxThrottleTries}) exceeded. Last status: ${response.statusCode}`, { itemIndex });
|
|
279
268
|
}
|
|
280
269
|
const baseWait = (0, throttling_1.computeWaitMs)(response.headers, defaultWaitMs);
|
|
281
270
|
const wait = (0, throttling_1.applyJitter)(baseWait, jitterPercent);
|
|
282
|
-
this.logger.info(`[Throttling] Status ${response.statusCode} –
|
|
271
|
+
this.logger.info(`[Throttling] Status ${response.statusCode} – item ${itemIndex}, attempt ${throttleAttempt}/${maxThrottleTries}, waiting ${Math.round(wait)}ms`);
|
|
283
272
|
await sleep(wait);
|
|
284
|
-
continue;
|
|
273
|
+
continue;
|
|
285
274
|
}
|
|
286
|
-
// ──
|
|
275
|
+
// ── Non-throttle error ────────────────────────────────────────────
|
|
287
276
|
if (response.statusCode >= 400) {
|
|
288
277
|
const continueOnFail = this.continueOnFail();
|
|
289
278
|
if (continueOnFail) {
|
|
@@ -298,7 +287,7 @@ class HttpRequestThrottled {
|
|
|
298
287
|
}
|
|
299
288
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `HTTP ${response.statusCode}: ${JSON.stringify(response.body)}`, { itemIndex });
|
|
300
289
|
}
|
|
301
|
-
// ──
|
|
290
|
+
// ── Success ──────────────────────────────────────────────────────────
|
|
302
291
|
const body = response.body;
|
|
303
292
|
const json = typeof body === "object" && body !== null
|
|
304
293
|
? body
|
|
@@ -307,7 +296,7 @@ class HttpRequestThrottled {
|
|
|
307
296
|
json,
|
|
308
297
|
pairedItem: { item: itemIndex },
|
|
309
298
|
});
|
|
310
|
-
break;
|
|
299
|
+
break;
|
|
311
300
|
}
|
|
312
301
|
}
|
|
313
302
|
return [returnData];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpRequestThrottled.node.js","sourceRoot":"","sources":["../../../src/nodes/HttpRequest/HttpRequestThrottled.node.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"HttpRequestThrottled.node.js","sourceRoot":"","sources":["../../../src/nodes/HttpRequest/HttpRequestThrottled.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nodeView": {
|
|
3
|
+
"displayName": "HTTP-Anfrage (Throttled)"
|
|
4
|
+
},
|
|
5
|
+
"header": {
|
|
6
|
+
"displayName": "HTTP-Anfrage (Throttled)",
|
|
7
|
+
"description": "Führt eine HTTP-Anfrage aus und gibt die Antwortdaten zurück (mit Throttling-Unterstützung)"
|
|
8
|
+
},
|
|
9
|
+
"properties": {
|
|
10
|
+
"method": {
|
|
11
|
+
"displayName": "Methode"
|
|
12
|
+
},
|
|
13
|
+
"url": {
|
|
14
|
+
"displayName": "URL"
|
|
15
|
+
},
|
|
16
|
+
"authentication": {
|
|
17
|
+
"displayName": "Authentifizierung",
|
|
18
|
+
"options": {
|
|
19
|
+
"none": { "displayName": "Keine" },
|
|
20
|
+
"basicAuth": { "displayName": "Basic Auth" },
|
|
21
|
+
"headerAuth": { "displayName": "Header Auth" },
|
|
22
|
+
"oAuth1": { "displayName": "OAuth1" },
|
|
23
|
+
"oAuth2": { "displayName": "OAuth2" }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"sendHeaders": {
|
|
27
|
+
"displayName": "Header senden"
|
|
28
|
+
},
|
|
29
|
+
"headerParameters": {
|
|
30
|
+
"displayName": "Header-Parameter",
|
|
31
|
+
"options": {
|
|
32
|
+
"parameters": {
|
|
33
|
+
"displayName": "Header",
|
|
34
|
+
"values": {
|
|
35
|
+
"name": { "displayName": "Name" },
|
|
36
|
+
"value": { "displayName": "Wert" }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"sendBody": {
|
|
42
|
+
"displayName": "Body senden"
|
|
43
|
+
},
|
|
44
|
+
"contentType": {
|
|
45
|
+
"displayName": "Body-Inhaltstyp"
|
|
46
|
+
},
|
|
47
|
+
"body": {
|
|
48
|
+
"displayName": "Body"
|
|
49
|
+
},
|
|
50
|
+
"throttlingEnabled": {
|
|
51
|
+
"displayName": "Throttling aktivieren",
|
|
52
|
+
"description": "Wartet automatisch bei Rate-Limit-Antworten (429 etc.) und wertet Response-Header aus"
|
|
53
|
+
},
|
|
54
|
+
"throttling": {
|
|
55
|
+
"displayName": "Throttling-Einstellungen",
|
|
56
|
+
"placeholder": "Einstellung hinzufügen",
|
|
57
|
+
"options": {
|
|
58
|
+
"throttleCodes": {
|
|
59
|
+
"displayName": "HTTP-Codes",
|
|
60
|
+
"description": "Bei diesen HTTP-Statuscodes wird Throttling ausgelöst"
|
|
61
|
+
},
|
|
62
|
+
"defaultWaitMs": {
|
|
63
|
+
"displayName": "Standard-Wartezeit (ms)",
|
|
64
|
+
"description": "Wartezeit in Millisekunden, wenn kein passender Response-Header vorhanden ist"
|
|
65
|
+
},
|
|
66
|
+
"jitterPercent": {
|
|
67
|
+
"displayName": "Zufällige Abweichung (±%)",
|
|
68
|
+
"description": "Streut die Wartezeit um ±N%, um Thundering-Herd-Effekte bei parallelen Executions zu vermeiden"
|
|
69
|
+
},
|
|
70
|
+
"maxThrottleTries": {
|
|
71
|
+
"displayName": "Max. Throttle-Versuche",
|
|
72
|
+
"description": "Maximale Anzahl Throttling-Retries bevor ein Fehler geworfen wird"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
package/package.json
CHANGED
|
@@ -1,64 +1,69 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@bauer-group/n8n-nodes-http-throttled-request",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "n8n community node with built-in HTTP request throttling (rate limiting)",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "https://github.com/bauer-group/EXT-n8n-httpThrottled.git"
|
|
9
|
-
},
|
|
10
|
-
"main": "dist/nodes/HttpRequest/HttpRequestThrottled.node.js",
|
|
11
|
-
"n8n": {
|
|
12
|
-
"nodes": [
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
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
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@bauer-group/n8n-nodes-http-throttled-request",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"description": "n8n community node with built-in HTTP request throttling (rate limiting)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/bauer-group/EXT-n8n-httpThrottled.git"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/nodes/HttpRequest/HttpRequestThrottled.node.js",
|
|
11
|
+
"n8n": {
|
|
12
|
+
"nodes": [
|
|
13
|
+
"dist/nodes/HttpRequest/HttpRequestThrottled.node.js"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist/",
|
|
18
|
+
"package.json",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"keywords": [
|
|
23
|
+
"n8n-community-node-package",
|
|
24
|
+
"n8n",
|
|
25
|
+
"http",
|
|
26
|
+
"throttling",
|
|
27
|
+
"rate-limit"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public",
|
|
31
|
+
"registry": "https://registry.npmjs.org/"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"clean": "rimraf dist",
|
|
35
|
+
"build": "tsc -p tsconfig.json && cp -r src/nodes/HttpRequest/translations dist/nodes/HttpRequest/",
|
|
36
|
+
"rebuild": "npm run clean && npm run build",
|
|
37
|
+
"test": "jest",
|
|
38
|
+
"prepublishOnly": "npm run build"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"n8n-workflow": ">=2.9.0 <3",
|
|
43
|
+
"n8n-core": ">=2.9.0 <3"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"typescript": "^5.9.3",
|
|
47
|
+
"@types/node": "^25.3.0",
|
|
48
|
+
"jest": "^30.2.0",
|
|
49
|
+
"@types/jest": "^30.0.0",
|
|
50
|
+
"ts-jest": "^29.4.6",
|
|
51
|
+
"n8n-workflow": "^2.9.0",
|
|
52
|
+
"n8n-core": "^2.9.0",
|
|
53
|
+
"rimraf": "^6.1.3"
|
|
54
|
+
},
|
|
55
|
+
"jest": {
|
|
56
|
+
"testEnvironment": "node",
|
|
57
|
+
"testMatch": [
|
|
58
|
+
"**/test/**/*.test.ts"
|
|
59
|
+
],
|
|
60
|
+
"transform": {
|
|
61
|
+
"^.+\\.ts$": [
|
|
62
|
+
"ts-jest",
|
|
63
|
+
{
|
|
64
|
+
"tsconfig": "tsconfig.test.json"
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|