Module 05 · business · beginner
Lesson 05 · Form to CRM Follow-up
Goal
Build the most requested small-business automation: a lead form that saves to a CRM, replies instantly, and follows up on its own. Speed to lead wins deals; this replies in seconds, every time.
Prerequisites
- Module 03 (Google Sheets credentials, Append or Update)
- Gmail credential (same Google Cloud OAuth client as Sheets, with the Gmail API enabled)
Concepts
- n8n Form Trigger: a hosted form, no website needed. The test URL is
/form-test/<path>; the production URL (published) is/form/<path>. - Field labels become keys: a field labeled
What do you need help with?arrives as$json['What do you need help with?']. Normalize them into clean keys right away. - Lead scoring: a simple rule (
budget === 'Over $5k'→high) is enough to start prioritizing. - Referencing earlier nodes: after the Sheets node,
$jsonis the sheet row. Use$('Normalize Lead').item.jsonto get the lead. - Wait node: pauses this execution (for minutes or days) and resumes it later. Waiting executions survive restarts.
Build it
Step 1: Form
n8n Form Trigger Contact Form:
- Title
Work with me, description of your choice - Fields: Name (required), Email (type Email, required), Company, What do you need help with? (Dropdown: Automation / AI agent / Integration / Something else, required), Budget (Dropdown: Under $1k / $1k-$5k / Over $5k, required), Details (Textarea)
- Options → Path:
work-with-me; Form Response → custom text "Thanks! Check your inbox…"
Step 2: Normalize and score
Edit Fields Normalize Lead:
name={{ $json['Name'].trim() }},first_name={{ $json['Name'].trim().split(' ')[0] }}email={{ $json['Email'].trim().toLowerCase() }}company={{ ($json['Company'] ?? '').trim() }}need={{ $json['What do you need help with?'] }},budget={{ $json['Budget'] }},details={{ $json['Details'] ?? '' }}priority={{ $json['Budget'] === 'Over $5k' ? 'high' : 'normal' }}status=new,submitted_at={{ $now.toISO() }}
Step 3: Save to the CRM sheet
Create a sheet with a CRM tab using the headers in assets/crm-template.csv. Google Sheets Save to CRM → Append or Update Row, match on email, map every column.
Step 4: Welcome email
Gmail Send Welcome Email → Send:
- To:
{{ $('Normalize Lead').item.json.email }} - Subject:
Got it, {{ $('Normalize Lead').item.json.first_name }}! Next steps for your … project - Email type HTML; message greets them by first name, mentions their need and company, and asks two questions that make the first call useful.
- Options → Append n8n Attribution off.
Step 5: Wait and follow up
Wait Wait 2 Days (After Time Interval, 2 days) → Gmail Send Follow-up with a short "does a 20-minute call work?" email.
Publish. Open http://localhost:5678/form/work-with-me and submit with your own email.
Test it
./test/test.sh
WITH_CREDS=1 TEST_EMAIL=you@example.com ./test/test.sh
Tip: while testing, set the Wait to 1 minute, then change it back to 2 days.
Common problems
$json.Nameis undefined: keys are the exact field labels, including spaces and?. Use bracket notation.- Form 404: the test URL (
/form-test/) only works after clicking Execute workflow;/form/only works when published. - Gmail 403 / insufficient scopes: enable the Gmail API in Google Cloud and reconnect the credential.
- Email shows raw HTML: Email Type is Text. Switch to HTML.
- Follow-up goes to someone who already replied: that's Exercise 1.