2026-01-10
Your first n8n workflow in 30 minutes: form → Google Sheet → Slack
Step-by-step: accept a lead via webhook, append a row in Google Sheets, notify the team in Slack. No invented ROI—only what to click and how to verify.
Problem you solve: someone submits a form on your site and you want a row in a spreadsheet and a Slack ping without manual copy-paste.
What you ship in ~30 minutes: an n8n workflow (self-hosted or cloud) that handles a POST, appends to Google Sheets, and posts to Slack.
How you know it works: you send a fake JSON with curl and see a new row plus a Slack message.
Make and Zapier can do the same with less wiring; n8n is used here because it is easy to reproduce for free (self-hosted) and the same flow maps 1:1 to the other tools (same credentials, different UI).
Prerequisites
- An n8n instance (n8n.io cloud or self-hosted).
- A Google Cloud project with Google Sheets API enabled and an OAuth client (type per n8n’s Google credential docs).
- Slack: an app with an Incoming Webhook to a test channel (or a bot with OAuth if you prefer).
Official n8n docs: Google Sheets, Slack, Webhook.
Step 1 — Inbound webhook
- Create a new workflow.
- Add a Webhook node, method
POST, path e.g.lead-ingest. - Activate the workflow and copy the Production URL (use Production if external forms will call it).
- Optional: set Response Mode to
Using Respond to Webhookand add a Respond to Webhook node at the end returning{ "ok": true }.
Example minimal payload:
{
"email": "lead@example.com",
"name": "Jane Doe",
"message": "I need a quote"
}
Step 2 — Google Sheet
- Create a sheet with headers in row 1:
timestamp,email,name,message. - Add Google Sheets → Append row.
- Connect OAuth credentials and pick the document + sheet tab.
- Map fields from the Webhook output, e.g.
{{ $json.body.email }}(exact expressions depend on whether you normalize with a Set node first).
Tip: add a Set node right after the Webhook with fixed keys email, name, message so a client schema change does not break the sheet mapping.
Step 3 — Slack
- Slack node → Post Message with OAuth or HTTP Request to the Incoming Webhook URL with JSON
{"text": "..."}. - Message body like:
New lead: {{ $json.email }} — {{ $json.message }}.
Step 4 — Verify with curl
curl -sS -X POST 'https://<your-n8n>/webhook/lead-ingest' \
-H 'Content-Type: application/json' \
-d '{"email":"test@example.com","name":"Test","message":"Hello"}'
Check: new row in the sheet, message in Slack. If it fails, open the execution in n8n and read the failing node (401 Google = credentials; 403 Slack = revoked webhook).
Zapier and Make (same problem, different UI)
- Zapier: “Webhooks by Zapier” (Catch Hook) → Google Sheets “Create Spreadsheet Row” → Slack “Send Channel Message”.
- Make: Webhook module → Google Sheets “Add a row” → Slack “Create a message”.
Logic is identical. Idempotent rows are not automatic—if you must not duplicate the same lead, add deduplication (e.g. email + day in a Code node or a small lookup table).
Limits to remember
- Provider rate limits (Slack, Google).
- Webhook hardening: in production add
Authorization: Bearer <token>and gate with an IF node before writing to the sheet. - Self-hosted n8n: you own upgrades and backups of the credentials database.
Summary
- Webhook POST → 2. (optional) Set to normalize JSON → 3. Append row → 4. Slack.
- Verify with
curl. - Rebuild the same graph in Make/Zapier if you prefer a managed SaaS.
You do not need a made-up “ROI percentage” to know this is valuable: if you currently copy leads manually and this flow removes that work, the problem is solved in a measurable way (manual time per lead → ~0 after deploy).