Synopsis |
Control File |
IVR Overview |
Downloads |
Annotated Source
Synopsis:
This is an IVR (Interactive Voice Response) scheme that shows how a
FacetPhone caller on hold can be played a series of monthly-specific
messages. Frequent callers placed on hold are not bored by the
same old message repeated time after time after time. Callers can
skip through messages or mute the message playback while they wait on
hold. If "sold-on-hold" type messages are not desired,
prompt directories can be populated with music files to provide
seasonal music on hold.
The IVR script has several control parameters stored in a simple text
file that define its behavior as described below. If desired a
simple webpage interface could manipulate the control file.
If you would like to present this kind service to callers on hold,
please contact FacetCorp Support to discuss your needs.
Synopsis |
Control File |
IVR Overview |
Downloads |
Annotated Source
Parameter Control File:
The main IVR routine parses the control file for these directives.
PLAY_ALL_OR_MONTHLY
|
If set to all will play through prompts located
in the "All" directory. Set to monthly
for monthly message mode.
|
PLAY_ORDER
|
If set to alphabetical will play through prompts
in alphabetical order. If set to playlist
will play through prompts in the order provided in a file called
"playlist" located in the same directory as prompts. If set to
random will play through in random order.
|
GREETING_PROMPT
|
Name of greeting prompt (without any path or file extension.)
|
PLAY_GREETING
|
If set to yes will play greeting prompt before any
message. If set to no will not play greeting.
|
MENU_PROMPT
|
Name of menu prompt (without any path or file extension.)
|
PLAY_MENU_FIRST
|
If set to yes will play menu prompt before any
message. If set to no  play message first.
|
NUMBER_OF_MESSAGES_BEFORE_MENU
|
Number of messages to play before playing menu prompt. Set
to zero 0 will only play menu and not play any
messages. Set to a very high number will play only messages
without menu.
|
MAX_NUMBER_TO_PLAY
|
Number of messages to play before dropping caller into group voice
mail. If set to zero 0 will loop indefinitely.
|
Synopsis |
Control File |
IVR Overview |
Downloads |
Annotated Source
IVR Script to Play Monthly Messages On Hold (overview):
This IVR script includes a support subroutine, get_param(),
which takes a control file name and a parameter name, then searches
the control file for the parameter, and if found returns parameter
value. Expects parameters in the control file like this:
PARAMETER_NAME=setting.
Other support subroutines include, play_next_random(),
which randomly plays a prompt from a prompt directory,
play_next_alphabetical(), which takes a prompt name and plays
the next one in alphabetical order found in the prompt directory,
and play_next_playlist(), which takes a prompt name and plays
the next one in the playlist from the prompt directory.
The main subroutine, monthly_message_on_hold(), has a pretty
straight-forward flow:
(ON HOLD)
|
|-- Find FacetPhone directory and Control File
|
|-- Parse Parameter Control File for Directives
|
|-- Determine Month and Set Monthly Prompt Directory
|
|-- Play Greeting if so Configured
|
|-- Play Menu if so Configured
|
L1 |-- PLAY MESSAGE PROMPTS
| |
| 1 |-- Let Caller Leave Voice Mail
| |
| 2 |-- Skip Current Message
| |
| 3 |-- Toggle Playback (Mute) On or Off
| |
| 0 |-- Ring Back to Operator
| |
| |-- Display Prompt Name on Desktop Interfaces
| |
| |-- Play Prompt in Alphabetical, Random, or List Order
| |
| +-- Repeat from L1 (MESSAGES_BEFORE_MENU times)
|
|-- Play Menu Prompt
|
+-- Repeat from L1 (until MAX_MESSAGES played)
|
+-- Let Max'ed Out Caller Leave Group Voice Mail
Synopsis |
Control File |
IVR Overview |
Downloads |
Annotated Source
Download Example Script and Associated Files:
3243 Nov 8 11:12 IVR-monthly_message_on_hold - Parameter Control File
17061 Nov 8 11:07 monthly_message_on_hold.ivr - IVR Script Source
Synopsis |
Control File |
IVR Overview |
Downloads |
Annotated Source
IVR Script to Play Monthly Messages On Hold (not yet annotated):
/*
* monthly_message_on_hold.ivr
*
* IVR routine to entertain and inform folks on hold by playing through
* a series of month-specific message prompts while they wait. Scheme
* cycles through a set of "month" directories, based upon the server
* date, and can be controlled thusly through a parameter file:
*
* play mode: prompts in "All" dir, or in monthly dirs
* play order: random, alphabetically, or playlist order
* greeting prompt: name of greeting propmt
* menu prompt: name of menu prompt
* play greeting: on, or off
* menu first: play menu before messages?
* msgs/menu: number of messages to play before menu
*
* Paramter Control file:
*
* /usr/facetphone/control/IVR-monthly_message_on_hold
*
*
* Script defaults unless overridden in Parameter Control file:
*
* PLAY_ALL_OR_MONTHLY=monthly
* PLAY_ORDER=random
* GREETING_PROMPT=monthly_message_greeting
* PLAY_GREETING=yes
* MENU_PROMPT=monthly_message_menu
* PLAY_MENU_FIRST=yes
* NUMBER_OF_MESSAGES_BEFORE_MENU=2
*
*
* Requires pre-recorded WAV files:
*
* monthly_message_greeting.wav : [ optional 1-time play greeting ]
* :
* monthly_message_menu.wav : 'Thank you for holding. While on
* : hold the following options are
* : available: To leave a voice mail,
* : press '1'. To change the message,
* : press '2'. To toggle message play
* : on and off, press '3'. To transfer
* : to an operator, press 'zero'.
* :
* All/msg01.wav : [ set of all (or misc.) prompts 1 ]
* All/msg02.wav : [ set of all (or misc.) prompts 2 ]
* [ ... ] :
* :
* Jan/msg01.wav : [ January-specific prompt 1 ]
* Jan/msg02.wav : [ January-specific prompt 2 ]
* [ ... ] :
* :
* Feb/msg01.wav : [ February-specific prompt 2 ]
* Feb/msg02.wav : [ February-specific prompt 2 ]
* [ ... ] :
* :
*
*
* Include in "/usr/facetphone/ivr/localsystem/ivrscripts/localsys.ivr":
*
* #include <monthly_message_on_hold.ivr>
*
*
* Include in "/usr/facetphone/config/ivr.local.cfg":
*
* <ivr_script=monthly_message_on_hold>
* <ivr_prompt=monthly_message_greeting>
* <ivr_prompt=monthly_message_menu>
*
*
* Example of calling:
*
* Set as ON HOLD Script for Group from Admin GUI:
*
* Admin | Change System Configuration | Configure Groups | Edit
* ON HOLD Script name: [ monthly_message_on_hold ]
*
* Set as ON HOLD Script for Individual from User GUI:
*
* Action | My Configuration | Voice Mail Handling
* On Hold Script: [ monthly_message_on_hold ]
*
*
* NOTES:
*
* Cannot have duplicate prompts in "playlist" files.
*
* Good idea to name prompts in preferred alphabetical order:
*
* 01_first_alphabetically_played_prompt
* 02_second_alphabetically_played_prompt
* 03_third_alphabetically_played_prompt
*
*
* 11/01/03 Eric Yundt -- FacetCorp Tech Support, support@facetcorp.com
*
***************************************************************************
*/
/*************************************************************
*
* get_param( control_file, parameter_name, *setting )
*
* Searches 'control_file' for 'parameter_name' and if
* found returns value in 'setting'. If parameter not
* found returns no value in 'setting'.
*
* Expects parameter at beginning of line, immediately
* followed by '=' and then paramter setting, e.g.:
*
* PARAMETER_NAME=setting
*
*************************************************************
*/
subroutine get_param( control_file, parameter_name, *setting )
{
string cmd;
setting = "";
cmd = "grep \^" + parameter_name + "= " + control_file;
cmd += " | cut -d= -f2";
Popen( cmd );
Pread( setting );
Pclose();
}
/*************************************************************
*
* play_next_random( facetphonedir, prompt_dir )
*
* Randomly plays one of the prompts found in:
*
* .../ivr/localsystem/vmprompts/'prompt_dir'
*
*************************************************************
*/
subroutine play_next_random( facetphonedir, prompt_dir )
{
int ret;
int prompt_cnt;
int r;
string cmd, lscmd;
string prompt_path;
string prompt_count;
string prompt;
string ivr_name;
prompt_path = facetphonedir + "/ivr/localsystem/vmprompts/";
prompt_path += prompt_dir;
lscmd = "cd " + prompt_path + ";";
lscmd += " ls *.wav";
cmd = lscmd + " | wc -l";
Popen( cmd );
Pread( prompt_count );
Pclose();
prompt_cnt = atoi( prompt_count );
dbgprt( prompt_cnt );
r = rand() % prompt_cnt;
r += 1;
Log_string( r ); /* CONVERTS 'r' TO STRING */
cmd = lscmd + " | head -" + r;
cmd += " | tail -1";
cmd += " | cut -d. -f1";
prompt = "";
Popen( cmd );
Pread( prompt );
Pclose();
ivr_name = "On Hold: (R) " + prompt_dir + ": "+ prompt;
Set_ivr_name( ivr_name );
prompt = prompt_dir + "/" + prompt;
dbgprt( prompt);
ret = Play_prompt_if_exists( prompt );
return ( ret );
}
/*********************************************************************
*
* play_next_alphabetical( facetphonedir, prompt_dir, *last_prompt )
*
* Plays in alphabetical order from 'last_prompt' a prompt in:
*
* .../ivr/localsystem/vmprompts/'prompt_dir'
*
* If 'last_prompt' really is the last prompt alphabetically
* then it rewinds to alphabetically first prompt.
*
* Name of prompt being played is returned in 'last_prompt'.
*
*********************************************************************
*/
subroutine play_next_alphabetical( facetphonedir, prompt_dir, *last_prompt )
{
int ret;
string cmd, lscmd;
string prompt_path;
string omega_prompt;
string prompt;
string ivr_name;
prompt_path = facetphonedir + "/ivr/localsystem/vmprompts/";
prompt_path += prompt_dir;
lscmd = "cd " + prompt_path + ";";
lscmd += " ls *.wav";
cmd = lscmd + " | tail -1";
cmd += " | cut -d. -f1";
omega_prompt="";
Popen( cmd );
Pread( omega_prompt );
Pclose();
dbgprt( omega_prompt );
prompt = "";
if ( last_prompt == "" || last_prompt == omega_prompt )
{
cmd = lscmd + " | head -1";
cmd += " | cut -d. -f1";
Popen( cmd );
Pread( prompt );
Pclose();
}
else
{
cmd = lscmd + " | cut -d. -f1";
cmd += " | while read x; do";
cmd += " if [ $x = " + last_prompt + " ];";
cmd += " then";
cmd += " read x;";
cmd += " echo $x;";
cmd += " exit;";
cmd += " fi;";
cmd += " done";
Popen( cmd );
Pread( prompt );
Pclose();
}
last_prompt = prompt;
ivr_name = "On Hold: (A) " + prompt_dir + ": " + prompt;
Set_ivr_name( ivr_name );
prompt = prompt_dir + "/" + prompt;
dbgprt( prompt );
ret = Play_prompt_if_exists( prompt );
return ( ret );
}
/*********************************************************************
*
* play_next_playlist( facetphonedir, prompt_dir, *last_prompt )
*
* Plays in listed order from 'last_prompt' a prompt in:
*
* .../ivr/localsystem/vmprompts/'prompt_dir'
*
* Playlist file called 'playlist' is located in 'prompt_dir'.
*
* Does not support duplicate entries in playlist. Expects the
* playlist to be a simple list of prompt names without filename
* extentions or paths, for example:
*
* "playlist":
* ------------
* message_01
* message_02
* message_03
* ------------
*
* Name of prompt being played is returned in 'last_prompt'.
*
*********************************************************************
*/
subroutine play_next_playlist( facetphonedir, prompt_dir, *last_prompt )
{
int ret;
string cmd, lscmd;
string prompt_path;
string omega_prompt;
string prompt;
string ivr_name;
prompt_path = facetphonedir + "/ivr/localsystem/vmprompts/";
prompt_path += prompt_dir;
cmd = "tail -1 " + prompt_path + "/playlist";
omega_prompt="";
Popen( cmd );
Pread( omega_prompt );
Pclose();
dbgprt( omega_prompt );
prompt = "";
if ( last_prompt == "" || last_prompt == omega_prompt )
{
cmd = "head -1 " + prompt_path + "/playlist";
Popen( cmd );
Pread( prompt );
Pclose();
}
else
{
cmd = "cat " + prompt_path + "/playlist";
cmd += " | while read x; do";
cmd += " if [ $x = " + last_prompt + " ];";
cmd += " then";
cmd += " read x;";
cmd += " echo $x;";
cmd += " exit;";
cmd += " fi;";
cmd += " done";
Popen( cmd );
Pread( prompt );
Pclose();
}
last_prompt = prompt;
ivr_name = "On Hold: (L) " + prompt_dir + ": " + prompt;
Set_ivr_name( ivr_name );
prompt = prompt_dir + "/" + prompt;
dbgprt( prompt );
ret = Play_prompt_if_exists( prompt );
return ( ret );
}
/*************************************************************
*
* monthly_message_on_hold()
*
* IVR routine to entertain and inform folks on hold by playing through
* a series of month-specific message prompts while they wait. Scheme
* cycles through a set of "month" directories, based upon the server
* date, and can be controlled thusly through a parameter file:
*
* play mode: prompts in "All" dir, or in monthly dirs
* play order: random, alphabetically, or playlist order
* greeting prompt: name of greeting propmt
* menu prompt: name of menu prompt
* play greeting: on, or off
* menu first: play menu before messages?
* msgs/menu: number of messages to play before menu
*
* Paramter Control file:
*
* /usr/facetphone/control/IVR-monthly_message_on_hold
*
*
* Script defaults unless overridden in Parameter Control file:
*
* PLAY_ALL_OR_MONTHLY=monthly
* PLAY_ORDER=random
* GREETING_PROMPT=monthly_message_greeting
* PLAY_GREETING=yes
* MENU_PROMPT=monthly_message_menu
* PLAY_MENU_FIRST=yes
* NUMBER_OF_MESSAGES_BEFORE_MENU=2
*
*
*************************************************************
*/
subroutine monthly_message_on_hold()
{
int ret, i;
int loops;
int user_logged_in;
int nbr_of_messages_before_menu;
int max_nbr_to_play;
int played_in_a_row;
int gag;
int menu_flag;
string cmd, script_out;
string ivr_name;
string control_file;
string setting;
string facetphonedir, prompt_dir;
string play_all_or_monthly;
string play_order;
string greeting_prompt;
string play_greeting;
string menu_prompt;
string play_menu_first;
string number_of_messages_before_menu;
string max_number_to_play;
string last_prompt_played;
Log_string( "Starting script: monthly_message_on_hold" );
user_logged_in = User_logged_in();
/* GET FACETPHONEDIR */
get_param( "/etc/facetphonedir", "FACETPHONEDIR", facetphonedir );
if ( facetphonedir == "" )
{
facetphonedir = "/usr/facetphone";
}
dbgprt( facetphonedir );
/* ASSUMES PARAMETER CONTROL FILE IS HERE */
control_file = facetphonedir + "/control/IVR-monthly_message_on_hold";
dbgprt ( control_file );
/*
* GET CONTROL PARAMETERS
*
* Defaults:
*
* PLAY_ALL_OR_MONTHLY=monthly
* PLAY_ORDER=random
* GREETING_PROMPT=monthly_message_greeting
* PLAY_GREETING=yes
* MENU_PROMPT=monthly_message_menu
* PLAY_MENU_FIRST=yes
* NUMBER_OF_MESSAGES_BEFORE_MENU=2
*
*/
/* GET PLAY_ALL_OR_MONTHLY */
get_param( control_file, "PLAY_ALL_OR_MONTHLY", play_all_or_monthly );
if ( play_all_or_monthly == "" )
{
play_all_or_monthly = "monthly";
}
dbgprt( play_all_or_monthly );
/* GET PLAY_ORDER */
get_param( control_file, "PLAY_ORDER", play_order );
if ( play_order == "" )
{
play_order = "random";
}
dbgprt( play_order );
/* GET GREETING_PROMPT */
get_param( control_file, "GREETING_PROMPT", greeting_prompt );
if ( greeting_prompt == "" )
{
greeting_prompt = "monthly_message_greeting";
}
dbgprt( greeting_prompt );
/* GET PLAY_GREETING */
get_param( control_file, "PLAY_GREETING", play_greeting );
if ( play_greeting == "" )
{
play_greeting = "yes";
}
dbgprt( play_greeting );
/* GET MENU_PROMPT */
get_param( control_file, "MENU_PROMPT", menu_prompt );
if ( menu_prompt == "" )
{
menu_prompt = "monthly_message_menu";
}
dbgprt( menu_prompt );
/* GET PLAY_MENU_FIRST */
get_param( control_file, "PLAY_MENU_FIRST", play_menu_first );
if ( play_menu_first == "" )
{
play_menu_first = "yes";
}
dbgprt( play_menu_first );
/* GET NUMBER_OF_MESSAGES_BEFORE_MENU */
get_param( control_file, "NUMBER_OF_MESSAGES_BEFORE_MENU",
number_of_messages_before_menu );
if ( number_of_messages_before_menu == "" )
{
number_of_messages_before_menu = "2";
}
nbr_of_messages_before_menu = atoi( number_of_messages_before_menu );
dbgprt( nbr_of_messages_before_menu );
/* GET MAX_NUMBER_TO_PLAY */
get_param( control_file, "MAX_NUMBER_TO_PLAY", max_number_to_play );
if ( max_number_to_play == "" )
{
max_number_to_play = "10";
}
max_nbr_to_play = atoi( max_number_to_play );
dbgprt( max_nbr_to_play );
/* SET PROMPT DIRECTORY */
if ( play_all_or_monthly == "all" )
{
/* prompt_dir = "all"; */
prompt_dir = "All";
}
else
{
prompt_dir = "";
/* cmd = "date +%b | tr 'A-Z' 'a-z'"; *//* lower-case */
cmd = "date +%b";
dbgprt( cmd );
Popen( cmd );
Pread( prompt_dir );
Pclose();
}
dbgprt( prompt_dir );
/* FINALLY READY TO ROCK! */
ret = E_DONE;
if ( play_greeting == "yes" )
{
ivr_name = "On Hold: greeting";
Set_ivr_name( ivr_name );
ret = Play_prompt( greeting_prompt );
}
if ( ret == E_DONE && play_menu_first == "yes" )
{
ivr_name = "On Hold: menu";
Set_ivr_name( ivr_name );
ret = Play_prompt( menu_prompt );
menu_flag = 1;
}
i = 0;
played_in_a_row = 0;
last_prompt_played = "";
gag = 0;
/* PLAY AT MOST MAX_NUMBER THEN DROP IN VOICE MAIL */
while ( i < max_nbr_to_play || ! max_nbr_to_play )
{
/* EXIT ON HANGUP */
if ( ret == E_STOP || ret == E_ERROR )
{
exit ( 0 );
}
dbgprt( i );
dbgprt( max_nbr_to_play );
dbgprt( played_in_a_row );
dbgprt( nbr_of_messages_before_menu );
/* TIME TO PLAY MENU? */
if ( played_in_a_row >= nbr_of_messages_before_menu
&& ret == E_DONE )
{
ivr_name = "On Hold: menu";
Set_ivr_name( ivr_name );
ret = Play_prompt( menu_prompt );
menu_flag = 1;
/* IF NBR_BEFORE = 0, SKIP MESSAGES */
if ( nbr_of_messages_before_menu == 0 )
{
i++;
continue;
}
played_in_a_row = 0;
}
/* CALLER PRESS MUTE BUTTON? */
if ( ret == E_DONE && gag )
{
ivr_name = "On Hold: ( silence )";
Set_ivr_name( ivr_name );
ret = Play_prompt( "silence" );
if ( ret == E_DONE )
{
ret = Wait( 60 );
}
if ( ret == E_TIMEOUT )
{
ret = E_DONE;
}
}
/* PLAY IN RANDOM ORDER? */
if ( ret == E_DONE && ! gag && play_order == "random" )
{
ret = play_next_random( facetphonedir, prompt_dir );
menu_flag = 0;
}
/* PLAY IN ALPHABETICAL ORDER? */
if ( ret == E_DONE && ! gag && play_order == "alphabetical" )
{
ret = play_next_alphabetical(
facetphonedir, prompt_dir, last_prompt_played );
menu_flag = 0;
}
/* PLAY IN PLAYLIST ORDER? */
if ( ret == E_DONE && ! gag && play_order == "playlist" )
{
ret = play_next_playlist(
facetphonedir, prompt_dir, last_prompt_played );
menu_flag = 0;
}
/* MESSAGE PLAYED, GOT KEY-PRESS? */
/* 'ZERO' FOR OPERATOR */
if ( ret == E_TT_0 )
{
ret = Transfer_to_oper( 6 );
if ( ret == E_STOP )
{
exit( 0 );
}
else if ( ret == E_OPERS_BUSY )
{
ret = Play_prompt( "operators_busy" );
}
else if ( ret == E_NO_OPER_ANSWER )
{
ret = Play_prompt( "operators_busy" );
}
}
/* '1' TO LEAVE A VOICE MAIL */
else if ( ret == E_TT_1 )
{
if ( user_logged_in )
{
vm_generic();
}
else
{
company_voice_mail_menu();
}
}
/* '2' TO SKIP A MESSAGE */
else if ( ret == E_TT_2 )
{
ret = E_DONE;
if ( gag )
{
gag = 0;
}
if ( menu_flag )
{
continue;
}
}
/* '3' TO TOGGLE MESSAGE PLAYING ON/OFF */
else if ( ret == E_TT_3 )
{
ret = E_DONE;
gag = ( gag + 1 ) % 2;
}
/* INVALID KEY, PLAY MENU NEXT */
else if ( ret == E_TT_4 || ret == E_TT_5 || ret == E_TT_6
|| ret == E_TT_7 || ret == E_TT_8 || ret == E_TT_9
|| ret == E_TT_POUND )
{
ret = Play_prompt( "keyinv" );
played_in_a_row = nbr_of_messages_before_menu;
}
played_in_a_row++;
i++;
}
/* EXIT ON HANGUP */
if ( ret == E_STOP || ret == E_ERROR )
{
exit ( 0 );
}
if ( i >= max_nbr_to_play )
{
Log_string( "monthly_message_on_hold: played max number of messages" );
dbgprt( i );
dbgprt( max_nbr_to_play );
}
/* PLAYED MAX MESSAGES, DROP TO VOICE MAIL */
Play_prompt( "operators_busy" );
if ( user_logged_in )
{
vm_generic();
}
else
{
company_voice_mail_menu();
}
Log_string( "Leaving script: monthly_message_on_hold" );
return ( ret );
}
/***** END OF SCRIPT *****/
|
Synopsis |
Control File |
IVR Overview |
Downloads |
Annotated Source
|