morteza.moradi
All projects
Internal tooling2026

Delivery-Run Touch-Base Agent

Production agentic workflow that turns each delivery route into reviewed, personalized customer outreach — CRM → Claude → Gmail drafts.

Stack

n8nHighrise CRMClaude Haiku 4.5Gmail APIn8n MCP
Delivery-Run Touch-Base Agent — product screenshot

A production n8n agent that runs ahead of each delivery route: it pulls the right contacts from the CRM for the route's area, filters to those not contacted in the last 60 days, and drafts a personalized restock email per contact — grounded in that contact's most recent note — landing them as Gmail drafts for human review. A person always reviews before anything sends, and each sent reply is BCC'd back to auto-log onto the contact's record. It replaces hours of repetitive manual drafting with a sub-two-minute review.

The problem

Before every delivery route, someone on the team manually emails the purchasing contact at each customer along the route to ask whether they need a restock. It's roughly 30 near-identical emails per route, several routes a week — hours of repetitive drafting, and exactly the kind of personal-but-templated outreach that quietly slips when things get busy.

The goal wasn't to automate the relationship away — it was to keep a genuine, personalized touch on every route without spending the morning writing the same email thirty times.

What I built

  • A pre-route agent, not a mail-merge. It reads the route's area from the CRM, pulls the right purchasing contacts, and filters to only those not contacted in the last 60 days — so nobody gets pestered and nobody gets forgotten.
  • Personalized per contact. Claude Haiku 4.5 drafts a short email for each contact, grounded in that contact's most recent note — a real detail, not a generic template. The result reads like it was written for them, because in effect it was.
  • Human-in-the-loop by design. Every email lands in Gmail Drafts for review — nothing sends itself. Each draft is BCC'd to the CRM so the eventual reply auto-logs back onto the contact record.
  • Workflow-as-code. The whole 19-node n8n workflow lives in a version-controlled source file, validated and deployed through the official n8n MCP — not clicked together in a UI. The full v1 → v6.2 history (including a reverted experiment) is in the changelog.
  • Safety engineered into the prompt. Dates are computed in code and handed to the model so it can never hallucinate "tomorrow" or "next week," and personalization is gated to skip anything personal or sensitive in a contact's notes — business details only.

Architecture

A single n8n workflow on n8n Cloud orchestrates the run; Claude does the writing; Gmail holds the output for a human. The interesting part is the build loop: the workflow is treated as code and pushed through an MCP, so it's diffable and reviewable like any other source.

Runtime (n8n Cloud — 19 nodes)
├── Highrise CRM — resolve area + purchaser tags (XML API)
├── cross-filter purchasers to the route's area
├── per contact: fetch notes → 60-day eligibility gate
├── Claude Haiku 4.5 → draft, grounded in the latest note
└── Gmail draft (BCC'd to the CRM to auto-log the reply)
Build-time
└── workflow.ts (version-controlled) ⇄ n8n MCP
validate_workflow · update_workflow · get_execution

The non-obvious work is in the seams: cross-filtering the CRM's tag model (geographic tags live on companies, role tags on people), XML parsing that tolerates the CRM's mixed record shapes, and rate-limit-aware batching so a route's worth of contacts never trips the API.

What I learned

Most of the work here was deciding what to automate and what to keep human. A few things it taught me:

  • An n8n workflow can be real code. Treating it as a version-controlled source file deployed through an MCP — rather than click-ops in a UI — made it reviewable, diffable, and safe to iterate. v1 → v6.2 with documented reversals is a workflow with an engineering history, not a canvas someone is afraid to touch.
  • Prompt engineering is risk engineering. The two real failure modes — a hallucinated date and a personal note leaking into a business email — are designed out, not hoped away: dates computed in code, personalization gated. Knowing a model's failure modes and fencing them is the job.
  • Human-in-the-loop is the feature. The agent drafts; a person sends. For outreach that stands in for a relationship, "reviewed by a human first" isn't a limitation to engineer away — it's the whole point.