InTouch Hub · Blue Isle Software

Invoice Reminder (Sheets-driven, escalating)

Sheet-driven invoice reminder. Reads an InvoiceLog Sheet, sends personalized reminder emails for overdue invoices with escalating tone (friendly → follow-up → final), stamps each row to prevent duplicate chases. Replaces the thin CSV-driven invoice-reminder workflow that sent one generic email regardless of which invoice was overdue.

sheetsgmailinvoicereminderfreelancersmall-businessaccounts-receivable

invoice-reminder-sheets

Sheet-driven invoice reminder for freelancers, consultants, and small businesses. Reads an InvoiceLog Sheet, finds rows whose due_date has passed, and sends a personalized reminder email to each overdue client referencing their specific invoice number, amount, and days past due. Escalates tone across three stages — friendly → follow-up → final — and stamps each row to prevent duplicate chases.

Why this exists

The original invoice-reminder hub workflow reads a local CSV and then sends ONE generic email body ("This is a friendly reminder that your invoice is now 14 days old") regardless of which client is overdue or for how much. That's not a real reminder system — it's a placebo.

This variant fixes both gaps: - The data lives in a Sheet you edit on your phone, not a CSV on the server's filesystem. - The email body includes the actual invoice number, amount, due date, and days past due, addressed to the actual client by name. - The tone escalates: a 7-day-past-due reminder reads differently from a 60-day-past-due one. - A stamp on each row prevents re-chasing every day for the same invoice.

Setup

  1. Credentials (Credentials view): - google-workspace — Google Workspace service-account JSON
  2. Runtime environment (Runtime Environments view): - python — auto-created on every install
  3. InvoiceLog Sheet (one-time): - Create a Sheet with a tab InvoiceLog and 10 columns: A invoice_no | B client_name | C client_email | D invoice_date E due_date | F amount | G currency | H status I last_reminder | J notes - Row 1 is the header. Data starts at row 2. - You maintain A–G and J. The workflow updates H and I. - Status flow: leave H blank or open when an invoice is sent → workflow sets it to reminded-1 after first chase, reminded-2 after second, reminded-3+ after subsequent → you set it to paid or written-off when the matter closes.
  4. Edit workflow.yaml — replace the three placeholders: - <<INVOICE_LOG_SHEET_ID>> — spreadsheet ID from the Sheet's URL - <<YOUR_NAME_OR_BUSINESS>> — used in the email signature - <<OWNER_PUBLISHER>> — user name for the daily "what got sent" summary
  5. Schedule once daily, 9:00 AM (or whenever you'd want to send chase emails).

Reminder cadence

Status when workflow sees row Threshold to send Sets status to Tone
open (or blank) days past due ≥ 7 reminded-1 friendly: "this is a friendly reminder…"
reminded-1 14 days since last reminder reminded-2 follow-up: "I sent a reminder a couple weeks ago…"
reminded-2 14 days since last reminder reminded-3+ final: "this is a final reminder, please remit within 7 days…"
reminded-3+ 14 days since last reminder stays reminded-3+ final (continues)
paid, written-off ignored

Thresholds are constants at the top of the python script — adjust to your collection policy.

Pipeline

  1. chaseruntimeenv (python). Reads InvoiceLog!A2:J, decides per row which reminder stage applies (if any), sends the corresponding personalized email, updates the row's status + last_reminder columns. Prints a summary.
  2. notify-selfmessage. Pipes the summary to your owner user so you see, every morning, what got sent (or "No invoices need a reminder today").

Sample summary

INVOICE REMINDERS — Monday, May 11, 2026

Sent 3 reminder(s):
  [1st] INV-2026-044  Acme Corp           (9 days past due)
  [2nd] INV-2026-031  Beta Services       (28 days past due)
  [FINAL] INV-2026-018  Gamma Engineering  (62 days past due)

Customization

Companion artifacts

Verified

gog sheets get/update syntax, gog gmail send --to/--subject/--body flags, and the pipe-separated multi-cell update format all verified against the bundled gog v0.19.0 (2026-06-01); re-verify output shapes on first run. Status-stage state machine logic walked manually against worked examples.

Source

See workflow.yaml.