Powered by FusionSync AI
n8n Hub logon8nAutomationHub

AI form replies with human-in-the-loop: architecture for n8n, Slack, and Google Sheets

Design a form-to-reply pipeline in n8n: capture submissions, draft with an AI agent, route Slack approvals, send email only after sign-off, and track every row in Google Sheets.

n8n Hub Team7 min read

Inbound form submissions are easy to collect. They are much harder to answer well at speed without sending something you will regret.

The pattern teams ask for looks like this:

  1. A prospect fills out a form (website, Typeform, Tally, native n8n form, etc.).
  2. n8n captures the submission and normalizes the payload.
  3. An AI agent analyzes context and drafts a first reply (usually email, sometimes another channel).
  4. A human reviews the draft in Slack: approve, request changes, or reject.
  5. Only after approval does the workflow call a send tool (Gmail, Outlook, SendGrid, etc.).
  6. Google Sheets is the system of record: one row per submission, status, draft text, reviewer, timestamps, and send outcome.

This playbook is the architecture for that automation. The companion implementation guide (step-by-step, screenshots, importable workflow JSON) is published separately as implement-ai-form-replies-human-in-the-loop when the build assets are ready.

The problem#

Most teams sit in one of two bad places:

  • Manual replies: someone copies the form into a doc, writes a reply, sends it. Quality is high, speed is low, nothing is auditable at scale.
  • Fully automated replies: an LLM fires email the second the form lands. Speed is high, quality is inconsistent, and one hallucinated promise in an outbound email is an incident.

What you want is speed with a gate: AI does the first pass, humans keep authority over what leaves the building, and operations can see every state in a sheet the whole company already understands.

What good looks like#

After this workflow is live:

  • Every submission gets a structured row in Google Sheets within seconds.
  • The team sees a Slack message with summary, risk flags, and the proposed reply (not a wall of JSON).
  • Nothing customer-facing sends until a human taps Approve (or edits, then approves).
  • Rejected or "needs changes" items stay in the sheet with a clear status so nothing falls through a DM thread.
  • You can report on volume, approval time, and rejection reasons without exporting from five tools.

Target architecture#

1Form provider

Website, Typeform, Tally, or native n8n form submission.

webhook / trigger
2n8n

Normalize fields, enrich, write the first sheet row (status: received).

3AI agent

Analyze the submission, draft a first reply, update the row (status: draft_ready).

4Slack

Post an interactive review: approve, request changes, or reject.

human action
5n8n

Branch on the decision. Optional re-draft loop. Run the send tool only on approve.

  • Email / messaging API (send on approve only)
  • Google Sheets: status log (sent, rejected, needs_changes, failed)
Form to reply, with a human approval gate before anything sends.

Split this into at least two n8n workflows in production:

  1. Ingest + draft (triggered by form): fast path, no Slack buttons yet.
  2. Review + send (triggered by Slack interactivity or a sub-workflow): handles human decisions and side effects.

Keeping review logic separate stops a single giant workflow from becoming unmaintainable when Slack payload shapes change.

Components and why#

Form capture (trigger)#

Use whatever your site already runs. Common choices:

Sourcen8n entry
Native n8n Form TriggerBuilt-in, good for prototypes
Typeform / Tally / JotformWebhook trigger
Webflow / Framer / custom siteGeneric Webhook node

Normalize early with a Set or Code node so downstream steps always see the same field names: email, name, company, message, source, submitted_at.

n8n orchestration#

n8n is the state machine, not the brain. It should:

  • Validate required fields (do not LLM-analyze an empty email).
  • Write and update the Google Sheets row at each milestone.
  • Call the AI agent with a tight system prompt and structured output (JSON schema or a fixed set of fields).
  • Post to Slack with Block Kit and interactive buttons.
  • Execute the send node only on the approved branch.

AI agent (analysis + first reply)#

Treat the agent as a drafter, not an autonomous sender. Give it:

  • The normalized form fields.
  • Optional enrichment you trust (CRM account tier, past tickets) if you have it.
  • Brand voice rules (length, tone, what not to promise).
  • Output fields such as: summary, intent, risk_flags[], proposed_subject, proposed_body, confidence.

Run evaluation on real historical submissions before go-live. Keep temperature low for outbound copy.

Slack (human-in-the-loop)#

Post a channel message (or DM a queue owner) with:

  • One-line summary and intent.
  • Risk flags (pricing question, legal, angry tone).
  • Collapsible or threaded draft body.
  • Buttons: Approve, Request changes, Reject.

Approve should pass the sheet row id and the approved text hash so n8n can verify nothing changed between click and send.

Request changes should open a modal or thread prompt for edit notes, set sheet status to needs_changes, and optionally re-invoke the agent with the notes.

Reject sets status to rejected and stops the send branch. No email leaves.

Use Slack interactivity URL pointing at an n8n Webhook node. Verify Slack signing secret on every callback.

Send tool (post-approval only)#

On approve:

  1. Re-read the sheet row (source of truth for final body).
  2. Send via Gmail / Microsoft Outlook / SendGrid / etc.
  3. Update sheet: status=sent, sent_at, sent_by_slack_user, provider_message_id if available.

On failure, set status=send_failed and alert a different Slack channel so ops can retry manually.

Google Sheets (system of record)#

Sheets wins here because ops teams already live there, filters are free, and you get a cheap audit log without standing up a database on day one.

Suggested columns:

ColumnPurpose
submission_idStable id (UUID from n8n)
received_atISO timestamp
form_sourceWhich form or campaign
contact_emailReply-to
contact_nameDisplay name
companyOptional
raw_payloadJSON string for debugging
ai_summaryShort internal summary
ai_intente.g. pricing, support, partnership
risk_flagsComma-separated or JSON
draft_subjectProposed email subject
draft_bodyProposed email body
statusreceived · draft_ready · pending_review · needs_changes · approved · rejected · sent · send_failed
reviewer_slack_idWho approved or rejected
reviewed_atTimestamp
revision_notesFrom request changes flow
sent_atWhen email actually sent
error_messageLast failure reason

Lock the sheet tab permissions. n8n service account edits rows; humans do not hand-edit draft_body in production unless you explicitly allow it.

Status machine (sheet + Slack)#

Keep statuses boring and enumerable:

  1. received: row created, AI not finished.
  2. draft_ready: AI output written, Slack message posted (pending_review).
  3. needs_changes: human asked for edits; optional re-draft loop.
  4. approved: human approved; send branch running.
  5. rejected: closed, no send.
  6. sent: provider accepted the message.
  7. send_failed: requires ops follow-up.

Every transition should be triggered by n8n, not manual sheet edits, or you will lose sync with Slack button state.

Guardrails#

  • PII: minimize what you post in public Slack channels; use a private #inbound-review channel or DMs.
  • Idempotency: form providers retry webhooks. Dedupe on submission_id or provider event id before creating a second row.
  • Rate limits: batch Slack updates; do not post ten messages per field.
  • Prompt injection: form message body is untrusted input. Instruct the model to treat it as data, not instructions.
  • Compliance: if you are in regulated industries, log who approved what and keep the sheet as audit evidence.

When a deterministic workflow beats an agent#

Not every field needs an LLM. If the form only has "Schedule a demo" with four known answers, use a template node and skip the agent. Reserve the agent for free-text messages where intent actually varies.

Implementation guide (next)#

The installable post will cover:

  • Exact n8n nodes and credential setup.
  • Slack app scopes and interactivity URL.
  • Sheet template + column mapping in n8n.
  • Screenshot walkthrough of each branch.
  • Exportable workflow JSON to import into your instance.

Planned slug: implement-ai-form-replies-human-in-the-loop. Set companionSlug on both posts so readers can jump between architecture and build.