Lead Capture Mini
A free TinyFlowLab workflow. Every new inquiry from a Google Form lands in one clean “Leads” tab — checked for missing details, never added twice, with a next step, an owner and a due date. You still write every reply yourself.
Google Form → Validate details → "Leads" tab → Next step for a person
(trigger) (required fields, (status: New or (owner + due date;
duplicates) Needs review) nothing is sent)
- Time to set up: about 15–20 minutes the first time.
- You need: a Google account. Nothing else — no API key, no paid plan, no other tools.
- Cost: €0. Google Forms, Sheets and Apps Script are free within Google’s usage limits (see Limits).
- Version: 1.1 · November 2026 · changelog
What it does — and doesn’t
| It does | It doesn’t |
|---|---|
| Copy each new form response into a tidy Leads tab | Send emails, messages or auto-replies |
| Check that name, a valid-looking email and a message are present | Verify that an email address actually exists |
| Mark incomplete or suspicious requests Needs review, with the reason | Delete or edit your original form responses |
| Skip a submission it has already processed, even if you run it again | Merge two different requests from the same person (it flags them instead) |
| Add a next step, an owner and a due date (next business day) | Connect to a CRM, Slack or any outside service |
Files
Code.gs— the script you paste into your sheet.sample-responses.csv— 7 made-up inquiries for testing (2 valid, 5 that should go to review).
Step 1 — Create the form
-
Go to forms.google.com and create a blank form, e.g. “Work with me”.
-
Add these questions. Titles must match exactly (or change them in the script’s
CONFIGlater):Question title Type Required in the form? Your nameShort answer Yes Email addressShort answer (turn on Response validation → Text → Email) Yes Company or websiteShort answer No What do you need help with?Paragraph Yes Why check again in the script if the form already requires these? Because responses can also arrive by import or copy-paste, form settings get changed, and “asdf” passes a required field. The script is your safety net.
-
Open the Responses tab → Link to Sheets → Create a new spreadsheet. Google creates a sheet with a tab called Form Responses 1.
Step 2 — Add the script
- In the new spreadsheet: Extensions → Apps Script.
- Delete everything in the editor, paste the entire contents of
Code.gs, and click Save (💾). - Optional: in the
CONFIGblock at the top, setowner: 'Me'to your name or email. - Close the Apps Script tab and reload the spreadsheet. A Lead Capture menu appears after a few seconds.
Step 3 — Run setup and authorise
- Lead Capture → 1. Set up.
- Google asks you to authorise the script. You’ll see two permissions:
- View and manage spreadsheets that this application has been installed in — only this one sheet
(the script uses
@OnlyCurrentDoc). - Allow this application to run when you are not present — needed so the trigger runs on new responses.
- View and manage spreadsheets that this application has been installed in — only this one sheet
(the script uses
- Google may show “Google hasn’t verified this app.” That warning appears for any script that hasn’t gone
through Google’s review, including one you wrote or pasted yourself. Treat it seriously:
- Continue only if the project is the one you just created in your own spreadsheet and you have read
Code.gs. It is short, uses only the two permissions above, and contains noUrlFetchApp,MailApporGmailAppcalls (search for them with Ctrl/Cmd + F). - Never approve this screen for a script someone else shared with you, or if the permission list asks for more (Gmail, Drive, contacts, “connect to an external service”).
- If both checks pass, use Advanced → Go to (your project name) and approve.
- You can remove access any time at myaccount.google.com/permissions.
- Continue only if the project is the one you just created in your own spreadsheet and you have read
- A toast confirms: Setup done. A new Leads tab now exists.
Run Lead Capture → Check setup any time. It tells you whether every question title was found and whether the trigger is installed.
Step 4 — Test with sample data (recommended)
Use a copy of your sheet, or test before you share the form.
- Open the Form Responses 1 tab.
- File → Import → Upload
sample-responses.csv→ Import location: Append to current sheet → Separator type: Comma. Google adds the rows below your existing ones, including the CSV’s header row — the script recognises that row and ignores it, so you don’t need to delete it. Check that the columns line up with your headers (Timestamp, Your name, Email address, Company or website, What do you need help with?). If they don’t, undo, then paste the rows manually. - Lead Capture → Process all responses now.
Expected result in Leads (7 rows):
| Name | Status | Issues |
|---|---|---|
| Emma Clarke | New | — |
| Tom Becker | New | — |
| Lea Novak | Needs review | Missing email |
| Sam Okafor | Needs review | Email looks invalid |
| (blank) | Needs review | Missing name |
| Emma Clarke | Needs review | Email already sent a request |
| Priya Shah | Needs review | Message is very short |
- Run Process all responses now again. The toast says Added 0 lead(s), skipped 7 already processed — nothing is duplicated.
- Delete the sample rows from both tabs when you’re done.
Finally, submit your real form once yourself. Within a few seconds a new row should appear in Leads.
Step 5 — Use it every day
- Sort or filter Leads by Status. New rows are ready for a reply; Needs review rows say why.
- Reply from your own inbox, then tick Done.
- Change Owner or Due freely — the script never touches existing rows.
Columns in the Leads tab
| Column | Meaning |
|---|---|
| Submission ID | A fingerprint of timestamp + email + name (without a timestamp: email + name + message). Same response → same ID → never added twice. |
| Received | When the form was submitted |
| Name, Email, Company, Need | Cleaned-up answers (extra spaces removed, email lower-cased) |
| Status | New or Needs review |
| Issues | Why it needs review, e.g. Missing email; Message is very short |
| Next step | What a person should do next |
| Owner | Who handles it (CONFIG.owner) |
| Due | Next business day by default (CONFIG.replyWithinBusinessDays) |
| Done | Tick when handled |
Customising
All settings are in the CONFIG block at the top of Code.gs:
- Different question titles → change
fields. - Different required fields → edit
required(keys fromfields). - Allow shorter messages → lower
minNeedLength. - Don’t flag repeat emails → set
flagRepeatEmails: false. - Renamed responses tab → change
responsesSheet.
Privacy
- Everything stays in your Google account. The script makes no outside requests and sends nothing.
- You collect personal data (names, emails). Tell people why in your form description and how long you keep it, and delete old leads you no longer need. Depending on where you and your leads are, privacy laws such as the GDPR may apply.
- Sample data uses
.exampledomains and invented names. Don’t test with real people’s details. - Answers that start with
=,+,-or@are saved as plain text (with a leading'), so nobody can slip a spreadsheet formula into your Leads tab through the form.
Limits
- Google applies daily quotas to Apps Script (for example, total trigger runtime per day). One run of this script takes well under a second, so a small business is very unlikely to hit them — check the current numbers on Google’s quota page.
- The email check is a format check only.
[email protected]will pass. - Rows pasted without a timestamp are identified by email + name + message instead. Two identical pasted rows are therefore treated as one submission.
- Several responses arriving at the same moment are processed one after another (the script takes a lock), so they don’t overwrite each other.
- Two different people sharing one email address will be flagged as a repeat.
Troubleshooting
| Problem | Fix |
|---|---|
| No Lead Capture menu | Reload the spreadsheet and wait ~10 seconds. Check the script was saved in this sheet (Extensions → Apps Script). |
| No tab named “Form Responses 1” | Your responses tab has another name (e.g. in another language). Set CONFIG.responsesSheet to it. |
| Everything is Needs review — Missing … | A question title doesn’t match. Run Check setup; it lists the titles it couldn’t find. |
| New responses don’t appear | Run Check setup. If the trigger is missing, run Set up again. In Apps Script → Executions you can see errors. |
| Authorization required again | You edited the script in a way that needs a new permission. Run Set up again and approve. |
| I want to start over | Delete the Leads tab and run Process all responses now. |
Want more?
The paid Lead Intake Starter (in development) builds on this with smarter de-duplication, owner assignment, an exception queue and optional AI summaries. It isn’t for sale yet — join the list on tinyflowlab.com/free or follow @workflowin60s.
Made by TinyFlowLab. Free to use in your own business. Provided as-is, without warranty — test it with sample data before relying on it.