Time of day routing
It is common for routing of calls to be different, depending upon 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, 8AM to 5PM. Additionally, we will add a day_part
variable to reflect morning (midnight to noon), afternoon (noon to 5PM), or evening (6PM to midnight).
How to do it...
Create an extension at the beginning of your dialplan by following these steps:
Add this extension to the beginning of your dialplan context:
<extension name="Time of day, day of week setup" continue="true"> <condition wday="2-6" hour="8-17" 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 variables
office_status
andday_part
.office_status
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 upon whether or not the office is open. Add these dialplan extensions, which will accomplish the task:<extension name="tod route, x5001"> <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 press F6 or issue the
reloadxml
command at thefs_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 for 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"
set, when the dialplan matched one of the conditions in the Time of day
, day of week setup extension, then it would stop 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 chapters 5 and 8 of Packt Publishing's FreeSWITCH 1.0.6 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 both of those destinations with the extensions "office is open" and "office is closed," respectively. Now we can play different greetings to the caller—one for when the office is open and a different one for 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 value is in the channel variable day_part
.
Tip
The execute_extension and transfer dialplan applications
These two applications both 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 a transfer
sends 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 value open
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 almost trivial. Let's make it a bit more challenging by adding a lunch period that runs from 11:30AM to 12:30PM. We cannot use hour="11.5-12.5"
, however, 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 is 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-17" 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 wiki page (http://wiki.freeswitch.org/wiki/Dialplan_XML) for more information on the usage of break
, continue
, and inline
attributes.