STORMLINE ROOFING - AUTOMATION BUILD

The full Stormline build, wired stage by stage.

One connected system for the Stormline demo account: 15 workflows that carry a homeowner from their first inquiry to a signed job, a finished roof, and a standing referral - plus the two standalone responders (Review Engine and Missed Call Text-Back) and the pipelines, tags, triggers, custom values, and email templates that hold it together. Foundation first, so a build team can execute it in order.

15 workflows 2 cycles: sales + delivery 70 email + SMS templates Demo / sandbox Built by Gokai.pro - v1, Jun 29 2026
Trigger / Entry Action Wait Decision Grant / Win End / Handoff V1 - JUN 29, 2026
Demo company: Stormline Roofing is a fictional dummy business, not a real client. It exists only to show how this automation system is built and how it runs, on a demo/sandbox account with no real customer data.

Build status: NSR is verified live (16 Jun 2026); WF1, WF2, WF4 and WF3 are built; WF5, WF6, WF7 and the Delivery series (D1-D5) are design-ahead spec not yet built in GHL. Confirm current state in the master logic map before building any workflow.
01

Naming Convention

One consistent vocabulary across workflows, pipelines, tags, emails, and fields. Foundation before behavior - do this first.

Why this matters

As Stormline grows past a handful of workflows, naming discipline is the difference between a clean library and a maze nobody can navigate.

The conventions

  • Workflows + Helpers
  • Pipelines + Stages
  • Tags
  • Emails / SMS / Notifications
  • Custom Fields
Rule of thumbIf you can't tell what a workflow does from its name alone, the name is wrong. Open it, rename it, save it.
Figure 01 - Naming Patterns

Workflows

PATTERN
WF[N] - [NNN] [Stage Name]
WF1 - 001 New Lead
WF4 - 004 Estimate Sent
NSR - No-Show Recovery
D3 - Delivery 003 Project Complete
  • WF / D prefix - Sales-cycle vs Delivery-cycle workflow
  • NNN number - the stage position it owns
  • Helper sub-workflows sit beside the WF they support (see Helpers)

Emails, SMS, Notifications

PATTERN
P[Phase]_[WF#]_[Purpose]
P1_003_ThankYou (email)
P1_005_SMS_Urgency (sms)
P1_004_Notify_RepTakeOver (internal)
  • P1 = Sales phase, P2 = Delivery phase. SMS + Notify infixes keep types sortable.

Tags + Custom Fields

PATTERN
snake_case
tags: new_lead, no_show_lost, sales_to_delivery
fields: follow_up_count (number)
  • Tags are case-sensitive - always paste, never retype.
02

Offer & Entry Point

Stormline is a lead-generation funnel, not a checkout. There are no paid GHL products - the entry points are a lead form and a booking calendar.

Why no products

Roofing is sold by inspection and estimate, not online checkout. Nothing fires off ORDER_SUBMITTED here - entry is a form opt-in and a booked consultation.

Path

Sites & Funnels (lead form) + Calendars (Roofing Consultation)

No payment gateway neededNo Stripe/products to configure. If Stormline later sells a paid inspection or deposit, add it as a GHL product and a matching WF - the rest of the system is unaffected.
Figure 02 - Entry Points
Entry PointTypeFiresInto Stage
Stormline Lead FormFormForm SubmittedNew Lead
Roofing ConsultationCalendarAppointment confirmedInspection Booked
Roofing ConsultationCalendarAppointment no-show(stays Inspection Booked, NSR runs)
03

Pipelines

Two pipelines: a Sales pipeline (lead to signed) and a Delivery pipeline (build to retained). WF6 hands the deal from one to the other.

Why two pipelines

Sales tracking and crew/fulfillment tracking serve different teams. Splitting them keeps each board readable and reporting clean.

The handoff

WF6 (Project Won) moves the opportunity out of Sales and into the Delivery pipeline at Project Scheduled - that's where D1 picks it up.

7-stage ruleGHL best practice: keep pipelines at or under 7 stages. The Sales pipeline sits exactly at 7.
Figure 03 - Pipeline Architecture
flowchart TD
    A0(["New Lead"]):::trigger
    A1["Inspection Booked"]:::action
    A2["Inspection Complete"]:::action
    A3["Estimate Sent"]:::action
    A4{"Decision Pending"}:::decision
    A5(["Project Won"]):::grant
    A6(["Project Lost"]):::end_
    A0 --> A1 --> A2 --> A3 --> A4
    A4 -->|Signs| A5
    A4 -->|Declines| A6
    A5 -.->|Handoff to Delivery| B0

    B0(["Project Scheduled"]):::trigger
    B1["In Progress"]:::action
    B2["Project Complete"]:::action
    B3["Review Requested"]:::action
    B4["Warranty Follow Up"]:::action
    B5(["Client Retained"]):::grant
    B0 --> B1 --> B2 --> B3 --> B4 --> B5

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
  • Sales pipeline - StormLine Sales Pipeline Demo (7 stages)
  • Delivery pipeline - Stormline Delivery Pipeline (6 stages)
04

Tag Taxonomy

Tags are the routing layer. They persist on the contact where a one-shot trigger can't see history - so workflows can branch on what already happened.

Two tag classes

Identity tags persist across cycles (new_lead, returning_lead, won). Transactional flags are stripped at the top of WF1 so a returning lead doesn't trigger the wrong branch.

Case-sensitiveTypos break workflow conditions silently. Always paste tags, never retype.
Figure 04 - Tag Reference
TagSet ByPurpose
new_lead / returning_leadWF1Identity - kept across cycles
inspection_bookedWF2Consultation confirmed
no_show / no_show_lostNSRMissed appt / lost after no rebook
inspection_completeWF3Inspection done, awaiting estimate
estimate_sentWF4Quote delivered
decision_pendingWF5Quote out, awaiting answer
won + sales_to_deliveryWF6Signed - handing to crew
lost / re_engagement_journeyWF7Lost / in long-term win-back
in_progress / project_completeD2 / D3Delivery stage flags
build_scheduledHelperBuild booked (set outside WF6 to dodge instant-goal)
review_sent / review_clickedHelper / D4Review submitted / link clicked
project_concernHelper (inbound reply)Homeowner flagged a problem - stop auto-advance
client_retainedD5Long-term retained customer
05

Trigger to Workflow Map

Most of the system is driven by Pipeline Stage Changed - each workflow advances the stage, which fires the next workflow. The chain runs itself.

Trigger sources

  • FORM_SUBMITTED - lead capture
  • APPOINTMENT_STATUS - confirmed / no-show
  • PIPELINE_STAGE_CHANGED - the main engine
  • OPP_STATUS_CHANGED - Lost (rep manual)
  • REVIEW_LINK_CLICKED - advocacy
Always filter the stageA Pipeline Stage Changed trigger with no stage filter fires on EVERY move - it must be scoped to the one stage it owns.
Figure 05 - Trigger Map
flowchart LR
    F["Form Submitted"]:::trigger -->|capture| W1["WF1 New Lead"]:::action
    C1["Appt confirmed"]:::trigger -->|book| W2["WF2 Inspection Booked"]:::action
    C2["Appt no-show"]:::trigger -->|recover| NS["NSR No-Show"]:::action
    S1["Stage: Inspection Complete"]:::trigger --> W3["WF3"]:::action
    S2["Stage: Estimate Sent"]:::trigger --> W4["WF4"]:::action
    S3["Stage: Decision Pending"]:::trigger --> W5["WF5"]:::action
    S4["Stage: Project Won"]:::trigger --> W6["WF6 + Delivery handoff"]:::grant
    S5["Status: Lost"]:::trigger --> W7["WF7 Win-Back"]:::action
    S6["Stage: Project Scheduled"]:::trigger --> D["D1..D5 Delivery"]:::action

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
      
WF 01

Form Submitted -> New Lead Nurture

Speed-to-lead capture: greet, book, chase, and only mark Lost if they never schedule.
As-built
Lead fills out form
Say it simply The moment someone fills out your form, they get a friendly text and email with a link to book - and if they don't book yet, we keep gently reminding them, so no lead ever goes cold.

What it does

Captures new vs returning leads, sends a welcome + booking link, runs email/SMS nudges, and marks Lost if they never book.

Figure WF01 - New Lead
flowchart TD
    T(["Form Submitted: Stormline Lead Form"]):::trigger
    R["Remove stale transactional tags"]:::action
    F{"Find Opportunity"}:::decision
    UF["Found: Update opp -> New Lead, Open"]:::action
    TF["Tag: returning_lead"]:::action
    CN["Not Found: Create opp -> New Lead"]:::action
    TN["Tag: new_lead"]:::action
    E1["Email: Welcome + Booking link"]:::action
    S1["SMS 1: Speed-to-lead"]:::action
    N["Notify team: New Lead Alert"]:::action
    W1["Wait 1 day"]:::wait
    E2["Email 2: Nudge"]:::action
    S2["SMS 2: Nudge"]:::action
    W2["Wait 2 days"]:::wait
    E3["Email 3: Last Call"]:::action
    EB["Email: Lost Breakup"]:::action
    UL["Update opp -> Project Lost, Lost"]:::action
    G{"Goal: appt confirmed?"}:::decision
    Z(["End"]):::end_
    T --> R --> F
    F -->|Found| UF --> TF --> E1
    F -->|Not Found| CN --> TN --> E1
    E1 --> S1 --> N --> W1 --> E2 --> S2 --> W2 --> E3 --> EB --> UL --> G
    G -->|Books -> WF2| Z
    G -->|Never books| Z

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
WF 02

Appointment Confirmed -> Inspection Booked

Confirm the booking, then remind the day before and an hour before - anchored to the real appointment time.
As-built
Appointment confirmed

What it does

Confirms the inspection immediately, sends anchored day-before and hour-before reminders, and alerts the team to schedule the inspector.

Figure WF02 - Inspection Booked
flowchart TD
    T(["Appt confirmed: Roofing Consultation"]):::trigger
    F{"Find Opportunity"}:::decision
    UF["Found: Update opp -> Inspection Booked, Open"]:::action
    TG["Tag: inspection_booked"]:::action
    EC["Email: WF2_Confirmation"]:::action
    N["Notify team: inspection booked"]:::action
    WA["Wait until 1 day before appt"]:::wait
    ED["Email: WF2_DayBefore"]:::action
    SD["SMS: WF2_SMS_DayBefore"]:::action
    WH["Wait until 1 hour before appt"]:::wait
    EH["Email: WF2_HeadsUp"]:::action
    SH["SMS: WF2_SMS_HeadsUp"]:::action
    G{"Goal: cancelled / no-show?"}:::decision
    CN["Not Found: Create opp -> Inspection Booked"]:::action
    Z(["End (helper marks Complete on show)"]):::end_
    T --> F
    F -->|Found| UF --> TG --> EC
    F -->|Not Found| CN --> TG
    EC --> N --> WA --> ED --> SD --> WH --> EH --> SH --> G
    G -->|Cancel/No-show -> NSR| Z
    G -->|Shows| Z

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
NSR

Appointment No-Show -> Rebook Recovery

Re-engage a no-show with a few gentle nudges; mark Lost only if they truly vanish.
Verified live - 16 Jun 2026
Appointment no-show

What it does

When an inspection is marked no-show, it chases a rebook over several days, then marks Lost only if they never return. Without it, no-shows dead-end at Inspection Booked forever.

Figure NSR - No-Show Recovery
flowchart TD
    T(["Appt no-show: Roofing Consultation"]):::trigger
    FO["Find Opportunity (Latest)"]:::action
    U["Update opp -> Status Open (keep Inspection Booked)"]:::action
    TG["Tag: no_show"]:::action
    E1["Email: NSR_Rebook1 (immediate)"]:::action
    S1["SMS: NSR_SMS_Rebook"]:::action
    N["Notify team: they ghosted"]:::action
    W1["Wait 2 days"]:::wait
    E2["Email: NSR_Rebook2"]:::action
    W2["Wait 3 days"]:::wait
    UL["Update opp -> Project Lost, Lost"]:::action
    TL["Tag: no_show_lost"]:::action
    G{"Goal: appt confirmed (rebook)?"}:::decision
    Z(["End"]):::end_
    T --> FO --> U --> TG --> E1 --> S1 --> N --> W1 --> E2 --> W2 --> UL --> TL --> G
    G -->|Rebooks -> WF2| Z
    G -->|Vanishes| Z

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
WF 03

Inspection Complete -> Thank + Estimate Prep

Thank them while the visit is fresh, set the estimate ETA, poke the team, advance to Estimate Sent.
As-built
Stage = Inspection Complete

What it does

After the inspection: same-day thank-you, an estimate-timing email/SMS, then a team notification to actually build the quote - then it advances the stage to fire WF4.

Figure WF03 - Inspection Complete
flowchart TD
    T(["Stage = Inspection Complete"]):::trigger
    FO["Find Opportunity"]:::action
    U["Update opp -> Inspection Complete"]:::action
    TG["Tag: inspection_complete"]:::action
    E1["Email: P1_003_ThankYou (same-day)"]:::action
    W1["Wait 4 hours"]:::wait
    E2["Email: P1_003_EstimateTimeline"]:::action
    S1["SMS: P1_003_SMS_Timeline"]:::action
    W2["Wait 1 day"]:::wait
    N["Notify team: estimate due"]:::action
    ES(["Update opp -> Estimate Sent -> WF4"]):::end_
    T --> FO --> U --> TG --> E1 --> W1 --> E2 --> S1 --> W2 --> N --> ES

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
WF 04

Estimate Sent -> Follow-up Loop (x3)

Deliver the quote, then nudge up to 3 times with one reusable template via a counter loop - then hand to a rep at Decision Pending.
As-built
Stage = Estimate Sent

What it does

Sends the estimate, then loops one follow-up template up to 3 times (follow_up_count +1 each pass), and advances to Decision Pending so nothing dead-ends.

Figure WF04 - Estimate Follow-up Loop
flowchart TD
    T(["Stage = Estimate Sent"]):::trigger
    FO["Find Opportunity"]:::action
    U["Update opp -> Estimate Sent, Open"]:::action
    TG["Tag: estimate_sent"]:::action
    RC["Reset follow_up_count = 0"]:::action
    E1["Email: P1_004_Estimate"]:::action
    N1["Notify team: estimate out"]:::action
    WL["Wait 2 days (loop top)"]:::wait
    EF["Email: P1_004_FollowUp"]:::action
    SF["SMS: P1_004_SMS_FollowUp"]:::action
    INC["follow_up_count + 1"]:::action
    D{"3+ nudges sent?"}:::decision
    NR["Notify team: rep take over"]:::action
    DP(["Update opp -> Decision Pending -> WF5"]):::end_
    T --> FO --> U --> TG --> RC --> E1 --> N1 --> WL --> EF --> SF --> INC --> D
    D -->|No| WL
    D -->|Yes| NR --> DP

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
WF 05

Decision Pending -> Decision Nudge (x2)

Gently push the undecided homeowner up to 2 times, then notify the rep to close. WF5 never marks Won/Lost itself.
Design-ahead spec
Stage = Decision Pending

What it does

Chases a decision with an email/SMS nudge looped up to twice via the counter, then alerts the rep. The rep moving the opp to Won/Lost is what fires WF6 or WF7.

Figure WF05 - Decision Nudge Loop
flowchart TD
    T(["Stage = Decision Pending"]):::trigger
    F{"Find Opportunity"}:::decision
    U["Found: Update opp -> Decision Pending, Open"]:::action
    TG["Tag: decision_pending"]:::action
    RC["Reset follow_up_count = 0"]:::action
    E1["Email: P1_005_CheckIn"]:::action
    N1["Notify team: pending"]:::action
    WL["Wait 3 days (loop top)"]:::wait
    EU["Email: P1_005_Urgency"]:::action
    SU["SMS: P1_005_SMS_Urgency"]:::action
    INC["follow_up_count + 1"]:::action
    D{"2+ nudges sent?"}:::decision
    NR["Notify team: rep decides"]:::action
    CN["Not Found: Create opp -> Decision Pending"]:::action
    Z(["End - rep moves Won/Lost -> WF6/WF7"]):::end_
    T --> F
    F -->|Found| U --> TG --> RC --> E1 --> N1 --> WL --> EU --> SU --> INC --> D
    F -->|Not Found| CN --> TG
    D -->|No| WL
    D -->|Yes| NR --> Z

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
WF 06

Project Won -> Celebrate + Delivery Handoff

Celebrate the signed deal, lock in build dates, and move the opportunity from Sales into the Delivery pipeline.
Design-ahead spec
Stage = Project Won

What it does

Welcomes the signed homeowner, alerts the crew, drives scheduling, then hands the deal to the Delivery pipeline at Project Scheduled (where D1 picks up).

Figure WF06 - Project Won + Handoff
flowchart TD
    T(["Stage = Project Won"]):::trigger
    F{"Find Opportunity"}:::decision
    U["Found: Update opp -> Won"]:::action
    RT["Remove stale Sales tags"]:::action
    TG["Tag: won + sales_to_delivery"]:::action
    E1["Email: P1_006_Welcome"]:::action
    W1["Wait 1 hour"]:::wait
    N["Notify crew: schedule + materials"]:::action
    E2["Email: P1_006_Scheduling (booking link)"]:::action
    S2["SMS: P1_006_SMS_Schedule"]:::action
    W2["Wait 2 days"]:::wait
    D{"Has build_scheduled tag?"}:::decision
    SR["SMS: P1_006_SMS_ScheduleReminder"]:::action
    CN["Not Found: Create opp -> Won"]:::action
    H(["Handoff: Delivery pipeline, Project Scheduled -> D1"]):::grant
    T --> F
    F -->|Found| U --> RT --> TG --> E1 --> W1 --> N --> E2 --> S2 --> W2 --> D
    F -->|Not Found| CN --> TG
    D -->|Scheduled| H
    D -->|Not yet| SR --> H

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
WF 07

Project Lost -> Win-Back Nurture

Part kindly, wait 30 days, then a seasonal check-in - and a Goal to catch them if they ever rebook.
Design-ahead spec
Status = Lost

What it does

Sends a gracious goodbye, waits a month, then a storm-season nudge, and tags them into a long-term campaign - with a Goal that re-welcomes anyone who rebooks.

Figure WF07 - Win-Back
flowchart TD
    T(["Status = Lost / Project Lost"]):::trigger
    F{"Find Opportunity"}:::decision
    U["Found: Update opp -> Lost"]:::action
    TG["Tag: lost"]:::action
    E1["Email: P1_007_ReEngage (goodbye)"]:::action
    N1["Notify team: log why lost"]:::action
    W1["Wait 30 days"]:::wait
    E2["Email: P1_007_SeasonalCheckIn"]:::action
    S2["SMS: P1_007_SMS_StormSeason"]:::action
    TR["Tag: re_engagement_journey"]:::action
    G{"Goal: appt confirmed (rebook)?"}:::decision
    TB["Tag: reengaged_rebooked"]:::action
    NB["Notify team: won back"]:::action
    CN["Not Found: Create opp -> Lost"]:::action
    WB(["Won back -> WF2"]):::grant
    Z(["End"]):::end_
    T --> F
    F -->|Found| U --> TG --> E1 --> N1 --> W1 --> E2 --> S2 --> TR --> G
    F -->|Not Found| CN --> TG
    G -->|Rebooks| TB --> NB --> WB
    G -->|Never returns| Z

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
D 01

Project Scheduled -> Build Onboarding

Welcome the customer into the build, tell them how to prep, give them the dates, alert the crew.
Design-ahead spec
Delivery: Project Scheduled

What it does

Onboards a signed customer into the build phase with welcome, prep, and timeline messages, plus a start reminder anchored to the build date.

Figure D01 - Build Onboarding
flowchart TD
    T(["Delivery: Project Scheduled"]):::trigger
    F{"Find Opportunity"}:::decision
    U["Found: Update opp -> Project Scheduled, Open"]:::action
    TG["Tag: sales_to_delivery"]:::action
    E1["Email: P2_001_Welcome"]:::action
    N["Notify crew: onto calendar"]:::action
    W1["Wait 1 day"]:::wait
    E2["Email: P2_001_Preparation"]:::action
    S1["SMS: P2_001_SMS_Prep"]:::action
    W2["Wait 1 day"]:::wait
    E3["Email: P2_001_Timeline"]:::action
    W3["Wait until 1 day before start"]:::wait
    S2["SMS: P2_001_SMS_StartReminder"]:::action
    CN["Not Found: Create opp -> Project Scheduled"]:::action
    Z(["End - helper advances to In Progress"]):::end_
    T --> F
    F -->|Found| U --> TG --> E1 --> N --> W1 --> E2 --> S1 --> W2 --> E3 --> W3 --> S2 --> Z
    F -->|Not Found| CN --> TG

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
D 02

In Progress -> Build Reassurance

Keep the homeowner calm while the crew builds, then hand to Project Complete - unless they flag a problem.
Design-ahead spec
Delivery: In Progress

What it does

Reassures the customer during the build, preps them for wrap-up, then advances to Project Complete - but stops and calls a human if a concern was raised.

Figure D02 - Build Reassurance
flowchart TD
    T(["Delivery: In Progress"]):::trigger
    F{"Find Opportunity"}:::decision
    U["Found: Update opp -> In Progress, Open"]:::action
    TG["Tag: in_progress"]:::action
    E1["Email: P2_002_ProgressUpdate"]:::action
    S1["SMS: P2_002_SMS_Started"]:::action
    N["Notify crew: dispatch"]:::action
    E2["Email: P2_002_CompletionPrep"]:::action
    W1["Wait 3 days"]:::wait
    D{"project_concern raised?"}:::decision
    NC["Notify team: concern - human steps in"]:::action
    ZC(["End - hold for human"]):::end_
    E3["Email: P2_002_StatusUpdate"]:::action
    S2["SMS: P2_002_SMS_Wrapup"]:::action
    PC(["Update opp -> Project Complete -> D3"]):::end_
    CN["Not Found: Create opp -> In Progress"]:::action
    T --> F
    F -->|Found| U --> TG --> E1 --> S1 --> N --> E2 --> W1 --> D
    F -->|Not Found| CN --> TG
    D -->|Concern| NC --> ZC
    D -->|All good| E3 --> S2 --> PC

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
D 03

Project Complete -> Warranty + Review Ask

Thank them, deliver warranty info, then ask for a Google review with one gentle nudge - exit the moment they review.
Design-ahead spec
Delivery: Project Complete

What it does

Sends the completion + warranty email, waits a day, asks for a review, and nudges once more if they don't review - then advances to Review Requested.

Figure D03 - Warranty + Review
flowchart TD
    T(["Delivery: Project Complete"]):::trigger
    F{"Find Opportunity"}:::decision
    U["Found: Update opp -> Project Complete, Open"]:::action
    TG["Tag: project_complete"]:::action
    E1["Email: P2_003_Completion (warranty)"]:::action
    N["Notify team: complete"]:::action
    W1["Wait 1 day"]:::wait
    E2["Email: P2_003_Review_Request"]:::action
    S1["SMS: P2_003_SMS_Review"]:::action
    W2["Wait 2 days"]:::wait
    D{"review_sent?"}:::decision
    E3["Email: P2_003_Email_Reminder"]:::action
    S2["SMS: P2_003_SMS_Reminder"]:::action
    RR(["Update opp -> Review Requested -> D4"]):::end_
    Z(["End - they reviewed"]):::end_
    CN["Not Found: Create opp -> Project Complete"]:::action
    T --> F
    F -->|Found| U --> TG --> E1 --> N --> W1 --> E2 --> S1 --> W2 --> D
    F -->|Not Found| CN --> TG
    D -->|Reviewed| Z
    D -->|No review| E3 --> S2 --> RR

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
D 04

Review Requested -> Referral Activation

Turn a review-link clicker into a referral-primed advocate, then graduate them to Warranty care.
Design-ahead spec
Review link clicked

What it does

Thanks the happy customer (no ask), alerts the team to reply publicly, then asks for a referral at peak goodwill before moving them to Warranty Follow Up.

Figure D04 - Referral Activation
flowchart TD
    T(["Review link clicked"]):::trigger
    F{"Find Opportunity"}:::decision
    U["Found: Update opp -> Review Requested, Open"]:::action
    TG["Tag: review_clicked"]:::action
    E1["Email: P2_004_ThankYou (no ask)"]:::action
    N["Notify team: reply publicly"]:::action
    W1["Wait 2 days"]:::wait
    D{"Already referred?"}:::decision
    E2["Email: P2_004_Referral"]:::action
    S1["SMS: P2_004_SMS_Referral"]:::action
    TR["Tag: referral_requested"]:::action
    WF(["Update opp -> Warranty Follow Up -> D5"]):::end_
    CN["Not Found: Create opp -> Review Requested"]:::action
    T --> F
    F -->|Found| U --> TG --> E1 --> N --> W1 --> D
    F -->|Not Found| CN --> TG
    D -->|Yes| WF
    D -->|Not yet| E2 --> S1 --> TR --> WF

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
D 05

Warranty Follow Up -> Retention + Referral

Turn a one-time customer into a long-term referring client: warranty, seasonal care, standing referral incentive.
Design-ahead spec
Delivery: Warranty Follow Up

What it does

Hands over the warranty, teaches seasonal roof care, keeps a referral incentive in front of them, then advances to Client Retained - the completion signal.

Figure D05 - Retention
flowchart TD
    T(["Delivery: Warranty Follow Up"]):::trigger
    F{"Find Opportunity"}:::decision
    U["Found: Update opp -> Warranty Follow Up, Open"]:::action
    TG["Tag: warranty_followup"]:::action
    E1["Email: P2_005_Warranty"]:::action
    N["Notify team: retention"]:::action
    W1["Wait 4 days"]:::wait
    E2["Email: P2_005_MaintenanceTips"]:::action
    W2["Wait 7 days"]:::wait
    E3["Email: P2_005_ReferralOffer"]:::action
    S1["SMS: P2_005_SMS_Referral"]:::action
    W3["Wait 3 days"]:::wait
    CR(["Update opp -> Client Retained + tag"]):::grant
    CN["Not Found: Create opp -> Warranty Follow Up"]:::action
    T --> F
    F -->|Found| U --> TG --> E1 --> N --> W1 --> E2 --> W2 --> E3 --> S1 --> W3 --> CR
    F -->|Not Found| CN --> TG

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
REV

Review Requested -> Google Review Engine

The paid offer. Ask a happy customer for a Google review, nudge once, and stop the moment they leave one. One workflow plus one tiny helper - no pipeline.
Design-ahead spec
Tag review_requested added
Say it simply When a job is finished, your happy customer gets one friendly text and email asking for a quick Google review. We nudge them once, and the second they leave it, we stop - so your star rating climbs and more homeowners find you.

What it does

Fires when the job is marked done (tag review_requested), sends the review ask by SMS and email, waits 2 days, then sends one reminder only if they have not reviewed yet - and a tiny helper stops the nudge the moment a review lands.

Figure REV - Review Engine
flowchart TD
    T(["Tag added: review_requested"]):::trigger
    S1["SMS: Review ask + Google link"]:::action
    E1["Email: Review ask (backup)"]:::action
    W1["Wait 2 days"]:::wait
    G{"Has tag review_sent?"}:::decision
    Z1(["Yes: already reviewed -> End"]):::end_
    S2["No: one reminder SMS"]:::action
    Z2(["End"]):::end_
    H(["Helper: New Review / link clicked -> tag review_sent + thank"]):::grant
    T --> S1 --> E1 --> W1 --> G
    G -->|Yes| Z1
    G -->|No| S2 --> Z2
    H -.stops the nudge.-> G

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
MCTB

Missed Call -> Instant Text-Back

A missed call is a missed job. Text them back in seconds, flag the team, nudge once. Standalone responder - no pipeline.
Design-ahead spec
Inbound call goes unanswered
Say it simply If someone calls and you cannot pick up, they get a text back within seconds - so you do not lose the job to the next company. Your team gets pinged to call them back, and if they go quiet, one polite nudge, then it stops.

What it does

When an inbound call is missed, it tags the caller, texts them back within seconds, alerts the team to call back, waits an hour, then sends one follow-up only if they stayed silent - and can optionally park them as a real lead.

Figure MCTB - Missed Call Text-Back
flowchart TD
    T(["Call Status Missed: No Answer/Voicemail + Inbound"]):::trigger
    TG["Tag: missed_call"]:::action
    S1["SMS: Instant text-back (seconds)"]:::action
    N["Notify team: call them back"]:::action
    W1["Wait 1 hour"]:::wait
    S2["SMS: One follow-up (Stop on Response ON)"]:::action
    O["Optional: Create opp -> parks at New Lead"]:::action
    Z(["End"]):::end_
    T --> TG --> S1 --> N --> W1 --> S2 --> O --> Z

    classDef trigger fill:#14213D,stroke:#14213D,color:#ffffff,font-weight:bold
    classDef action fill:#ffffff,stroke:#CBD5E1,color:#14213D
    classDef wait fill:#EEF2F8,stroke:#9DB2CC,color:#475569
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#78350F
    classDef grant fill:#2E5E96,stroke:#1E3A5F,color:#ffffff,font-weight:bold
    classDef end_ fill:#0C1730,stroke:#14213D,color:#ffffff
      
06

Email & SMS Library

Every copy-paste-ready template for the whole journey - grouped by workflow. Sent via LeadConnector (mail.gokai.pro). Set the merge tags in Custom Values before you go live, and confirm each sending number is A2P/10DLC verified before enabling SMS.
Before you paste: every merge tag below pulls from the Custom Values you built in the foundation step - set those first or the emails send with blank fields. Merge tags are shown in this style and must be copied exactly, braces and all. Emoji inside the body copy are intentional and meant to ship as-is.
WF1 New Lead Welcome 3 emails + 2 SMS + 1 team alert · Trigger: Form Submitted
Email formatting - apply to every email before saving: Ctrl+A to select all · Font Arial · Size 14px · Line height 1.5 · Save action · Publish.
TriggerForm Submitted
Demo StormLine Lead Form Submitted
Fires the instant the lead sends the form. Filter: Form is -> demo StormLine Lead Form
WF1_WelcomeImmediately
Subject: We got your request, {{contact.first_name}}
Hi {{contact.first_name}}, Thanks for reaching out to {{custom_values.business_name}}. We've received your storm damage assessment request and we're ready to help. To prevent hidden damage from getting worse, the next step is to schedule your free roof inspection. - No obligation - Professional storm damage assessment - Insurance claim assistance if needed It only takes about 2 minutes to book: -> {{custom_values.booking_link}} Once you choose a time, you'll receive a confirmation with all the details. If you'd prefer to speak with someone immediately, call us at {{custom_values.company_phone}}. Stay safe, The {{custom_values.business_name}} Team {{custom_values.company_phone}} · {{custom_values.from_email}}
WF1_Nudge1+1 day (if not booked)
Subject: Don't let storm damage spread, {{contact.first_name}}
Hi {{contact.first_name}}, Quick reminder - your free roof inspection with {{custom_values.business_name}} is still open. With storm damage, waiting is the costly part. Small leaks get bigger, and insurers get stricter over time. Takes 2 minutes, zero obligation: -> {{custom_values.booking_link}} Prefer to talk? Call {{custom_values.company_phone}}. Stay safe, The {{custom_values.business_name}} Team
WF1_Nudge2_Value+2 days after Nudge1 (last call)
Subject: Last reminder, {{contact.first_name}}
Hi {{contact.first_name}}, We don't want to crowd your inbox, so this is our last note about your free storm damage inspection. If you'd still like {{custom_values.business_name}} to take a look - no cost, no obligation - grab a time here: -> {{custom_values.booking_link}} If now's not the right time, no worries at all. We're here when you need us. Stay safe, The {{custom_values.business_name}} Team {{custom_values.company_phone}}
WF1 SMS - speed-to-lead text + nudge
SMS rules: keep under 160 characters (1 segment) · opt-out pulls from {{custom_values.sms_output}} ("Reply STOP to opt out") · requires a verified A2P/10DLC sending number.
SMSWF1_SMS_WelcomeImmediately (after Welcome email)
Speed-to-lead text
Hi {{contact.first_name}}, it's {{custom_values.business_name}}. Got your storm damage request - a real person will call you in about 10 minutes to set up your free inspection. Prefer to pick a time yourself? {{custom_values.booking_link}} {{custom_values.sms_output}}
SMSWF1_SMS_Nudge+2 min after Nudge1 email (if not booked)
Booking nudge text
Hi {{contact.first_name}}, just following up - still want that free roof inspection? Pick a time that works and we'll handle the rest: {{custom_values.booking_link}} {{custom_values.sms_output}}
WF1 Internal Notification - alerts your team, not the contact
Team AlertWF1_Notify_NewLead
Title: New Lead Alert
New Roof Quote Lead {{contact.first_name}} {{contact.phone}} {{contact.email}} Redirect Page: Opportunity
WF2 Appointment Reminder 3 emails + 2 SMS + 1 team alert · Trigger: Appointment Booked (Roofing Consultation)
Email formatting: Ctrl+A · Arial · 14px · line height 1.5 · Save · Publish.
WF2_ConfirmationImmediately on booking
Subject: You're booked! Here's what to expect
Hey {{contact.first_name}}, Your free roof inspection is confirmed. {{appointment.start_time}} {{contact.full_address}} What to expect: Our inspector will assess the roof, document any visible damage, and answer your questions. Most inspections take about 30-45 minutes. No preparation is needed - just be available when we arrive. Questions? Reply to this email or call us at {{custom_values.company_phone}}. - {{custom_values.business_name}} {{custom_values.from_email}}
WF2_DayBefore1 day before appointment
Subject: Reminder: your inspection is tomorrow
Hey {{contact.first_name}}, Just a quick reminder - your roof inspection is tomorrow. {{appointment.start_time}} {{contact.full_address}} A few tips for tomorrow: - Make sure we can access the property - If you have a gate code or dog, let us know - You're welcome to be home or not - totally up to you Need to reschedule? Just reply to this email or call us at {{custom_values.company_phone}}. See you tomorrow, - {{custom_values.business_name}}
WF2_HeadsUp1 hour before appointment
Subject: We're on our way - inspection in ~1 hour
Hey {{contact.first_name}}, Heads up - our inspector is on the way and your roof inspection starts in about 1 hour. {{appointment.start_time}} If anything changes before we arrive, reply to this email or call us at {{custom_values.company_phone}}. See you soon, - {{custom_values.business_name}}
WF2 SMS - the two no-show killers
SMS rules: keep short (~160 chars) · opt-out from {{custom_values.sms_output}} · verified A2P/10DLC number · time each Wait before the appointment.
SMSWF2_SMS_DayBefore1 day before appt
Day-before reminder text
Hi {{contact.first_name}}, reminder from {{custom_values.business_name}}: your free roof inspection is tomorrow at {{appointment.start_time}} Reply here if anything changes. {{custom_values.sms_output}}
SMSWF2_SMS_HeadsUp1 hour before appt
On-our-way text
{{contact.first_name}}, {{custom_values.business_name}} here - our inspector is on the way, about 1 hour out. See you soon at {{contact.full_address}}! {{custom_values.sms_output}}
WF2 Internal Notification
Team AlertWF2_Notify_Team
Title: New inspection booked
New inspection booked {{contact.first_name}} {{contact.last_name}} {{appointment.start_time}} {{contact.full_address}} {{contact.phone}} Redirect: Opportunity
NSR No-Show Recovery 3 emails + 1 SMS · Trigger: Appointment Status = No-Show · branches by tag existing_customer
NSR_NoShow_ExistingCustomerBranch: has tag existing_customer
Subject: We missed you today, {{contact.first_name}}
Hey {{contact.first_name}}, It looks like we missed each other today - no worries at all, things come up. We'd love to get your inspection rescheduled whenever it works for you. Since you've worked with us before, we'll make it as easy as possible. -> {{custom_values.booking_link}} Or just reply to this email and we'll find a time together. - {{custom_values.business_name}} {{custom_values.company_phone}}
NSR_NoShow_FirstTimerBranch: no existing_customer tag
Subject: Still interested in a free quote?
Hey {{contact.first_name}}, We stopped by for your inspection today but couldn't connect - totally fine, life gets busy. Your free quote is still waiting. Storm damage doesn't fix itself and your window to file an insurance claim may be limited. It only takes a few minutes to rebook: -> {{custom_values.booking_link}} No pressure - just want to make sure you get the help you reached out for. - {{custom_values.business_name}} {{custom_values.company_phone}}
NSR_LastTryFinal attempt · exits to rep notify
Subject: Last chance - closing your file soon
Hey {{contact.first_name}}, We've tried to connect a few times and we don't want to keep filling your inbox if the timing isn't right. This is our last reach-out. If you'd still like a free roof inspection, grab a time here: -> {{custom_values.booking_link}} Or call us directly: {{custom_values.company_phone}} If we don't hear back, we'll close your file and you're always welcome to reach out again when you're ready. - {{custom_values.business_name}} {{custom_values.from_email}}
NSR SMS - rebook nudge (rides after the first "we missed you" email)
SMSNSR_SMS_RebookAfter the rebook email
Rebook nudge text
Hi {{contact.first_name}}, sorry we missed each other! Grab a new time for your roof inspection here whenever you're ready. {{custom_values.sms_output}}
WF4 Estimate Sent 1 email (reused x3 via Go To loop) + 1 SMS + 1 team alert · follow_up_count increments each cycle
WF4_QuoteFU_LoopReused up to 3x
Subject: Quick question about your Stormline estimate
Hey {{contact.first_name}}, We sent over your roof estimate a little while ago and wanted to check in - do you have any questions about what we put together? We know estimates can feel overwhelming, especially when insurance is involved. We're happy to walk you through it line by line, talk through the timeline, or adjust the scope if needed. Just reply to this email or give us a call at {{custom_values.company_phone}} - no pressure, just here to help you make the right call. - {{custom_values.business_name}} {{custom_values.company_phone}} · {{custom_values.from_email}}
Loop logic
Cycle 1: Sent when stage -> Estimate Sent. follow_up_count = 0 -> 1

Cycle 2: 3 days wait -> loop back. Count = 1 -> 2

Cycle 3: 3 days wait -> loop back. Count = 2 -> 3

Exit: Count ≥ 3 -> If/Else exits -> rep notified -> contact stays in Decision Pending

Reset follow_up_count to 0 any time a new estimate is issued.
WF4 SMS - rides after each follow-up email (reused every cycle)
SMSWF4_SMS_FollowUpAfter each WF4_QuoteFU_Loop email
Estimate follow-up text
Hi {{contact.first_name}}, any questions on your roof estimate? Happy to walk you through it. {{custom_values.sms_output}}
WF4 Internal Notification
Team AlertWF4_Notify_EstimateOut
Title: Estimate sent - watch for a reply
Estimate sent - watch for a reply {{contact.first_name}} {{contact.last_name}} {{contact.phone}} Estimate is out. Catch any reply or call quickly while it's top of mind. Redirect: Opportunity
Review Review Engine (the paid offer, Delivery D4) 3 templates (2 required, 1 optional) + canonical lean copy · Trigger: tag request_review (after Project Complete)
Review_Ask2 days after Project Complete
Subject: How did we do, {{contact.first_name}}?
Hey {{contact.first_name}}, We hope your roof project went smoothly and you're feeling good about the work we did. If you have 60 seconds, leaving us a Google review would mean the world to our small team - it helps other homeowners find us when they need help most. -> {{custom_values.google_review_link}} Honest feedback only - we read every review and use it to get better. Thank you for trusting {{custom_values.business_name}} with your home. - The {{custom_values.business_name}} Team {{custom_values.company_phone}}
Review_Reminder+4 days (if no review_left tag)
Subject: One quick favor, {{contact.first_name}}
Hey {{contact.first_name}}, We reached out a few days ago about leaving a review - we know things get busy, so just bumping this up in case it got buried. If the project went well, a quick star rating helps us more than you might think: -> {{custom_values.google_review_link}} This is the last we'll ask - promise. - {{custom_values.business_name}} {{custom_values.company_phone}}
Review_ThanksOptional · fires if tag review_left exists
Subject: Thank you for the review!
Hey {{contact.first_name}}, We saw your review - thank you so much! It genuinely makes a difference and we're grateful you took the time. If you ever need us again or want to refer a neighbor, we're always here. - The {{custom_values.business_name}} Team {{custom_values.company_phone}} · {{custom_values.from_email}} OPTIONAL - only build if you set up a webhook/Zapier to tag contacts when a review is submitted.
Review Engine - canonical lean copy (matches the blueprint's Reviews tab 1:1, the version to actually build)
The canonical lean offer - 1 email + 2 SMS. Each message has a "not happy? reply first" service-recovery valve so unhappy customers route to you privately, not to Google. (The 3 longer emails above are an optional extended variant.)
SMSReview_SMS_AskImmediate
Review ask text
Hi {{contact.first_name}}, thanks for trusting {{custom_values.business_name}} with your roof! Would you mind leaving us a quick Google review? {{custom_values.google_review_link}} And if anything fell short, just reply here first - we'll make it right. {{custom_values.sms_output}}
Review_Email_AskImmediate
Subject: How did we do, {{contact.first_name}}?
Hi {{contact.first_name}}, Thank you for choosing {{custom_values.business_name}}. If you're happy with your new roof, a quick Google review would mean the world to our team: -> {{custom_values.google_review_link}} If anything wasn't perfect, just reply to this email first - we'd rather fix it than have you leave unhappy. - The {{custom_values.business_name}} Team
SMSReview_SMS_Reminder2 days later · only if no review
Review reminder text
Hi {{contact.first_name}}, quick nudge from {{custom_values.business_name}} - a 1-minute Google review really helps our small team get found by other homeowners: {{custom_values.google_review_link}}. Thank you! {{custom_values.sms_output}}
Not yet built - paste-ready copy for the rest of the journey
Everything below is written and ready but not built in GHL yet. Subjects and SMS bodies match the master doc (ghl-workflow-maps.html) 1:1; the email bodies are new.
WF3 Inspection Complete 2 emails + 1 SMS + 1 team alert · Trigger: Appt Status = showed -> stage Inspection Complete
P1_003_ThankYouImmediately after the inspection
Subject: Thanks for having us out, {{contact.first_name}} - here's what we found
Hey {{contact.first_name}}, Thanks for having us out today - it was a pleasure taking a look at your roof. Here's the short version: our inspector documented everything we saw, took photos, and is now putting together your detailed assessment and estimate. What happens next: - We write up the findings + a clear, itemized estimate - You'll have it within 1-2 business days - If insurance is involved, we'll flag exactly what to file No surprises and no pressure - just a straight answer on where your roof stands. Questions in the meantime? Reply here or call {{custom_values.company_phone}}. - {{custom_values.business_name}} {{custom_values.company_phone}} · {{custom_values.from_email}}
P1_003_EstimateTimeline+1 day (sets the expectation)
Subject: Your estimate is on the way - here's when to expect it
Hi {{contact.first_name}}, Quick update - your roof estimate from {{custom_values.business_name}} is being finalized right now. You'll have it in your inbox within the next business day. When it lands, you'll see: - A clear breakdown of the work + materials - Photos of what we found up top - Your options, with no obligation to move forward If a storm caused the damage, we'll also point out what's typically covered so you can decide whether to file. Sit tight - it's coming. Questions? Just reply. - {{custom_values.business_name}} {{custom_values.company_phone}}
WF3 SMS - rides after the thank-you email
SMSP1_003_SMS_TimelineAfter P1_003_ThankYou email
Estimate-timeline text
Hi {{contact.first_name}}, thanks again for having us out today - your estimate will be over within 1-2 business days. {{custom_values.sms_output}}
WF3 Internal Notification
Team AlertInternal Notification - Estimate due
Title: Estimate due - prepare + send for {{contact.first_name}} {{contact.last_name}}
Estimate due - build it + send it {{contact.first_name}} {{contact.last_name}} {{contact.phone}} {{contact.full_address}} A human prepares & sends the estimate within 1-2 business days. Redirect: Opportunity
WF5 Decision Pending 1 email + 1 SMS + 1 team alert · Trigger: stage Decision Pending · gentle nudge while they decide
P1_005_CheckInA few days after the estimate (loops)
Subject: Any questions about your estimate?
Hey {{contact.first_name}}, Just checking in on the roof estimate we sent over - did everything make sense? A lot of homeowners have questions once they sit with it, and that's completely normal. Happy to walk you through any line item, talk timeline, or explain how the insurance side works. One thing worth knowing: if a storm caused the damage, insurance claim windows can close, so it's worth not letting it sit too long. Want to talk it through? Just reply or call {{custom_values.company_phone}} - no pressure either way. - {{custom_values.business_name}} {{custom_values.company_phone}} · {{custom_values.from_email}}
Nudge loop
Same as WF4 - follow_up_count increments each cycle. After 2-3 check-ins with no reply, the loop exits and the rep is notified (P1_005_Notify_Pending). Contact stays in Decision Pending.
WF5 SMS - the urgency nudge
SMSP1_005_SMS_UrgencyAfter P1_005_CheckIn email
Claim-window nudge
Hi {{contact.first_name}}, heads-up - insurance claim windows can close fast. Happy to help you decide. {{custom_values.sms_output}}
WF5 Internal Notification
Team AlertP1_005_Notify_Pending
Title: Awaiting decision - auto-chase started
Awaiting decision - auto-chase running {{contact.first_name}} {{contact.last_name}} {{contact.phone}} Estimate sent, no reply yet. Nudge loop is running (cap 2). When it ends, a rep should call to close. Stays Decision Pending · Open. Redirect: Opportunity
WF6 Won 1 email + 2 SMS + 1 team alert · Trigger: Status = Won · welcome + lock in build dates
P1_006_WelcomeImmediately on Won
Subject: Welcome to the family, {{contact.first_name}}! Here's what's next
Hey {{contact.first_name}}, Welcome to the {{custom_values.business_name}} family - we're genuinely excited to get your new roof done right. Here's how the next stretch looks: 1. Lock in your build dates (pick a slot below) 2. We'll send a simple prep checklist before we start 3. Our crew handles the rest - and we keep you posted the whole way -> {{custom_values.booking_link}} You made a smart call protecting your home, and we don't take that lightly. Any questions at all, reply here or call {{custom_values.company_phone}}. - The {{custom_values.business_name}} Team {{custom_values.company_phone}} · {{custom_values.from_email}}
Then
Team alert P1_006_Internal_CrewScheduling fires for scheduling, and the opp advances to Project Won. The 2 SMS below chase the build-date booking if they haven't picked a slot.
WF6 SMS - book the build dates, then a reminder
SMSP1_006_SMS_ScheduleAfter P1_006_Welcome email
Lock-in-dates text
Hi {{contact.first_name}}, congrats again! Let's lock in your build dates - grab a slot here: {{custom_values.booking_link}} {{custom_values.sms_output}}
SMSP1_006_SMS_ScheduleReminder+2 days if not booked
Booking reminder text
Hi {{contact.first_name}}, just making sure you got a chance to pick your build dates - here's the link again: {{custom_values.booking_link}} {{custom_values.sms_output}}
WF6 Internal Notification
Team AlertP1_006_Internal_CrewScheduling
Title: New WON deal - start crew scheduling + order materials
New WON deal {{contact.first_name}} {{contact.last_name}} {{contact.phone}} {{contact.full_address}} Start crew scheduling + order materials. Redirect: Opportunity
WF7 Lost 1 email + 1 SMS + 2 team alerts · Trigger: Status = Lost · soft win-back, leave the door open
P1_007_ReEngageShortly after marked Lost
Subject: No worries, {{contact.first_name}} - we're here whenever you're ready
Hey {{contact.first_name}}, Totally understand - the timing isn't right for everyone, and there's zero hard feelings on our end. We'll close out your file for now, but the door stays open. If anything changes - a new leak, another storm, or you just want a second opinion - we'd be glad to take another look. We'll keep your assessment on record, so picking back up later is easy. No need to start over. Take care of that roof, and reach out anytime: {{custom_values.company_phone}}. - {{custom_values.business_name}} {{custom_values.company_phone}} · {{custom_values.from_email}}
Win-back
Team is alerted (P1_007_Notify_Lost) and the opp moves to Project Lost. The storm-season SMS below is the long-game re-engage; if they bite, P1_007_Notify_WonBack pings the rep.
WF7 SMS - storm-season re-engage
SMSP1_007_SMS_StormSeasonLong-delay win-back
Storm-season text
Hi {{contact.first_name}}, storm season's coming up - if your roof's still on your mind, we'd love to take another look, no pressure. {{custom_values.sms_output}}
WF7 Internal Notifications - one when Lost, one if the win-back lands
Team AlertP1_007_Notify_LostOn Status = Lost
Title: Deal lost - try a save call + log WHY
Deal lost {{contact.first_name}} {{contact.last_name}} {{contact.phone}} Try a save call before it goes cold - and log WHY we lost it. Redirect: Opportunity
Team AlertP1_007_Notify_WonBackIf they re-book
Title: Win-back! A Lost lead just re-booked a consultation
Win-back! {{contact.first_name}} {{contact.last_name}} {{contact.phone}} A Lost lead just re-booked a consultation - give them priority. Redirect: Opportunity
Delivery pipeline (D1-D5) - post-sale, after the Sales -> Delivery handoff
The build experience: scheduled -> in progress -> complete -> review -> warranty. The review ask (your paid offer) lives at D3/D4.
D1 Project Scheduled (P2_001) 3 emails + 2 SMS + 1 team alert · Trigger: tag Sales to Delivery
P2_001_WelcomeOn handoff to Delivery
Subject: Welcome aboard, {{contact.first_name}} - your build is officially scheduled!
Hey {{contact.first_name}}, Great news - your roof build is officially on the schedule. You're now working with our delivery crew, the team that actually gets it done. Here's what you can count on from us: - Clear communication at every stage - A clean, respectful job site - A finished roof we both stand behind Over the next few days you'll get a prep checklist and your project timeline. Nothing you need to do right now - just sit tight. Questions any time: {{custom_values.company_phone}}. - The {{custom_values.business_name}} Team {{custom_values.company_phone}} · {{custom_values.from_email}}
P2_001_PreparationA few days before start
Subject: How to prep your property before we start, {{contact.first_name}}
Hi {{contact.first_name}}, Your build is coming up - here's a quick prep checklist so the day goes smoothly: - Clear cars from the driveway the morning of - Keep pets indoors (roof work is loud) - Cover or move valuables stored in the attic - Take down loose wall decor - vibrations can shake frames - Make sure we can access the yard / gate That's it. Our crew handles the rest, including a full cleanup with a magnetic nail sweep before we leave. Anything you're unsure about? Just reply or call {{custom_values.company_phone}}. - {{custom_values.business_name}}
P2_001_Timeline~1 day before start
Subject: Your project dates & milestones, {{contact.first_name}}
Hey {{contact.first_name}}, Here's what to expect once we start: Day 1: Crew arrives, tear-off + inspection of the decking Day 1-2: Underlayment, flashing, and new shingles go on Final: Full cleanup, nail sweep, and a walkthrough with you Most roofs finish in 1-2 days, weather permitting. If anything shifts, we'll tell you right away - no guessing. We're looking forward to getting started. See you soon! - {{custom_values.business_name}} {{custom_values.company_phone}}
D1 SMS - prep checklist + start reminder
SMSP2_001_SMS_PrepAfter P2_001_Preparation email
Prep text
Hi {{contact.first_name}}, quick heads-up before your build: please clear cars from the driveway, keep pets indoors, and cover items in the attic. Full checklist in your email! {{custom_values.sms_output}}
SMSP2_001_SMS_StartReminder1 day before start
Start-tomorrow text
Hi {{contact.first_name}}, your roof build starts tomorrow! Please have the driveway clear and pets secured. We're excited to get going. {{custom_values.sms_output}}
D1 Internal Notification
Team AlertP2_001_Notify_Crew
Title: New build scheduled - get it on the crew/PM build calendar
New build scheduled {{contact.first_name}} {{contact.last_name}} {{contact.phone}} {{contact.full_address}} Get it on the crew/PM build calendar. Redirect: Opportunity
D2 In Progress (P2_002) 3 emails + 2 SMS + 2 team alerts · Trigger: tag In Progress · keep them in the loop
P2_002_ProgressUpdateWhen crew starts
Subject: We've started, {{contact.first_name}} - your roof build is underway
Hey {{contact.first_name}}, It's happening - our crew is on site and your new roof is officially underway. We'll keep you posted at the big milestones so you always know where things stand. You don't need to be home; the team has everything they need. If you have any questions while we work, just reply here or call {{custom_values.company_phone}} - someone will get right back to you. Thanks for trusting us with your home. - {{custom_values.business_name}}
P2_002_CompletionPrepAs the job nears the end
Subject: What to expect as we wrap up your roof, {{contact.first_name}}
Hi {{contact.first_name}}, We're getting close to the finish line on your roof. Here's what happens as we wrap up: - Final shingles, flashing, and detail work - A complete site cleanup + magnetic nail sweep - A quick walkthrough so you can see the finished result Once it's done, we'll send your completion summary and warranty details. Almost there - thanks for your patience! - {{custom_values.business_name}} {{custom_values.company_phone}}
P2_002_StatusUpdateIf the job runs long / delay branch
Subject: Quick status update on your roof, {{contact.first_name}}
Hey {{contact.first_name}}, Quick update on your build - we want to keep you in the loop. Roofing depends on weather and what we find under the old layer, so timelines occasionally shift. If yours has, here's where things stand and what's next. Our goal is always to do it right, not just fast. We'll have you fully finished as soon as conditions allow, and we'll flag anything that affects your dates. Questions? Reply here or call {{custom_values.company_phone}} anytime. - {{custom_values.business_name}}
D2 SMS - build started + wrap-up
SMSP2_002_SMS_StartedAfter P2_002_ProgressUpdate email
Build-started text
Hi {{contact.first_name}}, our crew is on your roof and the build is officially underway. We'll keep you posted every step of the way. {{custom_values.sms_output}}
SMSP2_002_SMS_WrapupAfter P2_002_CompletionPrep email
Wrap-up text
Hi {{contact.first_name}}, we're heading into the wrap-up stage on your roof - almost done! We'll let you know the moment it's complete. {{custom_values.sms_output}}
D2 Internal Notifications - dispatch on start, plus a concern alert from the If/Else
Team AlertP2_002_Internal_CrewDispatchOn build start
Title: Build started - confirm crew, materials, dumpster, permit
Build started {{contact.first_name}} {{contact.last_name}} {{contact.full_address}} Confirm crew, materials, dumpster, and permit are in place. Redirect: Opportunity
Team AlertP2_002_Internal_ConcernIf/Else FALSE branch
Title: Concern raised on a live build - PM must resolve before advancing
Concern raised on a live build {{contact.first_name}} {{contact.last_name}} {{contact.phone}} PM must resolve before advancing. Do NOT auto-advance to Complete. Redirect: Opportunity
D3 Project Complete (P2_003) 2 emails + 2 SMS + 1 team alert · Trigger: tag Complete · the review ask lives here
P2_003_CompletionOn Project Complete
Subject: All done, {{contact.first_name}} - your new roof + warranty info inside
Hey {{contact.first_name}}, It's official - your new roof is complete! Thank you for trusting {{custom_values.business_name}} with your home. A few things for your records: - Your workmanship + manufacturer warranty details (attached / linked) - Final cleanup is done, including a magnetic nail sweep of the yard - Photos of the finished work, if you'd like a copy - just ask If you spot anything that needs a second look, reply here or call {{custom_values.company_phone}}. We stand behind our work. It's been a pleasure. Enjoy the peace of mind! - The {{custom_values.business_name}} Team {{custom_values.company_phone}} · {{custom_values.from_email}}
P2_003_Review_Request~2 days after Complete
Subject: {{contact.first_name}}, would you share a quick review?
Hey {{contact.first_name}}, Now that your roof's done and you've had a couple of days to enjoy it - how did we do? If you're happy with the work, a quick Google review would mean a lot to our team. It's the #1 way other homeowners find a roofer they can trust. -> {{custom_values.google_review_link}} It takes about 30 seconds. And if anything fell short of what you expected, reply to this email instead - I'd rather hear it directly and make it right. Thank you, truly. - The {{custom_values.business_name}} Team {{custom_values.company_phone}}
D3 SMS - review ask + gentle reminder (the review engine)
SMSP2_003_SMS_ReviewAfter P2_003_Review_Request email
Review-ask text
Hi {{contact.first_name}}, hope you're loving the new roof! If you have 30 seconds, a quick review means the world to us: {{custom_values.google_review_link}} {{custom_values.sms_output}}
SMSP2_003_SMS_Reminder+days if no review_left tag
Review reminder text
Hi {{contact.first_name}}, just a gentle reminder - if you have a sec, we'd love a quick review: {{custom_values.google_review_link}}. Not happy with anything? Reply here and I'll call you. {{custom_values.sms_output}}
D3 Internal Notification
Team AlertP2_003_Internal_Complete
Title: Project complete - file the warranty packet + mark referral-eligible
Project complete {{contact.first_name}} {{contact.last_name}} {{contact.full_address}} File the warranty packet + mark referral-eligible. Redirect: Opportunity
D4 Review Requested (P2_004) 2 emails + 1 SMS + 1 team alert · Trigger: stage Review Requested · thank + ask for referrals
P2_004_ThankYouAfter a review is left
Subject: Thank you, {{contact.first_name}} - it means the world to us
Hey {{contact.first_name}}, We just saw your review - thank you so much! For a local team like ours, a few honest words from a happy homeowner genuinely changes who finds us and trusts us next. We don't take it for granted. If you ever need us - a repair, a question, or just a second opinion down the road - you're family now. We're one call away: {{custom_values.company_phone}}. Thanks again for letting us protect your home. - The {{custom_values.business_name}} Team {{custom_values.company_phone}} · {{custom_values.from_email}}
P2_004_Referral+days after thank-you
Subject: Know a neighbor who needs a roof, {{contact.first_name}}?
Hey {{contact.first_name}}, Storms don't hit just one house - odds are a neighbor or two could use the same help you just got. If you know someone with a roof that's seen better days, we'd love an introduction. And because referrals are the best compliment we can get, there's a thank-you in it for both of you. Just reply with their name, or pass along our number: {{custom_values.company_phone}}. We'll take great care of them, same as we did for you. Thanks for spreading the word. - {{custom_values.business_name}} {{custom_values.company_phone}}
D4 SMS - referral ask
SMSP2_004_SMS_ReferralAfter P2_004_Referral email
Referral text
Hi {{contact.first_name}}, so glad you're happy with your new roof! If a neighbor could use us, we'd love an intro - there's a perk in it for you both. {{custom_values.sms_output}}
D4 Internal Notification
Team AlertP2_004_Notif_HappyCustomer
Title: Happy customer clicked the review link - reply publicly within 24 hrs
Happy customer clicked the review link {{contact.first_name}} {{contact.last_name}} {{contact.phone}} Reply publicly to their review within 24 hrs. Redirect: Opportunity
D5 Warranty Follow-Up (P2_005) 3 emails + 1 SMS + 1 team alert · Trigger: tag Warranty_followup · the long-game retention loop
P2_005_WarrantyShortly after completion
Subject: Your roof warranty, {{contact.first_name}} - proof + how to file
Hi {{contact.first_name}}, Keep this one - it's your proof of warranty and how to use it. Your new roof is covered by both a manufacturer warranty (on materials) and our workmanship warranty (on the install). If you ever need to file: - Reply to this email or call {{custom_values.company_phone}} - We'll walk you through it and handle the paperwork side Save this for your records, and you're all set. Nothing to do today. - {{custom_values.business_name}} {{custom_values.company_phone}} · {{custom_values.from_email}}
P2_005_MaintenanceTipsSeasonal (e.g. +90 days)
Subject: Keep your new roof in top shape, {{contact.first_name}} - seasonal care tips
Hey {{contact.first_name}}, Your roof is built to last - a little simple upkeep keeps it that way: Keep gutters clear so water drains properly Trim branches that hang over the roof After any big storm, glance up for missing or lifted shingles Watch for ice dams along the eaves in winter See something you're not sure about? Send us a photo - we'll tell you if it's nothing or worth a look, no charge. We're here for the long haul: {{custom_values.company_phone}}. - {{custom_values.business_name}}
P2_005_ReferralOfferLater in the loop
Subject: Know a neighbor with storm damage, {{contact.first_name}}? Here's our referral offer
Hi {{contact.first_name}}, It's been a little while since we finished your roof - we hope it's still keeping you dry and worry-free. Quick favor: if a neighbor, friend, or family member has storm damage or an aging roof, we'd love an introduction. Our referral offer: when someone you send us books an inspection, there's a thank-you in it for both of you. Just reply with their name, or share our number: {{custom_values.company_phone}}. We'll treat them exactly the way we treated you. Thanks for being a customer - and for spreading the word. - {{custom_values.business_name}} {{custom_values.company_phone}}
D5 SMS - referral nudge
SMSP2_005_SMS_ReferralAfter P2_005_ReferralOffer email
Referral text
Hi {{contact.first_name}}, loved having you as a customer! If you know anyone with storm damage, send them our way - there's a thank-you in it for you. {{custom_values.sms_output}}
D5 Internal Notification
Team AlertP2_005_Notif_Retention
Title: Handed to retention - file warranty docs + add to maintenance list
Handed to retention {{contact.first_name}} {{contact.last_name}} {{contact.full_address}} File warranty docs + add to the maintenance list. Redirect: Opportunity
MCTB Missed Call Text-Back 2 SMS + 1 team alert · Trigger: Call Status = Missed (inbound) · not yet built
SMSMissedCall_SMS_TextBackImmediately on missed call (≤10s)
Instant text-back
Hi, this is {{custom_values.business_name}} - sorry we just missed your call! How can we help? Reply here and we'll get right back to you. {{custom_values.sms_output}}
SMSMissedCall_SMS_FollowUp+1 hour (only if no reply)
One polite nudge
Hi, {{custom_values.business_name}} here - still happy to help with your roof whenever you're ready. Just reply and we'll take care of you. {{custom_values.sms_output}}
MCTB Internal Notification
Team AlertInternal Notification MissedCall_CallBack
Title: Missed call - call them back now
Missed call - call them back now {{contact.first_name}} {{contact.last_name}} {{contact.phone}} Text-back already sent - try a human callback. Redirect: Contact
Ref Merge Tags & Custom Values Build these in Settings -> Custom Values before templates - every merge tag pulls from here
Figure 06 - Custom Values reference (11 values)
FieldMerge tagSample valueUsed in
Booking Link{{custom_values.booking_link}}https://gokai.pro/roofing-calendarWF1 Welcome, Nudge1, Nudge2 + both WF1 SMS - the booking link
calendar_link{{custom_values.calendar_link}}https://gokai.pro/roofing-calendarWF2 Confirmation - embedded calendar URL
google_review_link{{custom_values.google_review_link}}https://google.comReview Engine Ask + Reminder - Google review CTA
company_name{{custom_values.business_name}}Stormline RoofingAll email headers & signatures + both WF1 SMS
from_name{{custom_values.from_name}}Stormline RoofingEmail "From" display name in all WFs
Company Phone{{custom_values.company_phone}}(305) 555-7842Email footers, WF2 HeadsUp, NSR LastTry, WF4 FU Loop
Company Address{{custom_values.company_address}}2450 NW 79th Ave, Miami, Florida 33122Email footers / business address - NOT the inspection address (that's {{contact.full_address}})
From Email{{custom_values.from_email}}support@stormlineroofing.comEmail footers / reply-to reference
offer_name{{custom_values.offer_name}}Free Roof InspectionWF1 Nudge2 value prop, NSR re-engagement
signature{{custom_values.signature}}(empty - add your sign-off)All email footers - reusable signature block
sms_output{{custom_values.sms_output}}Reply STOP to opt outLive in WF1_SMS_Welcome + WF1_SMS_Nudge - compliance footer
Build orderSet Custom Values before the form and before templates. Contact- and appointment-level tags ({{contact.first_name}}, {{contact.full_address}}, {{appointment.start_time}}) come from GHL directly and don't need setup here.
H

Helper Workflows

Small single-purpose workflows that set a tag or advance a stage on a real-world signal - kept separate so they don't cause instant-goal or self-trigger traps.

Why separate

A tag a workflow checks for must be set OUTSIDE that workflow - if the same flow sets and reads it, the goal fires too early or never. These helpers hold that boundary.

Pending buildThese helpers are referenced by WF2, WF6, D2, D3 and D4. Confirm each exists (and listens to the right calendar / inbound trigger) before publishing the workflow that depends on it.
Figure H - Helper Index
HelperListens ForDoesUsed By
Showed -> CompleteAppt status = showed (Roofing Consultation)Update opp -> Inspection CompleteWF2 -> WF3
Build BookedAppt booked on Build calendarTag build_scheduledWF6
Concern FlagInbound reply (problem)Tag project_concernD2
Review SignalReview submittedTag review_sentD3
Referral FlagReferral submittedTag referral_submittedD4