checkBusinessHoursstableCheck business hours
Branches the call on whether a named business-hours schedule is currently open, closed, or on a holiday. Reads one of the org's saved business-hours sets…
What it does
Evaluates one of your org's business-hours sets against the current time and
routes the call by the result: open, closed, holiday, or error. A set
(weekly schedule + holidays + timezone) is managed in Settings → Business
hours; this node only references one by id and branches on it — there is no
schedule on the node itself.
Evaluation is synchronous (one cheap RLS read of the named business_hours_sets
row, then the shared isWithinHours evaluator) and is timezone-, overnight-, and
holiday-aware. It stamps three vars for the rest of the call:
vars.hoursStatus (open | closed | holiday | error), vars.hoursIsOpen
(boolean), and vars.nextOpenLabel (e.g. Mon 09:00, set on closed/holiday when
computable). Leave Business-hours set blank to evaluate the org's default set.
When to use it
- Gate an inbound flow: route to the receptionist or a queue during open hours, and to voicemail or an after-hours message otherwise
- Play a distinct holiday greeting on the
holidaybranch ("We're closed for the holiday — we reopen {{vars.nextOpenLabel}}") - Offer a callback on
closedand a live path onopen - Branch a single number between Sales hours and Support hours by pointing two
checkBusinessHoursnodes at different sets
Configuration
Branches the call on whether a named business-hours schedule is currently open, closed, or on a holiday. Reads one of the org's saved business-hours sets (manage them under Settings → Business hours) — the same schedules the AI receptionist answers from — and evaluates it for "now" (timezone-, overnight-, and holiday-aware). Four outcomes: Open, Closed, Holiday, Error. The result also lands in {{vars.hoursStatus}} and {{vars.hoursIsOpen}}, with the next open time in {{vars.nextOpenLabel}} for an after-hours message.
| Field | Label | Type | Required | Default | Notes |
|---|---|---|---|---|---|
hoursSetId | Business-hours set | text | Optional | "" | Which saved business-hours set to evaluate, by id. Manage sets under Settings → Business hours. Leave blank to use the org's default set; if there is no default either, the line is treated as always-open. |
atOverride | Evaluate at (advanced) | text | Optional | {{vars.callbackAt}} | Optional. A {{vars.x}} template resolving to an ISO timestamp to evaluate against instead of "now" — for testing or scheduled callbacks. Blank or unparseable falls back to the current time. |
Outgoing events: __next
Examples
Open / closed / holiday split
Reference the "Sales" hours set and branch each outcome. The right-edge __next
catches anything not explicitly wired (here, error).
{
"id": "hours",
"type": "checkBusinessHours",
"config": {
"hoursSetId": "a1b2c3d4-0000-0000-0000-000000000000",
"cases": [
{ "path": "vars.hoursStatus", "op": "==", "value": "open", "nodeId": "to-receptionist" },
{ "path": "vars.hoursStatus", "op": "==", "value": "holiday", "nodeId": "say-holiday" },
{ "path": "vars.hoursStatus", "op": "==", "value": "closed", "nodeId": "say-after-hours" }
]
},
"on": { "__next": "say-after-hours" }
}
Open-vs-not only
If you only care about open/closed, wire one edge and let everything else fall
through the right-edge __next.
{
"id": "open-check",
"type": "checkBusinessHours",
"config": {
"cases": [
{ "path": "vars.hoursStatus", "op": "==", "value": "open", "nodeId": "live-path" }
]
},
"on": { "__next": "voicemail" }
}
Gotchas
- The schedule lives on the set, not the node. The node holds only a
hoursSetIdreference; edit the weekly hours + holidays in Settings → Business hours. Deleting the referenced set makes the node evaluate toerror— wire that branch (or__next) defensively. - Blank
hoursSetId⇒ the org default set. If you don't pick a set, the node evaluates the org'sis_defaultset. If the org has no default either, there's no schedule to check and it routesopen(fail-open — it never strands the call on a missing schedule). erroris a real outcome, not a crash. A missing set / load failure routeserrorand stampsvars.hoursStatus = "error"; it never halts the call. Unwired,errorfalls throughon.__next.- Holiday is closed-with-a-reason. A date in the set's
exceptions(holidays) routesholiday, distinct from a normal out-of-hoursclosed, so you can play a holiday-specific message. A holiday that carries override windows can still beopenduring those windows. nextOpenLabelis best-effort. It's set onclosed/holidaywhen the next opening is computable; guard your after-hours template rather than assuming it's always present.- Outcome handles are stored as
cfg.casesonvars.hoursStatus— the same canonical case shape asbranch/aiAgent(invariant I-3); the editor renders the four outcomes as handles. Don't hand-edit a casepath/valueaway fromvars.hoursStatus=open|closed|holiday|error, or both the canvas handle classification and runtime routing break.
