n8n-nodes-tornado-api 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 +467 -0
- package/dist/credentials/TornadoApi.credentials.d.ts +10 -0
- package/dist/credentials/TornadoApi.credentials.js +46 -0
- package/dist/credentials/TornadoApi.credentials.js.map +1 -0
- package/dist/nodes/TornadoApi/TornadoApi.node.d.ts +5 -0
- package/dist/nodes/TornadoApi/TornadoApi.node.js +591 -0
- package/dist/nodes/TornadoApi/TornadoApi.node.js.map +1 -0
- package/dist/nodes/TornadoApi/tornado.svg +3 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
# 🌪️ Tornado API for n8n
|
|
2
|
+
|
|
3
|
+
Download YouTube videos & Spotify podcasts directly in your n8n workflows.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Via npm (recommended)
|
|
8
|
+
```bash
|
|
9
|
+
cd ~/.n8n/custom
|
|
10
|
+
npm install n8n-nodes-tornado-api
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Via Docker
|
|
14
|
+
```bash
|
|
15
|
+
docker run -it --rm -p 5678:5678 \
|
|
16
|
+
-v n8n_data:/home/node/.n8n \
|
|
17
|
+
-v /path/to/n8n-nodes-tornado-api:/home/node/.n8n/custom/n8n-nodes-tornado-api \
|
|
18
|
+
n8nio/n8n
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Credentials Setup
|
|
24
|
+
|
|
25
|
+
1. Go to **Credentials** → **New**
|
|
26
|
+
2. Search for **Tornado API**
|
|
27
|
+
3. Enter your API Key (starts with `sk_`)
|
|
28
|
+
4. Base URL: `https://tornado.velys.software` (default)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Operations
|
|
33
|
+
|
|
34
|
+
### Job → Create
|
|
35
|
+
|
|
36
|
+
Creates a download job. Returns immediately with a `job_id`.
|
|
37
|
+
|
|
38
|
+
**Input:**
|
|
39
|
+
| Field | Type | Required | Description |
|
|
40
|
+
|-------|------|----------|-------------|
|
|
41
|
+
| URL | string | ✅ | YouTube or Spotify URL |
|
|
42
|
+
| Format | select | ❌ | mp4, mkv, webm, mov |
|
|
43
|
+
| Video Codec | select | ❌ | copy, h264, h265, vp9 |
|
|
44
|
+
| Audio Codec | select | ❌ | copy, aac, opus, mp3 |
|
|
45
|
+
| Audio Bitrate | select | ❌ | 64k to 320k |
|
|
46
|
+
| Video Quality | number | ❌ | CRF 0-51 (lower = better) |
|
|
47
|
+
| Filename | string | ❌ | Custom filename |
|
|
48
|
+
| Folder | string | ❌ | S3 folder prefix |
|
|
49
|
+
| Webhook URL | string | ❌ | Notification URL |
|
|
50
|
+
|
|
51
|
+
**Output (YouTube):**
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"job_id": "550e8400-e29b-41d4-a716-446655440000"
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Output (Spotify Show):**
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"batch_id": "550e8400-e29b-41d4-a716-446655440001",
|
|
62
|
+
"total_episodes": 142,
|
|
63
|
+
"episode_jobs": ["job-1", "job-2", "..."]
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### Job → Get Status
|
|
70
|
+
|
|
71
|
+
Check the current status of a job.
|
|
72
|
+
|
|
73
|
+
**Input:**
|
|
74
|
+
| Field | Type | Required |
|
|
75
|
+
|-------|------|----------|
|
|
76
|
+
| Job ID | string | ✅ |
|
|
77
|
+
|
|
78
|
+
**Output:**
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
82
|
+
"url": "https://youtube.com/watch?v=...",
|
|
83
|
+
"status": "Completed",
|
|
84
|
+
"s3_url": "https://your-bucket.s3.amazonaws.com/videos/video.mp4?X-Amz-Algorithm=...",
|
|
85
|
+
"step": "Finished",
|
|
86
|
+
"error": null
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### Job → Wait for Completion
|
|
93
|
+
|
|
94
|
+
Polls until the job is complete or fails. **Best for simple workflows.**
|
|
95
|
+
|
|
96
|
+
**Input:**
|
|
97
|
+
| Field | Type | Default | Description |
|
|
98
|
+
|-------|------|---------|-------------|
|
|
99
|
+
| Job ID | string | - | The job UUID |
|
|
100
|
+
| Timeout | number | 600 | Max wait time (seconds) |
|
|
101
|
+
| Poll Interval | number | 5 | Time between checks (seconds) |
|
|
102
|
+
|
|
103
|
+
**Output:** Same as Get Status (when completed)
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 📦 S3 Storage - How It Works
|
|
108
|
+
|
|
109
|
+
### Default Flow
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
1. You create a job → Tornado downloads the video
|
|
113
|
+
2. Video is uploaded to S3 → Tornado generates a presigned URL
|
|
114
|
+
3. You get the s3_url → Valid for 24 hours
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### The `s3_url` Field
|
|
118
|
+
|
|
119
|
+
When a job completes, you receive a **presigned S3 URL**:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"s3_url": "https://bucket.s3.region.amazonaws.com/videos/my-video.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=..."
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This URL:
|
|
128
|
+
- ✅ Can be downloaded directly (no auth needed)
|
|
129
|
+
- ✅ Works in browsers, wget, curl
|
|
130
|
+
- ✅ Valid for **24 hours**
|
|
131
|
+
- ❌ Expires after 24h (request new URL via Get Status)
|
|
132
|
+
|
|
133
|
+
### Using s3_url in n8n
|
|
134
|
+
|
|
135
|
+
**Download the file:**
|
|
136
|
+
```
|
|
137
|
+
HTTP Request node:
|
|
138
|
+
- Method: GET
|
|
139
|
+
- URL: {{ $json.s3_url }}
|
|
140
|
+
- Response: File
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Send to user:**
|
|
144
|
+
```
|
|
145
|
+
Telegram/Slack/Discord node:
|
|
146
|
+
- File URL: {{ $json.s3_url }}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Save to Google Drive:**
|
|
150
|
+
```
|
|
151
|
+
Google Drive node:
|
|
152
|
+
- Upload from URL: {{ $json.s3_url }}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 🔄 Workflow Examples
|
|
158
|
+
|
|
159
|
+
### Example 1: Simple YouTube Download
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
163
|
+
│ Trigger │ → │ Tornado API │ → │ Tornado API │
|
|
164
|
+
│ (Manual) │ │ Job:Create │ │ Job:Wait │
|
|
165
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
166
|
+
│ │
|
|
167
|
+
▼ ▼
|
|
168
|
+
{ job_id: ... } { s3_url: ... }
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Node 1 - Tornado API (Create):**
|
|
172
|
+
- Resource: Job
|
|
173
|
+
- Operation: Create
|
|
174
|
+
- URL: `https://youtube.com/watch?v=dQw4w9WgXcQ`
|
|
175
|
+
|
|
176
|
+
**Node 2 - Tornado API (Wait):**
|
|
177
|
+
- Resource: Job
|
|
178
|
+
- Operation: Wait for Completion
|
|
179
|
+
- Job ID: `{{ $json.job_id }}`
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### Example 2: Download + Send to Telegram
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
187
|
+
│ Telegram │ → │ Tornado API │ → │ Tornado API │ → │ Telegram │
|
|
188
|
+
│ Trigger │ │ Job:Create │ │ Job:Wait │ │ Send Video │
|
|
189
|
+
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Telegram Trigger:** Receives YouTube URL from user
|
|
193
|
+
**Tornado Create:** URL = `{{ $json.message.text }}`
|
|
194
|
+
**Tornado Wait:** Job ID = `{{ $json.job_id }}`
|
|
195
|
+
**Telegram Send:** Video URL = `{{ $json.s3_url }}`
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### Example 3: Batch Spotify Podcast
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
203
|
+
│ Trigger │ → │ Tornado API │ → │ Split In │ → │ Tornado API │
|
|
204
|
+
│ │ │ Job:Create │ │ Batches │ │ Job:Wait │
|
|
205
|
+
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
|
206
|
+
│
|
|
207
|
+
▼
|
|
208
|
+
{ batch_id: ...,
|
|
209
|
+
episode_jobs: [...] }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Tornado Create:**
|
|
213
|
+
- URL: `https://open.spotify.com/show/...`
|
|
214
|
+
- Folder: `my-podcast`
|
|
215
|
+
|
|
216
|
+
**Split In Batches:**
|
|
217
|
+
- Input: `{{ $json.episode_jobs }}`
|
|
218
|
+
- Batch Size: 10
|
|
219
|
+
|
|
220
|
+
**Tornado Wait (for each):**
|
|
221
|
+
- Job ID: `{{ $json }}`
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### Example 4: Configure Custom S3 Bucket + Download
|
|
226
|
+
|
|
227
|
+
Use your own S3 bucket (AWS, Cloudflare R2, MinIO):
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
231
|
+
│ Manual │ → │ Tornado API │ → │ Tornado API │ → │ Tornado API │
|
|
232
|
+
│ Trigger │ │ Storage: │ │ Job:Create │ │ Job:Wait │
|
|
233
|
+
│ │ │ Configure │ │ │ │ │
|
|
234
|
+
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
|
235
|
+
│ │
|
|
236
|
+
▼ ▼
|
|
237
|
+
Bucket linked! s3_url points to
|
|
238
|
+
YOUR bucket!
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Node 1 - Tornado API (Configure Bucket):**
|
|
242
|
+
- Resource: **Storage**
|
|
243
|
+
- Operation: **Configure Bucket**
|
|
244
|
+
- Provider: Amazon S3 / Cloudflare R2 / MinIO
|
|
245
|
+
- Endpoint URL: `https://s3.us-east-1.amazonaws.com`
|
|
246
|
+
- Bucket Name: `my-videos-bucket`
|
|
247
|
+
- Region: `us-east-1`
|
|
248
|
+
- Access Key ID: `AKIA...`
|
|
249
|
+
- Secret Access Key: `********`
|
|
250
|
+
|
|
251
|
+
**Node 2 - Tornado API (Create Job):**
|
|
252
|
+
- Resource: Job
|
|
253
|
+
- Operation: Create
|
|
254
|
+
- URL: `https://youtube.com/watch?v=...`
|
|
255
|
+
|
|
256
|
+
**Node 3 - Tornado API (Wait):**
|
|
257
|
+
- Resource: Job
|
|
258
|
+
- Operation: Wait for Completion
|
|
259
|
+
- Job ID: `{{ $json.job_id }}`
|
|
260
|
+
|
|
261
|
+
**Output:**
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"status": "Completed",
|
|
265
|
+
"s3_url": "https://my-videos-bucket.s3.us-east-1.amazonaws.com/videos/video.mp4?X-Amz-..."
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
### Example 5: Cloudflare R2 Setup
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
┌─────────────┐
|
|
275
|
+
│ Tornado API │
|
|
276
|
+
│ Storage: │
|
|
277
|
+
│ Configure │
|
|
278
|
+
└─────────────┘
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Settings for R2:**
|
|
282
|
+
- Provider: **Cloudflare R2**
|
|
283
|
+
- Endpoint URL: `https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com`
|
|
284
|
+
- Bucket Name: `my-r2-bucket`
|
|
285
|
+
- Region: `auto`
|
|
286
|
+
- Access Key ID: (from R2 API Tokens)
|
|
287
|
+
- Secret Access Key: (from R2 API Tokens)
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
### Example 6: Reset to Default Storage
|
|
292
|
+
|
|
293
|
+
If you want to stop using your custom bucket:
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
┌─────────────┐
|
|
297
|
+
│ Tornado API │
|
|
298
|
+
│ Storage: │
|
|
299
|
+
│ Reset │
|
|
300
|
+
└─────────────┘
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
- Resource: **Storage**
|
|
304
|
+
- Operation: **Reset to Default**
|
|
305
|
+
|
|
306
|
+
Files will be uploaded to Tornado's default storage again.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## 📊 Status Values
|
|
311
|
+
|
|
312
|
+
| Status | Description | s3_url |
|
|
313
|
+
|--------|-------------|--------|
|
|
314
|
+
| `Pending` | In queue | ❌ |
|
|
315
|
+
| `Processing` | Downloading/encoding | ❌ |
|
|
316
|
+
| `Completed` | Done! | ✅ |
|
|
317
|
+
| `Failed` | Error occurred | ❌ |
|
|
318
|
+
|
|
319
|
+
## 📍 Processing Steps
|
|
320
|
+
|
|
321
|
+
| Step | Description |
|
|
322
|
+
|------|-------------|
|
|
323
|
+
| `Queued` | Waiting in queue |
|
|
324
|
+
| `Downloading` | Fetching video/audio |
|
|
325
|
+
| `Muxing` | Combining with FFmpeg |
|
|
326
|
+
| `Uploading` | Sending to S3 |
|
|
327
|
+
| `Finished` | Complete |
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## ⚠️ Error Handling
|
|
332
|
+
|
|
333
|
+
Use the **IF** node to handle errors:
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
337
|
+
│ Tornado API │ → │ IF │ → │ Success │
|
|
338
|
+
│ Job:Wait │ │status=Done? │ │ Path │
|
|
339
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
340
|
+
│
|
|
341
|
+
▼ (else)
|
|
342
|
+
┌─────────────┐
|
|
343
|
+
│ Error │
|
|
344
|
+
│ Handler │
|
|
345
|
+
└─────────────┘
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**IF Condition:**
|
|
349
|
+
```
|
|
350
|
+
{{ $json.status }} == "Completed"
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 🛠️ Development
|
|
356
|
+
|
|
357
|
+
### Build from Source
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
git clone https://github.com/velys-software/n8n-nodes-tornado-api
|
|
361
|
+
cd n8n-nodes-tornado-api
|
|
362
|
+
npm install
|
|
363
|
+
npm run build
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Local Testing
|
|
367
|
+
|
|
368
|
+
1. Build the node: `npm run build`
|
|
369
|
+
2. Link to n8n:
|
|
370
|
+
```bash
|
|
371
|
+
# Windows
|
|
372
|
+
mklink /D "%USERPROFILE%\.n8n\custom\n8n-nodes-tornado-api" "D:\path\to\n8n-nodes-tornado-api"
|
|
373
|
+
|
|
374
|
+
# Linux/Mac
|
|
375
|
+
ln -s /path/to/n8n-nodes-tornado-api ~/.n8n/custom/n8n-nodes-tornado-api
|
|
376
|
+
```
|
|
377
|
+
3. Start n8n: `n8n start`
|
|
378
|
+
|
|
379
|
+
### Watch Mode
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
npm run dev
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Automatically rebuilds on file changes.
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 📦 Publishing to npm
|
|
390
|
+
|
|
391
|
+
To publish this node so others can install it via `npm install`:
|
|
392
|
+
|
|
393
|
+
### 1. Prerequisites
|
|
394
|
+
|
|
395
|
+
- npm account ([npmjs.com](https://www.npmjs.com/))
|
|
396
|
+
- Node.js 18+ installed
|
|
397
|
+
|
|
398
|
+
### 2. Login to npm
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
npm login
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### 3. Update package.json
|
|
405
|
+
|
|
406
|
+
Ensure these fields are correct:
|
|
407
|
+
```json
|
|
408
|
+
{
|
|
409
|
+
"name": "n8n-nodes-tornado-api",
|
|
410
|
+
"version": "1.0.0",
|
|
411
|
+
"description": "n8n node for Tornado API - Download YouTube videos & Spotify podcasts",
|
|
412
|
+
"author": "Velys Software",
|
|
413
|
+
"license": "MIT"
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### 4. Build & Publish
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
npm run build
|
|
421
|
+
npm publish
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### 5. Versioning
|
|
425
|
+
|
|
426
|
+
For updates:
|
|
427
|
+
```bash
|
|
428
|
+
npm version patch # 1.0.0 → 1.0.1 (bug fixes)
|
|
429
|
+
npm version minor # 1.0.0 → 1.1.0 (new features)
|
|
430
|
+
npm version major # 1.0.0 → 2.0.0 (breaking changes)
|
|
431
|
+
npm publish
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## ✅ n8n Community Verification (Optional)
|
|
437
|
+
|
|
438
|
+
To get your node listed in the official n8n integrations:
|
|
439
|
+
|
|
440
|
+
### 1. Requirements
|
|
441
|
+
|
|
442
|
+
- Node must be published on npm
|
|
443
|
+
- Must follow n8n node naming: `n8n-nodes-*`
|
|
444
|
+
- Include proper documentation
|
|
445
|
+
- Include icon (SVG or PNG)
|
|
446
|
+
- Pass basic functionality tests
|
|
447
|
+
|
|
448
|
+
### 2. Submit for Review
|
|
449
|
+
|
|
450
|
+
1. Go to [n8n Community Nodes](https://docs.n8n.io/integrations/community-nodes/)
|
|
451
|
+
2. Submit your node for review via their process
|
|
452
|
+
3. n8n team will review and potentially feature it
|
|
453
|
+
|
|
454
|
+
### 3. Benefits of Verification
|
|
455
|
+
|
|
456
|
+
- Listed in n8n's official integrations
|
|
457
|
+
- Discoverable in n8n node search
|
|
458
|
+
- Increased trust and visibility
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## 🔗 Links
|
|
463
|
+
|
|
464
|
+
- [Tornado API](https://tornado.velys.software)
|
|
465
|
+
- [API Documentation](https://docs.tornado.velys.software)
|
|
466
|
+
- [Get API Key](https://tornado.velys.software/dashboard)
|
|
467
|
+
- [Support](mailto:support@velys.software)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class TornadoApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
icon: string;
|
|
6
|
+
documentationUrl: string;
|
|
7
|
+
properties: INodeProperties[];
|
|
8
|
+
authenticate: IAuthenticateGeneric;
|
|
9
|
+
test: ICredentialTestRequest;
|
|
10
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TornadoApi = void 0;
|
|
4
|
+
class TornadoApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'tornadoApi';
|
|
7
|
+
this.displayName = 'Tornado API';
|
|
8
|
+
this.icon = 'file:tornado.svg';
|
|
9
|
+
this.documentationUrl = 'https://docs.tornado.velys.software/authentication';
|
|
10
|
+
this.properties = [
|
|
11
|
+
{
|
|
12
|
+
displayName: 'API Key',
|
|
13
|
+
name: 'apiKey',
|
|
14
|
+
type: 'string',
|
|
15
|
+
typeOptions: { password: true },
|
|
16
|
+
default: '',
|
|
17
|
+
required: true,
|
|
18
|
+
description: 'Your Tornado API key (starts with sk_)',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
displayName: 'Base URL',
|
|
22
|
+
name: 'baseUrl',
|
|
23
|
+
type: 'string',
|
|
24
|
+
default: 'https://tornado.velys.software',
|
|
25
|
+
description: 'The base URL of the Tornado API',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
this.authenticate = {
|
|
29
|
+
type: 'generic',
|
|
30
|
+
properties: {
|
|
31
|
+
headers: {
|
|
32
|
+
'x-api-key': '={{$credentials.apiKey}}',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
this.test = {
|
|
37
|
+
request: {
|
|
38
|
+
baseURL: '={{$credentials.baseUrl}}',
|
|
39
|
+
url: '/usage',
|
|
40
|
+
method: 'GET',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.TornadoApi = TornadoApi;
|
|
46
|
+
//# sourceMappingURL=TornadoApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TornadoApi.credentials.js","sourceRoot":"","sources":["../../credentials/TornadoApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,UAAU;IAAvB;QACC,SAAI,GAAG,YAAY,CAAC;QACpB,gBAAW,GAAG,aAAa,CAAC;QAC5B,SAAI,GAAG,kBAAkB,CAAC;QAC1B,qBAAgB,GAAG,oDAAoD,CAAC;QACxE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,wCAAwC;aACrD;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,gCAAgC;gBACzC,WAAW,EAAE,iCAAiC;aAC9C;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,WAAW,EAAE,0BAA0B;iBACvC;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,2BAA2B;gBACpC,GAAG,EAAE,QAAQ;gBACb,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AAxCD,gCAwCC"}
|
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TornadoApi = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
class TornadoApi {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Tornado API',
|
|
9
|
+
name: 'tornadoApi',
|
|
10
|
+
icon: 'file:tornado.svg',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
14
|
+
description: 'Download videos and podcasts from YouTube, Spotify and more with Tornado API',
|
|
15
|
+
defaults: {
|
|
16
|
+
name: 'Tornado API',
|
|
17
|
+
},
|
|
18
|
+
inputs: ['main'],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
credentials: [
|
|
21
|
+
{
|
|
22
|
+
name: 'tornadoApi',
|
|
23
|
+
required: true,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
properties: [
|
|
27
|
+
// Resource
|
|
28
|
+
{
|
|
29
|
+
displayName: 'Resource',
|
|
30
|
+
name: 'resource',
|
|
31
|
+
type: 'options',
|
|
32
|
+
noDataExpression: true,
|
|
33
|
+
options: [
|
|
34
|
+
{
|
|
35
|
+
name: 'Job',
|
|
36
|
+
value: 'job',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'Batch',
|
|
40
|
+
value: 'batch',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'Storage',
|
|
44
|
+
value: 'storage',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Account',
|
|
48
|
+
value: 'account',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
default: 'job',
|
|
52
|
+
},
|
|
53
|
+
// ==================== JOB OPERATIONS ====================
|
|
54
|
+
{
|
|
55
|
+
displayName: 'Operation',
|
|
56
|
+
name: 'operation',
|
|
57
|
+
type: 'options',
|
|
58
|
+
noDataExpression: true,
|
|
59
|
+
displayOptions: {
|
|
60
|
+
show: {
|
|
61
|
+
resource: ['job'],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
options: [
|
|
65
|
+
{
|
|
66
|
+
name: 'Create',
|
|
67
|
+
value: 'create',
|
|
68
|
+
description: 'Create a new download job',
|
|
69
|
+
action: 'Create a download job',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'Get Status',
|
|
73
|
+
value: 'getStatus',
|
|
74
|
+
description: 'Get the status of a job',
|
|
75
|
+
action: 'Get job status',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'Wait for Completion',
|
|
79
|
+
value: 'waitForCompletion',
|
|
80
|
+
description: 'Wait for a job to complete',
|
|
81
|
+
action: 'Wait for job completion',
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
default: 'create',
|
|
85
|
+
},
|
|
86
|
+
// Job Create Fields
|
|
87
|
+
{
|
|
88
|
+
displayName: 'URL',
|
|
89
|
+
name: 'url',
|
|
90
|
+
type: 'string',
|
|
91
|
+
required: true,
|
|
92
|
+
displayOptions: {
|
|
93
|
+
show: {
|
|
94
|
+
resource: ['job'],
|
|
95
|
+
operation: ['create'],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
default: '',
|
|
99
|
+
placeholder: 'https://www.youtube.com/watch?v=...',
|
|
100
|
+
description: 'The video or Spotify show URL to download',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
displayName: 'Additional Options',
|
|
104
|
+
name: 'additionalOptions',
|
|
105
|
+
type: 'collection',
|
|
106
|
+
placeholder: 'Add Option',
|
|
107
|
+
default: {},
|
|
108
|
+
displayOptions: {
|
|
109
|
+
show: {
|
|
110
|
+
resource: ['job'],
|
|
111
|
+
operation: ['create'],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
options: [
|
|
115
|
+
{
|
|
116
|
+
displayName: 'Format',
|
|
117
|
+
name: 'format',
|
|
118
|
+
type: 'options',
|
|
119
|
+
options: [
|
|
120
|
+
{ name: 'MP4', value: 'mp4' },
|
|
121
|
+
{ name: 'MKV', value: 'mkv' },
|
|
122
|
+
{ name: 'WebM', value: 'webm' },
|
|
123
|
+
{ name: 'MOV', value: 'mov' },
|
|
124
|
+
],
|
|
125
|
+
default: 'mp4',
|
|
126
|
+
description: 'Output container format',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
displayName: 'Video Codec',
|
|
130
|
+
name: 'video_codec',
|
|
131
|
+
type: 'options',
|
|
132
|
+
options: [
|
|
133
|
+
{ name: 'Copy (No Re-encode)', value: 'copy' },
|
|
134
|
+
{ name: 'H.264', value: 'h264' },
|
|
135
|
+
{ name: 'H.265 (HEVC)', value: 'h265' },
|
|
136
|
+
{ name: 'VP9', value: 'vp9' },
|
|
137
|
+
],
|
|
138
|
+
default: 'copy',
|
|
139
|
+
description: 'Video codec to use',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
displayName: 'Audio Codec',
|
|
143
|
+
name: 'audio_codec',
|
|
144
|
+
type: 'options',
|
|
145
|
+
options: [
|
|
146
|
+
{ name: 'Copy (No Re-encode)', value: 'copy' },
|
|
147
|
+
{ name: 'AAC', value: 'aac' },
|
|
148
|
+
{ name: 'Opus', value: 'opus' },
|
|
149
|
+
{ name: 'MP3', value: 'mp3' },
|
|
150
|
+
],
|
|
151
|
+
default: 'copy',
|
|
152
|
+
description: 'Audio codec to use',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
displayName: 'Audio Bitrate',
|
|
156
|
+
name: 'audio_bitrate',
|
|
157
|
+
type: 'options',
|
|
158
|
+
options: [
|
|
159
|
+
{ name: '64 kbps', value: '64k' },
|
|
160
|
+
{ name: '128 kbps', value: '128k' },
|
|
161
|
+
{ name: '192 kbps', value: '192k' },
|
|
162
|
+
{ name: '256 kbps', value: '256k' },
|
|
163
|
+
{ name: '320 kbps', value: '320k' },
|
|
164
|
+
],
|
|
165
|
+
default: '192k',
|
|
166
|
+
description: 'Audio bitrate when transcoding',
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
displayName: 'Video Quality (CRF)',
|
|
170
|
+
name: 'video_quality',
|
|
171
|
+
type: 'number',
|
|
172
|
+
typeOptions: {
|
|
173
|
+
minValue: 0,
|
|
174
|
+
maxValue: 51,
|
|
175
|
+
},
|
|
176
|
+
default: 23,
|
|
177
|
+
description: 'Video quality CRF (0-51, lower = better). Only used when video codec is not "copy".',
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
displayName: 'Custom Filename',
|
|
181
|
+
name: 'filename',
|
|
182
|
+
type: 'string',
|
|
183
|
+
default: '',
|
|
184
|
+
description: 'Custom filename (without extension)',
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
displayName: 'Folder',
|
|
188
|
+
name: 'folder',
|
|
189
|
+
type: 'string',
|
|
190
|
+
default: '',
|
|
191
|
+
description: 'S3 folder prefix for organizing files',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
displayName: 'Webhook URL',
|
|
195
|
+
name: 'webhook_url',
|
|
196
|
+
type: 'string',
|
|
197
|
+
default: '',
|
|
198
|
+
description: 'URL to receive completion notification',
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
// Job Get Status Fields
|
|
203
|
+
{
|
|
204
|
+
displayName: 'Job ID',
|
|
205
|
+
name: 'jobId',
|
|
206
|
+
type: 'string',
|
|
207
|
+
required: true,
|
|
208
|
+
displayOptions: {
|
|
209
|
+
show: {
|
|
210
|
+
resource: ['job'],
|
|
211
|
+
operation: ['getStatus', 'waitForCompletion'],
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
default: '',
|
|
215
|
+
description: 'The UUID of the job',
|
|
216
|
+
},
|
|
217
|
+
// Wait for Completion Options
|
|
218
|
+
{
|
|
219
|
+
displayName: 'Timeout (Seconds)',
|
|
220
|
+
name: 'timeout',
|
|
221
|
+
type: 'number',
|
|
222
|
+
displayOptions: {
|
|
223
|
+
show: {
|
|
224
|
+
resource: ['job'],
|
|
225
|
+
operation: ['waitForCompletion'],
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
default: 600,
|
|
229
|
+
description: 'Maximum time to wait for completion',
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
displayName: 'Poll Interval (Seconds)',
|
|
233
|
+
name: 'pollInterval',
|
|
234
|
+
type: 'number',
|
|
235
|
+
displayOptions: {
|
|
236
|
+
show: {
|
|
237
|
+
resource: ['job'],
|
|
238
|
+
operation: ['waitForCompletion'],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
default: 5,
|
|
242
|
+
description: 'Time between status checks',
|
|
243
|
+
},
|
|
244
|
+
// ==================== BATCH OPERATIONS ====================
|
|
245
|
+
{
|
|
246
|
+
displayName: 'Operation',
|
|
247
|
+
name: 'operation',
|
|
248
|
+
type: 'options',
|
|
249
|
+
noDataExpression: true,
|
|
250
|
+
displayOptions: {
|
|
251
|
+
show: {
|
|
252
|
+
resource: ['batch'],
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
options: [
|
|
256
|
+
{
|
|
257
|
+
name: 'Get Status',
|
|
258
|
+
value: 'getStatus',
|
|
259
|
+
description: 'Get the status of a batch',
|
|
260
|
+
action: 'Get batch status',
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
default: 'getStatus',
|
|
264
|
+
},
|
|
265
|
+
// Batch Get Status Fields
|
|
266
|
+
{
|
|
267
|
+
displayName: 'Batch ID',
|
|
268
|
+
name: 'batchId',
|
|
269
|
+
type: 'string',
|
|
270
|
+
required: true,
|
|
271
|
+
displayOptions: {
|
|
272
|
+
show: {
|
|
273
|
+
resource: ['batch'],
|
|
274
|
+
operation: ['getStatus'],
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
default: '',
|
|
278
|
+
description: 'The UUID of the batch',
|
|
279
|
+
},
|
|
280
|
+
// ==================== STORAGE OPERATIONS ====================
|
|
281
|
+
{
|
|
282
|
+
displayName: 'Operation',
|
|
283
|
+
name: 'operation',
|
|
284
|
+
type: 'options',
|
|
285
|
+
noDataExpression: true,
|
|
286
|
+
displayOptions: {
|
|
287
|
+
show: {
|
|
288
|
+
resource: ['storage'],
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
options: [
|
|
292
|
+
{
|
|
293
|
+
name: 'Configure Bucket',
|
|
294
|
+
value: 'configureBucket',
|
|
295
|
+
description: 'Configure your own S3/R2 bucket for file uploads',
|
|
296
|
+
action: 'Configure S3 bucket',
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: 'Reset to Default',
|
|
300
|
+
value: 'resetBucket',
|
|
301
|
+
description: 'Reset to use Tornado default storage',
|
|
302
|
+
action: 'Reset to default storage',
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
default: 'configureBucket',
|
|
306
|
+
},
|
|
307
|
+
// Storage Provider
|
|
308
|
+
{
|
|
309
|
+
displayName: 'Provider',
|
|
310
|
+
name: 'provider',
|
|
311
|
+
type: 'options',
|
|
312
|
+
displayOptions: {
|
|
313
|
+
show: {
|
|
314
|
+
resource: ['storage'],
|
|
315
|
+
operation: ['configureBucket'],
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
options: [
|
|
319
|
+
{ name: 'Amazon S3', value: 'aws' },
|
|
320
|
+
{ name: 'Cloudflare R2', value: 'r2' },
|
|
321
|
+
{ name: 'MinIO', value: 'minio' },
|
|
322
|
+
{ name: 'Other S3-Compatible', value: 'other' },
|
|
323
|
+
],
|
|
324
|
+
default: 'aws',
|
|
325
|
+
description: 'Your storage provider',
|
|
326
|
+
},
|
|
327
|
+
// S3 Endpoint
|
|
328
|
+
{
|
|
329
|
+
displayName: 'Endpoint URL',
|
|
330
|
+
name: 'endpoint',
|
|
331
|
+
type: 'string',
|
|
332
|
+
required: true,
|
|
333
|
+
displayOptions: {
|
|
334
|
+
show: {
|
|
335
|
+
resource: ['storage'],
|
|
336
|
+
operation: ['configureBucket'],
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
default: '',
|
|
340
|
+
placeholder: 'https://s3.us-east-1.amazonaws.com',
|
|
341
|
+
description: 'S3 endpoint URL. For AWS use https://s3.REGION.amazonaws.com, for R2 use https://ACCOUNT_ID.r2.cloudflarestorage.com',
|
|
342
|
+
},
|
|
343
|
+
// Bucket Name
|
|
344
|
+
{
|
|
345
|
+
displayName: 'Bucket Name',
|
|
346
|
+
name: 'bucket',
|
|
347
|
+
type: 'string',
|
|
348
|
+
required: true,
|
|
349
|
+
displayOptions: {
|
|
350
|
+
show: {
|
|
351
|
+
resource: ['storage'],
|
|
352
|
+
operation: ['configureBucket'],
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
default: '',
|
|
356
|
+
placeholder: 'my-videos-bucket',
|
|
357
|
+
description: 'The name of your S3 bucket',
|
|
358
|
+
},
|
|
359
|
+
// Region
|
|
360
|
+
{
|
|
361
|
+
displayName: 'Region',
|
|
362
|
+
name: 'region',
|
|
363
|
+
type: 'string',
|
|
364
|
+
required: true,
|
|
365
|
+
displayOptions: {
|
|
366
|
+
show: {
|
|
367
|
+
resource: ['storage'],
|
|
368
|
+
operation: ['configureBucket'],
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
default: 'us-east-1',
|
|
372
|
+
placeholder: 'us-east-1',
|
|
373
|
+
description: 'AWS region (use "auto" for Cloudflare R2)',
|
|
374
|
+
},
|
|
375
|
+
// Access Key
|
|
376
|
+
{
|
|
377
|
+
displayName: 'Access Key ID',
|
|
378
|
+
name: 'accessKey',
|
|
379
|
+
type: 'string',
|
|
380
|
+
required: true,
|
|
381
|
+
displayOptions: {
|
|
382
|
+
show: {
|
|
383
|
+
resource: ['storage'],
|
|
384
|
+
operation: ['configureBucket'],
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
default: '',
|
|
388
|
+
description: 'Your S3 Access Key ID',
|
|
389
|
+
},
|
|
390
|
+
// Secret Key
|
|
391
|
+
{
|
|
392
|
+
displayName: 'Secret Access Key',
|
|
393
|
+
name: 'secretKey',
|
|
394
|
+
type: 'string',
|
|
395
|
+
typeOptions: { password: true },
|
|
396
|
+
required: true,
|
|
397
|
+
displayOptions: {
|
|
398
|
+
show: {
|
|
399
|
+
resource: ['storage'],
|
|
400
|
+
operation: ['configureBucket'],
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
default: '',
|
|
404
|
+
description: 'Your S3 Secret Access Key',
|
|
405
|
+
},
|
|
406
|
+
// ==================== ACCOUNT OPERATIONS ====================
|
|
407
|
+
{
|
|
408
|
+
displayName: 'Operation',
|
|
409
|
+
name: 'operation',
|
|
410
|
+
type: 'options',
|
|
411
|
+
noDataExpression: true,
|
|
412
|
+
displayOptions: {
|
|
413
|
+
show: {
|
|
414
|
+
resource: ['account'],
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
options: [
|
|
418
|
+
{
|
|
419
|
+
name: 'Get Usage',
|
|
420
|
+
value: 'getUsage',
|
|
421
|
+
description: 'Get account usage statistics',
|
|
422
|
+
action: 'Get usage statistics',
|
|
423
|
+
},
|
|
424
|
+
],
|
|
425
|
+
default: 'getUsage',
|
|
426
|
+
},
|
|
427
|
+
],
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
async execute() {
|
|
431
|
+
const items = this.getInputData();
|
|
432
|
+
const returnData = [];
|
|
433
|
+
const credentials = await this.getCredentials('tornadoApi');
|
|
434
|
+
const baseUrl = credentials.baseUrl;
|
|
435
|
+
for (let i = 0; i < items.length; i++) {
|
|
436
|
+
try {
|
|
437
|
+
const resource = this.getNodeParameter('resource', i);
|
|
438
|
+
const operation = this.getNodeParameter('operation', i);
|
|
439
|
+
let responseData;
|
|
440
|
+
// ==================== JOB ====================
|
|
441
|
+
if (resource === 'job') {
|
|
442
|
+
if (operation === 'create') {
|
|
443
|
+
const url = this.getNodeParameter('url', i);
|
|
444
|
+
const additionalOptions = this.getNodeParameter('additionalOptions', i);
|
|
445
|
+
const body = { url };
|
|
446
|
+
// Add optional fields
|
|
447
|
+
if (additionalOptions.format)
|
|
448
|
+
body.format = additionalOptions.format;
|
|
449
|
+
if (additionalOptions.video_codec)
|
|
450
|
+
body.video_codec = additionalOptions.video_codec;
|
|
451
|
+
if (additionalOptions.audio_codec)
|
|
452
|
+
body.audio_codec = additionalOptions.audio_codec;
|
|
453
|
+
if (additionalOptions.audio_bitrate)
|
|
454
|
+
body.audio_bitrate = additionalOptions.audio_bitrate;
|
|
455
|
+
if (additionalOptions.video_quality !== undefined)
|
|
456
|
+
body.video_quality = additionalOptions.video_quality;
|
|
457
|
+
if (additionalOptions.filename)
|
|
458
|
+
body.filename = additionalOptions.filename;
|
|
459
|
+
if (additionalOptions.folder)
|
|
460
|
+
body.folder = additionalOptions.folder;
|
|
461
|
+
if (additionalOptions.webhook_url)
|
|
462
|
+
body.webhook_url = additionalOptions.webhook_url;
|
|
463
|
+
responseData = await this.helpers.httpRequest({
|
|
464
|
+
method: 'POST',
|
|
465
|
+
url: `${baseUrl}/jobs`,
|
|
466
|
+
body,
|
|
467
|
+
json: true,
|
|
468
|
+
headers: {
|
|
469
|
+
'x-api-key': credentials.apiKey,
|
|
470
|
+
'Content-Type': 'application/json',
|
|
471
|
+
},
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
if (operation === 'getStatus') {
|
|
475
|
+
const jobId = this.getNodeParameter('jobId', i);
|
|
476
|
+
responseData = await this.helpers.httpRequest({
|
|
477
|
+
method: 'GET',
|
|
478
|
+
url: `${baseUrl}/jobs/${jobId}`,
|
|
479
|
+
json: true,
|
|
480
|
+
headers: {
|
|
481
|
+
'x-api-key': credentials.apiKey,
|
|
482
|
+
},
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
if (operation === 'waitForCompletion') {
|
|
486
|
+
const jobId = this.getNodeParameter('jobId', i);
|
|
487
|
+
const timeout = this.getNodeParameter('timeout', i);
|
|
488
|
+
const pollInterval = this.getNodeParameter('pollInterval', i);
|
|
489
|
+
const startTime = Date.now();
|
|
490
|
+
const timeoutMs = timeout * 1000;
|
|
491
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
492
|
+
responseData = await this.helpers.httpRequest({
|
|
493
|
+
method: 'GET',
|
|
494
|
+
url: `${baseUrl}/jobs/${jobId}`,
|
|
495
|
+
json: true,
|
|
496
|
+
headers: {
|
|
497
|
+
'x-api-key': credentials.apiKey,
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
if (responseData.status === 'Completed') {
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
if (responseData.status === 'Failed') {
|
|
504
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Job failed: ${responseData.error || 'Unknown error'}`, { itemIndex: i });
|
|
505
|
+
}
|
|
506
|
+
// Wait before next poll
|
|
507
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval * 1000));
|
|
508
|
+
}
|
|
509
|
+
if (responseData.status !== 'Completed' && responseData.status !== 'Failed') {
|
|
510
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Timeout waiting for job completion. Last status: ${responseData.status}`, { itemIndex: i });
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
// ==================== BATCH ====================
|
|
515
|
+
if (resource === 'batch') {
|
|
516
|
+
if (operation === 'getStatus') {
|
|
517
|
+
const batchId = this.getNodeParameter('batchId', i);
|
|
518
|
+
responseData = await this.helpers.httpRequest({
|
|
519
|
+
method: 'GET',
|
|
520
|
+
url: `${baseUrl}/batch/${batchId}`,
|
|
521
|
+
json: true,
|
|
522
|
+
headers: {
|
|
523
|
+
'x-api-key': credentials.apiKey,
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
// ==================== STORAGE ====================
|
|
529
|
+
if (resource === 'storage') {
|
|
530
|
+
if (operation === 'configureBucket') {
|
|
531
|
+
const endpoint = this.getNodeParameter('endpoint', i);
|
|
532
|
+
const bucket = this.getNodeParameter('bucket', i);
|
|
533
|
+
const region = this.getNodeParameter('region', i);
|
|
534
|
+
const accessKey = this.getNodeParameter('accessKey', i);
|
|
535
|
+
const secretKey = this.getNodeParameter('secretKey', i);
|
|
536
|
+
responseData = await this.helpers.httpRequest({
|
|
537
|
+
method: 'POST',
|
|
538
|
+
url: `${baseUrl}/user/bucket`,
|
|
539
|
+
body: {
|
|
540
|
+
endpoint,
|
|
541
|
+
bucket,
|
|
542
|
+
region,
|
|
543
|
+
access_key: accessKey,
|
|
544
|
+
secret_key: secretKey,
|
|
545
|
+
},
|
|
546
|
+
json: true,
|
|
547
|
+
headers: {
|
|
548
|
+
'x-api-key': credentials.apiKey,
|
|
549
|
+
'Content-Type': 'application/json',
|
|
550
|
+
},
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
if (operation === 'resetBucket') {
|
|
554
|
+
responseData = await this.helpers.httpRequest({
|
|
555
|
+
method: 'DELETE',
|
|
556
|
+
url: `${baseUrl}/user/bucket`,
|
|
557
|
+
json: true,
|
|
558
|
+
headers: {
|
|
559
|
+
'x-api-key': credentials.apiKey,
|
|
560
|
+
},
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
// ==================== ACCOUNT ====================
|
|
565
|
+
if (resource === 'account') {
|
|
566
|
+
if (operation === 'getUsage') {
|
|
567
|
+
responseData = await this.helpers.httpRequest({
|
|
568
|
+
method: 'GET',
|
|
569
|
+
url: `${baseUrl}/usage`,
|
|
570
|
+
json: true,
|
|
571
|
+
headers: {
|
|
572
|
+
'x-api-key': credentials.apiKey,
|
|
573
|
+
},
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
returnData.push({ json: responseData });
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
if (this.continueOnFail()) {
|
|
581
|
+
returnData.push({ json: { error: error.message } });
|
|
582
|
+
continue;
|
|
583
|
+
}
|
|
584
|
+
throw error;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return [returnData];
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
exports.TornadoApi = TornadoApi;
|
|
591
|
+
//# sourceMappingURL=TornadoApi.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TornadoApi.node.js","sourceRoot":"","sources":["../../../nodes/TornadoApi/TornadoApi.node.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-tornado-api",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n node for Tornado API - Download YouTube videos & Spotify podcasts",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"n8n",
|
|
8
|
+
"tornado",
|
|
9
|
+
"video",
|
|
10
|
+
"downloader",
|
|
11
|
+
"youtube",
|
|
12
|
+
"spotify",
|
|
13
|
+
"podcast",
|
|
14
|
+
"mp4",
|
|
15
|
+
"mp3"
|
|
16
|
+
],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"homepage": "https://tornado.velys.software",
|
|
19
|
+
"author": {
|
|
20
|
+
"name": "Velys Software",
|
|
21
|
+
"email": "support@velys.software"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/velys/n8n-nodes-tornado-api.git"
|
|
26
|
+
},
|
|
27
|
+
"main": "index.js",
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc && gulp build:icons",
|
|
30
|
+
"dev": "tsc --watch",
|
|
31
|
+
"format": "prettier nodes credentials --write",
|
|
32
|
+
"lint": "eslint nodes credentials package.json",
|
|
33
|
+
"lintfix": "eslint nodes credentials package.json --fix",
|
|
34
|
+
"prepublishOnly": "npm run build"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist"
|
|
38
|
+
],
|
|
39
|
+
"n8n": {
|
|
40
|
+
"n8nNodesApiVersion": 1,
|
|
41
|
+
"credentials": [
|
|
42
|
+
"dist/credentials/TornadoApi.credentials.js"
|
|
43
|
+
],
|
|
44
|
+
"nodes": [
|
|
45
|
+
"dist/nodes/TornadoApi/TornadoApi.node.js"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^20.10.0",
|
|
50
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
51
|
+
"eslint": "^8.56.0",
|
|
52
|
+
"gulp": "^5.0.1",
|
|
53
|
+
"n8n-workflow": "^1.17.0",
|
|
54
|
+
"prettier": "^3.1.0",
|
|
55
|
+
"typescript": "^5.3.0"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"n8n-workflow": "*"
|
|
59
|
+
}
|
|
60
|
+
}
|