Time-of-day routing
It is common for routing of calls to be different, depending on the time of day or day of the week. The FreeSWITCH XML dialplan has a number of parameters to allow this functionality.
Getting ready
Determine the parameters for your routing. In this example, we will define business hours as Monday through Friday from 8:00 a.m. to 5:00 p.m. Additionally, we will include a day_part
variable to reflect morning (midnight to noon), afternoon (noon to 6:00 p.m.), and evening (6:00 p.m. to midnight).
How to do it...
Start at the beginning of your dialplan by following these steps:
- Add this extension to the beginning of your context:
<extension name="Time of day, day of week setup" continue="true"> <condition wday="2-6" hour="8-16" break="never"> <action application="set" data="office_status=open"inline="true"/> <anti-action application="set" data="office_status=closed" inline="true"/> </condition> <condition hour="0-11" break="never"> <action application="set" data="day_part=morning" inline="true"/> </condition> <condition hour="12-17" break="never"> <action application="set" data="day_part=afternoon" inline="true"/> </condition> <condition hour="18-23" break="never"> <action application="set" data="day_part=evening" inline="true"/> </condition> </extension>
- Later in your dialplan, you can use the
office_status
andday_part
variables. Theoffice_status
variable will contain either "open" or "closed", andday_part
will contain "morning", "afternoon", or "evening". A typical usage would be to play different greetings to the caller, depending on whether or not the office is open. Add these dialplan extensions, which will accomplish the task:<extension name="tod route, 5001_X"> <condition field="destination_number" expression="^(5001)$"> <action application="execute_extension" data="5001_${office_status}"/> </condition> </extension> <extension name="office is open"> <condition field="destination_number" expression="^(5001_open)$"> <action application="answer"/> <action application="sleep" data="1000"/> <action application="playback" data="ivr/ivr-good_${day_part}.wav"/> <action application="sleep" data="500"/> <!-- play IVR for office open --> </condition> </extension> <extension name="office is closed"> <condition field="destination_number" expression="^(5001_closed)$"> <action application="answer"/> <action application="sleep" data="1000"/> <action application="playback" data="ivr/ivr-good_${day_part}.wav"/> <action application="sleep" data="500"/> <!-- play IVR for office closed --> </condition> </extension>
- Save your XML file and issue the
reloadxml
command atfs_cli
.
How it works...
The Time of day, day of week setup
extension defines two channel variables, namely office_status
and day_part
. Note the use of inline="true"
in our set applications. These allow immediate use of the channel variables in later dialplan condition statements. Every call that hits this dialplan context will now have these two channel variables set (they will also show up in CDR records if you need them). You may have also noticed continue="true"
in the extension tag and break="never"
in the condition tags. These tell the dialplan parser to keep looking for more matches when it would otherwise stop doing so. For example, without continue="true"
, when the dialplan matches one of the conditions in the Time of day, day of week setup
extension, it stops looking at any more extensions in the dialplan. In a similar way, the break="never"
attribute tells the parser to keep looking for more conditions to match within the current extension (by default, when the parser hits a failed condition, it stops processing any more conditions within the current extension).
Note
A detailed discussion of dialplan processing can be found in Packt Publishing's FreeSWITCH 1.2 book.
Our sample extension number is 5001. Note the action it takes:
<action application="execute_extension" data="5001_${office_status}"/>
This sends the call back through the dialplan looking for a destination_number
of 5001_open
or 5001_closed
. We have defined these destinations with the "office is open" and "office is closed" extensions respectively. Now we can play different greetings to the caller: one when the office is open and a different one when the office is closed. As a nice touch, for all calls, we play a sound file that says "Good morning", "Good afternoon", or "Good evening", depending on what the value in the day_part
channel variable is.
Tip
The execute_extension and transfer dialplan applications
These two applications tell FreeSWITCH to execute another part of the dialplan. The primary difference is that execute_extension
will return after executing another portion of the dialplan, whereas transfer
will send control to the target extension. In programming parlance, execute_extension
is like a gosub
command and transfer
is like a goto
command. The former comes back, but the latter does not.
There's more...
You may be wondering why we did not simply use a condition
to test office_status
for the open
value, and then use action
tags for "office open" and anti-action
tags for "office closed". There is nothing preventing us from doing this. However, what if you need to have an office status other than "open" or "closed"? For example, what if you have an office that needs to play a completely different greeting during lunch time? This is difficult to accomplish with only anti-action
tags, but with our example, it is very simple. Let's make it a bit more challenging by adding a lunch period that runs from 11:30 a.m. to 12:30 p.m. We cannot use hour="11.5-12.5"
, but we do have another value we can test — time-of-day
. This parameter lets us define periods in the day at a granularity of minutes, or even seconds. The value range can be 00:00 through 23:59 or 00:00:00 through 23:59:59. Consider this new Time of day
, day of week setup
snippet:
<extension name="Time of day, day of week setup" continue="true"> <condition wday="2-6" hour="8-16 break="never"> <action application="set" data="office_status=open" inline="true"/> <anti-action application="set" data="office_status=closed" inline="true"/> </condition> <condition wday="2-6" time-of-day="11:30-12:30" break="never"> <action application="set" data="office_status=lunch" inline="true"/> </condition> ....
Notice that we need to explicitly define the weekend, since we cannot rely on a simple Boolean "open" or "closed" condition. However, we now have a new office_status
of "lunch" available to us. We define an additional extension to handle this case:
<extension name="office is at lunch"> <condition field="destination_number" expression="^(5001_lunch)$">
Add the specific dialplan actions for handling calls during the office's lunch hour, and you are done. You can add as many new office statuses as you need.
See also
- Refer to the XML dialplan page at http://freeswitch.org/confluence/display/FREESWITCH/XML+Dialplan for more information on the usage of the
break
,continue
, andinline
attributes.