Back to blog

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

  1. Create a new workflow.
  2. Add a Webhook node, method POST, path e.g. lead-ingest.
  3. Activate the workflow and copy the Production URL (use Production if external forms will call it).
  4. Optional: set Response Mode to Using Respond to Webhook and 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

  1. Create a sheet with headers in row 1: timestamp, email, name, message.
  2. Add Google SheetsAppend row.
  3. Connect OAuth credentials and pick the document + sheet tab.
  4. 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

  1. Slack node → Post Message with OAuth or HTTP Request to the Incoming Webhook URL with JSON {"text": "..."}.
  2. 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

  1. Webhook POST → 2. (optional) Set to normalize JSON → 3. Append row → 4. Slack.
  2. Verify with curl.
  3. 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).

Want to ship ideas like these into your product?

Share context, constraints, and goals. We will tell you if partnering makes sense and how to frame the first step.