Movements VIII–XII aren't only documents. Underneath sit five n8n workflows (107 nodes) and two Dify bots that do the work: keep lead attribution, set the SLA within working hours, hand a medical question to a doctor, catch a broken form in a day, stop a campaign at a threshold.
Anything inbound, from any channel, passes through n8n, lands in one sheet, and is dispatched to the right people with a timer. There is no separate system of record — everything writes to the same place the Movement VIII report reads from.
One data layer. Every workflow reads and writes to a single sheet (LUME_SHEET_ID): raw_leads, raw_spend, comms_log, creative_board, campaign_thresholds, alert_state, ops_log. The Movement VIII report reads the same raw_* — the automation fills it, it does not duplicate it.
Each node does one legible thing. All are in the repository, ready to import.
Normalises a lead, brings the phone to E.164, captures all click IDs (gclid, fbclid, wbraid). From the number's prior enquiries it keeps first-touch and last-touch attribution and flags repeat contact. Scores the lead by the service of interest — SMAS, a course, an injectable programme is HOT, with a separate ping to the doctor. Sets the SLA to 15 working minutes within studio hours (Europe/Kyiv 09:00–21:00) — a lead at 23:50 doesn't wake the manager at midnight. If the sheet write fails, the lead goes to dead_letter, not into the void. The marketing digest carries only actions: leads with no contact, missed SLA, pace below plan.
A keyword pre-classifier catches acute medical markers and legal threats before the model; Claude handles the rest. It assigns a type (10 classes), an owner, an SLA in working hours, a Telegram chat. Acute cases are mirrored to “LUME-911” with “call now”. If the inbound is a lead (Lead Ads, or phone + intent to book), it flows into the Movement VIII lead pipeline, not just the comms log. The weekly marketing summary: response time p50/p90, bot deflection, which campaigns the inbound came from.
Checks Definition of Ready — a brief with a missing field, wrong checkpoint order, or no contractor does not enter the queue, and the form gets back the list of gaps. Daily it scans the board: checkpoint tomorrow → reminder to the creative team; overdue, or the critical-chain buffer running out → alert to the marketing lead. The Friday retro arrives only if on-time is below 80% or revision rounds above 1.3 — otherwise the sprint went fine, nothing to write.
Per active campaign it computes CPL and CAC by channel, checks them against campaign_thresholds and the kill / hold / iterate / scale grid. It messages the marketing lead only when there is a call — “KILL: CAC ₴4,400, LTV/CAC below 4”, “ITERATE: 22% of leads are the wrong budget — tighten the audience”. Deduped via alert_state: the same flag doesn't repeat every day. A UTM validator on the lead layer catches a broken tag in the first hour of a launch.
Every day it sends a synthetic lead to every live landing page and checks it reached the CRM with the right tags within 3 minutes — a broken form shows up in a day, not a month. It watches ad-account balances (alert below 5 days of runway). Weekly: a UTM audit (signal only if more than 1% of tags have drifted) and page HTTP status. On the 1st: the month-close checklist for the paperwork.
Classifies intent and answers INFO / PRICE / BOOK from a knowledge base (price ranges from the Bible, procedure cards, addresses), and helps people book. Everything else it hard-hands off with a [HANDOFF:*] tag into the right Telegram chat.
The hard line: the bot never answers a medical question on the merits, even when the answer is in the knowledge base — only a verbatim script and a handoff to a doctor. One wrong medical suggestion in “LUMÉ's” voice costs more than the entire automation saves.
Spec and system prompt — 12_communications/dify_faq_bot.md.
Input: JSON from DASH_funnel and DASH_channels; output: text — “what changed this week, where the bottleneck is, three recommendations.” The report stays numbers; the bot turns them into an agenda.
Prompt — 11_crm_metrics/dify_weekly_summary.md.
Full guide — automation/SETUP.md. Everything except access to third-party systems works on test data right after import.
| Component | What | Status |
|---|---|---|
| Self-hosted n8n | import 5 JSON, attach credentials, check typeVersion | already available |
| Google Sheets | service account + a sheet with tabs per the spec | ≈ 30 minutes |
| Telegram Bot | @BotFather → token, ~13 chat_id variables | 10 minutes |
| Anthropic API | key for the classifier in workflow 2 | already available |
| Dify | 2 apps per the specs | already available |
| EasyWeek API | visits export, lead-status updates | owner access |
| Meta / Google accounts | spend and balance export | owner access |
| Instagram / Telegram webhooks | workflow 2 input and bot channels | owner access |
The workflows have not been run in a live n8n — these are reference implementations. Checked programmatically: valid JSON, no duplicate node names, no broken links, no orphan nodes, no invalid IF operations, no invented node types; Code-node logic reviewed. The classifier is a direct HTTP call to the Anthropic API, no dependency on LangChain nodes. On first import n8n flags nodes that need a credential or a typeVersion tweak — 15–20 minutes per workflow.
The bots are a specification, not deployed apps. System prompts, Chatflow structure and knowledge bases are fully written; assembly in Dify follows SETUP.md.
Some inputs need owner access (EasyWeek, ad accounts, Instagram webhooks). Without them the logic still runs, but on manual data entry.
This is a model client. LUMÉ is a fictional network. The workflows are written to be real (the author builds similar automation for actual beauty businesses), but they calibrate against a live stream.