Skip to content
LogiccheckBusinessHoursstable

Check 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 holiday branch ("We're closed for the holiday — we reopen {{vars.nextOpenLabel}}")
  • Offer a callback on closed and a live path on open
  • Branch a single number between Sales hours and Support hours by pointing two checkBusinessHours nodes 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.

FieldLabelTypeRequiredDefaultNotes
hoursSetIdBusiness-hours settextOptional""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.
atOverrideEvaluate at (advanced)textOptional{{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 hoursSetId reference; edit the weekly hours + holidays in Settings → Business hours. Deleting the referenced set makes the node evaluate to error — wire that branch (or __next) defensively.
  • Blank hoursSetId ⇒ the org default set. If you don't pick a set, the node evaluates the org's is_default set. If the org has no default either, there's no schedule to check and it routes open (fail-open — it never strands the call on a missing schedule).
  • error is a real outcome, not a crash. A missing set / load failure routes error and stamps vars.hoursStatus = "error"; it never halts the call. Unwired, error falls through on.__next.
  • Holiday is closed-with-a-reason. A date in the set's exceptions (holidays) routes holiday, distinct from a normal out-of-hours closed, so you can play a holiday-specific message. A holiday that carries override windows can still be open during those windows.
  • nextOpenLabel is best-effort. It's set on closed/holiday when the next opening is computable; guard your after-hours template rather than assuming it's always present.
  • Outcome handles are stored as cfg.cases on vars.hoursStatus — the same canonical case shape as branch/aiAgent (invariant I-3); the editor renders the four outcomes as handles. Don't hand-edit a case path/value away from vars.hoursStatus = open|closed|holiday|error, or both the canvas handle classification and runtime routing break.