Set it up
Step-by-step setup
Follow the steps in order. Each one ends with something you can check, so you know it worked before moving on.
#Copy the Google Sheet
Open the sample Sheet that came with the kit → File → Make a copy. No sample link? Create a new Sheet, then File → Import → Upload
sample/leads-sample.csvinto a tab named exactlyLeads.Make sure there's a second tab named
Error Logwith this header row:logged_at, workflow, execution_id, execution_url, failed_node, error_message, lead_idKeep row 1 of
Leadsexactly as it is (19 headers). Extra columns to the right are fine; the workflow ignores them.Optional: select column G (phone) → Format → Number → Plain text, so numbers you type by hand keep their
+.Copy the Sheet ID from the address bar. It's the long part between
/d/and/edit, for example1AbC…xyz.When you go live, delete the sample rows and keep the header row.
Leads and Error Log, with headers in row 1.#Import the workflows
- In n8n, go to Overview → Create workflow, then top-right ⋯ → Import from File… and pick
lead-capture-error-handler.json. Click Save. - Do the same for
lead-capture-alerts.json→ Save. - Optional, for the hosted form: do the same for
lead-capture-demo-form.json→ Save.
They import unpublished, and nodes that need a credential show a warning badge. That's expected; you'll fix the badges in the next steps.
#Fill in the Config node
Open the Config node in the main workflow. It's the only node you need to edit. Change at least these fields:
| Field | Example | Notes |
|---|---|---|
business_name |
Santos Family Dental |
Used in the email and the alerts |
sheet_id |
1AbC…xyz |
From step 1 |
ack_from_name |
Santos Family Dental |
Sender name on the thank-you email |
ack_signature |
— Dr. Santos & team |
Last line of the email |
n8n_base_url |
https://n8n.yourdomain.com |
Builds execution links in the Error Log |
alert_telegram / alert_slack / alert_discord |
true / false / false |
Any combination |
telegram_chat_id |
-1001234567890 |
From step 5 |
slack_channel_id |
C07ABCDEF12 |
From step 6 |
discord_webhook_url |
https://discord.com/api/webhooks/… |
Only if alert_discord = true |
default_country_code |
63 |
Turns 0917… into +63917… |
timezone |
Asia/Manila |
Time zone for Sheet timestamps |
Then open Error Config in the error-handler workflow and set the same sheet_id, business_name and telegram_chat_id.
Every other field (spam rules, email wording, duplicate behavior) is listed in the node reference.
#Connect Google Sheets and Gmail
The workflow uses two n8n credentials: Google Sheets OAuth2 API and Gmail OAuth2 API. Create each once under Credentials → Add credential.
#On n8n Cloud
Open each credential → Sign in with Google → choose the account that owns the Sheet → allow access. Done; skip to using the credentials.
#On self-hosted n8n (one time per n8n instance)
Self-hosted n8n needs its own Google Cloud OAuth client. This takes about 10 minutes.
- Open the Google Cloud console and create a project, for example
n8n-leads. - Go to APIs & Services → Library and enable Google Sheets API, Google Drive API and Gmail API.
- Go to Google Auth Platform (labelled OAuth consent screen in older consoles) → Get started. Enter an app name and your support email, choose External as the audience, add your contact email, and create it.
- Under Audience → Test users, add the Google account you'll sign in with.
- In n8n, create the Google Sheets OAuth2 API credential and copy the OAuth Redirect URL it shows. It looks like
https://n8n.yourdomain.com/rest/oauth2-credential/callback. - Back in Google Cloud: Clients → Create client → Web application. Under Authorized redirect URIs, paste the n8n redirect URL. Create it, then copy the Client ID and Client secret.
- In n8n, paste the Client ID and secret into the credential → Sign in with Google → allow access.
- Create the Gmail OAuth2 API credential the same way. You can reuse the same Client ID and secret.
Official n8n guide: Google OAuth2 single service.
#Use the credentials on the nodes
Open each node with a warning badge and pick the credential:
| Credential | Nodes |
|---|---|
| Google Sheets | Read Existing Leads, Update Lead Row, Append Lead Row, Log Notification Failure, and Log Error to Sheet in the error handler |
| Gmail | Gmail: Acknowledge Lead |
#Set up Telegram alerts
In Telegram, open a chat with @BotFather → send
/newbot→ pick a name and username → copy the token (looks like123456:ABC…).In n8n, create a Telegram API credential and paste the token. Select it on Telegram: Alert Team and, in the error handler, Telegram: Error Alert.
Add the bot to your team group. Then send a message in the group that mentions it, such as
/start@YourLeadsBot. (Bots in groups only see commands and mentions by default.)Open this address in your browser, with your token in place of
<TOKEN>:https://api.telegram.org/bot<TOKEN>/getUpdatesFind
"chat":{"id":-100…in the reply and copy the number, including the minus sign. Paste it intotelegram_chat_idin Config and Error Config.
Docs: Telegram credentials in n8n.
#Add Slack or Discord (optional)
#Slack
- Go to api.slack.com/apps → Create New App → From scratch.
- OAuth & Permissions → Bot Token Scopes: add
chat:write. Addchannels:readtoo if you want n8n's channel picker. - Install to Workspace → copy the Bot User OAuth Token (
xoxb-…) into an n8n Slack API credential. Select it on Slack: Alert Team. - In the Slack channel, type
/invite @YourApp. - Get the channel ID: click the channel name → the ID is at the bottom of the details (starts with
C). Paste it intoslack_channel_idand setalert_slack = true.
Docs: Slack credentials in n8n.
#Discord (no credential needed)
- In Discord: channel → Edit Channel → Integrations → Webhooks → New Webhook → Copy Webhook URL.
- Paste it into
discord_webhook_urland setalert_discord = true.
Treat the webhook URL like a password: anyone who has it can post to your channel.
#Turn off channels you don't use
If you don't use a channel, for example Slack, do both of these:
- Set its toggle in Config to
false(alert_slack = false). - Either add its credential anyway, or deactivate the node: select Slack: Alert Team and press
D, or right-click → Deactivate.
Otherwise n8n shows a red missing-credential badge on the node, which looks broken to a client even though the workflow runs. In our live demo, Slack: Alert Team is deactivated.
#Publish and connect the error handler
- Open Lead Capture → Error Handler and click Publish.
- Open the main workflow → ⋯ → Settings → Error Workflow → choose Lead Capture → Error Handler → Save.
The imported file has a placeholder for this setting, so n8n shows no error workflow selected until you pick one. Picking it in Settings replaces the placeholder.
#Connect the Demo Form (optional)
Skip this if every lead comes from your own website.
- Open Lead Capture → Demo Form → node Save Lead (run main workflow).
- Set Source to Database, then Workflow → From list → Lead Capture → Sheet + Alerts. You can also choose By ID and paste the main workflow's ID, which is the part after
/workflow/in its address. - Leave Mode on Run once with all items and Wait For Sub-Workflow Completion on. Both are already set.
- Save. To try it, click Execute workflow in the Demo Form workflow and fill in the popup form.
- Publish the Demo Form workflow to get the public address:
https://YOUR-N8N-DOMAIN/form/lead-capture-demo. - To change the wording, edit the Demo Lead Form node (title and fields) and the Thank-You Page and Error Page nodes.
The main workflow doesn't need to be published for the Demo Form: Execute Workflow runs its saved version. We confirmed this on n8n 2.47.3.
#Test, then publish
- In the main workflow, click Execute workflow. It now waits for one test request.
- Send the sample request from Test and go live to the test address,
/webhook-test/lead-capture. - Check all three: a new row in
Leads, a thank-you email (use your own address while testing), and an alert in your team chat. - Click Execute workflow again and send the same request. The row is updated, not duplicated.
- Click Publish on the main workflow.
Publishing is only needed for the public website address, /webhook/lead-capture. The Demo Form works without it.
#Point your website at it
Use the production address on your live site:
https://YOUR-N8N-DOMAIN/webhook/lead-captureConnect your website has copy-ready HTML and JavaScript forms plus settings for WordPress, Webflow and others. If you set up the Demo Form, you can also share its link, adding UTM tags to see which link brought each lead:
https://YOUR-N8N-DOMAIN/form/lead-capture-demo?utm_source=facebook