Solutions Showcase: part 3 of 4

The complete text of the site in 4 parts. Parts:

Part 1 has the contents list of every section and case study.

Case studies in full

AI-Powered Construction Report SaaS (MeinBüromeister)

Turning construction-site voice notes, photos, and messages into structured reports through an automated AI-powered backend for German trade companies.

Section: Custom SaaS Platforms

Overview

MeinBüromeister is a B2B SaaS platform for German construction and trade companies. It allows workers to submit job updates through WhatsApp instead of preparing every report manually. The backend organizes incoming information, generates structured reports, and asks workers to review them before submission.

The Business Problem

Construction workers often send separate voice notes, photos, and text corrections from job sites. Office staff must identify the correct customer and project, organize materials and working hours, and format the information into professional reports. This creates repetitive administrative work and makes report preparation more time-consuming. The goal was to reduce this manual effort while keeping workers involved in reviewing and approving their reports.

The Solution

An n8n-based backend receives WhatsApp messages and groups related inputs into a single session. OpenAI Whisper transcribes voice recordings, while Claude AI extracts relevant report information into structured data. After the worker reviews and approves the report, the backend stores it in Supabase for delivery to the office dashboard. Supporting workflows automate customer onboarding, subscription management, team access, and error handling.

Project Snapshot

A production backend connecting WhatsApp messaging, AI-powered report extraction, worker approval, report storage, customer onboarding, and subscription lifecycle management.

How the System Works

System Architecture

The backend is organized around an n8n automation layer that sits between WhatsApp, the AI services used for transcription and extraction, and the Supabase/Stripe infrastructure that powers the office dashboard.

Supporting Integrations

Core Automation Workflows

The backend is built around interconnected n8n workflows that automate WhatsApp message handling, AI-powered report generation, customer onboarding, and subscription management. Each workflow handles a specific responsibility and integrates with the relevant APIs and backend services to support the complete reporting lifecycle. Some main automation workflows are shown below.

1. Core Onboarding & Workflow Management

This workflow handles company onboarding, setup-code verification, worker registration, subscription checks, report approval, project management, and notifications through interconnected n8n automation nodes.

Image: Core onboarding and workflow management: company setup, worker registration, subscription checks, report approval, project handling, and notifications across 15 interconnected automation groups.

2. AI-Powered Report Processing Workflow

This workflow processes WhatsApp messages using Whisper and Claude AI to extract structured report data, enrich customer and project details, validate reports, and handle database updates and notifications.

Image: AI-powered report processing: message intake, voice transcription, Claude-based data extraction, report generation, and save/notification handling.

Product Experience

Report inbox

Image: The office inbox organizes incoming reports by date, technician, customer/project, category, and status.

Customers and projects

Image: The project view groups customers and highlights open-report counts and recent work.

WhatsApp work history

Image: Workers review and approve each AI-generated report directly in WhatsApp before it goes to the office.

Image: Once approved, the report is saved, confirmed back to the worker on WhatsApp, and delivered to the office as a PDF.

Core Backend Capabilities

Results & Metrics

The project delivered five production workflows connecting WhatsApp, AI-powered report extraction, Supabase, and Stripe. Across five rounds of end-to-end testing, more than 25 bugs were identified and fixed, with over 30 test scenarios executed per round.

Technical Challenges & Solutions

During development and end-to-end testing, several integration and AI reliability issues required targeted solutions.

1. Stripe Subscription Data Handling

Challenge

The Stripe checkout event did not always contain all the subscription information required by the workflow.

Solution

Retrieved the complete subscription details directly through the Stripe API before continuing with subscription processing.

Outcome

Improved the reliability of subscription data handling.

2. Subscription Plan Mapping

Challenge

Mapping subscription plans based on payment amounts could lead to incorrect plan identification.

Solution

Used Stripe product IDs to identify plans instead of relying on monetary amounts.

Outcome

Made plan identification more consistent across subscription events.

3. AI Hallucination Control

Challenge

Claude AI could occasionally introduce materials or details that were not present in the worker’s input.

Solution

Refined the AI prompt with guardrails to discourage unsupported details and keep extraction grounded in the supplied information.

Outcome

Improved the consistency of structured report generation.

4. Supabase PATCH Response Handling

Challenge

Some Supabase PATCH operations returned empty responses, creating difficulties for downstream workflow nodes.

Solution

Explicitly referenced upstream node outputs where required instead of relying on the PATCH response to provide all subsequent data.

Outcome

Made downstream data handling more reliable.

5. End-to-End Integration Testing

Challenge

The system depended on multiple connected services, including WhatsApp, AI models, Supabase, and Stripe, making integration failures difficult to isolate.

Solution

Conducted five rounds of end-to-end testing, covering more than 30 scenarios per round, and fixed over 25 identified bugs.

Outcome

Improved integration reliability across the production workflows.

Key Takeaways & Future Development

Key Takeaways

Closing Summary

MeinBüromeister demonstrates how workflow automation, AI-powered information extraction, and integrated SaaS infrastructure can simplify construction reporting. The primary contribution was engineering the backend workflows and integrations that connect field communication with structured reports, subscription management, and the office dashboard.

Page · Plain text

WhatsApp Voice & Business Agent with n8n

Turning customer voice notes, photos and text messages on WhatsApp into instant, database-backed answers through an n8n workflow.

Section: n8n Automations, AI Agents for WhatsApp

Overview

This project is a WhatsApp business assistant for an online store. Customers write, speak or send a photo, and the workflow replies on WhatsApp with facts taken from the store’s Supabase product database, answering by voice when the customer used voice. It runs on n8n cloud with OpenAI models and replaces manual answering of repetitive product questions.

The business problem

Store owners answer the same questions all day: is this in stock, what does it cost, how long is delivery. Customers send these as voice notes, typed messages or screenshots of a product, so a simple keyword bot cannot read them. Slow replies lose sales, and a bot that guesses prices or stock damages trust.

The solution

An n8n workflow receives every WhatsApp message and routes it by type. Voice notes are transcribed, photos are described by a vision model, and text goes straight through. All three are normalized into one message and passed to an AI agent that must look up facts in Supabase before answering. The reply goes back as text, or as a voice note when the customer sent audio. Memory keyed on the customer’s phone number keeps the conversation connected.

Project snapshot

ItemDetail
Platformn8n cloud
ChannelWhatsApp Business Cloud API
Input typesVoice note, text, photo
AI modelsOpenAI transcription, GPT-4o-mini vision, GPT-4.1-mini agent, OpenAI speech
Knowledge baseSupabase vector store, products table
Workflow size21 nodes after cleanup (22 in the first export)

How the System Works

Every message passes through six stages, from the customer’s WhatsApp message to the reply, in a single n8n workflow.

StepProcess
1. WhatsApp inputThe customer sends a voice note, a text or a photo. The WhatsApp Trigger node receives it.
2. RoutingA Switch node checks the message type and sends it down the audio, text or image path.
3. Media handlingVoice notes and photos are downloaded through the WhatsApp media API. A voice note is transcribed and a photo is described by a vision model.
4. NormalizingEdit Fields nodes turn each path into the same two fields: the message text and the customer’s phone number as session id.
5. AI agentThe agent looks up facts in the Supabase products table, thinks again, and writes a short reply. It remembers the conversation by phone number.
6. ReplyIf the customer sent audio, the reply is converted to speech and sent as a voice note. Otherwise it is sent as text.

The workflow in n8n

Image: The top branch handles voice notes, the middle branch handles text, and the bottom branch handles photos. All three meet at the AI Agent, which has its model, memory, a Think tool and the Supabase Vector Store attached.

Supporting integrations

Core Workflow Configuration

The workflow is built from a handful of node groups. Each one has a single job and passes the same two fields forward, so the agent never needs to know how the message arrived.

Node groupConfiguration
WhatsApp TriggerListens for message updates from the WhatsApp Business Cloud API.
SwitchThree rules: audio (by mime type), text (by message type) and image (by mime type).
Download media + HTTP RequestGets the media URL from WhatsApp, then downloads the file with the WhatsApp credential. Used for both audio and images.
Transcribe a recordingOpenAI audio transcription of the downloaded voice note.
Analyze imageOpenAI vision (GPT-4o-mini) on the downloaded photo, returned as a text description.
Edit Fields (three)Set userMessage (the text, transcript or image description) and sessionId (the customer’s phone number).
AI AgentGPT-4.1-mini with a system prompt: short WhatsApp-style replies under 80 words, one emoji at most, never guess, answer only from the database, hand complex issues to human support.
Simple MemoryWindow memory keyed on the customer’s phone number.
Supabase Vector StoreRetrieve-as-tool on the products table, with OpenAI embeddings.
ThinkA reasoning tool the agent can use before answering.
IfChecks whether the original message was audio.
Generate audio + Send voice replyTurns the answer into speech and sends it back as an audio message.
Send messageSends the answer as a WhatsApp text message.

Product Experience

These three mockups show how the assistant is meant to feel on the customer’s phone, one for each input type. They are illustrative designs, not screenshots of live conversations. The status messages (“Transcribing…”, “Searching our catalog…”) and the Shopify order lookup and replacement order shown in scenarios 1 and 3 are not in the current workflow and belong to a planned extension.

Scenario 1: voice input

Image: The customer sends a voice note. The workflow transcribes it, the agent finds the answer, and the reply comes back as a voice note because the customer used voice.

Scenario 2: text input

Image: A typed question goes straight to the agent, which checks the product data and answers in two or three short lines, with a follow-up question to move the sale forward.

Scenario 3: image input

Image: A photo is described by the vision model, and that description is handled as the customer’s message. In the current workflow the agent matches it against the product table. Order lookup and replacement orders are future work.

Results & Metrics

The workflow is built and cleaned up, and no live customer data has been measured yet. The figures below describe what was delivered. Response time, accuracy and conversion numbers should be added after a pilot with real conversations.

MetricResult
Production workflows1 main agent workflow
n8n nodes21 after cleanup
Input types supported3: voice note, text, photo
Reply formats2: text and voice note
AI models used4: transcription, vision, agent, speech
Knowledge sourceSupabase products table, searched by the agent as a tool
Workflow defects fixed2 (placeholder Code node, wrong message type)
Live response time and accuracyNot measured yet

Technical Challenges & Solutions

Reviewing the exported workflow turned up problems that would have stopped it from working in production.

Voice reply could not be sent

Challenge

The voice path ended in a Code node that still held the placeholder YOUR_BASE64_STRING_HERE, and the send node used the document message type.

Solution

Removed the Code node, connected “Generate audio” directly to the send node, renamed it “Send voice reply”, and set its message type to audio with the customer’s number as recipient.

Outcome

The voice path is complete from the audio message to the voice reply.

Credentials missing after import

Challenge

After importing the workflow into a new n8n account, every WhatsApp, OpenAI and Supabase node showed a warning.

Solution

Reselect the credentials on each flagged node. For presentations, a demo copy with sample output pinned on the main-path nodes can be used.

Outcome

The nodes can be run green once credentials are set. A demo copy was prepared for the voice path.

AI answers must stay factual

Challenge

A sales assistant that invents prices or stock levels loses customer trust.

Solution

The system prompt requires the agent to retrieve facts from Supabase before answering, to ask when data is missing, and to hand complex issues to human support. Replies are capped at 80 words.

Outcome

Answers stay short and grounded in the product table.

Secrets inside workflow files

Challenge

A related Shopify workflow contains an access token written directly into its HTTP nodes.

Solution

Rotate the token and move it into an n8n credential before sharing or publishing that workflow.

Outcome

Open item, to be done by the store owner.

Key Takeaways & Future Development

Key takeaways

Future development

Page · Plain text

AI Lead Qualification & Sales Routing Agent

An end-to-end system for automated inbound lead scoring, enrichment, and real-time sales routing, powered by GPT-4.1 and n8n.

Section: Custom SaaS Platforms

Image: The lead form with a sample lead and the AI results card: score, HOT category, intent, budget, urgency, ICP match, summary and recommended action.

Why we built this

Most sales teams receive inbound leads from multiple sources (website contact forms, paid ad landing pages, partner referrals, and API integrations) and have no consistent, fast way to decide which ones deserve immediate attention.

The core problems the team was facing:

The goal was to build a fully automated intake-to-routing pipeline: AI scoring that runs in under two seconds, automatic company enrichment from the email domain, tiered alerts that reach the right person at the right time, and a central record of every lead with full analysis history.

What this system does

The system is composed of three interconnected layers: a lead intake API, a backend processing pipeline, and a real-time alerting engine, all orchestrated through n8n and a Node.js Express server.

Lead intake

AI scoring engine

Enrichment layer

Alerting and routing

CRM integration

Benefits

How it works (simplified)

System architecture (simplified)

Image: Architecture: four lead sources feed an Express backend with a five-step pipeline (validate, repeat detection, Clearbit enrichment, GPT-4.1 scoring, store), which routes to Slack alerts, an Airtable CRM and a nurture queue.

Ops-controlled settings (thresholds, routing rules, and CRM field mappings) are managed through environment configuration:

SettingWhere ConfiguredWhat It Controls
OPENAI_API_KEY.env fileEnables AI scoring via GPT-4.1
SLACK_WEBHOOK_URL.env fileDestination channel for HOT lead alerts
AIRTABLE_API_KEY + BASE_ID.env fileCRM destination for all processed leads
CLEARBIT_API_KEY.env fileEnables full company enrichment (optional)
Alert Toggle (per lead)Google Sheets control layerEnable or disable alerts per lead source
Score thresholdsPrompt config in aiService.jsAdjustable scoring bands per business context

Dashboard overview

Lead analysis results panel

The lead form renders a live results card immediately after submission, displaying the AI score, category, intent rating, budget signal, urgency level, ICP match, and a plain-English summary of why the lead scored the way it did, along with a specific recommended next action.

Renders in the browser within ~2 seconds of form submission

Slack alert panel

When a lead is classified as HOT, a Block Kit alert fires to the configured Slack channel. The message includes: lead name and company, email, phone, all five scoring dimensions, the AI-generated summary, recommended action, estimated deal size, and assigned sales team, formatted as a structured card with section dividers.

Delivered to the #sales-alerts channel within seconds of submission

Analytics dashboard

The /dashboard page provides a live operations view of all processed leads: total volume, HOT / WARM / COLD breakdown, average score, conversion rate, leads today, leads this week, top sources by volume, and a filterable lead feed. Data is drawn directly from the in-memory store and refreshes on page load.

Accessible at /dashboard: no login required in base configuration

Project evolution & key milestones

The system scope grew significantly from the initial lead scoring proof-of-concept. Key additions and refinements delivered across the project lifecycle:

Core scoring engine

Enrichment layer

Alerting system

Data and integration

Memory layer and analytics

Security and production hardening

Data flow architecture

How data moves through each stage and at what cadence, a key reference for ops teams integrating this system into existing stacks:

StageSourceDestinationTrigger
IntakeForm / API / n8n webhookExpress backendOn submission (real-time)
EnrichmentClearbit API / domain analysisLead record (in memory)Per lead, synchronous
AI ScoringOpenAI GPT-4.1Lead record (in memory)Per lead, synchronous
CRM PushIn-memory lead recordAirtable (18 fields)Per lead, async (non-blocking)
Slack AlertIn-memory lead recordSlack channel (HOT only)Per lead, async (non-blocking)
DashboardIn-memory lead storeBrowser via /dashboardOn page load / manual refresh

Note

The current storage layer uses an in-memory Map for speed and simplicity. For production deployments requiring persistence across restarts or horizontal scaling, this is designed to be swapped for PostgreSQL, Supabase, or MongoDB, the storage service exposes a clean interface with no direct database calls in the route layer.

Lead scoring & classification

The AI scoring engine evaluates every lead across five weighted dimensions and assigns a 0–100 score. Classification thresholds are:

CategoryScore RangeRouting ActionCriteria
HOT80 – 100Immediate Slack alert + rep assignmentClear budget, urgency signal, decision-maker identified, strong ICP match
WARM50 – 79Added to nurture email sequenceSome buying signals, partial ICP match, needs further qualification
COLD0 – 49Archived, no immediate actionNo clear intent, no budget signals, poor ICP fit or generic enquiry

The five scoring dimensions GPT-4.1 evaluates are:

Page · Plain text

HubSpot Industry Classifier with Gemini

Automatically sorting a backlog of HubSpot companies into industry groups with Google Gemini, and flagging the ones that need a human.

Section: n8n Automations, AI Agents

Overview

This project is an automation that fills in the Industry Group field on HubSpot company records. An n8n workflow runs every hour, takes companies from a HubSpot list, skips the ones that already have an industry group, asks Google Gemini to pick one group for each, and writes the answer back to HubSpot together with a confidence score and a one-line reason. Companies it cannot classify with confidence are marked Needs R&D for a person to review instead of being forced into a wrong category.

The business problem

A CRM is only useful for segmentation and reporting when every company has an industry. Filling the field by hand for a long backlog of companies is slow, and different people choose different categories for the same kind of business. Letting an AI write straight into the CRM brings its own risks: an invented category, a low-confidence guess recorded as fact, or the same company processed over and over.

The solution

The workflow reads the allowed Industry Group options directly from HubSpot, so the AI can only choose values that exist. Each company is handled one at a time. Gemini returns a single group, a confidence score and a reason in JSON, and a code node checks that the answer matches a real HubSpot option and clears a confidence threshold before anything is written. Anything that fails that check is labelled Needs R&D. A dry-run switch lets the team test the whole flow without changing any record.

Project snapshot

ItemDetail
Platformn8n
TriggerSchedule, every hour
CRMHubSpot (companies, a list of companies to process, the hs_industry_group property)
AI modelGoogle Gemini Flash, temperature 0.2, no web search
Batch sizeUp to 100 companies per run, one at a time
Confidence threshold0.6
Safety switchdryRun setting, off by default
Workflow size22 nodes
StatusActive

How the System Works

Each run follows the same six stages, from the schedule firing to a company updated in HubSpot.

StepProcess
1. Schedule and setupThe Schedule Trigger starts the run every hour. Two things happen in parallel: the workflow loads the allowed Industry Group options from HubSpot, and sets its configuration (companies per run, confidence threshold, dry-run flag and the HubSpot list id).
2. Collect the backlogThe workflow pages through the HubSpot list, 250 members at a time, until it has the configured maximum of 100 companies, then splits them into single items.
3. One company at a timeA loop takes each company and fetches its name, domain, website, additional domains and current industry group. Companies that already have an industry group are skipped.
4. Prepare and checkA code node cleans the domains. If a company has neither a domain nor a name, it is skipped because there is nothing to classify.
5. Gemini classificationGemini receives the name and domain with the list of allowed groups and the classification rules, and returns JSON with the industry, a confidence score and a reason.
6. Validate and writeA code node matches the answer to a real HubSpot option and applies the confidence gate. Unless dry run is on, the result is written to HubSpot, followed by a Wait node before the next company.

The workflow in n8n

Image: The two chains on the left prepare the run: the top one loads the valid industries, and the bottom one pages through the HubSpot list. The loop in the middle processes one company at a time through the Gemini step.

Supporting integrations

Core Workflow Configuration

The workflow is built from a handful of node groups. Settings that a person may want to change are kept together in one Init Search Config node.

Node groupConfiguration
Schedule TriggerRuns every hour.
Get Industry Group Options / Extract Valid IndustriesReads the hs_industry_group property definition from HubSpot. Builds the list of allowed labels, leaving out hidden options and Needs R&D (which is added back in the prompt), and keeps the raw options for matching later. Retries up to 3 times, 5 seconds apart.
Init Search ConfigSets maxCompanies 100, confidenceThreshold 0.6, dryRun false and listId 638.
Get List Memberships / Accumulate List Members / Has More List Pages?Pages through the HubSpot list 250 members at a time, stores them in workflow static data and stops at the company limit.
Collect List Members / Split Company IDsTrims the collected members to the limit, clears the stored data and splits them into one item per company.
Loop Companies (1 at a time)Processes one company per round. Its finished output goes to Backlog Run Complete, which records the completion time.
Get CompanyFetches name, domain, website, additional domains and current industry group from HubSpot. Retries up to 3 times.
IF Industry Group MissingContinues only when the industry group is empty, so companies already classified are never touched again.
Clean Domain (code)Strips protocol, www, paths and ports from the domain, website and additional domains, removes duplicates and builds a clean domain list.
IF SearchableContinues only if the company has at least one domain or a name.
Gemini Classify IndustryGemini Flash at temperature 0.2 with a detailed prompt: allowed groups, group definitions, classification rules and a JSON output format. Web search is off. Retries up to 5 times.
Match Industry Value (code)Reads the JSON from the model, caps the confidence at 0.65 when there is no domain, and matches the chosen group to a real HubSpot option by label, value or a normalized form.
Prepare Company Update (code)Applies the confidence gate and builds the HubSpot properties: the group (or Needs R&D), confidence, a reasoning text cleaned of stray characters and limited to 500 characters, a status and the check date.
IF Dry Run? / Dry Run - Skip UpdateIn dry run mode the update is skipped and the loop continues.
Update Company Industry GroupPATCH request to the HubSpot company record. Retries up to 3 times.
Wait1Pauses before the next company to stay within HubSpot rate limits.

Classification Rules and Scenarios

What the model is told

Gemini must choose exactly one group from the list HubSpot provides. The prompt defines each group (for example Manufacturing, eCommerce, Retail, Wholesale Distribution, SaaS, Development shop, IT / MSP, Low Voltage, Consulting, Finance, 3PL, Transportation, Energy Rebates and Self Storage) and sets rules for the edge cases:

Scenarios

These scenarios show how the workflow treats the main kinds of company. They are illustrative, derived from the prompt and code, and are not recordings of real HubSpot records.

ScenarioWhat arrivesWhat the workflow doesResult in HubSpot
1. Clearly known businessA company with a domain whose business model the model recognizes, for example a software platform.Gemini returns the matching group with confidence 0.80 or higher. The code matches it to a HubSpot option and it passes the 0.6 gate.Industry group set, status updated, confidence and reason saved.
2. Consumer brandA clothing or electronics brand selling to the public.Rule 3 sends it to Retail or eCommerce, never to Needs R&D.Retail or eCommerce group set.
3. Local consumer serviceA pizzeria, dental practice or salon.Excluded under rule 4 with confidence 1.0.Group set to Needs R&D for a human to see.
4. Unknown companyA company the model cannot identify.Returns Needs R&D with low confidence, so the gate fails.Group set to Needs R&D, status low_confidence or unmatched.
5. Name onlyA company with a name but no domain.Confidence is capped at 0.65 in code, so the model cannot be fully sure.Written only if it still clears 0.6, otherwise Needs R&D with status no_domain.
6. Already classifiedA company that already has an industry group.Stopped by IF Industry Group Missing, no model call.Unchanged.
7. Dry runAny company, with dryRun set to true.Everything runs except the HubSpot update.Nothing written.

Results & Metrics

The workflow is built and marked active. No run results were provided, so classification accuracy, the share of companies sent to Needs R&D and the time saved have not been measured.

MetricResult
Production workflows1
n8n nodes22
TriggerSchedule, every hour
Companies per runUp to 100, processed one at a time
Industry groupsRead live from HubSpot, so the model cannot pick a value that does not exist
Confidence gate0.6, with a 0.65 cap when a company has no domain
Fields written per companyIndustry group, confidence, reasoning, status and check date
Safety featuresDry-run switch, skip of already classified companies, Needs R&D fallback, retries on every network and model call
Accuracy, volume, time savedNot measured yet

Technical Challenges & Solutions

The model could invent a category

Challenge

A free-text answer such as “Software” or “Tech services” does not match any HubSpot option and would break the update or pollute the field.

Solution

The allowed groups are loaded from HubSpot on every run and given to the model to copy exactly. The answer is then matched to a real option by label, value or a normalized form that ignores case, punctuation and “&” versus “and”.

Outcome

Only values that exist in HubSpot can be written.

A weak guess recorded as fact

Challenge

A model will always give an answer, even when it knows nothing about the company.

Solution

The model must return a confidence score, name-only companies are capped at 0.65, and a code node only writes a group when the answer matches an option and reaches 0.6. Everything else becomes Needs R&D, and the confidence, reason, status and check date are saved on the record.

Outcome

Doubtful cases are visible to a person instead of hidden among correct ones.

Processing the same companies again

Challenge

An hourly schedule over the same list would classify the same companies on every run and waste model calls.

Solution

The workflow only continues when the industry group is empty, so each company is processed once.

Outcome

Each run moves on to the next unclassified companies.

Reading a long list from HubSpot

Challenge

The HubSpot list API returns 250 members per page, and the run must stop at a fixed number of companies.

Solution

A loop collects pages in workflow static data until the next page is missing or the limit is reached, then clears the data and splits the members into single items.

Outcome

Runs are bounded and predictable.

Testing without touching real data

Challenge

Changing the prompt or rules on live CRM records is risky.

Solution

A dryRun setting runs the whole flow, including the model call, but skips the HubSpot update.

Outcome

The prompt can be tuned and checked before records are changed.

Open items found in the export

Challenge

Three details in the workflow need checking. The Wait node after each update has an amount of 10 but no unit stored, and n8n’s default unit for that node is hours. The prompt refers to a Seamless Data field that no earlier node fills, so it is always “N/A”. The collected list members sit in static data, so a run that fails halfway through paging could leave old members behind for the next run.

Solution

Open the Wait node and set the unit to seconds. Either feed the Seamless description into the prompt or remove the line. Clear the stored list at the start of each run.

Outcome

Not done yet. These are the first improvements to make.

Key Takeaways & Future Development

Key takeaways

Future development

Page · Plain text

Support Email to ClickUp Ticket Automation

Turning every email sent to a shared support inbox into a correctly routed, duplicate-free ClickUp ticket through one n8n workflow.

Section: n8n Automations, ClickUp Setups

Overview

This project is a support-intake automation for RefureTech. Customers email the shared support address, and the n8n workflow reads each message, works out which client it belongs to from the sender’s email domain, and files it in ClickUp. It becomes a new ticket in that client’s support list, a ticket in a triage list when the client is unknown, or a comment when a ticket for the conversation already exists. Attachments and earlier messages in the thread travel with it.

The business problem

Support requests arrive as ordinary email. Copying them into a ticket system by hand is slow and easy to get wrong: the wrong client, a missed reply, an attachment left behind in the inbox. The work grows with every new client. Automating it is not simple either, because ClickUp has its own Email ClickApp that sends a confirmation to the customer and files later replies as comments. A naive automation creates duplicate tickets or, worse, turns its own confirmation emails into new tickets in an endless loop.

The solution

A single n8n workflow polls the support inbox every minute. It looks up the client list stored in ClickUp, matches the sender by domain, checks four different ways whether the conversation already has a ticket or is already managed by ClickUp, and only then creates a ticket or comment. It uses plain, explainable rules in code nodes rather than an AI model, so every decision can be traced to a header, a subject line or a ClickUp field. Wherever a step could fail, the workflow prefers a duplicate ticket over a lost customer email.

Project snapshot

Image: Project snapshot.

How the System Works

Every email passes through six stages, from arrival in the inbox to a ticket in ClickUp, inside one workflow.

StepProcess
1. Email inputThe Gmail Trigger polls the INBOX label every minute. The full message is fetched and its HTML body is converted to Markdown so it reads cleanly inside a ticket.
2. Client matchingThe workflow reads the client list from ClickUp, where each client has a Domain, a folder id and a support list id. A code node picks the customer contact from the To, Cc and From addresses and matches its domain (or a parent domain) to a client. Free-mail and internal domains are never mapped.
3. Duplicate checksThree lookups run: a ClickUp search by Gmail thread id, a ClickUp search by the thread ClickUp’s own confirmation email started, and a fetch of the full Gmail thread history.
4. DecisionRoute Decision labels the email new, default, comment or skip. Two guard nodes can still turn a write into a skip: one if ClickUp’s ticket id is at the end of the subject, one if the mail headers show a machine-generated reply.
5. Ticket actionA Switch creates a ticket in the client’s list, creates a ticket in the triage list, or adds a comment to the existing ticket. The description holds the new message plus earlier messages in the conversation.
6. Attachments, label, syncAttachments are downloaded and uploaded to the ticket, and the Gmail message is labelled as processed. For new tickets the workflow waits two minutes, finds ClickUp’s confirmation email and stores its thread id on the ticket so later replies are recognised.

The workflow in n8n

Image: The chain on the left reads the email, matches the client and checks for duplicates. The Switch in the middle sends each email to one of three ticket actions. Each action ends in its own attachment branch and a Gmail label step, and new tickets also pass through the wait and confirmation sync.

Supporting integrations

Core Workflow Configuration

The workflow is built from a handful of node groups. Each has a single job, and the routing decision is carried forward as one item holding the same fields (contact, domain, folder, list, thread id, reason, action), so the ticket nodes never need to know how the decision was reached.

Node groupConfiguration
Gmail TriggerPolls every minute, restricted to the INBOX label on purpose. ClickUp sends its confirmation as the support address, which leaves a copy in Sent. Polling Sent would turn that confirmation into a ticket and trigger another confirmation, forever.
Get HTML + MarkdownFetches the full message and converts the HTML body to Markdown. Retries up to 3 times, 2 seconds apart.
Get Support IDClickUp node that lists the client tasks. Each carries the custom fields Domain, folder_id and support_list_id.
Find ID from Domain (code)Builds a domain-to-client map, ignores free-mail and internal domains, records domain collisions, picks the customer contact (mapped client first, then any external address, then the sender), validates every address, fills up to 20 Cc fields and applies the one hard skip: the self-addressed ClickUp acknowledgment.
Find Existing Ticket / Find ClickUp Email ThreadTwo ClickUp API searches by custom field: the Gmail thread id, and the thread id of ClickUp’s own confirmation. If either call fails the workflow continues with no result, so a ticket is still created.
Get Thread HistoryGmail API call for every message in the conversation. Failure is non-fatal: the ticket is created with the newest email only.
Route Decision (code)Decides clickup_synced, comment, new or default, and assembles the ticket description with the earlier messages, capped at 60,000 characters.
ClickUp Already Owns This? (code)Skips when the subject ends with a ClickUp ticket id such as #RTS-1234, or the confirmation wording is found. Anchored to the end of the subject so a customer’s own mid-subject reference such as #PO-88231 still gets a ticket.
Machine Auto-Reply? (code)Skips out-of-office and bounce mail by reading headers (Auto-Submitted, X-Auto-Response-Suppress, Precedence, empty Return-Path), never the subject wording.
SwitchSix rules: new, default, comment, loop guard (skip), ClickUp synced (skip), auto-reply (skip). The fallback output goes to the triage list so an unexpected value cannot drop an email.
Create a task / Create Default TaskClickUp nodes that create the ticket with the Markdown description, customer contact, recipient, up to 20 Cc contacts and the Gmail thread id as custom fields. Tickets opened mid-chain are titled with an [Ongoing thread] prefix.
Add Comment to Existing TaskPosts the new email as a comment on the tracked ticket without notifying everyone.
Attachment branches (3 sets)Re-fetch the message with attachments, split them out, keep only files with a real file extension, upload them to the ticket and add the Gmail label. Emails without attachments still reach the label step.
Wait + confirmation syncWaits 2 minutes, re-reads the task for its custom id, searches Gmail for ClickUp’s confirmation and saves its thread id into the ticket so future replies are recognised.

Product Experience and Routing Scenarios

Every email the workflow has handled is marked with a Ticketed label in Gmail, so the team can see at a glance which messages already have a ticket or comment in ClickUp. Replies on the same conversation carry the label too.

Routing scenarios

These scenarios show how the workflow treats the main kinds of email. They are illustrative, derived from the workflow logic, and are not recordings of real customer emails.

ScenarioWhat arrivesWhat the workflow doesResult
1. Mapped client, new requestA first email from someone at a client whose domain is in the ClickUp client list.Matches the domain, finds no existing ticket, routes to the client’s folder and support list, uploads attachments, labels the email, then syncs ClickUp’s confirmation thread id after 2 minutes.New ticket in the client’s support list.
2. Unknown domainAn email from a domain that is not mapped, or with no usable contact address.Falls to the default branch. The ticket is still created, in the default triage list, with the sender as contact.New ticket in the triage list for a person to assign.
3. Reply on a tracked conversationA follow-up where a ticket already exists for the Gmail thread but ClickUp does not own the thread.Finds the ticket by the Gmail thread id custom field and posts the email as a comment, then handles any attachments.Comment and files added to the existing ticket.
4a. ClickUp-owned replyA customer reply whose subject ends with a ClickUp ticket id.Stops without writing. ClickUp’s Email ClickApp is already filing replies as comments, so acting would duplicate the ticket.Skipped, no duplicate.
4b. Out-of-office or bounceA vacation responder or delivery failure notice.Detected from mail headers and skipped. A colleague’s real reply on the same thread is not skipped, because headers are checked instead of subject words.Skipped, real replies kept.
4c. Our own confirmationThe ClickUp acknowledgment, sent from the support address back to the support address.Hard skip by the loop guard.Skipped, loop prevented.

Results & Metrics

The workflow is live and has run on the real support inbox. Business figures such as hours saved, tickets per week and routing accuracy have not been measured yet.

MetricResult
Production workflows1 main workflow, plus an error workflow attached in settings
n8n nodes38
TriggerGmail polling every minute, INBOX only
Routing outcomes6: new, default, comment, and three skip outcomes
Duplicate guards4 layers: Gmail thread id, ClickUp email thread id, ticket id in subject, confirmation wording
Failure handlingRetries up to 3 times, 2 seconds apart, on every network node. Lookups fail open, so an email becomes a ticket rather than being lost.
Reply channels coveredMapped client, unknown domain, existing thread, attachments

Execution history (29 Sep to 12 Oct 2026)

MetricResult
Executions retained in n8n11
Successful11 (100%)
Failed or crashed0
Run time9 runs took about 2 minutes (the path with the built-in 2-minute wait for ClickUp’s confirmation). 2 runs took about 4 seconds (paths without that wait).
Hours saved, accuracy, duplicate rateNot measured yet

The execution count reflects only the executions n8n still retains and is not a full volume figure. The link between run time and path is inferred from the workflow design.

Technical Challenges & Solutions

Most of the engineering effort went into edge cases around ClickUp’s own email feature and around real-world email, where a simple “new email creates ticket” flow breaks quickly.

The workflow could answer itself forever

Challenge

ClickUp sends its confirmation email from the support address, so a copy lands in Sent. If the workflow read Sent, that confirmation would become a ticket, which triggers another confirmation, and so on.

Solution

The trigger watches INBOX only, and a loop guard in code skips any email sent from the support address with the support address in To or Cc. It is the only unconditional skip.

Outcome

The loop is closed twice, at the trigger and in the logic.

Duplicate tickets next to ClickUp’s Email ClickApp

Challenge

Once a ticket exists, ClickUp already files replies as comments and sends its own acknowledgment. Creating another ticket from the same reply duplicates work and makes ClickUp send the customer a second acknowledgment.

Solution

Four independent checks decide whether ClickUp owns the conversation: a stored ClickUp email thread id, the ticket id at the end of the subject, the confirmation wording in the thread, and the Gmail thread id on an existing ticket. The subject check is the most dependable, because older tickets lack the stored thread id and the confirmation wording can change.

Outcome

Replies on ClickUp-managed conversations are skipped and n8n stays out of the way.

Out-of-office mail versus a colleague covering for someone

Challenge

An auto-reply sets the subject to “Out of Office Re: …”. A colleague who replies on the same thread keeps that subject, so matching subject words would silently drop a genuine customer email.

Solution

The check reads mail headers that no human mail client sets (Auto-Submitted, X-Auto-Response-Suppress, Precedence, empty Return-Path). If the headers cannot be matched confidently to the right message, nothing is skipped.

Outcome

Machine mail is filtered out, and real replies with the same subject still become tickets.

A duplicate is acceptable, a lost email is not

Challenge

Lookups against ClickUp and Gmail can fail, and an email that stops the workflow is a customer who never gets answered.

Solution

The ticket-search and thread-history calls retry three times and then continue with no result. Missing results default to creating a ticket, the Switch fallback sends unknown outcomes to the triage list, and the split-out steps continue on error so every email still reaches the labelling step.

Outcome

Failures become an extra ticket or less context, never a dropped message.

Tickets opened in the middle of a conversation

Challenge

When the first email the workflow sees is already a reply, a ticket with only the latest message has no background.

Solution

The full Gmail thread is fetched, earlier messages are sorted by date and appended to the ticket description (with sender, recipient, date and subject), capped at 60,000 characters, and the title gets an [Ongoing thread] prefix.

Outcome

A person opening the ticket sees the whole conversation.

Malformed addresses breaking ticket creation

Challenge

ClickUp rejects the whole task when an email-typed field receives something that is not an address, such as a group name or undisclosed-recipients. Messy Cc lines and display names are common.

Solution

Header values are normalised, every address is validated, the support address is never mapped into contact fields, and Cc contacts are capped at 20 fields with the overflow count recorded.

Outcome

Odd headers no longer cause ticket creation to fail.

Secrets inside the workflow (open item)

Challenge

The ClickUp API token is written directly into the Authorization header of 8 HTTP Request nodes instead of an n8n credential, so it is visible to anyone who can open or export the workflow.

Solution

Create a ClickUp credential in n8n, switch those nodes to it, and rotate the token.

Outcome

Not done yet. The token is deliberately not reproduced in this document.

Key Takeaways & Future Development

Key takeaways

Future development

Page · Plain text

End of part 3 of 4. Continue with part 4.