AgentSkillsCN

n8n-workflows

构建 n8n 工作流自动化——节点、表达式、JavaScript 代码,以及集成模式。当您需要创建或调试 n8n 工作流时,可使用此技能。

SKILL.md
--- frontmatter
name: n8n-workflows
description: Build n8n workflow automations - nodes, expressions, JavaScript code, and integration patterns. Use when creating or debugging n8n workflows.

n8n Workflow Automation

When to Use This Skill

  • Building n8n workflows
  • Writing n8n expressions
  • Creating Code nodes (JavaScript/Python)
  • Debugging workflow errors
  • Integrating n8n with external services

n8n Basics

Workflow Structure

code
Trigger Node → Processing Nodes → Output Nodes
     ↓              ↓                  ↓
  Webhook      Transform Data     Send Email
  Schedule     HTTP Request       Slack Message
  Manual       Code Node          Database Write

Node Types

TypeExamplesPurpose
TriggerWebhook, Schedule, ManualStart workflow
ActionHTTP Request, Email, SlackDo something
TransformSet, Function, SplitModify data
FlowIf, Switch, MergeControl logic
DataPostgres, MongoDB, RedisData operations

Expressions

Basic Syntax

javascript
// Access input data
{{ $json.fieldName }}

// Access specific item
{{ $('Node Name').item.json.field }}

// Access all items from a node
{{ $('Node Name').all() }}

// First/last item
{{ $('Node Name').first().json.field }}
{{ $('Node Name').last().json.field }}

// Current item index
{{ $itemIndex }}

// Workflow variables
{{ $vars.myVariable }}

Common Patterns

javascript
// Conditional value
{{ $json.status === 'active' ? 'Yes' : 'No' }}

// Default value
{{ $json.name ?? 'Unknown' }}
{{ $json.name || 'Unknown' }}

// String manipulation
{{ $json.email.toLowerCase() }}
{{ $json.name.split(' ')[0] }}

// Date formatting
{{ $now.format('YYYY-MM-DD') }}
{{ $json.date.toFormat('dd/MM/yyyy') }}

// Array operations
{{ $json.items.length }}
{{ $json.items.map(i => i.name).join(', ') }}
{{ $json.items.filter(i => i.active) }}

Built-in Variables

javascript
// Current timestamp
{{ $now }}
{{ $today }}

// Workflow info
{{ $workflow.id }}
{{ $workflow.name }}

// Execution info
{{ $execution.id }}
{{ $execution.mode }}

// Environment
{{ $env.API_KEY }}

Code Node (JavaScript)

Basic Structure

javascript
// Process each item
for (const item of $input.all()) {
  // Access data
  const name = item.json.name;
  const email = item.json.email;

  // Modify data
  item.json.processed = true;
  item.json.fullName = `${item.json.firstName} ${item.json.lastName}`;
}

return $input.all();

Return New Items

javascript
const newItems = [];

for (const item of $input.all()) {
  // Create new item structure
  newItems.push({
    json: {
      id: item.json.id,
      name: item.json.name.toUpperCase(),
      timestamp: new Date().toISOString(),
    },
  });
}

return newItems;

HTTP Requests in Code

javascript
const response = await fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${$env.API_KEY}`,
  },
  body: JSON.stringify({
    query: $json.query,
  }),
});

const data = await response.json();

return [{ json: data }];

Error Handling

javascript
try {
  const result = await riskyOperation();
  return [{ json: { success: true, data: result } }];
} catch (error) {
  // Option 1: Return error as data
  return [{ json: { success: false, error: error.message } }];

  // Option 2: Throw to stop workflow
  throw new Error(`Operation failed: ${error.message}`);
}

Async Operations

javascript
// Multiple parallel requests
const promises = $input.all().map(async (item) => {
  const response = await fetch(`https://api.example.com/users/${item.json.id}`);
  const user = await response.json();
  return { json: { ...item.json, user } };
});

return await Promise.all(promises);

Code Node (Python)

Basic Structure

python
# Access input items
items = _input.all()
new_items = []

for item in items:
    data = item.json

    # Process data
    result = {
        "name": data.get("name", "").upper(),
        "processed_at": datetime.now().isoformat(),
    }

    new_items.append({"json": result})

return new_items

Limitations

python
# Available modules:
# - datetime, json, math, os (limited)
# - No external package imports
# - No file system access
# - No subprocess

# For HTTP requests, use HTTP Request node instead

Common Workflow Patterns

Webhook → Process → Response

code
Webhook Trigger
     ↓
  Set Node (transform data)
     ↓
  HTTP Request (call API)
     ↓
  Respond to Webhook

Scheduled Data Sync

code
Schedule Trigger (every hour)
     ↓
  HTTP Request (fetch source data)
     ↓
  Split In Batches
     ↓
  Postgres (upsert records)
     ↓
  Slack (notify completion)

Error Handling Pattern

code
Main Flow
     ↓
  Try/Catch
     ├─ Success → Continue
     └─ Error → Error Handler
                    ↓
                Slack Alert
                    ↓
                Log to Database

Conditional Processing

code
HTTP Request
     ↓
  IF (status check)
     ├─ True → Process A
     │            ↓
     │         Send Email
     └─ False → Process B
                   ↓
               Log Warning

Debugging

View Execution Data

javascript
// Log to execution output
console.log('Debug:', JSON.stringify($json, null, 2));

// In expressions, check intermediate values
{{ JSON.stringify($json) }}

Common Errors

markdown
## "Cannot read property 'X' of undefined"
- Check if previous node output exists
- Use optional chaining: $json.data?.items

## "Items do not match"
- Ensure consistent item count between branches
- Use Merge node to combine items

## Expression evaluation failed
- Check syntax (missing braces, quotes)
- Verify node names match exactly
- Use $('Node Name') not $('node name')

Test Workflow

bash
# Pin data for testing
# 1. Execute workflow once
# 2. Click "Pin Data" on node output
# 3. Modify and test without re-triggering

Best Practices

Naming Conventions

markdown
- Descriptive node names: "Fetch User Data" not "HTTP Request"
- Use prefixes for flow: "IF: Check Status", "Merge: Combine Results"
- Version your workflows: "Email Processor v2"

Error Handling

markdown
- Always add error handling for external requests
- Use "On Error" settings on critical nodes
- Set up alerting for workflow failures
- Log errors to persistent storage

Performance

markdown
- Use "Split In Batches" for large datasets
- Avoid nested loops in Code nodes
- Cache external data when possible
- Use pagination for API requests

Security

markdown
- Store secrets in credentials, not expressions
- Use environment variables for config
- Validate webhook payloads
- Limit webhook exposure (authentication)

Credentials

javascript
// Access credentials in Code node
const apiKey = $credentials.myApi.apiKey;

// In expressions
{{ $credentials.myApi.apiKey }}

// Best practice: Use HTTP Request node
// with built-in credential support

Checklist

  • Use descriptive node names
  • Add error handling for external calls
  • Test with edge cases (empty data, errors)
  • Use Split In Batches for large datasets
  • Store secrets in credentials
  • Add notes explaining complex logic
  • Set up failure notifications
  • Version control workflow exports