Time of Day Routing

From FreeSWITCH Wiki
Jump to: navigation, search



Time of day routing allows calls to be sent to different extensions based upon the time of day, day of week and in some cases, holidays. As of SVN revision 14385, FreeSWITCH supports a number of matchable variables for time and date elements. These are discussed in the Dialplan XML wiki page. The new matching variables obviate the need for using the strftime API. (You may still use strftime if you so choose or if you have a specific need that only strftime meets.)

Available variables

  • year Calendar year, 0-9999
  • yday Day of year, 1-366
  • mon Month, 1-12 (Jan = 1, etc.)
  • mday Day of month, 1-31
  • week Week of year, 1-53
  • mweek Week of month, 1-6
  • wday Day of week, 1-7 (Sun = 1, Mon = 2, etc.) or "sun", "mon", "tue", etc.
  • hour Hour, 0-23
  • minute Minute (of the hour), 0-59
  • minute-of-day Minute of the day, (1-1440) (midnight = 1, 1am = 60, noon = 720, etc.)
  • time-of-day Time range formatted: hh:mm[:ss]-hh:mm[:ss] (seconds optional) Example: "08:00-17:00"
  • date-time Date/time range formatted: YYYY-MM-DD hh:mm[:ss]~YYYY-MM-DD hh:mm[:ss] (seconds optional, note tilde between dates) Example: 2010-10-01 00:00:01~2010-10-15 23:59:59

NOTE: these can be mixed into the same condition, e.g:

<condition wday="6" hour="8-12"> 

Time zone manipulation

By default, time based routing uses the local time kept by FreeSWITCH. If you want to use a different time zone, you have 2 options (as of 2012-11-01 in master, see FS-4741).

variable tod_tz_offset

tod_tz_offset will compare the current time to the time zone offset from gmt.

NOTE: the variable must actually be set before the comparison, so either set it inline, transfer, or set it in the user directory.

variable timezone

Alternatively, you can use the Timezone name and FS will lookup the correct offset for applying TOD routing.

NOTE: as with tod_tz_offset, the variable must actually be set before the comparison, so either set it inline, transfer, or set it in the user directory.

Setting Up

The examples presented here can be added to the conf/dialplan/default.xml file or you can create a new file in conf/dialplan/default/ directory and add them to the new file.

Provision an internal extension # for Sales

   <extension name="RS-Sales-x2002">
     <condition field="destination_number" expression="^2002$">
       <action application="transfer" data="RS-Sales"/>

Setup variables prior to transferring to call handler for sales

   <extension name="RS-Sales" continue="true">
     <condition field="destination_number" expression="^RS-Sales$"/>
     <condition wday="2-6"/>
     <condition minute-of-day="540-1020">
       <action application="set" data="RS-Sales_open=true"/>
       <action application="transfer" data="xfer-to-sales"/>
       <anti-action application="set" data="RS-Sales_open=false"/>
       <anti-action application="transfer" data="xfer-to-sales"/>

Handle Sales Call

If Sales is open then route to extension first then vMail; else direct to vMail. In this example; Sales have their own mailbox (#2001) - the configuration of that box forwards all vMail to email and does not store a local copy.

   <extension name="xfer-to-sales">
     <condition field="destination_number" expression="^xfer-to-sales$"/>
     <condition field="${RS-Sales_open}" expression="^true$">
       <action application="bridge" data="user/1001@${domain_name}"/>
       <action application="answer"/>
       <action application="sleep" data="2000"/>
       <action application="voicemail" data="default ${domain_name} 2001"/>
       <anti-action application="voicemail" data="default ${domain_name} 2001"/>

VoiceMail Config (in /usr/local/freeswitch/conf/directory/default/2001.xml)

 <user id="2001" number-alias="2001">
     <param name="password" value="2001"/>
     <param name="vm-password" value="2001"/>
     <param name="vm-email-all-messages" value="true"/>
     <param name="vm-notify-email-all-messages" value="true"/>
     <param name="vm-attach-file" value="true"/>
     <param name="vm-mailto" value="sales@foo.com"/>
     <param name="vm-notify-mailto" value="chris@foo.com"/>
     <param name="vm-keep-local-after-email" value="false"/>
     <variable name="toll_allow" value="domestic,international,local"/>
     <variable name="accountcode" value="2001"/>
     <variable name="user_context" value="default"/>
     <variable name="effective_caller_id_name" value="sales"/>
     <variable name="effective_caller_id_number" value="2001"/>
     <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
     <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
     <variable name="callgroup" value="fga"/>

How does the above work?

Thanks to Michael/Brian, here's why:

This is a classic case of "dialplan is parsed all at once." The reason that it is failing is because ${billingopen} is not defined when the extension named "billing" is parsed. You need another pass through the dialplan, for example by adding a transfer app to your "billing_open" extension:

 <extension name="billing_open" continue="true">
    <condition wday="2-6"/>
    <condition minute-of-day="540-1020">
      <action application="set" data="billing_open=true"/>
      <action application="transfer" data="billing"/>

This will send the call back through the dialplan and into the "billing" extension, this time with the value of ${billing_open} == "true" so you can now work with it. The originally dialed number is now available in the ${rdnis} channel variable in case you need it.


 <extension name="2012_memorial_day_weekend_routing">
   <condition date-time="2012-05-25 17:00:01~2012-05-29 08:00:00"/>
   <condition field="destination_number" expression="^1(2135551212)$">
     <action application="bridge" data="sofia/external/18185551212@"/>

Example for office open 09:00-16:00

Has inbound DID routed to extension 5001:

 <extension name="Time of day, day of week setup" continue="true">
   <condition wday="2-6" minute-of-day="540-960" break="never">
      <action application="set" data="office_status=open" inline="true"/>
      <anti-action application="set" data="office_status=closed" inline="true"/>

 <extension name="tod route, x5001">
   <condition field="destination_number" expression="^(5001)$">
       <action application="execute_extension" data="5001_${office_status}"/>

 <extension name="office is open">
   <condition field="destination_number" expression="^(5001_open)$">
       <action application="set" data="domain_name=$${domain}"/>
       <action application="answer"/>
       <action application="playback" data="/usr/local/freeswitch/recordings/welcome_message.wav"/>
       <action application="set" data="hangup_after_bridge=true"/>
       <action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,USER_BUSY,NO_ANSWER,TIMEOUT,NO_ROUTE_DESTINATION"/>
       <action application="set" data="ringback=local_stream://moh"/>
       <action application="set" data="transfer_ringback=local_stream://moh"/>
       <action application="pre_answer"/>
       <action application="bridge" data="{ignore_early_media=true,origination_caller_id_number=XXXXXXXX}sofia/gateway/<gateway name>/XXXXXXXX,sofia/gateway/<gateway name>/XXXXXXXX"/>
 <extension name="office is closed">
  <condition field="destination_number" expression="^(5001_closed)$">
     <action application="answer"/>
     <action application="sleep" data="1000"/>
     <action application="playback" data="/usr/local/freeswitch/recordings/9-16.wav"/>
     <action application="sleep" data="500"/>
     <action application="hangup" data="NORMAL_CLEARING"/>

See Also