22 October 20265 min read

Follow up without becoming a nuisance: the stop condition is the core

Workflow 02.04 sends a sequence of follow-up emails. Its useful lesson sits before the writing step: who is excluded, who merely waits, and why a reply does not yet stop the file as shipped.

The awkward fourth email

Mara asks a small agency for a proposal. The agency replies, then hears nothing. A follow-up is reasonable. Mara answers after the first reminder and says the project is paused. The next message should never leave the outbox. In an automated sequence, the quality of that outcome is decided before any model writes a polite sentence.

Workflow 02.04 is built around that decision. On each scheduled run, it reads the Leads sheet, chooses due rows, drafts one message at a time, sends through Gmail, updates the row and posts a summary in Slack. The visible sequence is a gentle nudge, an email that adds value, and a final check-in. The more important sequence is the set of exits inside Who Is Due Today?.

Every condition in the gate

The code examines each sheet row in order. A row produces no email when any of these conditions applies:

  • email is empty.
  • status is not new, replied or contacted, after conversion to lowercase.
  • followUpCount is greater than or equal to maxFollowUps.
  • Neither lastContact nor the fallback receivedAt can be parsed as a date.
  • The days since that date are fewer than the configured target for the next follow-up.

These exits do not all mean the same thing. A missing email or unusable date is bad data. The workflow silently skips it again on every run until somebody repairs the row. A lead that is not old enough is only waiting. It becomes eligible on a later weekday. A lead at the maximum count is finished. A status outside the allowlist is the business owner’s deliberate stop switch, or an unexpected value that behaves like one.

The defaults make the intended cadence visible: the targets are 3,7,14, and the maximum is 3. Those are product settings, not a general recommendation. They can be changed in Vault Config. The schedule itself runs on weekdays at 09:00; n8n documents that scheduled workflows use the workflow timezone when one is set and the instance timezone otherwise. That makes the configured timezone part of the setup, not decoration. The official Schedule Trigger documentation explains the timezone rule.

“Not today” is not “stop”

The date check deserves special care. The code calculates whole elapsed days from lastContact, selects a target using the number already sent, and skips the row while daysSilent is below that target. After an email, Update Lead Row writes the current time back to lastContact and increments followUpCount.

That means the configured targets are gaps measured from the most recent contact stored by the workflow. They are not dates measured from the original enquiry. With the defaults, the next eligibility check occurs after the first gap, then after a new second gap, then after a new third gap. The field names can tempt an operator to read them as milestones from one starting date, but the update makes them successive waits.

The workflow processes one lead at a time and updates the sheet only after Gmail has sent the message. That ordering avoids increasing the counter for a send that never reached the update step. It also leaves a failure window in the other direction: if Gmail sends successfully and the sheet update then fails, the unchanged row may be selected again later. The file contains no idempotency key or sent-message lookup to close that gap.

A reply does not stop this workflow

The sticky note says the sequence stops automatically when somebody replies. The executable path does not inspect Gmail for replies, and it does not contain a reply trigger. More strikingly, replied is one of the statuses that the gate accepts. A row marked replied can therefore continue when its date and count make it due.

For Mara’s answer to stop the sequence, another process or a person must change her sheet status to a value outside new, replied and contacted. The setup note names won, lost and paused; all three work because the code rejects every status outside the allowlist. So do misspellings and blank statuses, although those are accidental stops rather than useful controls.

The safe repair is explicit. A Gmail reply trigger or a separate inbox workflow should match the sender to the lead, record the reply, and set a terminal or held status such as paused. The sender match needs a review path for shared addresses and aliases. Until that path exists and has been tested with real accounts, the operator must update the status manually before the next scheduled run.

Where the model belongs

The model writes the subject and body only after the gate has selected a lead. It cannot rescue a wrong selection. Its prompt limits tone and asks for different language at each stage, but it receives whatever the sheet and gate provide. A beautifully written unwanted email is still an unwanted email.

That is also where this workflow may not fit. A CRM with reply tracking and sequence enrolment can offer stronger stop controls than a sheet plus Gmail. The sheet is easy to inspect and edit, which suits a small operation, but it makes status discipline part of the job. The supplied workflow has been checked against a real n8n installation; it has not been run end to end with real Google Sheets, OpenAI, Gmail and Slack accounts. Live reply matching is not merely untested here. It is absent.

The useful operating rule

Before activation, test the negative cases, not only the first successful email. Use test rows with no address, a held status, a finished count, a broken date and a date that is not due. Then simulate a reply and confirm that a status change prevents the next send. The official Google Sheets node documentation lists row-reading and row-updating operations used by this design. The n8n Google Sheets documentation describes those operations.

The core is not the three messages. It is the distinction between waiting, bad data and a real stop. Workflow 02.04 already stops for missing addresses, disallowed statuses, the configured maximum and invalid dates, while a not-yet-due row waits. What it does not do is detect an answer. That missing condition must be added or handled by a person before the sequence can honestly claim to stop when a lead replies.

Sources

← All posts Every claim here links to its source.
Pre-launch

Hourbench builds the workflows these posts talk about.

The Automation Vault is 20 ready-to-run n8n workflows plus a bonus one. It is built and installable, and in final testing against real accounts before it goes on sale.

See what's coming →