instruction: List the most common n8n nodes with their operations and authentication methods

output:
# n8n Node Integration Matrix

## Communication Nodes
| Node | Operations | Auth Method | Common Use Cases |
|------|------------|-------------|------------------|
| Gmail | Send, Reply, Get, Delete, Draft | OAuth2 | Notifications, lead follow-up |
| Slack | Post, Update, Upload, User Info | OAuth2/API Key | Team alerts, bot automation |
| Discord | Send, Edit, Delete, Webhook | Webhook/Bot Token | Community notifications |
| Telegram | Send Message, Edit, Get Updates | Bot Token | Alerts, chatbots |
| Microsoft Teams | Post, Reply, Channel List | OAuth2 | Enterprise notifications |
| Twilio | SMS Send, Call, WhatsApp | API Key + Secret | Multi-channel messaging |

## CRM Nodes
| Node | Operations | Auth Method | Common Use Cases |
|------|------------|-------------|------------------|
| HubSpot | Create/Update Contact, Deal, Company | OAuth2/API Key | Lead management |
| Salesforce | CRUD on any object, SOQL | OAuth2 | Enterprise CRM |
| Pipedrive | Deals, Persons, Orgs, Activities | API Token | Sales pipeline |
| Zoho CRM | Leads, Contacts, Deals | OAuth2 | SMB CRM automation |
| GoHighLevel | Contacts, Opportunities, Messages | API Key | Agency automation |

## Database Nodes
| Node | Operations | Auth Method | Common Use Cases |
|------|------------|-------------|------------------|
| PostgreSQL | Query, Insert, Update, Delete | Connection String | Data warehousing |
| MySQL | Query, Insert, Update, Delete | Connection String | Legacy systems |
| MongoDB | Find, Insert, Update, Aggregate | Connection String | NoSQL operations |
| Supabase | Select, Insert, Upsert, RPC | API Key + URL | Real-time backends |
| Airtable | List, Get, Create, Update | API Key | Spreadsheet-DB hybrid |
| Google Sheets | Append, Update, Read, Clear | OAuth2 | Lightweight data storage |

## AI/ML Nodes
| Node | Operations | Auth Method | Common Use Cases |
|------|------------|-------------|------------------|
| OpenAI | Chat, Complete, Embed, Image | API Key | Content generation, chatbots |
| Anthropic Claude | Message, Complete | API Key | Analysis, writing |
| Google AI | Generate, Embed | API Key | Multi-modal AI |
| Hugging Face | Inference | API Token | Custom models |

## Marketing Nodes
| Node | Operations | Auth Method | Common Use Cases |
|------|------------|-------------|------------------|
| Mailchimp | Subscribe, Campaign, Tag | API Key | Email marketing |
| SendGrid | Send, Template | API Key | Transactional email |
| Mailgun | Send, Validate | API Key + Domain | High-volume email |
| ActiveCampaign | Contact, Deal, Automation | API Key | Marketing automation |

## Storage Nodes
| Node | Operations | Auth Method | Common Use Cases |
|------|------------|-------------|------------------|
| AWS S3 | Upload, Download, List, Delete | Access Key + Secret | File storage |
| Google Drive | Upload, Download, Share | OAuth2 | Document management |
| Dropbox | Upload, Download, Move | OAuth2 | File sync |
| FTP/SFTP | Upload, Download, List | Username/Password or Key | Legacy file transfer |

type: reference


instruction: What HTTP Request configurations are needed for different API authentication types?

output:
# HTTP Request Authentication Patterns

## API Key in Header
```json
{
  "name": "API Request",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "url": "https://api.example.com/endpoint",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "options": {
      "headers": {
        "X-API-Key": "={{ $credentials.apiKey }}"
      }
    }
  }
}
```

## API Key in Query String
```json
{
  "parameters": {
    "url": "https://api.example.com/endpoint",
    "qs": {
      "api_key": "={{ $credentials.apiKey }}"
    }
  }
}
```

## Bearer Token
```json
{
  "parameters": {
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "options": {
      "headers": {
        "Authorization": "Bearer {{ $credentials.token }}"
      }
    }
  }
}
```

## Basic Auth
```json
{
  "parameters": {
    "authentication": "genericCredentialType",
    "genericAuthType": "httpBasicAuth"
  },
  "credentials": {
    "httpBasicAuth": {
      "user": "username",
      "password": "password"
    }
  }
}
```

## OAuth 2.0
```json
{
  "parameters": {
    "authentication": "oAuth2Api"
  },
  "credentials": {
    "oAuth2Api": {
      "accessTokenUrl": "https://auth.example.com/oauth/token",
      "authorizationUrl": "https://auth.example.com/oauth/authorize",
      "clientId": "{{ $credentials.clientId }}",
      "clientSecret": "{{ $credentials.clientSecret }}",
      "scope": "read write"
    }
  }
}
```

## HMAC Signature
```javascript
// Code node for HMAC signing
const crypto = require('crypto');
const timestamp = Date.now().toString();
const payload = JSON.stringify($json);
const signature = crypto
  .createHmac('sha256', $env.API_SECRET)
  .update(timestamp + payload)
  .digest('hex');

return {
  headers: {
    'X-Timestamp': timestamp,
    'X-Signature': signature
  },
  body: payload
};
```


instruction: How do I implement CI/CD pipelines for n8n workflows?

output:
# n8n CI/CD Pipeline Implementation

## Git-Backed Workflows

### 1. Export Workflows to Git
```bash
# Export all workflows
n8n export:workflow --all --output=./workflows/

# Export specific workflow
n8n export:workflow --id=123 --output=./workflows/my-workflow.json
```

### 2. GitHub Actions Pipeline
```yaml
# .github/workflows/n8n-deploy.yml
name: Deploy n8n Workflows

on:
  push:
    branches: [main]
    paths:
      - 'workflows/**'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Validate JSON
        run: |
          for file in workflows/*.json; do
            jq empty "$file" || exit 1
          done

      - name: Check for required nodes
        run: |
          for file in workflows/*.json; do
            if ! jq -e '.nodes | length > 0' "$file" > /dev/null; then
              echo "Error: $file has no nodes"
              exit 1
            fi
          done

  deploy:
    needs: validate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to n8n
        env:
          N8N_API_KEY: ${{ secrets.N8N_API_KEY }}
          N8N_HOST: ${{ secrets.N8N_HOST }}
        run: |
          for file in workflows/*.json; do
            WORKFLOW_ID=$(jq -r '.id' "$file")
            curl -X PUT "$N8N_HOST/api/v1/workflows/$WORKFLOW_ID" \
              -H "X-N8N-API-KEY: $N8N_API_KEY" \
              -H "Content-Type: application/json" \
              -d @"$file"
          done
```

## Testing Workflows
```yaml
  test:
    runs-on: ubuntu-latest
    services:
      n8n:
        image: n8nio/n8n
        ports:
          - 5678:5678
        env:
          N8N_BASIC_AUTH_ACTIVE: false
    steps:
      - name: Import and test workflow
        run: |
          # Import workflow
          curl -X POST "http://localhost:5678/api/v1/workflows" \
            -H "Content-Type: application/json" \
            -d @workflows/test-workflow.json

          # Execute and verify
          RESULT=$(curl -X POST "http://localhost:5678/webhook-test/test" \
            -H "Content-Type: application/json" \
            -d '{"test": true}')

          echo "$RESULT" | jq -e '.success == true'
```

## Environment Management
```yaml
# workflows/config/production.env
N8N_ENCRYPTION_KEY=prod-key-here
DATABASE_URL=postgresql://prod-db
WEBHOOK_URL=https://n8n.example.com

# workflows/config/staging.env
N8N_ENCRYPTION_KEY=staging-key
DATABASE_URL=postgresql://staging-db
WEBHOOK_URL=https://staging.n8n.example.com
```

topic: cicd

type: devops


instruction: How do I deploy n8n on Kubernetes with auto-scaling?

output:
# Kubernetes n8n Deployment with Auto-Scaling

## Deployment Manifest
```yaml
# n8n-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: n8n
  labels:
    app: n8n
spec:
  replicas: 2
  selector:
    matchLabels:
      app: n8n
  template:
    metadata:
      labels:
        app: n8n
    spec:
      containers:
      - name: n8n
        image: n8nio/n8n:latest
        ports:
        - containerPort: 5678
        env:
        - name: N8N_ENCRYPTION_KEY
          valueFrom:
            secretKeyRef:
              name: n8n-secrets
              key: encryption-key
        - name: DB_TYPE
          value: postgresdb
        - name: DB_POSTGRESDB_HOST
          value: postgres-service
        - name: EXECUTIONS_MODE
          value: queue
        - name: QUEUE_BULL_REDIS_HOST
          value: redis-service
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
        livenessProbe:
          httpGet:
            path: /healthz
            port: 5678
          initialDelaySeconds: 30
        readinessProbe:
          httpGet:
            path: /healthz
            port: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: n8n-service
spec:
  selector:
    app: n8n
  ports:
  - port: 80
    targetPort: 5678
  type: ClusterIP
```

## Horizontal Pod Autoscaler
```yaml
# n8n-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: n8n-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: n8n
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
      - type: Pods
        value: 2
        periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
```

## Queue Workers (Scaling Execution)
```yaml
# n8n-worker.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: n8n-worker
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: n8n-worker
        image: n8nio/n8n:latest
        command: ["n8n", "worker"]
        env:
        - name: EXECUTIONS_MODE
          value: queue
        - name: QUEUE_BULL_REDIS_HOST
          value: redis-service
```

## Ingress with SSL
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: n8n-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - n8n.example.com
    secretName: n8n-tls
  rules:
  - host: n8n.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: n8n-service
            port:
              number: 80
```

topic: kubernetes


instruction: How do I set up Docker Compose for n8n with PostgreSQL and Redis?

output:
# n8n Docker Compose Production Setup

## docker-compose.yml
```yaml
version: '3.8'

services:
  n8n:
    image: n8nio/n8n:latest
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=n8n.example.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - WEBHOOK_URL=https://n8n.example.com/
      # Database
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      # Queue mode for scaling
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      # Performance
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=168
      - GENERIC_TIMEZONE=America/New_York
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      - postgres
      - redis
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost:5678/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3

  n8n-worker:
    image: n8nio/n8n:latest
    restart: always
    command: worker
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    depends_on:
      - postgres
      - redis
      - n8n
    deploy:
      replicas: 2

  postgres:
    image: postgres:15-alpine
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: always
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  caddy:
    image: caddy:2-alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
    depends_on:
      - n8n

volumes:
  n8n_data:
  postgres_data:
  redis_data:
  caddy_data:
```

## Caddyfile (Reverse Proxy)
```
n8n.example.com {
    reverse_proxy n8n:5678
}
```

## .env file
```bash
N8N_ENCRYPTION_KEY=your-32-char-encryption-key-here
POSTGRES_PASSWORD=your-secure-password-here
```

## Start Commands
```bash
# Start all services
docker-compose up -d

# Scale workers
docker-compose up -d --scale n8n-worker=4

# View logs
docker-compose logs -f n8n

# Backup database
docker-compose exec postgres pg_dump -U n8n n8n > backup.sql
```

topic: docker


instruction: How do I build SMS marketing workflows with Twilio in n8n?

output:
# SMS Marketing Automation with Twilio

## Send SMS Campaign
```json
{
  "nodes": [
    {
      "name": "Get Subscribers",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "query": "SELECT phone, first_name, segment FROM subscribers WHERE sms_opt_in = true AND segment = '{{ $json.targetSegment }}'"
      }
    },
    {
      "name": "Personalize Message",
      "type": "n8n-nodes-base.set",
      "parameters": {
        "values": {
          "string": [{
            "name": "message",
            "value": "Hi {{ $json.first_name }}! {{ $json.campaignMessage }} Reply STOP to opt out."
          }]
        }
      }
    },
    {
      "name": "Send SMS",
      "type": "n8n-nodes-base.twilio",
      "parameters": {
        "operation": "send",
        "from": "={{ $env.TWILIO_PHONE }}",
        "to": "={{ $json.phone }}",
        "message": "={{ $json.message }}"
      }
    },
    {
      "name": "Log Delivery",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "operation": "insert",
        "table": "sms_log",
        "columns": "phone, message_sid, status, sent_at"
      }
    }
  ]
}
```

## Handle Inbound SMS (Opt-out)
```json
{
  "nodes": [
    {
      "name": "Twilio Webhook",
      "type": "n8n-nodes-base.webhook",
      "parameters": {"path": "twilio-inbound", "method": "POST"}
    },
    {
      "name": "Parse Message",
      "type": "n8n-nodes-base.set",
      "parameters": {
        "values": {
          "string": [
            {"name": "from", "value": "={{ $json.From }}"},
            {"name": "body", "value": "={{ $json.Body.toLowerCase().trim() }}"}
          ]
        }
      }
    },
    {
      "name": "Check Opt-Out",
      "type": "n8n-nodes-base.if",
      "parameters": {
        "conditions": {
          "string": [{
            "value1": "={{ $json.body }}",
            "operation": "contains",
            "value2": "stop"
          }]
        }
      }
    },
    {
      "name": "Update Opt-Out Status",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "query": "UPDATE subscribers SET sms_opt_in = false WHERE phone = '{{ $json.from }}'"
      }
    },
    {
      "name": "Confirm Opt-Out",
      "type": "n8n-nodes-base.twilio",
      "parameters": {
        "operation": "send",
        "to": "={{ $json.from }}",
        "message": "You've been unsubscribed. Reply START to resubscribe."
      }
    }
  ]
}
```

## SMS Drip Campaign
```javascript
// Day 0: Welcome SMS
// Day 3: Value SMS
// Day 7: Offer SMS

const campaigns = [
  { day: 0, message: "Welcome to {brand}! Reply HELP for support." },
  { day: 3, message: "Did you know? {tip}. Learn more: {link}" },
  { day: 7, message: "Special offer! Use code {code} for 20% off." }
];

const daysSinceSignup = Math.floor((Date.now() - new Date($json.signup_date)) / 86400000);
const campaign = campaigns.find(c => c.day === daysSinceSignup);

if (campaign) {
  return { send: true, message: campaign.message };
}
return { send: false };
```

type: workflow


instruction: How do I integrate WhatsApp Business API with n8n?

output:
# WhatsApp Business API Integration

## Send WhatsApp Message (via Twilio)
```json
{
  "name": "Send WhatsApp",
  "type": "n8n-nodes-base.twilio",
  "parameters": {
    "operation": "send",
    "from": "whatsapp:+14155238886",
    "to": "whatsapp:{{ $json.customerPhone }}",
    "message": "={{ $json.messageContent }}"
  }
}
```

## Send WhatsApp Template Message
```json
{
  "name": "Send Template",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "url": "https://graph.facebook.com/v18.0/{{ $env.WHATSAPP_PHONE_ID }}/messages",
    "method": "POST",
    "headers": {
      "Authorization": "Bearer {{ $env.WHATSAPP_TOKEN }}",
      "Content-Type": "application/json"
    },
    "body": {
      "messaging_product": "whatsapp",
      "to": "{{ $json.phone }}",
      "type": "template",
      "template": {
        "name": "order_confirmation",
        "language": {"code": "en"},
        "components": [
          {
            "type": "body",
            "parameters": [
              {"type": "text", "text": "{{ $json.customerName }}"},
              {"type": "text", "text": "{{ $json.orderNumber }}"}
            ]
          }
        ]
      }
    }
  }
}
```

## WhatsApp Webhook Handler
```json
{
  "nodes": [
    {
      "name": "WhatsApp Webhook",
      "type": "n8n-nodes-base.webhook",
      "parameters": {"path": "whatsapp", "method": "POST"}
    },
    {
      "name": "Extract Message",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const entry = $json.entry?.[0];\nconst change = entry?.changes?.[0];\nconst message = change?.value?.messages?.[0];\n\nif (!message) return { type: 'status_update' };\n\nreturn {\n  from: message.from,\n  type: message.type,\n  text: message.text?.body || '',\n  timestamp: message.timestamp\n};"
      }
    },
    {
      "name": "Route by Type",
      "type": "n8n-nodes-base.switch",
      "parameters": {
        "rules": [
          {"value": "text"},
          {"value": "image"},
          {"value": "location"}
        ]
      }
    },
    {
      "name": "Process Text",
      "type": "n8n-nodes-base.openAi",
      "parameters": {
        "prompt": "Customer message: {{ $json.text }}\n\nGenerate a helpful response."
      }
    },
    {
      "name": "Reply",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "url": "https://graph.facebook.com/v18.0/{{ $env.WHATSAPP_PHONE_ID }}/messages",
        "method": "POST",
        "body": {
          "messaging_product": "whatsapp",
          "to": "{{ $json.from }}",
          "type": "text",
          "text": {"body": "{{ $json.response }}"}
        }
      }
    }
  ]
}
```

## Multi-Channel Router
```javascript
// Route message to best channel
const customer = $json.customer;
const channelPriority = ['whatsapp', 'sms', 'email'];

for (const channel of channelPriority) {
  if (channel === 'whatsapp' && customer.whatsapp_opt_in) {
    return { channel: 'whatsapp', to: `whatsapp:${customer.phone}` };
  }
  if (channel === 'sms' && customer.sms_opt_in) {
    return { channel: 'sms', to: customer.phone };
  }
  if (channel === 'email' && customer.email_opt_in) {
    return { channel: 'email', to: customer.email };
  }
}
return { channel: 'none', reason: 'No opted-in channel' };
```

topic: whatsapp


instruction: How do I build an omnichannel notification system in n8n?

output:
# Omnichannel Notification System

## Architecture
```
Event → Determine Best Channel → Route → Send → Log → Track Delivery
```

## Main Workflow
```json
{
  "nodes": [
    {
      "name": "Notification Trigger",
      "type": "n8n-nodes-base.webhook",
      "parameters": {"path": "notify"}
    },
    {
      "name": "Get User Preferences",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "query": "SELECT * FROM user_preferences WHERE user_id = '{{ $json.userId }}'"
      }
    },
    {
      "name": "Select Channel",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const prefs = $json;\nconst priority = $json.priority || 'normal';\n\n// Urgent: Try all channels\nif (priority === 'urgent') {\n  return { channels: ['push', 'sms', 'email'] };\n}\n\n// Normal: Use preferred channel\nconst preferred = prefs.preferred_channel || 'email';\nreturn { channels: [preferred] };"
      }
    },
    {
      "name": "Split Channels",
      "type": "n8n-nodes-base.splitInBatches",
      "parameters": {"batchSize": 1}
    },
    {
      "name": "Route by Channel",
      "type": "n8n-nodes-base.switch",
      "parameters": {
        "rules": [
          {"value": "email"},
          {"value": "sms"},
          {"value": "push"},
          {"value": "whatsapp"},
          {"value": "slack"}
        ]
      }
    }
  ]
}
```

## Channel Implementations

### Email (SendGrid)
```json
{
  "name": "Send Email",
  "type": "n8n-nodes-base.sendGrid",
  "parameters": {
    "to": "={{ $json.email }}",
    "subject": "={{ $json.subject }}",
    "html": "={{ $json.htmlContent }}"
  }
}
```

### SMS (Twilio)
```json
{
  "name": "Send SMS",
  "type": "n8n-nodes-base.twilio",
  "parameters": {
    "to": "={{ $json.phone }}",
    "message": "={{ $json.smsContent }}"
  }
}
```

### Push (OneSignal)
```json
{
  "name": "Send Push",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "url": "https://onesignal.com/api/v1/notifications",
    "method": "POST",
    "headers": {"Authorization": "Basic {{ $env.ONESIGNAL_KEY }}"},
    "body": {
      "app_id": "{{ $env.ONESIGNAL_APP }}",
      "include_player_ids": ["{{ $json.pushToken }}"],
      "contents": {"en": "{{ $json.pushContent }}"}
    }
  }
}
```

## Delivery Tracking
```javascript
// Log all notification attempts
await db.insert('notification_log', {
  user_id: $json.userId,
  channel: $json.channel,
  message_id: $json.messageId,
  status: $json.deliveryStatus,
  sent_at: new Date(),
  metadata: JSON.stringify($json.metadata)
});

// Update user's last contact timestamp
await db.update('users')
  .set({ last_contacted: new Date() })
  .where('id', $json.userId);
```


instruction: How do I integrate Airbyte with n8n for ETL pipelines?

output:
# Airbyte + n8n ETL Integration

## Trigger Airbyte Sync
```json
{
  "name": "Trigger Airbyte Sync",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "url": "http://airbyte:8000/api/v1/connections/sync",
    "method": "POST",
    "headers": {
      "Authorization": "Basic {{ Buffer.from('airbyte:password').toString('base64') }}"
    },
    "body": {
      "connectionId": "{{ $json.connectionId }}"
    }
  }
}
```

## Monitor Sync Status
```json
{
  "nodes": [
    {
      "name": "Trigger Sync",
      "type": "n8n-nodes-base.httpRequest"
    },
    {
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "parameters": {"resume": "timeInterval", "interval": 30}
    },
    {
      "name": "Check Status",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "url": "http://airbyte:8000/api/v1/jobs/get",
        "body": {"id": "{{ $json.job.id }}"}
      }
    },
    {
      "name": "Is Complete?",
      "type": "n8n-nodes-base.if",
      "parameters": {
        "conditions": {
          "string": [{
            "value1": "={{ $json.job.status }}",
            "value2": "succeeded"
          }]
        }
      }
    },
    {
      "name": "Loop Back",
      "type": "n8n-nodes-base.noOp"
    }
  ]
}
```

## Post-Sync Processing
```javascript
// After Airbyte sync completes, process the data
const syncStats = $json.job.attempts[0].attempt.totalStats;

return {
  recordsSynced: syncStats.recordsEmitted,
  bytesEmitted: syncStats.bytesEmitted,
  status: 'completed',
  nextSteps: ['transform', 'validate', 'notify']
};
```

## Orchestration Pattern
```
Schedule → Trigger Airbyte → Wait for Completion →
Transform in n8n → Load to Destination → Notify Team
```

topic: airbyte

type: etl


instruction: How do I implement Change Data Capture with Debezium and n8n?

output:
# Debezium CDC with n8n

## Kafka Consumer for CDC Events
```json
{
  "nodes": [
    {
      "name": "Kafka Trigger",
      "type": "n8n-nodes-base.kafkaTrigger",
      "parameters": {
        "topic": "dbserver1.inventory.customers",
        "groupId": "n8n-cdc-consumer",
        "options": {
          "fromBeginning": false,
          "jsonParse": true
        }
      }
    },
    {
      "name": "Parse CDC Event",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const event = $json;\nreturn {\n  operation: event.op, // c=create, u=update, d=delete\n  before: event.before,\n  after: event.after,\n  source: {\n    table: event.source.table,\n    db: event.source.db,\n    ts_ms: event.ts_ms\n  }\n};"
      }
    },
    {
      "name": "Route by Operation",
      "type": "n8n-nodes-base.switch",
      "parameters": {
        "rules": [
          {"value": "c", "label": "Insert"},
          {"value": "u", "label": "Update"},
          {"value": "d", "label": "Delete"}
        ]
      }
    }
  ]
}
```

## Handle Insert Events
```javascript
// New customer created
const customer = $json.after;

// Sync to CRM
await triggerWorkflow('crm-sync', {
  action: 'create',
  data: customer
});

// Send welcome email
await triggerWorkflow('welcome-email', {
  email: customer.email,
  name: customer.name
});

return { processed: true, customerId: customer.id };
```

## Handle Update Events
```javascript
// Customer updated - detect what changed
const before = $json.before;
const after = $json.after;

const changes = {};
for (const key of Object.keys(after)) {
  if (before[key] !== after[key]) {
    changes[key] = { old: before[key], new: after[key] };
  }
}

// Special handling for email change
if (changes.email) {
  await triggerWorkflow('email-verification', {
    customerId: after.id,
    newEmail: after.email
  });
}

return { changes, customerId: after.id };
```

## Debezium Connector Config
```json
{
  "name": "postgres-connector",
  "config": {
    "connector.class": "io.debezium.connector.postgresql.PostgresConnector",
    "database.hostname": "postgres",
    "database.port": "5432",
    "database.user": "debezium",
    "database.password": "debezium",
    "database.dbname": "app",
    "database.server.name": "dbserver1",
    "table.include.list": "public.customers,public.orders",
    "plugin.name": "pgoutput",
    "slot.name": "debezium",
    "publication.name": "dbz_publication"
  }
}
```


instruction: How do I write automated tests for n8n workflows?

output:
# Automated Testing for n8n Workflows

## Test Framework Setup
```javascript
// tests/workflow-tests.js
const axios = require('axios');

const N8N_URL = process.env.N8N_URL || 'http://localhost:5678';
const API_KEY = process.env.N8N_API_KEY;

async function testWorkflow(workflowId, testData, expectedOutput) {
  // Execute workflow
  const response = await axios.post(
    `${N8N_URL}/api/v1/workflows/${workflowId}/execute`,
    { data: testData },
    { headers: { 'X-N8N-API-KEY': API_KEY } }
  );

  // Wait for completion
  const executionId = response.data.executionId;
  let execution;
  do {
    await new Promise(r => setTimeout(r, 1000));
    execution = await axios.get(
      `${N8N_URL}/api/v1/executions/${executionId}`,
      { headers: { 'X-N8N-API-KEY': API_KEY } }
    );
  } while (execution.data.status === 'running');

  // Validate output
  const output = execution.data.data.resultData.lastNodeExecutionStack;
  return validateOutput(output, expectedOutput);
}
```

## Test Cases
```javascript
describe('Lead Processing Workflow', () => {
  test('should score high-value lead correctly', async () => {
    const testData = {
      email: 'test@enterprise.com',
      company_size: 500,
      budget: 50000
    };

    const result = await testWorkflow('lead-scoring', testData);

    expect(result.score).toBeGreaterThan(70);
    expect(result.segment).toBe('enterprise');
  });

  test('should reject invalid email', async () => {
    const testData = {
      email: 'invalid-email',
      company_size: 10
    };

    const result = await testWorkflow('lead-scoring', testData);

    expect(result.error).toBe('Invalid email format');
  });

  test('should handle timeout gracefully', async () => {
    const testData = {
      email: 'slow@test.com',
      simulate_delay: true
    };

    const result = await testWorkflow('lead-scoring', testData, { timeout: 5000 });

    expect(result.fallback_used).toBe(true);
  });
});
```

## Webhook Testing
```javascript
async function testWebhook(webhookPath, payload, expectedStatus = 200) {
  const response = await axios.post(
    `${N8N_URL}/webhook/${webhookPath}`,
    payload,
    { validateStatus: () => true }
  );

  return {
    status: response.status,
    data: response.data,
    passed: response.status === expectedStatus
  };
}

// Test examples
await testWebhook('order-received', { orderId: '123', items: [] }, 400); // Should fail validation
await testWebhook('order-received', { orderId: '123', items: [{sku: 'A1', qty: 2}] }, 200);
```

## CI Integration
```yaml
# .github/workflows/test.yml
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      n8n:
        image: n8nio/n8n
        ports: ['5678:5678']
    steps:
      - uses: actions/checkout@v4
      - run: npm install
      - run: npm test
        env:
          N8N_URL: http://localhost:5678
```

topic: testing