Hours-of-operation routing: the patterns that actually hold up
Every IVR has one, and it is almost always the first thing that breaks: the check that decides whether the caller reaches a queue or a “we’re closed” message.
It looks like a single decision. It is usually four.
The four questions hiding in “are we open?”
- Is today a business day? Monday–Friday is a guess. Many centers run Saturday mornings.
- Is this a holiday? A separate list that changes every year and rarely lives near the schedule that uses it.
- Is it within today’s hours? Which are not the same on every day — Friday often closes early.
- Are we in an unplanned closure? Weather, an outage, a building problem.
Collapsing all four into one condition is what produces the classic failure: the center is technically open, the holiday list is stale, and callers get the closed message on a working Tuesday.
Keep the override separate and first
The unplanned closure has nothing to do with the schedule. It is a switch someone flips under pressure, often by phone, often by someone who did not build the flow. It belongs at the very top of the script, before any date arithmetic:
incomingCall
└─ ifElse "emergency closure active?"
├─ true → announcement (emergency message) → hangup
└─ false → normal hours check
Putting it first has a practical benefit beyond clarity: when someone has to flip it at 6am in a snowstorm, they are looking for one node, not hunting through a nested condition.
Holidays are data, not logic
The temptation is a chain of ifElse nodes comparing the date to each holiday. It works, and it rots — every January someone has to find and edit a dozen branches.
A single variable holding “is today a holiday”, set once near the top, gives you one place to maintain and one thing to test. The branch that consumes it stays the same year to year.
Half-days are the case nobody tests
A center that closes at 13:00 on Christmas Eve is not “open” or “closed” — it is both, four hours apart. If your hours check compares against a single open and close time for all days, the half-day is a special case you will discover from a complaint.
What to actually verify before you ship
Whatever structure you land on, the test set is small and worth writing down:
- A normal weekday, mid-morning
- The same weekday, one minute after close
- A Saturday, if you open on Saturdays
- A holiday that falls on a weekday
- A half-day, before and after the early close
- The emergency override, on a day that is otherwise open
Six cases. Every one of them is a real call somebody will make.
In ivrloom you can run these against the flow before it goes anywhere near Five9 — the simulator walks the same IR the editor shows you, so a branch that takes the wrong path shows up as a path you can see rather than a call you have to make. Its hours view draws each of these checks across a week and lists the holiday dates the script carries — there is a picture of it on the Five9 IVR Script Designer alternative page.