AI email first-responder for a renovation company — inquiry to reply draft + calendar event in ~9 seconds

Hi everyone,

I run a small automation practice in Japan. I built an AI email first-responder for a local renovation company use case and wanted to share the architecture and the four errors that cost me the most hours, since they seem to be the exact ones that bite people in the Questions category over and over.

The problem: small service businesses lose jobs to whoever replies first. A renovation inquiry that sits unanswered for half a day often just goes to a competitor.

What the workflow does the moment an inquiry email arrives:

  1. Classifies the inquiry (quote request / timeline question / pricing / complaint / other)
  2. Drafts a polite reply directly into the Gmail drafts folder
  3. Reads the requested date (“next Wednesday morning would be great”) and creates a tentative Google Calendar event
  4. Notifies the owner: “this came in, here’s what I’m about to say”

Measured end to end — from the email landing in the inbox to draft + calendar event + notification — it takes 9.1 to 10.5 seconds across my test runs.

One design rule I refuse to break: the AI never sends anything. It stops at the draft; a human reads it and hits send. One mis-sent email to a real customer costs more trust than the automation ever saves.

The build

Gmail Trigger
  → HTTP Request (LLM: classify + draft reply, JSON output)
  → Code (parse / repair the JSON)
  → Gmail: create draft
  → IF requested date exists → Google Calendar: tentative event
  → Gmail: notify the owner

For the LLM I used Groq’s free tier through the plain OpenAI-compatible chat/completions endpoint via a generic HTTP Request node — no AI bill while prototyping, and swapping providers later is just a URL + model + key change.

The 4 errors that actually cost me hours

1. “not valid JSON” — the expression-mode trap. If the HTTP Request node’s JSON body contains expressions like {{ $json.text }}, the field must be in expression mode (the value has to start with =). If it isn’t, n8n treats your template as literal text and fails with not valid JSON — an error that points nowhere near the actual cause. If you generate workflow JSON programmatically: jsonBody: '=' + JSON.stringify(bodyTemplate). That single = was hours of my life.

2. The sender is [object Object]. The Gmail trigger doesn’t always give you the sender as a string — depending on settings, from arrives as a nested object. Pass it straight through and your reply draft is addressed to [object Object], or the node dies with input.split is not a function. Fix: normalize in a Code node before anything else touches it:

function asText(v) {
  if (typeof v === 'string') return v;
  if (v?.text) return v.text;
  if (v?.value?.[0]?.address) return v.value[0].address;
  if (v?.address) return v.address;
  return '';
}

Three seemingly unrelated bugs traced back to this one field.

3. Placeholder credentials break imports. If you share a workflow JSON that still contains credentials blocks with placeholder ids, the import produces confusing “broken credential” errors. Delete the credentials blocks from exported nodes entirely — the importer then shows a clean empty credential picker and “Sign in with Google” behaves normally.

4. LLMs don’t know what “next Wednesday” is. The model parsed date requests happily and then booked them wrong, because it has no idea what today is. Injecting Today is {{ (new Date()).toISOString().slice(0,10) }}. into the system prompt fixed most of it; embedding a 14-day date→weekday table in the prompt fixed the rest (weekday arithmetic is exactly what LLMs get confidently wrong). After that: zero weekday errors in my tests.

Honest status

The system works and the numbers above are real measurements, but it hasn’t made money yet — I’m still pitching it to local businesses. Sharing it here because the debugging lessons transfer to basically any Gmail + AI workflow.

If you want to try the core piece, I packaged the entry point — AI labels each incoming Gmail by priority, runs on Groq’s free tier, no card needed — as a free importable template with a setup guide covering the pitfalls above: n8n AI Inbox Sorter — Free AI Gmail Workflow (Import & Run) (also submitted to the n8n template library, currently in review — creator profile: aijidokalab).

Happy to answer questions about any part of the setup — or hear about a fifth error I haven’t met yet.

1 « J'aime »

Nice build. The draft-only boundary is the part that actually matters in production.

A few things I’d bolt on before I’d trust this with a real renovation inbox:

Make the calendar event explicitly tentative. Until the owner has approved the draft and you’ve checked the time against real availability, nothing should look confirmed to the customer.

Don’t let the model invent dates on its own. Have it pull the customer’s wording, then feed the workflow today’s date, timezone, business hours, and a short list of valid slots. Validate the chosen date before you create the tentative event. Relative dates are where these things go sideways while still sounding sure of themselves.

Use the Gmail message ID or thread ID as an idempotency key. Retries happen. You don’t want two calendar events and three drafts for the same enquiry.

Anything uncertain should land in a visible REVIEW queue — missing dates, complaints, low-confidence classifications, parse failures — with the original email, extracted fields, proposed reply, and why it failed. No silent fallbacks that eat the message.

Log the decision, not just the final draft: category, extracted date, validation result, workflow version, approval status. Six months later you’ll want to know why that reply got proposed.

Short version: automate prep and routing hard, keep customer-facing sends and calendar commitments behind an explicit approval gate. Same model we use at BigLobster when we build auditable AI workflows for small businesses: How to Build an AI Agent for Your SMB Without Coding (2026 Guide) | BigLobster