The problem
A portfolio form is only useful if messages reach me quickly while I travel. The obvious build, a webhook on my own server, would put a door to the lab on the internet. I wanted the speed without the exposure.
The design
The static host stores each submission. A workflow on my lab asks the host for new ones every five minutes. All traffic goes outward, so the lab needs no inbound webhook. The host token lives in n8n’s credential store and stays out of every export.
What each step guards against
| Step | Guards against |
|---|---|
| Poll, outbound only | An internet-facing endpoint on the lab |
| Honeypot field | Simple form bots; filled-in submissions are dropped silently |
| Email check | Junk that no one can reply to |
| Seen-ID store | The same lead arriving twice when a poll overlaps or retries |
| Length limits and control-character stripping | Oversized or malformed input reaching the phone or the log |
| At most 20 per poll | A spam burst flooding the chat room |
| Self-hosted chat for alerts | A third-party messenger holding enquirers’ names and emails |
| Credentials in n8n’s store | Tokens in code or exports; the published JSON has none |
How it was tested
Before hosting existed, I pointed the workflow at a local copy of the host’s submissions format with three entries (rerun on 29 October 2026 after the alert moved from a third-party messenger to my self-hosted chat): one real-looking lead, one spam entry with the honeypot filled, and one with an invalid email. I ran the schedule every minute for six runs.
| Run | What the execution log recorded |
|---|---|
| First poll | 3 submissions fetched; 1 passed validation, was posted to the Talk room (my phone gets the notification) and was appended to the log file |
| Next five polls | the same 3 submissions fetched again; 0 passed de-duplication, nothing sent |
All six runs finished with status “success”, and the log file holds exactly one line afterwards. The per-run counts are in the test record (sender details omitted). I set the workflow back to five minutes, pointed it at the real form endpoint, and left it inactive until the site goes live.
Known limit: each poll reads the newest 100 submissions. The host’s free plan accepts 100 a month, so a backlog larger than one page between polls cannot happen at this volume. A busier site would need paging through older submissions. The final test after deploy is a real form submission end to end.
