@elitedcs/ghl-mcp 3.53.2 → 3.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -32
- package/README.md +9 -7
- package/dist/index.js +1922 -684
- package/package.json +4 -3
- package/skills/blueprint/README.md +27 -0
- package/skills/blueprint/SKILL.md +149 -0
- package/skills/blueprint/examples/medspa-approval-view.md +92 -0
- package/skills/blueprint/examples/medspa-brief.json +52 -0
- package/skills/blueprint/examples/medspa-build-plan.json +265 -0
- package/skills/blueprint/examples/medspa-dry-run-report.md +67 -0
- package/skills/blueprint/examples/sample-approval-view.md +82 -0
- package/skills/blueprint/examples/sample-brief.json +13 -0
- package/skills/blueprint/examples/sample-build-plan.json +227 -0
- package/skills/blueprint/examples/validate-plan.cjs +127 -0
- package/skills/blueprint/presets/clinic-launch-a2p.md +39 -0
- package/skills/blueprint/presets/clinic-launch-a2p.preset.json +337 -0
- package/skills/blueprint/presets/generic-client.md +36 -0
- package/skills/blueprint/presets/generic-client.preset.json +255 -0
- package/skills/blueprint/presets/med-spa.md +59 -0
- package/skills/blueprint/presets/med-spa.preset.json +264 -0
- package/skills/blueprint/references/agency-os-detection.md +80 -0
- package/skills/blueprint/references/approval-view.md +83 -0
- package/skills/blueprint/references/brief-schema.md +45 -0
- package/skills/blueprint/references/build-plan-schema.md +52 -0
- package/skills/blueprint/references/external-funnel.md +310 -0
- package/skills/blueprint/references/intake-question-set.md +141 -0
- package/skills/blueprint/references/preset-format.md +130 -0
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elitedcs/ghl-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.55.0",
|
|
4
4
|
"mcpName": "io.github.drjerryrelth/ghl-command",
|
|
5
|
-
"description": "GoHighLevel MCP Server for Claude.
|
|
5
|
+
"description": "GoHighLevel MCP Server for Claude. 235 tools — full CRM, automation, marketing control, account-wide workflow audit, live funnel-capture verification, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"ghl-mcp": "dist/index.js"
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"templates/external-funnel/cloudflare-worker.js",
|
|
17
17
|
"templates/external-funnel/README.md",
|
|
18
18
|
"README.md",
|
|
19
|
-
"CHANGELOG.md"
|
|
19
|
+
"CHANGELOG.md",
|
|
20
|
+
"skills"
|
|
20
21
|
],
|
|
21
22
|
"scripts": {
|
|
22
23
|
"build": "esbuild src/index.ts --bundle --platform=node --target=node20 --format=cjs --outfile=dist/index.js --packages=external && esbuild src/capture-helper.ts --bundle --platform=node --target=node20 --format=cjs --outfile=dist/capture-helper.js --packages=external",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# GHL Command Blueprint
|
|
2
|
+
|
|
3
|
+
Blueprint turns a new client's intake into a complete, reviewable GoHighLevel build plan for that client's sub-account, then hands you two checklists: what GHL Command will build for you, and what you have to do yourself, in order. It plans. You approve. Nothing is built until you say so.
|
|
4
|
+
|
|
5
|
+
v1 produces the reviewable build plan and the two-part checklist, and stops at the approval gate. One-shot auto-build is the next phase.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
1. Unzip this so the folder lands at `~/.claude/skills/blueprint/` (with `SKILL.md` directly inside it).
|
|
10
|
+
2. Restart Claude, or open a new session, so it loads the skill.
|
|
11
|
+
3. Run it: say **"run Blueprint"** (or "build my Blueprint", or `/blueprint`).
|
|
12
|
+
|
|
13
|
+
## Before you run it
|
|
14
|
+
|
|
15
|
+
- **Be in the right account.** Blueprint plans against whatever GoHighLevel sub-account you are currently in. Point it at the new, empty client account and confirm it first.
|
|
16
|
+
- **You need GHL Command** connected to your GoHighLevel.
|
|
17
|
+
|
|
18
|
+
## What you get back
|
|
19
|
+
|
|
20
|
+
- A build plan for the account: pipeline and stages, custom fields, tags, the intake form, a funnel outline, email and SMS sequences, and the workflows that wire them together.
|
|
21
|
+
- Two checklists: what Blueprint will build automatically once you approve, and what only you can do in the GHL UI or with an outside service (A2P, Stripe, calendar, phone number, sending domain), in the order you need to do it.
|
|
22
|
+
|
|
23
|
+
Every reference in the plan is a name, not a raw GoHighLevel ID. That is what stops the silent-failure bug where one dead ID skips every action under it and the workflow still shows green.
|
|
24
|
+
|
|
25
|
+
## Funnels: GHL-native or your own site
|
|
26
|
+
|
|
27
|
+
Each funnel can be built **inside GoHighLevel** (the default — zero setup on your part) or as a **custom site you host** on Cloudflare/Vercel and wire back to your GHL sub-account. The external path is for technically-capable users: you need your own host account + CLI, a GHL Private Integration token you store as a host secret, and comfort with a one-time command-line deploy. Blueprint generates the site, hands you the exact verified wiring values, and runs a live verification gate, but it never deploys for you or holds your keys. If that's not you, pick GHL-native and everything still works.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: blueprint
|
|
3
|
+
description: Turn a GHL Command client intake into a complete, reviewable GoHighLevel account build plan — the GHL Command Blueprint. Detects Agency OS for a deeper brief (else uses the built-in intake form), selects an industry preset, generates a structured build plan (pipeline, fields, tags, calendar, form, funnel, email/SMS, workflows) with symbolic refs not real IDs, and renders a two-part approval checklist (what GHL Command builds automatically vs. what you must do manually, in order). The plan stops at the human approve gate; GHL-native staging then runs via apply_build_plan. Each funnel can be GHL-native (default) or an external site the user hosts (Cloudflare/Vercel) and wires back to GHL — a power-user, capability-gated lane that generates the site, injects verified field IDs, walks the user through their own deploy, and finishes only when verify_funnel passes on the real URL. Triggers on build my Blueprint, run Blueprint, GHL Command Blueprint, build a client account, watch it build a client, new client account, client onboarding build, build plan, account build spec, external funnel, host my own funnel.
|
|
4
|
+
compatibility: Claude Code, Claude Cowork, Claude.ai
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# GHL Command Blueprint (plan generation)
|
|
8
|
+
|
|
9
|
+
You are a **senior GoHighLevel solutions architect**. You turn a client's intake into a complete, build-ready account plan — clean, minimal, every automation wired to fire, in the order it must be built so nothing references a dead ID. You have one professional obsession: the GHL silent-failure bug, where an action points at a pipeline, stage, field, or workflow whose ID no longer exists and GHL skips it and everything beneath it with no error and a workflow that still shows green. You design so that can never happen.
|
|
10
|
+
|
|
11
|
+
This skill produces a **build plan** (the contract in `references/brief-schema.md` and `references/build-plan-schema.md`) and renders it for human review. It runs against whatever account `get_current_location` returns. **It does not execute anything in v1** — it stops at the approval gate. Execution (`apply_build_plan`) is phase 2, owned by the MCP.
|
|
12
|
+
|
|
13
|
+
> Account-agnostic, always. No hardcoded IDs, no dependency on any specific agency's stack. The plan carries symbolic **refs** (`pipeline.main`, `stage.new_lead`), never real GHL IDs. The phase-2 executor resolves ref → id at build time, after each object is created and verified. That is what kills the silent-failure class.
|
|
14
|
+
|
|
15
|
+
## The pipeline you run
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Detect brief source ─► Source the brief (§2A) ─► Select preset ─► Fill skeleton ─► Derive handoffs ─► Generate copy ─► Assemble plan (per-funnel target) ─► Quality gate ─► Render approval view
|
|
19
|
+
│
|
|
20
|
+
external funnel only, AFTER approval ──────────────────────────────────────────────────────────────────────────────────►│ stage GHL side (apply_build_plan) ─► generate + inject site ─► deploy preview→confirm→promote ─► verify_funnel gate ─► done
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Read `references/preset-format.md` once; it defines the tokens (`{{...}}`), `conditionalOn`, `fillFrom`, and `copyDirection` you will resolve. Read `references/agency-os-detection.md` for the brief-source decision. Read `references/approval-view.md` for the final render. Read `references/external-funnel.md` only when a funnel is `target: "external"` (the capability gate + site gen/deploy + verify lane).
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## STEP 1 — Detect the brief source (do this first, before any questions)
|
|
28
|
+
|
|
29
|
+
Run the Agency OS detection in `references/agency-os-detection.md`:
|
|
30
|
+
- **Detected** (skills `agency-os:*` present / `agency-os@agency-os` installed / artifacts on disk) → **offer (default yes)** to build the brief from Brand DNA / ICA / Offer. Ingest existing `owner-profile.md` / `ica-output.md` / offer output; if installed-but-not-run, offer to run/chain the `build-*` skills with one confirmation (never silent auto-run — they are interactive interviews); if declined, fall back.
|
|
31
|
+
- **Not detected** → use the built-in intake question set, and surface the one-line credit to Agency OS by Muhammad Asmal (https://aileadbuilder.com).
|
|
32
|
+
|
|
33
|
+
Business OS is a deferred second detection target — do not detect it yet.
|
|
34
|
+
|
|
35
|
+
## STEP 2 — Source the brief (§4)
|
|
36
|
+
|
|
37
|
+
**Partner-OS path:** ingest the Agency OS artifacts per the mapping in `references/agency-os-detection.md`. Carry the deep ICA / offer / brand-DNA structures **verbatim** in `brief.extended`. Set `briefSource: "agency_os"` (or `"hybrid"` if you also collect channel/tech facts Agency OS does not capture — booking/email/SMS/A2P/payment/calendar state). Always resolve those channel/tech facts somewhere, because they drive the handoffs.
|
|
38
|
+
|
|
39
|
+
**Form path:** read the submission via `get_form_submissions_full` (the MCP installs the form from `references/intake-question-set.md`), or, if no submission exists yet, ask the §3 questions conversationally — only what changes the design, never a wall of questions. Normalize to the brief per the key→field map. Set `briefSource: "intake_form"`.
|
|
40
|
+
|
|
41
|
+
Either way you end with a §4-conforming brief: `business`, `offer`, `audience`, `goal`, `channels`, `assets`, derived `flags`, and (partner-OS) `extended`. Do not emit `null` for unknowns — omit the field. Compute `flags`: `needs_a2p`, `stripe_not_connected`, `calendar_oauth_needed`, `email_domain_needed`.
|
|
42
|
+
|
|
43
|
+
## STEP 3 — Select the preset
|
|
44
|
+
|
|
45
|
+
Resolve in this order:
|
|
46
|
+
1. If `brief.preset` is set, match it against each preset's `selectors.aliases`.
|
|
47
|
+
2. Else match `brief.business.type` against `selectors.businessTypes`.
|
|
48
|
+
3. Else use the library `default` preset (`med_spa`). (`generic` is the neutral fallback for clinic / coach / ecom / local-service / agency via its `businessTypes`; it is no longer the default.)
|
|
49
|
+
|
|
50
|
+
Special case: if the brief describes a **time-boxed on-site event + database reactivation** (event dates, deposit + balance, package tiers, SMS reactivation of an existing list), select `clinic_launch_a2p` even if business_type would route elsewhere. When ambiguous, ask the operator which model fits; do not guess into the heavy compliance preset silently.
|
|
51
|
+
|
|
52
|
+
Load the chosen preset's `skeleton`.
|
|
53
|
+
|
|
54
|
+
## STEP 4 — Fill the skeleton (deterministic; see preset-format §"fill algorithm")
|
|
55
|
+
|
|
56
|
+
Apply, in order:
|
|
57
|
+
1. **Evaluate `conditionalOn`** on every item (and every workflow action). Drop where false. Prune refs that now dangle, and record each prune (you will note these in the summary, not silently drop).
|
|
58
|
+
2. **Resolve `fillFrom`** lists. The main case is pipeline stages: if `goal.salesStages` is non-empty, build `stage.<slug>` refs from it in order; else use the preset `default`. If a workflow references a `stage.*` not in the chosen set, map it to the nearest equivalent (first stage for "new lead" creation) and note it — never ship a dead ref.
|
|
59
|
+
3. **Substitute `{{tokens}}`** (with `||` fallback). Where a token resolves empty and has no fallback, omit the field and note the default you used.
|
|
60
|
+
4. **Derive interest tags + field options** from the offer/business type (e.g. `interest-injectables` for a med spa) and add them to `tags` + the `field.interest` options, mirroring each other.
|
|
61
|
+
|
|
62
|
+
## STEP 5 — Derive flag-driven handoffs
|
|
63
|
+
|
|
64
|
+
Ensure the plan contains exactly the handoffs the brief calls for (the preset already declares the conditional ones; confirm and add any missing):
|
|
65
|
+
- `needs_a2p` → `handoff.a2p` (blocks all SMS sends)
|
|
66
|
+
- `stripe_not_connected` → `handoff.stripe`
|
|
67
|
+
- `calendar_oauth_needed` → `handoff.calendar_oauth` (produces the booking link)
|
|
68
|
+
- a calendar with `requiresStaff` and no known staff → `handoff.add_staff` (blocks the calendar)
|
|
69
|
+
- `email_domain_needed` → `handoff.email_domain` (blocks email sends)
|
|
70
|
+
|
|
71
|
+
Each handoff carries `owner` (**OPERATOR-UI** / **OPERATOR-EXT** / **TEAM** — customer-safe labels; never internal names. The MCP still accepts the legacy `JERRY-UI`/`JERRY-EXT`/`SASHA` and normalizes them, but EMIT the canonical ones), a precise `instruction`, a `successCheck`, and `blocks`. This is the honest "what GHL Command cannot do for you" layer; it is designed, not an afterthought.
|
|
72
|
+
|
|
73
|
+
**A2P gating is workflow-level.** For `handoff.a2p`, `blocks` must list each SMS-bearing **workflow** ref (e.g. `workflow.speed_to_lead`) so those workflows stay DRAFT until A2P is met — a bare `sms.*` wildcard gates only the asset surface, not a workflow's publish state. List the SMS-bearing workflow refs plus the `sms.*` asset refs, and prune any that conditional drops removed.
|
|
74
|
+
|
|
75
|
+
## STEP 6 — Generate copy (gated, grounded, editable)
|
|
76
|
+
|
|
77
|
+
Default for REVIEW: **outlines** (`subject` + `bodyOutline` + `mergeTags` for emails; `bodyOutline` for SMS; `outline` for pages). Turn each `copyDirection` into a concrete outline grounded in `offer`, `audience`, and — when present — `extended` (voice from brandDna, angle from ICA, value-stack language from offer). Keep SMS A2P-safe (opt-out line; for the launch preset, avoid the forbidden-words list). See RATIFICATION §3 for the copy-depth policy.
|
|
78
|
+
|
|
79
|
+
**Before execution, expand to full `body`.** A `send_email` / `send_sms` action whose asset carries only an outline (no `body`) is reported by `apply_build_plan` as `needsContent` and will NOT build. So any email/SMS that is actually SENT by a workflow must have a full `body` (not just `bodyOutline`) before you hand the plan to `apply_build_plan mode:"execute"`. Outlines are for the approval render; the sent assets get real copy. The worked example (`examples/medspa-build-plan.json`) ships the expanded `body` form — that is what dry-runs with 0 needs-content.
|
|
80
|
+
|
|
81
|
+
## STEP 7 — Assemble the plan (§5)
|
|
82
|
+
|
|
83
|
+
Emit a §5-conforming object: `schemaVersion`, `planId`, `briefId`, `preset`, `summary`, then the object arrays (`pipelines`, `customFields`, `tags`, `customValues`, `calendars`, `forms`, `funnels`, `emails`, `sms`, `workflows`, `handoffs`), `buildOrder`, and an empty `idMap`. Keep strictly to contract fields (the MCP validators may be strict). Record provenance (preset id + version, brief source) in the `summary` text, not as an extra field. Use GHL-correct enums: `dataType` ∈ {TEXT, LARGE_TEXT, NUMERICAL, PHONE, **MONETORY**, CHECKBOX, SINGLE_OPTIONS, MULTIPLE_OPTIONS, FLOAT, DATE, TEXTBOX_LIST, FILE_UPLOAD, SIGNATURE}; `calendarType` ∈ {round_robin, event, class_booking, collective, service_booking}.
|
|
84
|
+
|
|
85
|
+
Workflow actions stay **logical** (type + key params + refs). Do not emit GHL-native action JSON — the executor expands logical actions via `action-schemas.json` and owns the failure-prone shapes (`internal_update_opportunity` node-level discriminator, `internal_notification`/task-notification nesting, `remove_from_workflow` dual id, `wait` `startAfter`, `attachments:[]`, `html` vs `body`, node `next`/`parentKey` chaining). All object pointers are refs. Max 40 actions per workflow; split longer flows into linked + exit workflows.
|
|
86
|
+
|
|
87
|
+
**Triggers — use only native types** so they auto-build instead of falling through to a manual GHL-UI step: `contact_tag` (needs `tagRef`), `form_submission` (needs `formRef`), `appointment` (needs `appointmentStatus`: `confirmed`/`noshow`/`new`/`showed`/`cancelled`/`invalid`; `calendarRef` optional), `customer_reply`, `pipeline_stage_updated` (needs `pipelineRef`+`stageRef`), `inbound_webhook`, `payment_received`. `form_submitted`/`contact_replied` are accepted aliases, but `tag_added`/`appointment_status`/`appointment_booked` are NOT recognized and become manual steps — never emit them.
|
|
88
|
+
|
|
89
|
+
**`internal_notification.to` needs a real GHL user id.** A non-user value builds `selectedUser:""` = notify-all, which GHL will not publish. Resolve the operator's user id from `get_users` on the current location at fill time (the preset carries the `{{operator.userId}}` token) and substitute it. With multiple users, ask whom to notify. If none can be resolved, leave it as a `TEAM` handoff rather than ship an unpublishable notify-all. This is the one place a real id legitimately appears in a plan (Blueprint never creates users).
|
|
90
|
+
|
|
91
|
+
**Branching + appointment-relative actions.** `find_opportunity` is the only branching action and MUST be the last action in its workflow (its found/notFound branches do not rejoin). `wait_appointment` ("N before the appointment") only works in a workflow with an `appointment` trigger. The MCP validator enforces both, plus unique object names within each type and a 40-node cap (a workflow containing a `find_opportunity` branch cannot be auto-split).
|
|
92
|
+
|
|
93
|
+
**Per-funnel target (GHL-native vs external).** For each funnel, set `target` ∈ `ghl` (default) / `external` (+ `host`/`domain` when external). Ask once per funnel: "Build this funnel inside GHL, or as a custom site you host on Cloudflare/Vercel and wire back to GHL?" The brief may pre-answer. **The instant a funnel is set to `external`, run the capability gate in `references/external-funnel.md` §1** — plainly state the required access (own host account + CLI, a GHL Private Integration token they store as a host secret, comfort with a one-time CLI deploy, optional domain/DNS) and say outright it is for technically-capable users; if that is not them, steer to `target: "ghl"`. Default GHL; never assume dev skills. The chosen target renders per funnel in the approval view (external = the power-user path, with ownership facts).
|
|
94
|
+
|
|
95
|
+
## STEP 8 — Quality gate (run on yourself before showing anything)
|
|
96
|
+
|
|
97
|
+
Re-read the plan as the person who has to build it tomorrow and score 1-10 on:
|
|
98
|
+
1. Does every workflow have both a trigger and an exit (and do nurtures stop on response)?
|
|
99
|
+
2. Does every ref resolve to an object defined in the plan, with a build order that creates targets before dependents? (No dangling refs after the prune step.)
|
|
100
|
+
3. Is there anything in here the client will never use? (Cut it.)
|
|
101
|
+
4. Is speed-to-lead genuinely fast and automatic?
|
|
102
|
+
5. Does naming fit the client's industry and tier (from `business.type` and, if present, `extended`)?
|
|
103
|
+
6. Is every step the MCP cannot truly one-shot represented as an explicit handoff with a success check (A2P, Stripe, OAuth, staff, email domain)?
|
|
104
|
+
7. Do the enums match GHL (MONETORY spelling, calendarType values), so the plan will pass the MCP validators?
|
|
105
|
+
|
|
106
|
+
If any score is below 9, fix it and re-score. Then proceed.
|
|
107
|
+
|
|
108
|
+
## STEP 9 — Render the approval view (§5A)
|
|
109
|
+
|
|
110
|
+
Render the two-part checklist per `references/approval-view.md`:
|
|
111
|
+
1. **GHL Command will build this automatically** — every creatable object, grouped and counted, in plain English.
|
|
112
|
+
2. **You must do these yourself, in this order** — every handoff, topologically ordered by `blocks`/`produces`, with owner, instruction, success check, and what it unblocks.
|
|
113
|
+
|
|
114
|
+
Invite edits (rename / drop / reorder / adjust). Re-render after edits. End by stating plainly: nothing is built yet; the plan stops at approval. On approval, the GHL-native automatic list is staged via `apply_build_plan` — run `mode:"dry_run"` FIRST, show the two-part report, and only on the operator's go run `mode:"execute"`. A clean plan dry-runs with 0 `actionsNeedContent` and 0 unexpected `actionsManual` (the funnel page-content step and the declared handoffs are expected, not failures).
|
|
115
|
+
|
|
116
|
+
**Workflows default to DRAFT — prompt before publishing.** `apply_build_plan` builds workflows DRAFT unless `publishWorkflows:true`. Before any workflow goes live, ASK the operator: "Publish these now, or leave them DRAFT for review?" Pass `publishWorkflows:true` only on an explicit yes. Workflows gated by an unmet handoff (e.g. SMS workflows behind `handoff.a2p`) never auto-publish even when opted in; pass satisfied handoffs in `metHandoffs` to lift their gate. If any funnel is `target: "external"`, also run STEP 10 after approval.
|
|
117
|
+
|
|
118
|
+
## STEP 10 — External funnel lane (only if a funnel is `target: "external"`)
|
|
119
|
+
|
|
120
|
+
For each external funnel, run the lane in `references/external-funnel.md` after approval. Summary:
|
|
121
|
+
1. **Stage the GHL side.** Confirm the active sub-account, then `apply_build_plan` `mode:"dry_run"` → show the report → on the operator's go, `mode:"execute"`. Capture the returned `externalWiring` bundle (verified custom-field IDs, `bookingUrl`, trigger tag) and the speed-to-lead workflow id. If `externalWiring.unresolved` is non-empty, stop and re-run execute — never wire a form to an unresolved field.
|
|
122
|
+
2. **Generate + inject the site.** Generate the site with `frontend-design` from the page outlines + brand. Inject the lead form keyed by the bundle's **verified `fieldId`s** (custom fields under `custom: {<fieldId>: value}`, never name-guessed; option values must match GHL option values), the `bookingUrl` into the booking CTA, a honeypot, and Turnstile for production. Fail closed (never a silent success).
|
|
123
|
+
3. **Deploy — the user runs every command; the product deploys nothing and never handles the token.** Scaffold `wrangler.toml` (vars only); the user sets `GHL_PIT` as a host secret themselves. Deploy to a preview URL → confirm → promote to production. Never silently clobber a live deployment.
|
|
124
|
+
4. **Verify, then call it done.** Run `verify_funnel` on the real branded production URL (built from the bundle: `funnelUrl` = the Worker URL, `triggerTag`, `workflowId`, `expectCustom` from the form fields, `consentFieldId` if messaging). The funnel is done ONLY when `verify_funnel` passes (backend contact truth + field-value fidelity + tag landed + workflow not DRAFT + outreach fired + consent + dedup), a real browser submit on the branded URL landed with correct field values, and a burner booking is confirmed. Otherwise say what failed and stop.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Hard rules (do not violate)
|
|
129
|
+
- No real GHL IDs in a plan, ever. Refs only.
|
|
130
|
+
- No silent failures: every cross-reference resolves; every handoff has a success check; every prune is noted.
|
|
131
|
+
- No fabricated specifics. Mark assumptions `[ASSUMPTION]` and unconfirmed facts `[UNVERIFIED]`. Never fabricate prices, stats, phone numbers, or claims.
|
|
132
|
+
- Honest capability boundaries. Always show the steps only the operator can do. It makes the rest believable.
|
|
133
|
+
- Operator voice. No em-dashes, no hype, no emoji-spam. Client-ready.
|
|
134
|
+
- Do not clone or redistribute Agency OS / Business OS. Detect, integrate, credit.
|
|
135
|
+
- The plan never executes itself. Stop at approval. After approval, GHL-native staging runs only via `apply_build_plan` (confirm the account first); the external funnel lane (STEP 10) runs only on an informed yes through the capability gate.
|
|
136
|
+
- **External funnels are customer-managed, zero product involvement in their accounts.** The product generates, scaffolds, hands over verified wiring, and verifies — it never deploys for the user, never asks for or stores their token, never touches their host/GHL account beyond what the operator's own session does. The user owns hosting, the secret, uptime, and DNS.
|
|
137
|
+
- **External forms send verified GHL custom-field IDs, never name-guessed keys** (the silent-drop class). A funnel is not "done" until `verify_funnel` passes on the real branded production URL plus a burner booking — never on a thank-you page.
|
|
138
|
+
|
|
139
|
+
## Files in this skill
|
|
140
|
+
- `references/intake-question-set.md` — the built-in §3 questions (also the source the MCP form installer reads).
|
|
141
|
+
- `references/agency-os-detection.md` — §2A detect → offer → fallback + ingestion mapping.
|
|
142
|
+
- `references/preset-format.md` — token / conditional / fill grammar + the deterministic fill algorithm.
|
|
143
|
+
- `references/approval-view.md` — the §5A render spec + template.
|
|
144
|
+
- `references/external-funnel.md` — the `target: "external"` lane: capability gate, site gen + verified-fieldId injection, user-run deploy (preview→confirm→promote), and the `verify_funnel`-gated finish. Read only when a funnel is external.
|
|
145
|
+
- `presets/med-spa.preset.json` (+ `.md`) — the **default** reference preset (live-validated 2026-06-25).
|
|
146
|
+
- `presets/generic-client.preset.json` (+ `.md`) — the neutral fallback preset (clinic / coach / ecom / local-service / agency; not default).
|
|
147
|
+
- `presets/clinic-launch-a2p.preset.json` (+ `.md`) — the launch-event / A2P preset (not default).
|
|
148
|
+
- `examples/` — the worked `medspa-*` brief → plan → approval view, with `medspa-dry-run-report.md` (the live proof: `validate_build_plan` valid + `apply_build_plan` dry_run clean). `sample-*` is the older generic-preset example.
|
|
149
|
+
- `RATIFICATION.md` — the schema §7 decisions this skill is built on (#3 copy depth, #4 preset determinism, #9 ingest vs auto-run).
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Build Plan — Glow Aesthetics
|
|
2
|
+
|
|
3
|
+
A full lead-to-member account for your med spa: a pipeline that follows your own sales
|
|
4
|
+
stages, the fields and tags to track every lead, a booking calendar, an A2P-compliant
|
|
5
|
+
inquiry form and funnel, and a complete email + text follow-up system that stops the
|
|
6
|
+
moment a client replies. Below is what GHL Command builds for you automatically, and the
|
|
7
|
+
short list of things only you can do, in order.
|
|
8
|
+
|
|
9
|
+
Generated from the **Med Spa** preset (v1.0.0) · brief source: intake_form · schema v0.1.
|
|
10
|
+
This is a plan for your review. Nothing is built yet. Edit anything below, then approve.
|
|
11
|
+
|
|
12
|
+
> Live-validated 2026-06-25: `validate_build_plan` → valid, 48 refs, 0 dead. `apply_build_plan`
|
|
13
|
+
> dry_run → 40 objects, 28 actions auto-built, 0 needing copy, 0 needing a manual GHL step,
|
|
14
|
+
> every workflow trigger auto-built. See [`medspa-dry-run-report.md`](medspa-dry-run-report.md).
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 1. GHL Command will build this automatically (once you approve)
|
|
19
|
+
|
|
20
|
+
**Pipeline**
|
|
21
|
+
- Build pipeline "Glow Aesthetics Patient Journey" with 7 stages: New Lead → Contacted → Consult Booked → Showed → Treated → Member / Rebooked → Lost.
|
|
22
|
+
|
|
23
|
+
**Custom fields (5)**
|
|
24
|
+
- Lead Source (dropdown)
|
|
25
|
+
- Service Interest (multi-select: Injectables / Tox, Dermal Filler, Facials / Skin, Membership, Weight / Body)
|
|
26
|
+
- Appointment Date (date)
|
|
27
|
+
- Consult Deposit Paid (checkbox)
|
|
28
|
+
- Estimated Lifetime Value (monetary)
|
|
29
|
+
|
|
30
|
+
**Tags (17)**
|
|
31
|
+
- Source: source-website, source-instagram, source-facebook, source-google, source-referral
|
|
32
|
+
- Lifecycle: lifecycle-new-lead, contacted, consult-booked, showed, treated, member, lapsed, lost
|
|
33
|
+
- Interest: interest-injectables, interest-filler, interest-facials, interest-membership
|
|
34
|
+
|
|
35
|
+
**Custom values (1)**
|
|
36
|
+
- Booking Link (filled after you connect your calendar — step 1 below)
|
|
37
|
+
|
|
38
|
+
**Calendar**
|
|
39
|
+
- "Glow Aesthetics Consultation" (round-robin, Mon-Fri 9-5 default — edit hours after build). Auto-assigned to you as the solo provider.
|
|
40
|
+
|
|
41
|
+
**Form**
|
|
42
|
+
- "Glow Aesthetics New Client Inquiry": First name, Last name, Email, Phone (required), plus Service Interest mapped to the custom field.
|
|
43
|
+
|
|
44
|
+
**Funnel**
|
|
45
|
+
- "Glow Aesthetics Lead Funnel": a Free Skin Assessment opt-in page (→ the inquiry form, with the A2P-compliant consent block) and a Thank You page (booking CTA). Page content is yours to fill from the funnel template — see Part 2.
|
|
46
|
+
|
|
47
|
+
**Email + SMS assets**
|
|
48
|
+
- 5 emails: Welcome / First Touch, Nurture / Education, Pre-Consult Reminder, No-Show Re-offer, Win-back.
|
|
49
|
+
- 3 SMS: Speed-to-lead, Consult reminder, No-show rebook. _(Texts will not send until A2P is approved — step 2 below.)_
|
|
50
|
+
|
|
51
|
+
**Workflows (5)** _(all build DRAFT; you choose when to publish)_
|
|
52
|
+
- "Speed to Lead" — on inquiry → tag new lead, create opportunity at New Lead, send welcome email, alert you, wait 5 min, send a text. _(stops on reply; SMS held until A2P)_
|
|
53
|
+
- "Lead Nurture" — for leads who don't book: wait 1 day, educate by email, wait 3 days, mark lapsed. _(stops on reply; email-only, publishes freely)_
|
|
54
|
+
- "Replied - Stop and Route" — the moment a lead replies → pull them out of nurture, tag contacted, alert you.
|
|
55
|
+
- "New Patient Onboarding" — on a confirmed appointment → stop the nurture, tag booked, move the opportunity to Consult Booked, send the pre-visit email, then text a reminder one day before the appointment. _(SMS held until A2P)_
|
|
56
|
+
- "No-Show Win-back" — on a no-show → tag lapsed, alert you, send a re-offer email, then look up their opportunity: if one exists, move it back to Contacted and text a rebook nudge; if not, send the win-back email. _(SMS held until A2P)_
|
|
57
|
+
|
|
58
|
+
_Total: 40 objects across 11 types — a full pipeline, 5 fields, 17 tags, a custom value, a calendar, a form, a funnel, 5 emails, 3 texts, and 5 workflows. 28 workflow actions auto-built._
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 2. You must do these yourself, in this order
|
|
63
|
+
|
|
64
|
+
1. **Connect your calendar (Google / Outlook)** — **You (in GHL)**
|
|
65
|
+
- What: open the Glow Aesthetics Consultation calendar > Connections and authorize Google or Outlook, then copy the booking link into the Booking Link custom value.
|
|
66
|
+
- Why now: this is a login only you can approve, and it produces the Booking Link the emails and texts use.
|
|
67
|
+
- Done when: the calendar shows a connected account and the booking link resolves.
|
|
68
|
+
|
|
69
|
+
2. **Register A2P 10DLC (so texts can send)** — **You (external: carrier)**
|
|
70
|
+
- What: submit your A2P brand and campaign through the GHL Trust Center. Save your submission package first.
|
|
71
|
+
- Why now: the Speed to Lead, Onboarding, and No-Show workflows stay DRAFT and their texts stay dark until A2P is approved (7-14 day review).
|
|
72
|
+
- Done when: the A2P campaign shows submitted/approved.
|
|
73
|
+
|
|
74
|
+
3. **Design + populate your funnel pages** — **You (in GHL)**
|
|
75
|
+
- What: fill the opt-in and thank-you page content from the funnel template (`funnel-page-content-template.md`). The opt-in page MUST carry the A2P consent checkbox (not pre-checked), your legal business name + mailing address, and Privacy/Terms links.
|
|
76
|
+
- Why now: GHL Command builds the funnel and named steps; the page content and design are yours (and the A2P consent block must be present before A2P review).
|
|
77
|
+
- Done when: both pages are published with the required A2P, SEO, and FAQ elements.
|
|
78
|
+
|
|
79
|
+
4. **Connect Stripe (to take payment)** — **You (external: Stripe)**
|
|
80
|
+
- What: connect Stripe in Payments > Integrations and create your consult-deposit and membership products.
|
|
81
|
+
- Why now: the funnel is built, but the money connection is yours to authorize.
|
|
82
|
+
- Done when: Stripe shows connected and your products exist.
|
|
83
|
+
|
|
84
|
+
_Not included (not needed for this build): an email-domain step — your email sending is already set up._
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
_v1 stops here. When you approve, the automatic list above is ready for one-shot staging via
|
|
89
|
+
`apply_build_plan` (confirm the account first). Each manual step is verified before the steps
|
|
90
|
+
that depend on it run, so nothing is ever wired to something that does not exist yet. You
|
|
91
|
+
will be asked, before any workflow goes live, whether to publish now or leave them DRAFT for
|
|
92
|
+
review — they default to DRAFT._
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "0.1",
|
|
3
|
+
"briefId": "sub_medspa_demo",
|
|
4
|
+
"preset": "med_spa",
|
|
5
|
+
"briefSource": "intake_form",
|
|
6
|
+
"business": {
|
|
7
|
+
"name": "Glow Aesthetics",
|
|
8
|
+
"type": "med spa",
|
|
9
|
+
"website": "glowaesthetics.com",
|
|
10
|
+
"location": "Scottsdale, AZ",
|
|
11
|
+
"timezone": "America/Phoenix",
|
|
12
|
+
"teamSize": "Just me",
|
|
13
|
+
"monthlyLeadVolume": "100-500",
|
|
14
|
+
"hours": "Mon-Fri 9:00am-5:00pm"
|
|
15
|
+
},
|
|
16
|
+
"offer": {
|
|
17
|
+
"summary": "Injectables, dermal filler, and medical facials for first-time and returning clients, plus a membership for regulars.",
|
|
18
|
+
"pricePoints": [
|
|
19
|
+
{ "name": "New client consult", "price": "19" },
|
|
20
|
+
{ "name": "Tox session", "price": "350" },
|
|
21
|
+
{ "name": "Glow Membership", "price": "149/mo" }
|
|
22
|
+
],
|
|
23
|
+
"leadMagnet": "Free skin assessment",
|
|
24
|
+
"avgDealValue": "350"
|
|
25
|
+
},
|
|
26
|
+
"audience": {
|
|
27
|
+
"ideal": "Women 30-55 in North Scottsdale who want to look refreshed, not overdone",
|
|
28
|
+
"painPoints": ["early signs of aging", "not knowing who to trust with their face"],
|
|
29
|
+
"objections": ["price", "fear of looking overdone or fake"]
|
|
30
|
+
},
|
|
31
|
+
"goal": {
|
|
32
|
+
"primary": "book appointments",
|
|
33
|
+
"salesStages": ["New Lead", "Contacted", "Consult Booked", "Showed", "Treated", "Member / Rebooked", "Lost"],
|
|
34
|
+
"bookingNeeded": true,
|
|
35
|
+
"followUpStyle": "high-touch"
|
|
36
|
+
},
|
|
37
|
+
"channels": {
|
|
38
|
+
"email": true,
|
|
39
|
+
"sms": true,
|
|
40
|
+
"a2pStatus": "not started",
|
|
41
|
+
"payment": "Stripe not connected",
|
|
42
|
+
"calendarConnected": false,
|
|
43
|
+
"social": ["instagram", "facebook"]
|
|
44
|
+
},
|
|
45
|
+
"assets": {
|
|
46
|
+
"existingPipeline": "no",
|
|
47
|
+
"existingWorkflows": "",
|
|
48
|
+
"brand": "logo + navy/gold palette, domain ready",
|
|
49
|
+
"notes": "Solo operator for now; wants speed-to-lead and a no-show win-back."
|
|
50
|
+
},
|
|
51
|
+
"flags": ["needs_a2p", "stripe_not_connected", "calendar_oauth_needed"]
|
|
52
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "0.1",
|
|
3
|
+
"planId": "plan_medspa_demo",
|
|
4
|
+
"briefId": "sub_medspa_demo",
|
|
5
|
+
"preset": "med_spa",
|
|
6
|
+
"summary": "Generated by the GHL Command Blueprint plan-gen skill from preset med_spa v1.0.0 (brief source: intake_form). Builds Glow Aesthetics a med-spa lead-to-member system: a 7-stage Patient Journey pipeline, lead-source/service-interest/appointment custom fields, source + lifecycle + interest tags, a round-robin consult calendar, an A2P-compliant intake form + lead funnel, a full email/SMS follow-up library, and five workflows (speed-to-lead, nurture, reply-route, confirmed-appointment onboarding with an appointment-relative reminder, and a no-show win-back that branches on whether an opportunity exists). SMS-bearing workflows are held DRAFT behind the A2P handoff; the booking link is filled by the calendar-connect handoff. internal_notification targets the operator's real GHL user id (resolved live via get_users at plan-gen time; shown here as a placeholder). Nothing is built until you approve.",
|
|
7
|
+
"pipelines": [
|
|
8
|
+
{
|
|
9
|
+
"ref": "pipeline.patient_journey",
|
|
10
|
+
"name": "Glow Aesthetics Patient Journey",
|
|
11
|
+
"stages": [
|
|
12
|
+
{ "ref": "stage.new_lead", "name": "New Lead", "position": 0 },
|
|
13
|
+
{ "ref": "stage.contacted", "name": "Contacted", "position": 1 },
|
|
14
|
+
{ "ref": "stage.consult_booked", "name": "Consult Booked", "position": 2 },
|
|
15
|
+
{ "ref": "stage.showed", "name": "Showed", "position": 3 },
|
|
16
|
+
{ "ref": "stage.treated", "name": "Treated", "position": 4 },
|
|
17
|
+
{ "ref": "stage.member", "name": "Member / Rebooked", "position": 5 },
|
|
18
|
+
{ "ref": "stage.lost", "name": "Lost", "position": 6 }
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"customFields": [
|
|
23
|
+
{ "ref": "field.lead_source", "name": "Lead Source", "dataType": "SINGLE_OPTIONS", "model": "contact", "options": ["Website", "Instagram", "Facebook", "Google", "Referral", "Walk-in", "Other"] },
|
|
24
|
+
{ "ref": "field.service_interest", "name": "Service Interest", "dataType": "MULTIPLE_OPTIONS", "model": "contact", "options": ["Injectables / Tox", "Dermal Filler", "Facials / Skin", "Membership", "Weight / Body"] },
|
|
25
|
+
{ "ref": "field.appointment_date", "name": "Appointment Date", "dataType": "DATE", "model": "contact" },
|
|
26
|
+
{ "ref": "field.consult_deposit_paid", "name": "Consult Deposit Paid", "dataType": "CHECKBOX", "model": "contact", "options": ["Deposit paid"] },
|
|
27
|
+
{ "ref": "field.lifetime_value", "name": "Estimated Lifetime Value", "dataType": "MONETORY", "model": "contact" }
|
|
28
|
+
],
|
|
29
|
+
"tags": [
|
|
30
|
+
{ "ref": "tag.source_website", "name": "source-website" },
|
|
31
|
+
{ "ref": "tag.source_instagram", "name": "source-instagram" },
|
|
32
|
+
{ "ref": "tag.source_facebook", "name": "source-facebook" },
|
|
33
|
+
{ "ref": "tag.source_google", "name": "source-google" },
|
|
34
|
+
{ "ref": "tag.source_referral", "name": "source-referral" },
|
|
35
|
+
{ "ref": "tag.lc_new_lead", "name": "lifecycle-new-lead" },
|
|
36
|
+
{ "ref": "tag.lc_contacted", "name": "lifecycle-contacted" },
|
|
37
|
+
{ "ref": "tag.lc_consult_booked", "name": "lifecycle-consult-booked" },
|
|
38
|
+
{ "ref": "tag.lc_showed", "name": "lifecycle-showed" },
|
|
39
|
+
{ "ref": "tag.lc_treated", "name": "lifecycle-treated" },
|
|
40
|
+
{ "ref": "tag.lc_member", "name": "lifecycle-member" },
|
|
41
|
+
{ "ref": "tag.lc_lapsed", "name": "lifecycle-lapsed" },
|
|
42
|
+
{ "ref": "tag.lc_lost", "name": "lifecycle-lost" },
|
|
43
|
+
{ "ref": "tag.interest_injectables", "name": "interest-injectables" },
|
|
44
|
+
{ "ref": "tag.interest_filler", "name": "interest-filler" },
|
|
45
|
+
{ "ref": "tag.interest_facials", "name": "interest-facials" },
|
|
46
|
+
{ "ref": "tag.interest_membership", "name": "interest-membership" }
|
|
47
|
+
],
|
|
48
|
+
"customValues": [
|
|
49
|
+
{ "ref": "cv.booking_link", "name": "Booking Link", "value": "", "filledBy": "handoff.calendar_oauth" }
|
|
50
|
+
],
|
|
51
|
+
"calendars": [
|
|
52
|
+
{
|
|
53
|
+
"ref": "calendar.consult",
|
|
54
|
+
"name": "Glow Aesthetics Consultation",
|
|
55
|
+
"calendarType": "round_robin",
|
|
56
|
+
"openHours": [
|
|
57
|
+
{ "daysOfTheWeek": [1, 2, 3, 4, 5], "hours": [{ "openHour": 9, "openMinute": 0, "closeHour": 17, "closeMinute": 0 }] }
|
|
58
|
+
],
|
|
59
|
+
"availabilityType": 0,
|
|
60
|
+
"requiresStaff": true
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"forms": [
|
|
64
|
+
{
|
|
65
|
+
"ref": "form.intake",
|
|
66
|
+
"name": "Glow Aesthetics New Client Inquiry",
|
|
67
|
+
"fields": [
|
|
68
|
+
{ "type": "standard", "key": "first_name", "required": true },
|
|
69
|
+
{ "type": "standard", "key": "last_name", "required": false },
|
|
70
|
+
{ "type": "standard", "key": "email", "required": true },
|
|
71
|
+
{ "type": "standard", "key": "phone", "required": true },
|
|
72
|
+
{ "type": "custom", "fieldRef": "field.service_interest", "required": false }
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"funnels": [
|
|
77
|
+
{
|
|
78
|
+
"ref": "funnel.main",
|
|
79
|
+
"name": "Glow Aesthetics Lead Funnel",
|
|
80
|
+
"target": "ghl",
|
|
81
|
+
"pages": [
|
|
82
|
+
{
|
|
83
|
+
"ref": "page.optin",
|
|
84
|
+
"name": "Free Skin Assessment",
|
|
85
|
+
"role": "optin",
|
|
86
|
+
"outline": "HERO: H1 'Your Free Skin Assessment at Glow Aesthetics' + one-line subhead (refreshed, natural results for women in North Scottsdale); primary CTA 'Book my free assessment' to form.intake; logo + hero image (alt text). QUOTABLE SUMMARY (GEO): 2-4 plain sentences an answer engine can lift: what the free skin assessment is, who it serves (women 30-55 in North Scottsdale), and the next step. VALUE: 3-5 outcome-led benefits (natural-looking injectables, filler, medical facials, a plan to your goals). SOCIAL PROOF: real testimonials/credentials only, else omit. CAPTURE FORM (A2P-compliant, MANDATORY): name + email + phone (clearly labeled) + a NOT-pre-checked SMS consent checkbox with the four disclosures (opt-out, HELP, msg&data rates, frequency); visible business legal name + mailing address; Privacy Policy and Terms links at the point of capture; Privacy Policy states SMS/phone data is not shared or sold. FAQ: 4-8 real Q/A with FAQPage JSON-LD. FOOTER: NAP + legal links. HEAD: one H1, <title> under 60 chars, meta description under 155, canonical, LocalBusiness + Service + FAQPage JSON-LD. Fill from templates/funnel-page-content-template.md.",
|
|
87
|
+
"formRef": "form.intake"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"ref": "page.thankyou",
|
|
91
|
+
"name": "Thank You",
|
|
92
|
+
"role": "confirmation",
|
|
93
|
+
"outline": "Confirmation message ('Your assessment request is in'); set the next-step expectation; embed the booking widget via cv.booking_link / calendar.consult so they can self-schedule now. Keep NAP + Privacy/Terms links in the footer. No new opt-in needed. Fill from templates/funnel-page-content-template.md (confirmation role).",
|
|
94
|
+
"calendarRef": "calendar.consult"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"emails": [
|
|
100
|
+
{
|
|
101
|
+
"ref": "email.welcome_1",
|
|
102
|
+
"name": "Welcome / First Touch",
|
|
103
|
+
"subject": "Your free skin assessment with Glow Aesthetics",
|
|
104
|
+
"body": "Hi {{contact.first_name}},\n\nThank you for requesting your free skin assessment with Glow Aesthetics. We help women in North Scottsdale look refreshed and natural with injectables, dermal filler, and medical facials.\n\nYour next step is simple: book your complimentary consult and we will map a plan to your goals, with no pressure. Pick a time that works for you here:\n\n{{custom_values.booking_link}}\n\nIf now is not the right time, just reply to this email and we will help.\n\nWarmly,\nThe Glow Aesthetics Team",
|
|
105
|
+
"mergeTags": ["contact.first_name"]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"ref": "email.nurture_1",
|
|
109
|
+
"name": "Nurture / Education",
|
|
110
|
+
"subject": "The difference between refreshed and overdone",
|
|
111
|
+
"body": "Hi {{contact.first_name}},\n\nThe most common worry we hear is simple: nobody wants to look done. The good news is that natural results are a matter of technique and restraint, not luck.\n\nAt your free assessment we look at your face as a whole, explain your options in plain language, and only recommend what actually moves your goals. You leave with a plan, whether or not you treat that day.\n\nWhen you are ready, your assessment is here:\n\n{{custom_values.booking_link}}\n\nWarmly,\nThe Glow Aesthetics Team",
|
|
112
|
+
"mergeTags": ["contact.first_name"]
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"ref": "email.consult_reminder",
|
|
116
|
+
"name": "Pre-Consult Reminder",
|
|
117
|
+
"subject": "Your Glow Aesthetics consult is coming up",
|
|
118
|
+
"body": "Hi {{contact.first_name}},\n\nLooking forward to seeing you for your consult. A few quick notes so we make the most of your time:\n\n- Come with a clean face if you can, no makeup is needed.\n- Bring any questions about injectables, filler, or facials.\n- Plan for about 30 minutes.\n\nNeed to change your time? Reply to this email or use your booking link:\n\n{{custom_values.booking_link}}\n\nSee you soon,\nThe Glow Aesthetics Team",
|
|
119
|
+
"mergeTags": ["contact.first_name"]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"ref": "email.no_show",
|
|
123
|
+
"name": "No-Show Re-offer",
|
|
124
|
+
"subject": "We missed you, let us get you rebooked",
|
|
125
|
+
"body": "Hi {{contact.first_name}},\n\nWe had you down for a consult and you did not make it, which is completely okay. Life happens.\n\nYour free assessment is still open. Grab a new time whenever it suits you:\n\n{{custom_values.booking_link}}\n\nIf there is anything we can answer first, just reply.\n\nWarmly,\nThe Glow Aesthetics Team",
|
|
126
|
+
"mergeTags": ["contact.first_name"]
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"ref": "email.winback",
|
|
130
|
+
"name": "Win-back",
|
|
131
|
+
"subject": "It has been a while, {{contact.first_name}}",
|
|
132
|
+
"body": "Hi {{contact.first_name}},\n\nIt has been a little while since we connected about your skin goals. If looking refreshed for the season is on your mind, now is a good time.\n\nYour complimentary assessment is still available, and our calendar fills up fast this time of year:\n\n{{custom_values.booking_link}}\n\nWarmly,\nThe Glow Aesthetics Team",
|
|
133
|
+
"mergeTags": ["contact.first_name"]
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"sms": [
|
|
137
|
+
{
|
|
138
|
+
"ref": "sms.speed_to_lead",
|
|
139
|
+
"name": "Speed-to-lead text",
|
|
140
|
+
"body": "Hi {{contact.first_name}}, it's Glow Aesthetics. Thanks for requesting your free skin assessment. Want me to hold a consult time for you? Reply STOP to opt out.",
|
|
141
|
+
"mergeTags": ["contact.first_name"]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"ref": "sms.consult_reminder",
|
|
145
|
+
"name": "Consult reminder text",
|
|
146
|
+
"body": "Hi {{contact.first_name}}, a quick reminder about your Glow Aesthetics consult tomorrow. Reply here if you need to change the time. Reply STOP to opt out.",
|
|
147
|
+
"mergeTags": ["contact.first_name"]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"ref": "sms.no_show",
|
|
151
|
+
"name": "No-show rebook text",
|
|
152
|
+
"body": "Hi {{contact.first_name}}, we missed you at Glow Aesthetics today. Your free assessment is still open, want a new time? Reply STOP to opt out.",
|
|
153
|
+
"mergeTags": ["contact.first_name"]
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"workflows": [
|
|
157
|
+
{
|
|
158
|
+
"ref": "workflow.speed_to_lead",
|
|
159
|
+
"name": "Speed to Lead",
|
|
160
|
+
"trigger": { "type": "form_submission", "formRef": "form.intake" },
|
|
161
|
+
"stopOnResponse": true,
|
|
162
|
+
"actions": [
|
|
163
|
+
{ "type": "add_contact_tag", "tagRef": "tag.lc_new_lead" },
|
|
164
|
+
{ "type": "create_opportunity", "pipelineRef": "pipeline.patient_journey", "stageRef": "stage.new_lead", "name": "{{contact.name}} - New Lead" },
|
|
165
|
+
{ "type": "send_email", "emailRef": "email.welcome_1" },
|
|
166
|
+
{ "type": "internal_notification", "to": "REPLACEwithGetUsersId", "title": "New lead", "body": "New inquiry from {{contact.first_name}} {{contact.last_name}}" },
|
|
167
|
+
{ "type": "wait", "value": 5, "unit": "minutes" },
|
|
168
|
+
{ "type": "send_sms", "smsRef": "sms.speed_to_lead" }
|
|
169
|
+
]
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"ref": "workflow.lead_nurture",
|
|
173
|
+
"name": "Lead Nurture",
|
|
174
|
+
"trigger": { "type": "contact_tag", "tagRef": "tag.lc_new_lead" },
|
|
175
|
+
"stopOnResponse": true,
|
|
176
|
+
"actions": [
|
|
177
|
+
{ "type": "wait", "value": 1, "unit": "days" },
|
|
178
|
+
{ "type": "send_email", "emailRef": "email.nurture_1" },
|
|
179
|
+
{ "type": "wait", "value": 3, "unit": "days" },
|
|
180
|
+
{ "type": "add_contact_tag", "tagRef": "tag.lc_lapsed" }
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"ref": "workflow.reply_route",
|
|
185
|
+
"name": "Replied - Stop and Route",
|
|
186
|
+
"trigger": { "type": "customer_reply" },
|
|
187
|
+
"stopOnResponse": false,
|
|
188
|
+
"actions": [
|
|
189
|
+
{ "type": "remove_from_workflow", "workflowRef": "workflow.lead_nurture" },
|
|
190
|
+
{ "type": "add_contact_tag", "tagRef": "tag.lc_contacted" },
|
|
191
|
+
{ "type": "internal_notification", "to": "REPLACEwithGetUsersId", "title": "Lead replied", "body": "{{contact.first_name}} replied, follow up" }
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"ref": "workflow.onboarding",
|
|
196
|
+
"name": "New Patient Onboarding",
|
|
197
|
+
"trigger": { "type": "appointment", "appointmentStatus": "confirmed", "calendarRef": "calendar.consult" },
|
|
198
|
+
"stopOnResponse": false,
|
|
199
|
+
"actions": [
|
|
200
|
+
{ "type": "remove_from_workflow", "workflowRef": "workflow.lead_nurture" },
|
|
201
|
+
{ "type": "add_contact_tag", "tagRef": "tag.lc_consult_booked" },
|
|
202
|
+
{ "type": "update_opportunity", "pipelineRef": "pipeline.patient_journey", "stageRef": "stage.consult_booked" },
|
|
203
|
+
{ "type": "send_email", "emailRef": "email.consult_reminder" },
|
|
204
|
+
{ "type": "wait_appointment", "value": 1, "unit": "days" },
|
|
205
|
+
{ "type": "send_sms", "smsRef": "sms.consult_reminder" }
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"ref": "workflow.no_show",
|
|
210
|
+
"name": "No-Show Win-back",
|
|
211
|
+
"trigger": { "type": "appointment", "appointmentStatus": "noshow", "calendarRef": "calendar.consult" },
|
|
212
|
+
"stopOnResponse": true,
|
|
213
|
+
"actions": [
|
|
214
|
+
{ "type": "add_contact_tag", "tagRef": "tag.lc_lapsed" },
|
|
215
|
+
{ "type": "internal_notification", "to": "REPLACEwithGetUsersId", "title": "No-show", "body": "{{contact.first_name}} missed their consult" },
|
|
216
|
+
{ "type": "send_email", "emailRef": "email.no_show" },
|
|
217
|
+
{
|
|
218
|
+
"type": "find_opportunity",
|
|
219
|
+
"pipelineRef": "pipeline.patient_journey",
|
|
220
|
+
"found": [
|
|
221
|
+
{ "type": "update_opportunity", "pipelineRef": "pipeline.patient_journey", "stageRef": "stage.contacted" },
|
|
222
|
+
{ "type": "send_sms", "smsRef": "sms.no_show" }
|
|
223
|
+
],
|
|
224
|
+
"notFound": [
|
|
225
|
+
{ "type": "send_email", "emailRef": "email.winback" }
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
"handoffs": [
|
|
232
|
+
{
|
|
233
|
+
"ref": "handoff.calendar_oauth",
|
|
234
|
+
"owner": "OPERATOR-UI",
|
|
235
|
+
"title": "Connect your calendar (Google / Outlook)",
|
|
236
|
+
"trigger": "goal.bookingNeeded == true && channels.calendarConnected == false",
|
|
237
|
+
"instruction": "In the sub-account, open the Glow Aesthetics Consultation calendar > Connections and authorize your Google or Outlook account. This login can only be approved by you. Then copy the booking link into the Booking Link custom value.",
|
|
238
|
+
"produces": "cv.booking_link",
|
|
239
|
+
"successCheck": "Calendar shows a connected external account and the booking link resolves",
|
|
240
|
+
"blocks": ["cv.booking_link"]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"ref": "handoff.a2p",
|
|
244
|
+
"owner": "OPERATOR-EXT",
|
|
245
|
+
"title": "Register A2P 10DLC (so texts can send)",
|
|
246
|
+
"trigger": "channels.sms == true",
|
|
247
|
+
"instruction": "Submit your A2P brand and campaign through the GHL Trust Center / your carrier. The SMS steps are built but stay DRAFT and will not send until this is approved. Save your full submission package before submitting.",
|
|
248
|
+
"produces": null,
|
|
249
|
+
"successCheck": "A2P campaign status shows submitted or approved",
|
|
250
|
+
"blocks": ["workflow.speed_to_lead", "workflow.onboarding", "workflow.no_show", "sms.speed_to_lead", "sms.consult_reminder", "sms.no_show"]
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"ref": "handoff.stripe",
|
|
254
|
+
"owner": "OPERATOR-EXT",
|
|
255
|
+
"title": "Connect Stripe (to take payment)",
|
|
256
|
+
"trigger": "channels.payment != 'Stripe connected'",
|
|
257
|
+
"instruction": "Connect Stripe under Payments > Integrations and create your consult-deposit and membership products. The funnel is built; authorizing the money connection is yours to do.",
|
|
258
|
+
"produces": null,
|
|
259
|
+
"successCheck": "Stripe shows connected and products exist",
|
|
260
|
+
"blocks": []
|
|
261
|
+
}
|
|
262
|
+
],
|
|
263
|
+
"buildOrder": ["tag.*", "field.*", "cv.*", "pipeline.*", "calendar.*", "form.*", "funnel.*", "email.*", "sms.*", "workflow.*"],
|
|
264
|
+
"idMap": {}
|
|
265
|
+
}
|