Home / Lawn Care / Rain-day reschedule: tell tomorrow's customers with one decision, not 40 calls

Lawn Care problem 2: One rain day breaks the whole route, and the phone rings all morning with 'are you coming today?'

Rain-day reschedule

Tell tomorrow's customers with one decision, not 40 calls

Verified with mocksLast tested 2026-10-31 · pricing checked October 2026
Download the workflowlawn-rain-day-reschedule.zip

20/20 test scenarios passed against mock APIs. Includes the n8n workflow, mock data and the test runner.

  • n8n
  • Twilio
  • Resend
  • Jobber
  • NWS API
  • Google Sheets

At 6 p.m. on work days the workflow reads tomorrow's National Weather Service forecast for your shop. At or above a 70% chance of rain (you set it), it reads tomorrow's Jobber visits and tells each customer their visit moves to the next work day, by text if they accept texts, otherwise by email. Between 40% and 70% it texts the owner instead: reply RAIN TOMORROW to send the notices. The owner can also text RAIN TODAY. The office gets the list in route order, with who still needs a call. It reads Jobber visits and does not move them; the office reschedules in Jobber.

How the workflow runs

Trigger · On a schedule

Every evening 6 pm: check tomorrow

Steps

  1. Mode: forecast
  2. Rain desk: forecast / held texts
  3. Build visits query
  4. Jobber: visits that day
  5. Plan the rain day (customers + office list)

Outcome

  • Send texts + emails (Retry-After)
  • Send rain-day messages

Also runs on: Every hour 8 am-8 pm: send held texts → Mode: flush → Rain desk: forecast / held texts → Build visits query → Jobber: visits that day → Plan the rain day (customers + office list) → Send texts + emails (Retry-After) → Send rain-day messages

Also runs on: Twilio inbound SMS → Owner command / STOP / reply → Build visits query → Jobber: visits that day → Plan the rain day (customers + office list) → Send owner replies → Send rain-day messages

Drawn from the node names in the workflow file inside the download (workflow.json).

The problem

A trade publication, a vendor guide and owner forum threads; this is a practice problem, not a measured rate.

Background reading: Rain days in lawn care: a sample policy, the texts to send, and a 6 p.m. forecast check

Who it's for

US lawn care and landscape maintenance companies on Jobber with recurring mowing routes.

Tools and monthly cost

ToolOfficial price
Jobber (you probably already pay for it)Core $29 / month billed annually ($39 with a 1-year monthly commitment, $49 with no commitment); Connect from $99; Grow from $149; Plus from $399 (5 users). Jobber's developer docs say custom API integrations are only for approved customers, and the pricing page doesn't say which plan an API app needs pricing page
Twilio US local phone number$1.15 / month pricing page
Twilio US SMS, sent or received$0.0083 per segment, plus carrier fees on outbound texts of $0.0035-$0.005 per segment (AT&T $0.0035, T-Mobile $0.0045, Verizon $0.005) pricing page
A2P 10DLC registration (required to text US customers from a local number)One-time: $4.50 brand registration (Standard brands add $41.50 secondary vetting) and $15 campaign vetting. Monthly: $1.50-$10 per campaign by use case ($2 for sole proprietors) pricing page
Resend (sends the emails; any email API that accepts an Idempotency-Key works)Free: 3,000 emails / month, 100 / day. Pro: $20 / month for 50,000 emails pricing page
Google Sheets (opt-out list, replies, renewal list)Free with a Google Account; Google Workspace is optional pricing page
n8nCommunity Edition: free if you self-host (you pay for the server). n8n Cloud: Starter EUR 20 / month or Pro EUR 50 / month, billed annually pricing page
National Weather Service API (forecast)Free, no API key; NWS asks for a User-Agent that identifies your app and a contact pricing page

Example month: Illustrative arithmetic, not a measured result. One local number sending 200 single-segment texts and receiving 200 a month, at the highest listed carrier fee ($0.005): 200 x ($0.0083 + $0.005) + 200 x $0.0083 + $1.15 number = $5.47 a month in Twilio usage, plus the A2P 10DLC campaign fee ($1.50-$10 a month) and one-time registration ($4.50 brand + $15 campaign vetting). Emails stay inside Resend's free tier at this volume. n8n Cloud Starter (EUR 20 a month) or your own server, and your Jobber plan, come on top. Your volumes will differ.

Setup

  1. Jobber: create a Jobber developer app, add an n8n OAuth2 credential (authorization URL https://api.getjobber.com/api/oauth/authorize, token URL https://api.getjobber.com/api/oauth/token). n8n refreshes the token and stores the rotated refresh token. Set MSS_JOBBER_URL=https://api.getjobber.com/api/graphql. The X-JOBBER-GRAPHQL-VERSION header is pinned in the workflow.
  2. Texts need a Twilio number on an approved A2P 10DLC campaign. Set TWILIO_ACCOUNT_SID, TWILIO_BASIC_AUTH (base64 of SID:auth token) and LAWN_TWILIO_FROM. Texts only go out 8 a.m.-9 p.m. in the customer's time zone and only with recorded consent.
  3. Email: MSS_EMAIL_API (e.g. https://api.resend.com), EMAIL_API_KEY, LAWN_EMAIL_FROM, LAWN_OFFICE_EMAIL. Every send carries an Idempotency-Key, so a retried run never emails twice.
  4. Company details: LAWN_COMPANY_NAME, LAWN_COMPANY_PHONE, COMPANY_TZ. Every message names your company.
  5. Google Sheet stand-in: MSS_SHEET_URL points at the shared sheets (sms_optouts, inbound_texts and the recipe's own sheets). In production, swap these HTTP calls for n8n's Google Sheets node.
  6. Remove the test-only mss-lc*-tick webhook (or put it behind n8n header auth) and make sure MSS_TEST_CLOCK is NOT set in production.
  7. Weather: LAWN_LAT / LAWN_LON (shop or middle of the route), NWS_USER_AGENT like '(yourcompany.com, office@yourcompany.com)'. NWS_API defaults to https://api.weather.gov.
  8. RAIN_POP_SEND (default 70) and RAIN_POP_ASK (default 40) are the percent chance of rain thresholds. WORK_DAYS (1=Mon ... 7=Sun, default 1-6) decides the next work day.
  9. LAWN_OWNER_PHONE: only texts from this number with a valid Twilio signature can trigger RAIN TODAY / RAIN TOMORROW.
  10. Point your Twilio number's inbound webhook at /webhook/mss-lc2-sms. It records STOP/START and forwards customer replies to the office.

Download

Downloadlawn-rain-day-reschedule.zip

Contains the n8n workflow, the mock data, the test runner with its last results, and the mock server we tested against. All keys in .env.example are fake.

Test result

Every workflow was imported into n8n 2.45.4 on an isolated test instance and run end to end. Jobber (GraphQL, OAuth2 with refresh-token rotation and signed webhooks), Twilio, the National Weather Service API, the email API (Resend-style) and Google Sheets were replaced by a local mock server built from the vendors' public docs: same request shapes and auth headers, HMAC-signed webhooks, HTTP 429 with Retry-After and Jobber THROTTLED errors. A frozen test clock checks the 8 a.m.-9 p.m. texting window. These recipes use no AI model; every decision is a written rule. Customers, yards, invoices and addresses are invented. Verified with mocks; nothing was sent to a real person or account. How we test.

20/20 scenarios passed (run 2026-10-31)

PASSL2-016 pm Tuesday, 80% rain tomorrow: tomorrow's customers are told their visit moves to Thursday (text, else email); the office gets the list in route order with who still needs a call
PASSL2-02Second run the same evening: nothing (one decision per day)
PASSL2-03Borderline (55%): only the owner gets a text asking whether to call it; no customer hears anything
PASSL2-04Owner texts RAIN TOMORROW: same rain-day plan runs (customers told, office list)
PASSL2-05Owner texts it twice: no second round of customer texts, owner told it's already done
PASSL2-06Dry forecast (20%): nobody gets anything
PASSL2-07Owner texts RAIN at 6:30 am (no day given, before noon = today): emails go now, texts are held for quiet hours (before 8 am)
PASSL2-07b8:30 am Central is still 7:30 am in western Kansas: the text stays held
PASSL2-07c9:30 am flush: the held text goes out once, never again
PASSL2-08Saturday 6 pm: tomorrow is Sunday (not a workday), no forecast call, nothing sent
PASSL2-09Friday 6 pm, rain Saturday: the visit moves to Monday (skips Sunday)
PASSL2-10Weather service down (HTTP 500): owner and office are told to decide by hand; no customer messages
PASSL2-11Next evening: the NWS grid point is cached (no second /points call), only the forecast is read
PASSL2-12Customer texts STOP: recorded on the shared opt-out list
PASSL2-12bNext rain day: the opted-out customer gets email instead of a text
PASSL2-13Customer replies to a rain-day text: logged and forwarded to the office, no automatic answer
PASSL2-14A customer texting RAIN is not the owner: no rain day is triggered
PASSL2-15Forged Twilio signature with the owner's number: ignored
PASSL2-16Jobber THROTTLED when reading the visits: office and owner are told nobody was notified; no customer messages
PASSL2-17Twilio answers 429 once: waits per Retry-After, every text goes out exactly once

Actual output from the test run

Scenario L2-01: the evening-before rain notice to a customer with recorded text consent (invented customer and company). Names and numbers are invented.

Hi Dana, rain in the forecast for Wed Apr 14, so we're moving your weekly mowing to Thu Apr 15. No need to do anything. Reply if that day doesn't work. Reply STOP to opt out. - Prairie Edge Lawn Co.

Verified with mocks

  • 6 pm Tuesday, 80% rain tomorrow: tomorrow's customers are told their visit moves to Thursday (text, else email); the office gets the list in route order with who still needs a call
  • Second run the same evening: nothing (one decision per day)
  • Borderline (55%): only the owner gets a text asking whether to call it; no customer hears anything
  • Owner texts RAIN TOMORROW: same rain-day plan runs (customers told, office list)
  • Owner texts it twice: no second round of customer texts, owner told it's already done
  • Dry forecast (20%): nobody gets anything
  • Owner texts RAIN at 6:30 am (no day given, before noon = today): emails go now, texts are held for quiet hours (before 8 am)
  • 8:30 am Central is still 7:30 am in western Kansas: the text stays held
  • 9:30 am flush: the held text goes out once, never again
  • Saturday 6 pm: tomorrow is Sunday (not a workday), no forecast call, nothing sent
  • Friday 6 pm, rain Saturday: the visit moves to Monday (skips Sunday)
  • Weather service down (HTTP 500): owner and office are told to decide by hand; no customer messages
  • Next evening: the NWS grid point is cached (no second /points call), only the forecast is read
  • Customer texts STOP: recorded on the shared opt-out list
  • Next rain day: the opted-out customer gets email instead of a text
  • Customer replies to a rain-day text: logged and forwarded to the office, no automatic answer
  • A customer texting RAIN is not the owner: no rain day is triggered
  • Forged Twilio signature with the owner's number: ignored
  • Jobber THROTTLED when reading the visits: office and owner are told nobody was notified; no customer messages
  • Twilio answers 429 once: waits per Retry-After, every text goes out exactly once
  • Verified with mocks; invented customers, yards, invoices and addresses only.

Documented from official API docs only

Built to the vendor's documentation but not run against a live account. Check these on yours.

  • Jobber GraphQL field and mutation names, webhook signing (X-Jobber-Hmac-SHA256) and OAuth refresh-token rotation (from Jobber's developer docs; not run against a live account).
  • Twilio request signing, Messages API, 429 behavior and built-in STOP handling (from Twilio's docs). The email API follows Resend's documented request shape.
  • NWS API /points and gridpoint forecast endpoints and the User-Agent requirement (from the NWS API docs).

Limitations

  • One forecast point for the whole route; borderline days ask the owner for that reason.
  • The workflow doesn't move visits in Jobber; the office does it from the list.
  • If the NWS API is down, the owner and the office are told no forecast was read and nothing was sent.
  • Every message is checked against a word list first: safety claims like 'pet safe' or 'non-toxic' (the kind 40 CFR 156.10 treats as misbranding on a pesticide label), 'guaranteed' results and collection threats are blocked, and the office is told instead.
  • Written and tested for Jobber's API only. LMN, Aspire, Service Autopilot and other software are not built for this recipe, and we make no claim that it works with them. Jobber's developer docs say custom integrations are only possible for approved Jobber customers, so check with Jobber first.
  • Not legal advice and not a compliance guarantee. Texts go only to customers with recorded consent, only between 8 a.m. and 9 p.m. in the customer's time zone, and plain-English opt-outs are honored (47 CFR 64.1200 is the federal rule we design around). Some states are stricter than federal law; have your attorney review texting consent before going live.