fix(autominator): add critical format rules to n8n helpers
This commit is contained in:
parent
36ce3c42d2
commit
8a91c6fffe
|
|
@ -1,21 +1,51 @@
|
|||
# n8n Workflow Helpers
|
||||
|
||||
## UUID Generation
|
||||
|
||||
n8n uses UUIDs for node IDs, workflow IDs, and webhook IDs. Generate UUIDs in this format:
|
||||
|
||||
**Full UUID (36 characters):** `f8b7ff4f-6375-4c79-9b2c-9814bfdd0c92`
|
||||
|
||||
- Used for: node `id`, `webhookId`, `versionId`
|
||||
- Format: 8-4-4-4-12 hexadecimal characters with hyphens
|
||||
|
||||
**Short ID (16 characters):** `Wvmqb0POKmqwCoKy`
|
||||
|
||||
- Used for: workflow `id`, tag `id`
|
||||
- Format: alphanumeric (a-z, A-Z, 0-9)
|
||||
|
||||
**Assignment ID:** `id-1`, `id-2`, `id-3`
|
||||
|
||||
- Used for: Set node assignments, IF node conditions
|
||||
- Format: "id-" + sequential number
|
||||
|
||||
## Node Creation Guidelines
|
||||
|
||||
### Basic Node Structure
|
||||
### Basic Node Structure (Modern n8n Format)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "unique-node-id",
|
||||
"parameters": {},
|
||||
"id": "f8b7ff4f-6375-4c79-9b2c-9814bfdd0c92",
|
||||
"name": "Node Name",
|
||||
"type": "n8n-nodes-base.nodeName",
|
||||
"typeVersion": 1,
|
||||
"position": [x, y],
|
||||
"parameters": {},
|
||||
"typeVersion": 2,
|
||||
"position": [1424, 496],
|
||||
"webhookId": "b5f0b784-2440-4371-bcf1-b59dd2b29e68",
|
||||
"credentials": {}
|
||||
}
|
||||
```
|
||||
|
||||
**Critical Rules:**
|
||||
|
||||
- `parameters` comes FIRST
|
||||
- `id` must be UUID format (e.g., "f8b7ff4f-6375-4c79-9b2c-9814bfdd0c92")
|
||||
- `type` must be `n8n-nodes-base.nodeName` format (NOT @n8n/n8n-nodes-\*)
|
||||
- `typeVersion` must be INTEGER (e.g., 2, 3, 4) NOT float (2.1, 3.4)
|
||||
- `position` must be array of integers: [x, y]
|
||||
- `webhookId` required for webhook nodes (UUID format)
|
||||
- Field order matters for n8n compatibility
|
||||
|
||||
### Node Positioning
|
||||
|
||||
- Start node: [250, 300]
|
||||
|
|
@ -25,12 +55,30 @@
|
|||
|
||||
### Common Node Types
|
||||
|
||||
### ⚠️ CRITICAL: Node Type Format Rules
|
||||
|
||||
**ALWAYS use format:** `n8n-nodes-base.nodeName`
|
||||
|
||||
**NEVER use these formats:**
|
||||
|
||||
- ❌ `@n8n/n8n-nodes-slack.slackTrigger` (wrong package format)
|
||||
- ❌ `n8n-nodes-slack.slackTrigger` (missing base)
|
||||
- ❌ `slackTrigger` (missing prefix)
|
||||
|
||||
**Correct Examples:**
|
||||
|
||||
- ✅ `n8n-nodes-base.webhook`
|
||||
- ✅ `n8n-nodes-base.slackTrigger`
|
||||
- ✅ `n8n-nodes-base.gmail`
|
||||
- ✅ `n8n-nodes-base.if`
|
||||
|
||||
**Trigger Nodes:**
|
||||
|
||||
- `n8n-nodes-base.webhook` - HTTP webhook trigger
|
||||
- `n8n-nodes-base.scheduleTrigger` - Cron/interval trigger
|
||||
- `n8n-nodes-base.manualTrigger` - Manual execution trigger
|
||||
- `n8n-nodes-base.emailTrigger` - Email trigger
|
||||
- `n8n-nodes-base.slackTrigger` - Slack event trigger
|
||||
|
||||
**Action Nodes:**
|
||||
|
||||
|
|
@ -44,7 +92,8 @@
|
|||
**Integration Nodes:**
|
||||
|
||||
- `n8n-nodes-base.googleSheets` - Google Sheets
|
||||
- `n8n-nodes-base.slack` - Slack
|
||||
- `n8n-nodes-base.slack` - Slack actions
|
||||
- `n8n-nodes-base.gmail` - Gmail
|
||||
- `n8n-nodes-base.notion` - Notion
|
||||
- `n8n-nodes-base.airtable` - Airtable
|
||||
- `n8n-nodes-base.postgres` - PostgreSQL
|
||||
|
|
@ -54,21 +103,56 @@
|
|||
|
||||
### Connection Structure
|
||||
|
||||
### ⚠️ CRITICAL: Connection Format Rules
|
||||
|
||||
**CORRECT Format:**
|
||||
|
||||
```json
|
||||
{
|
||||
"node": "Source Node Name",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
"Source Node Name": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Target Node Name",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**WRONG Formats:**
|
||||
|
||||
```json
|
||||
// ❌ WRONG - Missing "main" wrapper
|
||||
{
|
||||
"Source Node Name": [
|
||||
[
|
||||
{
|
||||
"node": "Target Node Name",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
// ❌ WRONG - Direct array
|
||||
{
|
||||
"Source Node Name": [[{...}]]
|
||||
}
|
||||
```
|
||||
|
||||
### Connection Rules
|
||||
|
||||
1. Each connection has a source node and target node
|
||||
2. Main connections use type: "main"
|
||||
3. Index 0 is default output, index 1+ for conditional branches
|
||||
4. IF nodes have index 0 (true) and index 1 (false)
|
||||
5. Always validate that referenced node names exist
|
||||
2. Connections object structure: `{"Source": {"main": [[{...}]]}}`
|
||||
3. The "main" key is REQUIRED (wraps the connection array)
|
||||
4. Index 0 is default output, index 1+ for conditional branches
|
||||
5. IF nodes have index 0 (true) and index 1 (false)
|
||||
6. Always validate that referenced node names exist
|
||||
|
||||
### Connection Patterns
|
||||
|
||||
|
|
@ -116,26 +200,124 @@ Trigger → Split → [Branch1, Branch2, Branch3] → Merge
|
|||
|
||||
## Data Transformation Patterns
|
||||
|
||||
### Using Set Node
|
||||
### Using Set Node (Modern Format - typeVersion 3+)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Transform Data",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3,
|
||||
"parameters": {
|
||||
"mode": "manual",
|
||||
"values": {
|
||||
"string": [
|
||||
"assignments": {
|
||||
"assignments": [
|
||||
{
|
||||
"id": "id-1",
|
||||
"name": "outputField",
|
||||
"value": "={{ $json.inputField }}"
|
||||
"value": "={{ $json.inputField }}",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"includeOtherFields": true,
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Critical Rules for Set Node:**
|
||||
|
||||
- Use `assignments.assignments` structure (not `values`)
|
||||
- Each assignment needs `id` field (e.g., "id-1", "id-2")
|
||||
- Each assignment needs `type` field ("string", "number", "boolean")
|
||||
- Include `includeOtherFields: true` to pass through other data
|
||||
- Include `options: {}` for compatibility
|
||||
|
||||
### Using Gmail Node (typeVersion 2+)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Send Email",
|
||||
"type": "n8n-nodes-base.gmail",
|
||||
"typeVersion": 2,
|
||||
"parameters": {
|
||||
"sendTo": "user@example.com",
|
||||
"subject": "Email Subject",
|
||||
"message": "Email body content",
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Critical Rules for Gmail Node:**
|
||||
|
||||
- Use `message` parameter (NOT `text`)
|
||||
- Use `sendTo` (NOT `to`)
|
||||
- Include `options: {}` for compatibility
|
||||
|
||||
### Using Slack Node with Channel Selection
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Slack Action",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"typeVersion": 2,
|
||||
"parameters": {
|
||||
"channel": {
|
||||
"__rl": true,
|
||||
"value": "general",
|
||||
"mode": "list",
|
||||
"cachedResultName": "#general"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Critical Rules for Slack Channel:**
|
||||
|
||||
- Use `__rl: true` flag for resource locator
|
||||
- Include `mode: "list"` for channel selection
|
||||
- Include `cachedResultName` with # prefix
|
||||
|
||||
### Using IF Node (typeVersion 2+)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Check Condition",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": false,
|
||||
"leftValue": "",
|
||||
"typeValidation": "loose"
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"id": "id-1",
|
||||
"leftValue": "={{ $json.field }}",
|
||||
"rightValue": "value",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "equals"
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "and"
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Critical Rules for IF Node:**
|
||||
|
||||
- Use `conditions.conditions` structure
|
||||
- Each condition needs `id` field
|
||||
- Do NOT include `name` field in conditions
|
||||
- Use `operator` object with `type` and `operation`
|
||||
- Include `options` at root level
|
||||
|
||||
### Using Code Node
|
||||
|
||||
```json
|
||||
|
|
@ -171,7 +353,7 @@ Trigger → Split → [Branch1, Branch2, Branch3] → Merge
|
|||
- `httpHeaderAuth` - Header-based auth
|
||||
- `httpQueryAuth` - Query parameter auth
|
||||
|
||||
## Workflow Metadata
|
||||
## Workflow Metadata (Modern n8n Format)
|
||||
|
||||
### Required Fields
|
||||
|
||||
|
|
@ -179,15 +361,37 @@ Trigger → Split → [Branch1, Branch2, Branch3] → Merge
|
|||
{
|
||||
"name": "Workflow Name",
|
||||
"nodes": [],
|
||||
"pinData": {},
|
||||
"connections": {},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"tags": []
|
||||
"versionId": "7d745171-e378-411c-bd0a-25a8368a1cb6",
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "2229c21690ffe7e7b16788a579be3103980c4445acb933f7ced2a6a17f0bd18b"
|
||||
},
|
||||
"id": "Wvmqb0POKmqwCoKy",
|
||||
"tags": [
|
||||
{
|
||||
"name": "Automation",
|
||||
"id": "7FHIZPUaIaChwuiS",
|
||||
"updatedAt": "2025-11-21T19:39:46.484Z",
|
||||
"createdAt": "2025-11-21T19:39:46.484Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Critical Rules:**
|
||||
|
||||
- `pinData` must be empty object `{}`
|
||||
- `versionId` must be UUID
|
||||
- `meta` object with `templateCredsSetupCompleted` and `instanceId`
|
||||
- `id` must be short alphanumeric (e.g., "Wvmqb0POKmqwCoKy")
|
||||
- `tags` must be array of objects (not strings) with id, name, createdAt, updatedAt
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
- [ ] All node IDs are unique
|
||||
|
|
|
|||
Loading…
Reference in New Issue