🏠 Home / Hub

n8n 08 — Automation Capstone

Put it all together: build a complete lead capture pipeline — from form submission to CRM entry, welcome email, Slack notification, and dashboard row.

1. Capstone Project Overview

Goal: When a visitor fills out a contact form on your website:

  1. Receive the form data via Webhook
  2. Validate & normalize the data
  3. Append a row to Google Sheets (your CRM)
  4. Send a personalized welcome email via Gmail
  5. Post a Slack notification to the sales channel
  6. Respond 200 OK to the form submission

2. Workflow Design Diagram

  [Website Form]
       |
       | POST /webhook/lead-capture
       v
  [1] Webhook Trigger
       |
       v
  [2] Code — Validate & Transform
       |
       +---(invalid)---► [Respond 400 Bad Request]
       |
       v (valid)
  [3] Google Sheets — Append Row
       |
       v
  [4] Gmail — Send Welcome Email
       |
       v
  [5] Slack — Notify Sales Channel
       |
       v
  [6] Respond to Webhook — 200 OK

3. Node-by-Node Setup

Node 1: Webhook Trigger

Node type: Webhook
HTTP Method: POST
Path: lead-capture
Authentication: Header Auth
  Header Name: X-Form-Secret
  Header Value: my-form-secret-2024
Response Mode: Using Respond to Webhook node

Node 2: Code — Validate & Transform

// Run Once for All Items
const body = $input.first().json.body;

// Validate required fields
const required = ['name', 'email', 'message'];
for (const field of required) {
  if (!body[field] || body[field].trim() === '') {
    throw new Error(`Missing required field: ${field}`);
  }
}

// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(body.email)) {
  throw new Error('Invalid email format');
}

// Normalize & return
return [{
  json: {
    name: body.name.trim(),
    email: body.email.toLowerCase().trim(),
    message: body.message.trim(),
    phone: body.phone?.trim() || '',
    source: body.source || 'website',
    submittedAt: new Date().toISOString()
  }
}];

Node 3: Google Sheets — Append Row

Node type: Google Sheets
Operation: Append Row
Credential: My Google OAuth
Spreadsheet ID: (your sheet ID from URL)
Sheet Name: Leads
Columns:
  name        = {{ $json.name }}
  email       = {{ $json.email }}
  message     = {{ $json.message }}
  phone       = {{ $json.phone }}
  source      = {{ $json.source }}
  submitted   = {{ $json.submittedAt }}

Node 4: Gmail — Send Welcome Email

Node type: Gmail Operation: Send Email Credential: My Gmail OAuth To: {{ $json.email }} Subject: Thanks for reaching out, {{ $json.name }}! Body (HTML): <p>Hi {{ $json.name }},</p> <p>Thank you for contacting us! We received your message:</p> <blockquote>{{ $json.message }}</blockquote> <p>Our team will get back to you within 1 business day.</p> <p>Best regards,<br>The Team</p>

Node 5: Slack — Notify Sales Channel

Node type: Slack
Operation: Send a Message
Credential: My Slack App
Channel: #sales-leads
Message:
*New Lead Received* :tada:
*Name:* {{ $json.name }}
*Email:* {{ $json.email }}
*Source:* {{ $json.source }}
*Message:* {{ $json.message }}
_Received: {{ $now.toFormat('MMM d, yyyy HH:mm') }}_

Node 6: Respond to Webhook — 200 OK

Node type: Respond to Webhook
Response Code: 200
Response Body Type: JSON
Body:
{
  "success": true,
  "message": "Thank you! We will be in touch soon."
}

4. Testing End-to-End

  1. Open the workflow — click "Execute Workflow" to enter test mode
  2. Send a test POST using curl or Postman to the Test URL
  3. Inspect each node's output by clicking it after execution
  4. Check your Google Sheet — the row should appear
  5. Check your email inbox — welcome email should arrive
  6. Check the Slack channel — notification should appear
  7. The curl response should be {"success":true,"message":"..."}
curl -X POST https://your-n8n.com/webhook-test/lead-capture \
  -H "Content-Type: application/json" \
  -H "X-Form-Secret: my-form-secret-2024" \
  -d '{
    "name": "Test User",
    "email": "test@example.com",
    "message": "Hello, I am interested in your services.",
    "source": "website"
  }'

5. Workflow Versioning & Export

# Export workflow as JSON backup:
Workflow Editor → ⋮ menu → Download
# Saves a .json file you can commit to git

# Import a workflow:
n8n Home → Workflows → Import from File

# JSON structure overview:
{
  "name": "Lead Capture Pipeline",
  "nodes": [...],          // all node configs
  "connections": {...},    // how nodes connect
  "settings": {
    "errorWorkflow": "abc123",
    "timezone": "UTC"
  }
}

# Best practice: keep workflow JSON in a /n8n-workflows/ git repo
# Tag versions: v1.0-stable, v1.1-add-email, etc.

6. Scheduling & Production Activation

# Activate the workflow for production:
1. Save the workflow (Ctrl+S)
2. Toggle "Active" switch (top right) → ON
3. The production webhook URL is now live
4. Copy the Production URL (different from Test URL)
5. Update your website form action to the Production URL

# For scheduled workflows:
- Use Schedule Trigger instead of Webhook
- Set up the cron: 0 9 * * 1-5  (weekdays 9am)
- Activate the workflow
- Monitor first few executions in the Executions log

7. n8n Best Practices Checklist

n8n Course Complete!

You've covered all 8 lessons: intro, triggers, data & expressions, HTTP, credentials, error handling, AI agents, and the full capstone project.

You now have the foundation to automate almost any business workflow with n8n.

Back to n8n Index  |  Start AI Vibe Coding Course

📌 Study Checklist