Added more debug output to the agi-AGENT_route.agi script
Added FHG(file-http-get) message playback option to download file from website to the VD_amd.agi Added example script for AWS Polly TTS generation of audio prompts Updated documentation git-svn-id: svn://192.168.202.10@3594 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
# exten => _8320*.,1,AGI(VD_amd.agi,${EXTEN}-----YES)
|
# exten => _8320*.,1,AGI(VD_amd.agi,${EXTEN}-----YES)
|
||||||
# exten => _8320*.,2,Hangup
|
# exten => _8320*.,2,Hangup
|
||||||
#
|
#
|
||||||
# Copyright (C) 2020 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
#
|
#
|
||||||
# changes:
|
# changes:
|
||||||
# 60206-1434 - first build
|
# 60206-1434 - first build
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
# 200205-1839 - Fix for list override message
|
# 200205-1839 - Fix for list override message
|
||||||
# 200311-0041 - Added amd_agent_route_options feature
|
# 200311-0041 - Added amd_agent_route_options feature
|
||||||
# 200424-1839 - Added STC(settings-container) and LTT(lead temp table) message playback options
|
# 200424-1839 - Added STC(settings-container) and LTT(lead temp table) message playback options
|
||||||
|
# 220411-0833 - Added FHG(file-http-get) message playback option to download file from website
|
||||||
#
|
#
|
||||||
|
|
||||||
$script = 'VD_amd.agi';
|
$script = 'VD_amd.agi';
|
||||||
@@ -69,6 +70,7 @@ $script = 'VD_amd.agi';
|
|||||||
$A = 1; # set to 1 for AMD output messages mode
|
$A = 1; # set to 1 for AMD output messages mode
|
||||||
$AMD_LOG = 3; # set to 1 for logfile and 2 forDB log, 3 for both
|
$AMD_LOG = 3; # set to 1 for logfile and 2 forDB log, 3 for both
|
||||||
$wav='.wav';
|
$wav='.wav';
|
||||||
|
$US='_';
|
||||||
|
|
||||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
||||||
$year = ($year + 1900);
|
$year = ($year + 1900);
|
||||||
@@ -768,12 +770,13 @@ else
|
|||||||
if ($AGILOG) {$agi_string = "-- VDAD vicidial_lead_call_quota_counts AM update: |$affected_rows|$uniqueid|"; &agi_output;}
|
if ($AGILOG) {$agi_string = "-- VDAD vicidial_lead_call_quota_counts AM update: |$affected_rows|$uniqueid|"; &agi_output;}
|
||||||
}
|
}
|
||||||
|
|
||||||
##### BEGIN Check if prompt uses TTS, STC, LTT or DYN. If so, create TTS and set the filename to the generated prompt #####
|
##### BEGIN Check if prompt uses TTS, STC, LTT,DYN or FHG. If so, create TTS and set the filename to the generated prompt #####
|
||||||
if ($DB_am_message_exten =~ /^TTS|^STC|^LTT|^DYN/)
|
if ($DB_am_message_exten =~ /^TTS|^STC|^LTT|^DYN|^FHG/)
|
||||||
{
|
{
|
||||||
$useTTS=0;
|
$useTTS=0;
|
||||||
$useSTC=0;
|
$useSTC=0;
|
||||||
$useLTT=0;
|
$useLTT=0;
|
||||||
|
$useFHG=0;
|
||||||
# Cepstral Text-To-Speech, vicidial_tts_prompts
|
# Cepstral Text-To-Speech, vicidial_tts_prompts
|
||||||
if ($DB_am_message_exten =~ /^TTS/)
|
if ($DB_am_message_exten =~ /^TTS/)
|
||||||
{
|
{
|
||||||
@@ -798,6 +801,17 @@ else
|
|||||||
$TTS_filename =~s/^LTT//gi;
|
$TTS_filename =~s/^LTT//gi;
|
||||||
$TTS_filename =~s/\|.*//gi;
|
$TTS_filename =~s/\|.*//gi;
|
||||||
}
|
}
|
||||||
|
# File-HTTP-get entry
|
||||||
|
elsif ($DB_am_message_exten =~ /^FHGhttp/)
|
||||||
|
{
|
||||||
|
$useFHG++;
|
||||||
|
$TTS_filename = $DB_am_message_exten;
|
||||||
|
$TTS_filename =~ s/^FHG//gi;
|
||||||
|
$TTS_filename =~ s/;|\||\\//gi;
|
||||||
|
$TTS_filename =~ s/http\/\//http:\/\//gi;
|
||||||
|
$TTS_filename =~ s/https\/\//https:\/\//gi;
|
||||||
|
$TTS_text = $TTS_filename;
|
||||||
|
}
|
||||||
# dynamic filename lookup
|
# dynamic filename lookup
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -806,7 +820,7 @@ else
|
|||||||
$TTS_text = $TTS_filename;
|
$TTS_text = $TTS_filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($AGILOG) {$agi_string = "-- TTS : |$useTTS|$useSTC|$useLTT|$TTS_filename|"; &agi_output;}
|
if ($AGILOG) {$agi_string = "-- TTS : |$useTTS|$useSTC|$useLTT|$useFHG|$TTS_filename|"; &agi_output;}
|
||||||
|
|
||||||
$stmtA = "SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner FROM vicidial_list where lead_id='$VD_lead_id';";
|
$stmtA = "SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner FROM vicidial_list where lead_id='$VD_lead_id';";
|
||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
@@ -951,6 +965,101 @@ else
|
|||||||
$TTS_text =~ s/--A--group--B--/$VD_campaign_id/gi;
|
$TTS_text =~ s/--A--group--B--/$VD_campaign_id/gi;
|
||||||
### END replace variables with record values ###
|
### END replace variables with record values ###
|
||||||
|
|
||||||
|
### BEGIN download FHG web file for playback ###
|
||||||
|
if ($useFHG > 0)
|
||||||
|
{
|
||||||
|
# Request URL as '$TTS_text'
|
||||||
|
$parse_url = $TTS_text;
|
||||||
|
|
||||||
|
### insert a new url log entry
|
||||||
|
$SQL_log = "$parse_url";
|
||||||
|
$SQL_log =~ s/;|\||\\//gi;
|
||||||
|
$stmtA = "INSERT INTO vicidial_url_log SET uniqueid='$uniqueid',url_date=NOW(),url_type='amd_fhg',url='$SQL_log',url_response='';";
|
||||||
|
$affected_rows = $dbhA->do($stmtA);
|
||||||
|
$stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;";
|
||||||
|
$sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr;
|
||||||
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
|
$sthArows=$sthA->rows;
|
||||||
|
if ($sthArows > 0)
|
||||||
|
{
|
||||||
|
@aryA = $sthA->fetchrow_array;
|
||||||
|
$url_id = $aryA[0];
|
||||||
|
}
|
||||||
|
$sthA->finish();
|
||||||
|
|
||||||
|
$url = $parse_url;
|
||||||
|
$url =~ s/'/\\'/gi;
|
||||||
|
$url =~ s/"/\\"/gi;
|
||||||
|
|
||||||
|
$temp_OUTPUT_file = $PATHsounds . "/tts/FHG$US$TTS_lead_id$US$now_date_epoch";
|
||||||
|
$temp_OUTPUT_fileWAV = $temp_OUTPUT_file . ".wav";
|
||||||
|
|
||||||
|
my $secW = time();
|
||||||
|
|
||||||
|
# disconnect from the database to free up the DB connection
|
||||||
|
$dbhA->disconnect();
|
||||||
|
|
||||||
|
### find wget binary
|
||||||
|
$wgetbin = '';
|
||||||
|
if ( -e ('/bin/wget')) {$wgetbin = '/bin/wget';}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( -e ('/usr/bin/wget')) {$wgetbin = '/usr/bin/wget';}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( -e ('/usr/local/bin/wget')) {$wgetbin = '/usr/local/bin/wget';}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print "Can't find wget binary! Exiting...\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# request the web URL
|
||||||
|
`$wgetbin --no-check-certificate --output-document=$temp_OUTPUT_fileWAV --output-file=/tmp/ASUBtmpF$US$url_id$US$now_date_epoch $url `;
|
||||||
|
|
||||||
|
# reconnect to the database to log response and response time
|
||||||
|
$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass")
|
||||||
|
or die "Couldn't connect to database: " . DBI->errstr;
|
||||||
|
|
||||||
|
if ($DB) {print "$function|$wgetbin --no-check-certificate --output-document=$temp_OUTPUT_file --output-file=/tmp/ASUBtmpF$US$url_id$US$now_date_epoch $url|";}
|
||||||
|
|
||||||
|
my $secY = time();
|
||||||
|
my $response_sec = ($secY - $secW);
|
||||||
|
|
||||||
|
$FILEsizeFHG = (-s "$temp_OUTPUT_fileWAV");
|
||||||
|
|
||||||
|
open(Wfile, "/tmp/ASUBtmpF$US$url_id$US$now_date_epoch") || die "can't open /tmp/ASUBtmpF$US$url_id$US$now_date_epoch: $!\n";
|
||||||
|
@Wfile = <Wfile>;
|
||||||
|
close(Wfile);
|
||||||
|
$i=0;
|
||||||
|
$Wfileline_cat='';
|
||||||
|
foreach(@Wfile)
|
||||||
|
{
|
||||||
|
$Wfileline = $Wfile[$i];
|
||||||
|
$Wfileline =~ s/\n|\r/!/gi;
|
||||||
|
$Wfileline =~ s/ |\t|\'|\`//gi;
|
||||||
|
$Wfileline_cat .= "$Wfileline";
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
if (length($Wfileline_cat)<1)
|
||||||
|
{$Wfileline_cat='<HEADER EMPTY>';}
|
||||||
|
|
||||||
|
|
||||||
|
### update url log entry
|
||||||
|
$stmtA = "UPDATE vicidial_url_log SET url_response='$FILEsizeFHG|$temp_OUTPUT_fileWAV|$Wfileline_cat',response_sec='$response_sec' where url_log_id='$url_id';";
|
||||||
|
$affected_rows = $dbhA->do($stmtA);
|
||||||
|
if ($DB) {print "$affected_rows|$stmtA\n";}
|
||||||
|
|
||||||
|
$TTS_text = $temp_OUTPUT_file;
|
||||||
|
|
||||||
|
if ($AGILOG) {$agi_string = "FHG: File downloaded($FILEsizeFHG bytes, $response_sec seconds) |$TTS_text|"; &agi_output;}
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
### END download FHG web file for playback ###
|
||||||
|
|
||||||
if ($useTTS > 0)
|
if ($useTTS > 0)
|
||||||
{
|
{
|
||||||
### BEGIN check for --C-- and --D-- tags for static file replacement
|
### BEGIN check for --C-- and --D-- tags for static file replacement
|
||||||
@@ -1506,6 +1615,12 @@ else
|
|||||||
$affected_rows = $dbhA->do($stmtA);
|
$affected_rows = $dbhA->do($stmtA);
|
||||||
if ($AGILOG) {$agi_string = "-- VLM vicidial_lead_messages POST-CALL update: |$affected_rows|$stmtA|"; &agi_output;}
|
if ($AGILOG) {$agi_string = "-- VLM vicidial_lead_messages POST-CALL update: |$affected_rows|$stmtA|"; &agi_output;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($useFHG > 0)
|
||||||
|
{
|
||||||
|
# add 2 seconds of silence before hanging up for FHG messages
|
||||||
|
sleep(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
#
|
#
|
||||||
# agi-AGENT_route.agi version 2.6
|
# agi-AGENT_route.agi version 2.14
|
||||||
#
|
#
|
||||||
# for use with a Call Menu in the custom dialplan section or as an AGI route.
|
# for use with a Call Menu in the custom dialplan section or as an AGI route.
|
||||||
#
|
#
|
||||||
@@ -28,12 +28,13 @@
|
|||||||
#; example with 4-digit agent IDs
|
#; example with 4-digit agent IDs
|
||||||
# exten => _XXXX,1,AGI(agi-AGENT_route.agi,default---AGENTDIRECT---ACTIVE)
|
# exten => _XXXX,1,AGI(agi-AGENT_route.agi,default---AGENTDIRECT---ACTIVE)
|
||||||
#
|
#
|
||||||
# Copyright (C) 2013 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
#
|
#
|
||||||
# changes:
|
# changes:
|
||||||
# 100321-0108 - First Build
|
# 100321-0108 - First Build
|
||||||
# 100704-2128 - Added several options
|
# 100704-2128 - Added several options
|
||||||
# 130108-1811 - Changes for Asterisk 1.8 compatibility
|
# 130108-1811 - Changes for Asterisk 1.8 compatibility
|
||||||
|
# 220414-2122 - Added more debug output
|
||||||
#
|
#
|
||||||
|
|
||||||
$script = 'agi-AGENT_route.agi';
|
$script = 'agi-AGENT_route.agi';
|
||||||
@@ -174,6 +175,9 @@ if ($minimum_user_digits =~ /X/)
|
|||||||
$pound_finish = 1;
|
$pound_finish = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($AGILOG) {$agi_string = "$did_settings|$in_group|$agent_active_filter|$user_id_prompt|$minimum_user_digits|$invalid_prompt|$invalid_reenter_prompt|$retry_attempts|$invalid_ingroup|$transfer_prompt|$transfer_logout_prompt"; &agi_output;}
|
||||||
|
|
||||||
|
|
||||||
$|=1;
|
$|=1;
|
||||||
while(<STDIN>)
|
while(<STDIN>)
|
||||||
{
|
{
|
||||||
@@ -217,6 +221,7 @@ $stmtA = "SELECT did_id FROM vicidial_inbound_dids where did_pattern = '$did_set
|
|||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
$sthArows=$sthA->rows;
|
$sthArows=$sthA->rows;
|
||||||
|
if ($AGILOG) {$agi_string = "$stmtA|$sthArows"; &agi_output;}
|
||||||
if ($sthArows > 0)
|
if ($sthArows > 0)
|
||||||
{
|
{
|
||||||
@aryA = $sthA->fetchrow_array;
|
@aryA = $sthA->fetchrow_array;
|
||||||
@@ -232,6 +237,7 @@ if ($sthArows < 1)
|
|||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
$DIDs_in_system=$sthA->rows;
|
$DIDs_in_system=$sthA->rows;
|
||||||
|
if ($AGILOG) {$agi_string = "$stmtA|$DIDs_in_system"; &agi_output;}
|
||||||
if ($DIDs_in_system > 0)
|
if ($DIDs_in_system > 0)
|
||||||
{
|
{
|
||||||
@aryA = $sthA->fetchrow_array;
|
@aryA = $sthA->fetchrow_array;
|
||||||
@@ -246,6 +252,7 @@ $stmtA = "SELECT ext_context FROM servers where server_ip = '$VARserver_ip';";
|
|||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
$sthArows=$sthA->rows;
|
$sthArows=$sthA->rows;
|
||||||
|
if ($AGILOG) {$agi_string = "$stmtA|$sthArows"; &agi_output;}
|
||||||
while ($sthArows > $cbc)
|
while ($sthArows > $cbc)
|
||||||
{
|
{
|
||||||
@aryA = $sthA->fetchrow_array;
|
@aryA = $sthA->fetchrow_array;
|
||||||
@@ -286,6 +293,7 @@ else
|
|||||||
|
|
||||||
if ( ($agent_active_filter =~ /LOGGED_IN/) && ($logged_in_user < 1) && ($active_user > 0) )
|
if ( ($agent_active_filter =~ /LOGGED_IN/) && ($logged_in_user < 1) && ($active_user > 0) )
|
||||||
{
|
{
|
||||||
|
if ($AGILOG) {$agi_string = "user not logged in"; &agi_output;}
|
||||||
$transfer_prompt = $transfer_logout_prompt;
|
$transfer_prompt = $transfer_logout_prompt;
|
||||||
$active_user=0;
|
$active_user=0;
|
||||||
}
|
}
|
||||||
@@ -305,6 +313,7 @@ else
|
|||||||
|
|
||||||
if (length($invalid_ingroup) > 1)
|
if (length($invalid_ingroup) > 1)
|
||||||
{
|
{
|
||||||
|
if ($AGILOG) {$agi_string = "user not active"; &agi_output;}
|
||||||
$did_extension = "99909$S$did_id$S$invalid_ingroup$S$S";
|
$did_extension = "99909$S$did_id$S$invalid_ingroup$S$S";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -350,6 +359,7 @@ sub find_if_active_user
|
|||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
$sthArows=$sthA->rows;
|
$sthArows=$sthA->rows;
|
||||||
|
if ($AGILOG) {$agi_string = "$stmtA|$sthArows"; &agi_output;}
|
||||||
if ($sthArows > 0)
|
if ($sthArows > 0)
|
||||||
{
|
{
|
||||||
@aryA = $sthA->fetchrow_array;
|
@aryA = $sthA->fetchrow_array;
|
||||||
@@ -363,6 +373,7 @@ sub find_if_active_user
|
|||||||
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
|
||||||
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
|
||||||
$sthArows=$sthA->rows;
|
$sthArows=$sthA->rows;
|
||||||
|
if ($AGILOG) {$agi_string = "$stmtA|$sthArows"; &agi_output;}
|
||||||
if ($sthArows > 0)
|
if ($sthArows > 0)
|
||||||
{
|
{
|
||||||
@aryA = $sthA->fetchrow_array;
|
@aryA = $sthA->fetchrow_array;
|
||||||
@@ -383,7 +394,7 @@ sub user_id_gather
|
|||||||
|
|
||||||
$interrupt_digit = $AGI->stream_file("$user_id_prompt",'0123456789');
|
$interrupt_digit = $AGI->stream_file("$user_id_prompt",'0123456789');
|
||||||
|
|
||||||
print STDERR "interrupt_digit |$interrupt_digit|\n";
|
if ($AGILOG) {$agi_string = "interrupt_digit |$interrupt_digit|"; &agi_output;}
|
||||||
|
|
||||||
$digits_being_entered=1;
|
$digits_being_entered=1;
|
||||||
$extension='';
|
$extension='';
|
||||||
@@ -412,7 +423,7 @@ sub user_id_gather
|
|||||||
if ($digit =~ /\d/)
|
if ($digit =~ /\d/)
|
||||||
{
|
{
|
||||||
$extension = "$extension$digit";
|
$extension = "$extension$digit";
|
||||||
print STDERR "digit |$digit| extension |$extension|\n";
|
if ($AGILOG) {$agi_string = "digit |$digit| extension |$extension|"; &agi_output;}
|
||||||
# $AGI->say_digits("$digit");
|
# $AGI->say_digits("$digit");
|
||||||
undef $digit;
|
undef $digit;
|
||||||
}
|
}
|
||||||
@@ -426,7 +437,10 @@ sub user_id_gather
|
|||||||
}
|
}
|
||||||
|
|
||||||
$extension =~ s/\D//gi;
|
$extension =~ s/\D//gi;
|
||||||
if ($extension > 0) {print STDERR "digit collection done|$digit| extension |$extension|\n";}
|
if ($extension > 0)
|
||||||
|
{
|
||||||
|
if ($AGILOG) {$agi_string = "digit collection done|$digit| extension |$extension|"; &agi_output;}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
##### END collect the user id number ###############################################
|
##### END collect the user id number ###############################################
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
DNC.COM INTEGRATION Started: 2015-12-02 Updated: 2017-09-25
|
DNC.COM INTEGRATION Started: 2015-12-02 Updated: 2022-04-21
|
||||||
|
|
||||||
NOTE: for DNC.COM integration of batch cellphone filtering, see this document:
|
NOTE: for DNC.COM integration of batch cellphone filtering, see this document:
|
||||||
CELLPHONE_USA_TCPA_FCC_COMPLIANCE.txt
|
CELLPHONE_USA_TCPA_FCC_COMPLIANCE.txt
|
||||||
|
|
||||||
|
|
||||||
We have added a utility to allow for direct filtering of lists on your Vicidial system with a DNC.COM account, to allow for state, federal(FTC) and internal DNC lists as well as TCPA and Litigator Scrub direct through DNC.COM. We have also added a new inbound scrubbing option for calls coming in through DIDs on your system.
|
We have added a utility to allow for direct filtering of inactive lists on your Vicidial system with a DNC.COM account, to allow for state, federal(FTC) and internal DNC lists as well as TCPA and Litigator Scrub direct through DNC.COM. We have also added a new inbound scrubbing option for calls coming in through DIDs on your system.
|
||||||
|
|
||||||
DNC.COM is also offering a Free 15 day trial to VICIdial users of their Real-time Integrated TCPA and DNC Safe Harbor lead scrubbing. For more information on this free offer, contact us (http://www.vicidial.com/?page_id=7).
|
DNC.COM is also offering a Free 15 day trial to VICIdial users of their Real-time Integrated TCPA and DNC Safe Harbor lead scrubbing. For more information on this free offer, contact us (http://www.vicidial.com/?page_id=7).
|
||||||
|
|
||||||
|
|
||||||
########## OUTBOUND LIST FILTERING ############################################
|
########## OUTBOUND LIST FILTERING ############################################
|
||||||
|
|
||||||
|
NOTE: Outbound list filtering is currently only available in a batch mode application, it does NOT look phone numbers up as they are dialed.
|
||||||
|
|
||||||
The script that allows for this must be run from the Linux command-line(CLI):
|
The script that allows for this must be run from the Linux command-line(CLI):
|
||||||
AST_DNCcom_filter.pl
|
AST_DNCcom_filter.pl --lists=LISTID1-LISTID2
|
||||||
|
|
||||||
|
The DNC.com List Filtering is designed to work in batch mode, usually set up in the crontab of one of your system's dialers. We recommend running this script after-hours, or only during calling hours on inavtive lists.
|
||||||
|
|
||||||
In order for this script to work, you must have a Settings Container set up within Vicidial with the ID of "DNCDOTCOM". This settings container should be customized for your specific DNC.COM account, and how you want it to function.
|
In order for this script to work, you must have a Settings Container set up within Vicidial with the ID of "DNCDOTCOM". This settings container should be customized for your specific DNC.COM account, and how you want it to function.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,237 @@
|
|||||||
|
<?php
|
||||||
|
# vdc_AWS_polly_TTS.php
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
|
||||||
|
#
|
||||||
|
# This script is designed to send a request to Amazon's AWS Polly Text-to-Speech
|
||||||
|
# service and receive back a PCM audio file(8k, 16bit, mono). Then add a WAV
|
||||||
|
# file header to it so it can be played natively in Asterisk.
|
||||||
|
#
|
||||||
|
# !!! THE AWS PHP SDK IS REQUIRED!!! You can download it here:
|
||||||
|
# http://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip
|
||||||
|
# (the above zip file contains over 3,000 files, make sure you have space)
|
||||||
|
# (unzip it inside a new 'polly' directory in the 'agc' web directory)
|
||||||
|
#
|
||||||
|
# !!! IMPORTANT !!! You must customize this script to your needs, and you must
|
||||||
|
# populate the credentials and region for your AWS account
|
||||||
|
#
|
||||||
|
# !!! IMPORTANT !!! This script assumes that the directory exists and is writable:
|
||||||
|
# agc/polly/generated
|
||||||
|
#
|
||||||
|
### Example URL to use in a SCRIPT tab Iframe:
|
||||||
|
# http://127.0.0.1/agc/vdc_AWS_polly_TTS.php?user=--A--user--B--&pass=--A--pass--B--&counter=--A--lead_id--B--&message=message+goes+here
|
||||||
|
#
|
||||||
|
# CHANGELOG:
|
||||||
|
# 220410-2127 - First build of script
|
||||||
|
#
|
||||||
|
|
||||||
|
$version = '2.14-1';
|
||||||
|
$build = '220410-2127';
|
||||||
|
$api_script = 'AWS_polly';
|
||||||
|
|
||||||
|
$startMS = microtime();
|
||||||
|
|
||||||
|
require_once("dbconnect_mysqli.php");
|
||||||
|
require_once("functions.php");
|
||||||
|
|
||||||
|
$query_string = getenv("QUERY_STRING");
|
||||||
|
|
||||||
|
if (isset($_GET["user"])) {$user=$_GET["user"];}
|
||||||
|
elseif (isset($_POST["user"])) {$user=$_POST["user"];}
|
||||||
|
if (isset($_GET["pass"])) {$pass=$_GET["pass"];}
|
||||||
|
elseif (isset($_POST["pass"])) {$pass=$_POST["pass"];}
|
||||||
|
if (isset($_GET["message"])) {$message=$_GET["message"];}
|
||||||
|
elseif (isset($_POST["message"])) {$message=$_POST["message"];}
|
||||||
|
if (isset($_GET["counter"])) {$counter=$_GET["counter"];}
|
||||||
|
elseif (isset($_POST["counter"])) {$counter=$_POST["counter"];}
|
||||||
|
if (isset($_GET["force"])) {$force=$_GET["force"];}
|
||||||
|
elseif (isset($_POST["force"])) {$force=$_POST["force"];}
|
||||||
|
if (isset($_GET["voice"])) {$voice=$_GET["voice"];}
|
||||||
|
elseif (isset($_POST["voice"])) {$voice=$_POST["voice"];}
|
||||||
|
if (isset($_GET["DB"])) {$DB=$_GET["DB"];}
|
||||||
|
elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];}
|
||||||
|
|
||||||
|
$DB=preg_replace("/[^0-9a-zA-Z]/","",$DB);
|
||||||
|
$user=preg_replace("/\'|\"|\\\\|;| /","",$user);
|
||||||
|
$pass=preg_replace("/\'|\"|\\\\|;| /","",$pass);
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
##### START SYSTEM_SETTINGS LOOKUP #####
|
||||||
|
$stmt = "SELECT use_non_latin,allow_sipsak_messages,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,agent_debug_logging,allow_web_debug FROM system_settings;";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
#if ($DB) {echo "$stmt\n";}
|
||||||
|
$qm_conf_ct = mysqli_num_rows($rslt);
|
||||||
|
if ($qm_conf_ct > 0)
|
||||||
|
{
|
||||||
|
$row=mysqli_fetch_row($rslt);
|
||||||
|
$non_latin = $row[0];
|
||||||
|
$allow_sipsak_messages = $row[1];
|
||||||
|
$SSenable_languages = $row[2];
|
||||||
|
$SSlanguage_method = $row[3];
|
||||||
|
$meetme_enter_login_filename = $row[4];
|
||||||
|
$meetme_enter_leave3way_filename = $row[5];
|
||||||
|
$SSagent_debug_logging = $row[6];
|
||||||
|
$SSallow_web_debug = $row[7];
|
||||||
|
}
|
||||||
|
if ($SSallow_web_debug < 1) {$DB=0;}
|
||||||
|
##### END SETTINGS LOOKUP #####
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
header ("Content-type: text/html; charset=utf-8");
|
||||||
|
header ("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
|
||||||
|
header ("Pragma: no-cache"); // HTTP/1.0
|
||||||
|
|
||||||
|
$txt = '.txt';
|
||||||
|
$StarTtime = date("U");
|
||||||
|
$NOW_DATE = date("Y-m-d");
|
||||||
|
$NOW_TIME = date("Y-m-d H:i:s");
|
||||||
|
$CIDdate = date("mdHis");
|
||||||
|
$ENTRYdate = date("YmdHis");
|
||||||
|
$MT[0]='';
|
||||||
|
|
||||||
|
$message = preg_replace("/\'|\\\\|;/","",$message);
|
||||||
|
$counter = preg_replace("/[^0-9]/","",$counter);
|
||||||
|
$force = preg_replace("/[^0-9]/","",$force);
|
||||||
|
$voice = preg_replace("/[^-_0-9a-zA-Z]/","",$voice);
|
||||||
|
|
||||||
|
if ($non_latin < 1)
|
||||||
|
{
|
||||||
|
$user=preg_replace("/[^-_0-9a-zA-Z]/","",$user);
|
||||||
|
$pass=preg_replace("/[^-_0-9a-zA-Z]/","",$pass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$user = preg_replace('/[^-_0-9\p{L}]/u','',$user);
|
||||||
|
$pass = preg_replace('/[^-\.\+\/\=_0-9\p{L}]/u','',$pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
# check user auth
|
||||||
|
$auth=0;
|
||||||
|
$auth_message = user_authorization($user,$pass,'',0,0,0,0,'AWS_polly');
|
||||||
|
if ($auth_message == 'GOOD')
|
||||||
|
{$auth=1;}
|
||||||
|
|
||||||
|
if ( (strlen($user)<2) or (strlen($pass)<2) or ($auth==0) )
|
||||||
|
{
|
||||||
|
echo _QXZ("Invalid Username/Password:")." |$user|$pass|$auth|$authlive|$auth_message|\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (strlen($message) < 1)
|
||||||
|
{
|
||||||
|
echo "ERROR: invalid message: |$message|\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (strlen($message) < 10)
|
||||||
|
{$message = '<speak>this is a test of the AWS Polly text to speech service. Number test, <say-as interpret-as="characters">1234567890</say-as>. Currency test, 987654321 dollars and 98 cents. Done.</speak>';}
|
||||||
|
if (strlen($voice) < 1) {$voice = 'Matthew';}
|
||||||
|
|
||||||
|
require_once './polly/aws-autoloader.php';
|
||||||
|
|
||||||
|
$awsAccessKeyId = 'XXXXXXXXXXXXXXXXXXXX';
|
||||||
|
$awsSecretKey = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY';
|
||||||
|
$credentials = new \Aws\Credentials\Credentials($awsAccessKeyId, $awsSecretKey);
|
||||||
|
$client = new \Aws\Polly\PollyClient([
|
||||||
|
'version' => '2016-06-10',
|
||||||
|
'credentials' => $credentials,
|
||||||
|
'region' => 'us-east-1',
|
||||||
|
]);
|
||||||
|
$result = $client->synthesizeSpeech([
|
||||||
|
'Engine' => 'neural',
|
||||||
|
'OutputFormat' => 'pcm',
|
||||||
|
'SampleRate' => '8000',
|
||||||
|
'Text' => $message,
|
||||||
|
'TextType' => 'ssml',
|
||||||
|
'VoiceId' => $voice,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$resultData = $result->get('AudioStream')->getContents();
|
||||||
|
|
||||||
|
# $resultData = file_get_contents('polly.raw');
|
||||||
|
//Output file
|
||||||
|
$temp_filename = "./polly/generated/".$counter."_TTS.wav";
|
||||||
|
$fp = fopen($temp_filename, 'wb');
|
||||||
|
|
||||||
|
$pcm_size = strlen($resultData);
|
||||||
|
$size = 36 + $pcm_size;
|
||||||
|
$chunk_size = 16;
|
||||||
|
$audio_format = 1;
|
||||||
|
$channels = 1; //mono
|
||||||
|
$sample_rate = 8000; //Hz #From the AWS Polly documentation: Valid values for pcm are "8000" and "16000" The default value is "16000".
|
||||||
|
$bits_per_sample = 16;
|
||||||
|
$block_align = $channels * $bits_per_sample / 8;
|
||||||
|
$byte_rate = $sample_rate * $channels * $bits_per_sample / 8;
|
||||||
|
|
||||||
|
//RIFF chunk descriptor
|
||||||
|
fwrite($fp, 'RIFF');
|
||||||
|
fwrite($fp,pack('I', $size));
|
||||||
|
fwrite($fp, 'WAVE');
|
||||||
|
//fmt sub-chunk
|
||||||
|
fwrite($fp, 'fmt ');
|
||||||
|
fwrite($fp,pack('I', $chunk_size));
|
||||||
|
fwrite($fp,pack('v', $audio_format));
|
||||||
|
fwrite($fp,pack('v', $channels));
|
||||||
|
fwrite($fp,pack('I', $sample_rate));
|
||||||
|
fwrite($fp,pack('I', $byte_rate));
|
||||||
|
fwrite($fp,pack('v', $block_align));
|
||||||
|
fwrite($fp,pack('v', $bits_per_sample));
|
||||||
|
//data sub-chunk
|
||||||
|
fwrite($fp, 'data');
|
||||||
|
fwrite($fp,pack('i', $pcm_size));
|
||||||
|
fwrite($fp, $resultData);
|
||||||
|
|
||||||
|
fclose($fp);
|
||||||
|
|
||||||
|
|
||||||
|
$endMS = microtime();
|
||||||
|
$startMSary = explode(" ",$startMS);
|
||||||
|
$endMSary = explode(" ",$endMS);
|
||||||
|
$runS = ($endMSary[0] - $startMSary[0]);
|
||||||
|
$runM = ($endMSary[1] - $startMSary[1]);
|
||||||
|
$TOTALrun = ($runS + $runM);
|
||||||
|
|
||||||
|
echo "SUCCESS|".$counter."_TTS.wav|\n";
|
||||||
|
|
||||||
|
# Log request to vicidial_api_log
|
||||||
|
$stmt="INSERT INTO vicidial_api_log set user='polly',agent_user='$user',function='aws_polly',value='TTS',result=\"GOOD\",result_reason='$counter ".$counter."_TTS.wav bytes: $size voice: $voice',source='AWS',data='$message',api_date=NOW(),api_script='$api_script',run_time='$TOTALrun',webserver='',api_url='';";
|
||||||
|
$rslt=mysql_to_mysqli($stmt, $link);
|
||||||
|
$ALaffected_rows = mysqli_affected_rows($link);
|
||||||
|
if ($DB > 0) {echo "LOG: $ALaffected_rows|$stmt|\n";}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# example export of mp3 audio data
|
||||||
|
# header('Content-Transfer-Encoding: binary');
|
||||||
|
# header('Content-Type: audio/wave, audio/wav, audio/x-wav, audio/x-pn-wav');
|
||||||
|
# header('Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3');
|
||||||
|
# header('Content-length: ' . strlen($resultData));
|
||||||
|
# header('Content-Disposition: attachment; filename="pollyTTS.wav"');
|
||||||
|
# header('X-Pad: avoid browser bug');
|
||||||
|
# header('Cache-Control: no-cache');
|
||||||
|
# echo $resultData;
|
||||||
|
|
||||||
|
# output as MP3 to listen
|
||||||
|
# $size = strlen($resultData); // File size
|
||||||
|
# $length = $size; // Content length
|
||||||
|
# $start = 0; // Start byte
|
||||||
|
# $end = $size - 1; // End byte
|
||||||
|
# header('Content-Transfer-Encoding:chunked');
|
||||||
|
# header("Content-Type: audio/mpeg");
|
||||||
|
# header("Accept-Ranges: 0-$length");
|
||||||
|
# header("Content-Range: bytes $start-$end/$size");
|
||||||
|
# header("Content-Length: $length");
|
||||||
|
# echo $resultData;
|
||||||
|
|
||||||
|
# output as MP3 to download
|
||||||
|
# header('Content-length: ' . strlen($resultData));
|
||||||
|
# header('Content-Disposition: attachment; filename="polly-text-to-speech.mp3"');
|
||||||
|
# header('X-Pad: avoid browser bug');
|
||||||
|
# header('Cache-Control: no-cache');
|
||||||
|
# echo $resultData;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# version: 20220311081801
|
# version: 20220418230401
|
||||||
users-user User ID <QXZ>This field is where you put the users ID number, can be up to 8 digits in length, Must be at least 2 characters in length.</QXZ>
|
users-user User ID <QXZ>This field is where you put the users ID number, can be up to 8 digits in length, Must be at least 2 characters in length.</QXZ>
|
||||||
users-pass Password <QXZ>This field is where you put the users password. Must be at least 2 characters in length. Only letters and numbers are allowed in user passwords. A medium strength user password will be at least 10 characters in length, and a strong user password will be at least 20 characters in length and have letters as well as at least one number. It is recommended that you use a longer password if possible, stringing together several unrelated words with no spaces, and a number somewhere in the string. The maximum size of a password is 100 characters.</QXZ>
|
users-pass Password <QXZ>This field is where you put the users password. Must be at least 2 characters in length. Only letters and numbers are allowed in user passwords. A medium strength user password will be at least 10 characters in length, and a strong user password will be at least 20 characters in length and have letters as well as at least one number. It is recommended that you use a longer password if possible, stringing together several unrelated words with no spaces, and a number somewhere in the string. The maximum size of a password is 100 characters.</QXZ>
|
||||||
users-force_change_password Force Change Password <QXZ>If this option is set to Y then the user will be prompted to change their password the next time they log in to the administration webpage or the agent screen. Default is N.</QXZ>
|
users-force_change_password Force Change Password <QXZ>If this option is set to Y then the user will be prompted to change their password the next time they log in to the administration webpage or the agent screen. Default is N.</QXZ>
|
||||||
@@ -181,7 +181,7 @@ campaigns-dial_timeout Dial Timeout <QXZ>If defined, calls that would normally h
|
|||||||
campaigns-dial_timeout_lead_container Dial Timeout Lead Container <QXZ>This option allows you to select a Settings Container of the DIAL_TIMEOUTS type that will allow you to override the campaign dial timeouts on a per lead basis using a lead field value defined in the container. You can enable manual dialing and auto dialing overrides separately by defining which lead field is to be looked at for a dial timeout key value. If you wanted to use the -comments- lead field for manual dial timeouts, you would define manual_dial_field => comments. If you wanted to use the -comments- lead field for auto dial timeouts, you would define auto_dial_field => comments. after either or both of these are defined, you will need to define the key and value pairs for the dial timeouts. For example, if a key of -A- in the comments field should trigger a 50 second dial timeout override for the lead, you would define A => 50. You can define multiple key and value pairs in the settings container. Lead field names should be in lower case letters only. You must define the Lead Field Name above any Field Values that you define. Field value matching is case sensitive. We recommend not matching to field values that have spaces or special characters in them.</QXZ>
|
campaigns-dial_timeout_lead_container Dial Timeout Lead Container <QXZ>This option allows you to select a Settings Container of the DIAL_TIMEOUTS type that will allow you to override the campaign dial timeouts on a per lead basis using a lead field value defined in the container. You can enable manual dialing and auto dialing overrides separately by defining which lead field is to be looked at for a dial timeout key value. If you wanted to use the -comments- lead field for manual dial timeouts, you would define manual_dial_field => comments. If you wanted to use the -comments- lead field for auto dial timeouts, you would define auto_dial_field => comments. after either or both of these are defined, you will need to define the key and value pairs for the dial timeouts. For example, if a key of -A- in the comments field should trigger a 50 second dial timeout override for the lead, you would define A => 50. You can define multiple key and value pairs in the settings container. Lead field names should be in lower case letters only. You must define the Lead Field Name above any Field Values that you define. Field value matching is case sensitive. We recommend not matching to field values that have spaces or special characters in them.</QXZ>
|
||||||
campaigns-campaign_vdad_exten Routing Extension <QXZ>This field allows for a custom outbound routing extension. This allows you to use different call handling methods depending upon how you want to route calls through your outbound campaign. Formerly called Campaign VDAD extension.</QXZ><BR>- <QXZ>8364 - same as 8368</QXZ><BR>- <QXZ>8365 - Will send the call only to an agent on the same server as the call is placed on, DISABLED, now same as 8367</QXZ><BR>- <QXZ>8366 - Used for press-1, broadcast and survey campaigns</QXZ><BR>- <QXZ>8367 - Will try to first send the call to an agent on the local server, then it will look on other servers</QXZ><BR>- <QXZ>8368 - DEFAULT - Will send the call to the next available agent no matter what server they are on</QXZ><BR>- <QXZ>8369 - Used for Answering Machine Detection after that, same behavior as 8368</QXZ><BR>- <QXZ>8373 - Used for Answering Machine Detection after that same behavior as 8366</QXZ><BR>- <QXZ>8374 - Used for press-1, broadcast and survey campaigns with Cepstral Text-to-speech</QXZ><BR>- <QXZ>8375 - Used for Answering Machine Detection then press-1, broadcast and survey campaigns with Cepstral Text-to-speech</QXZ>
|
campaigns-campaign_vdad_exten Routing Extension <QXZ>This field allows for a custom outbound routing extension. This allows you to use different call handling methods depending upon how you want to route calls through your outbound campaign. Formerly called Campaign VDAD extension.</QXZ><BR>- <QXZ>8364 - same as 8368</QXZ><BR>- <QXZ>8365 - Will send the call only to an agent on the same server as the call is placed on, DISABLED, now same as 8367</QXZ><BR>- <QXZ>8366 - Used for press-1, broadcast and survey campaigns</QXZ><BR>- <QXZ>8367 - Will try to first send the call to an agent on the local server, then it will look on other servers</QXZ><BR>- <QXZ>8368 - DEFAULT - Will send the call to the next available agent no matter what server they are on</QXZ><BR>- <QXZ>8369 - Used for Answering Machine Detection after that, same behavior as 8368</QXZ><BR>- <QXZ>8373 - Used for Answering Machine Detection after that same behavior as 8366</QXZ><BR>- <QXZ>8374 - Used for press-1, broadcast and survey campaigns with Cepstral Text-to-speech</QXZ><BR>- <QXZ>8375 - Used for Answering Machine Detection then press-1, broadcast and survey campaigns with Cepstral Text-to-speech</QXZ>
|
||||||
campaigns-agent_search_method Agent Search Method Override <QXZ>This setting will allow you to override the dialplan agent search method and force one only for this campaign. LB will search for the next agent on any server to send the answered call to. LO will first search on the originating server then search for agents on other servers. SO will only search on the originating server for an agent to send the answered call to. Default is blank for disabled. WARNING, setting this to -SO- can result in a much higher number of dropped calls.</QXZ>
|
campaigns-agent_search_method Agent Search Method Override <QXZ>This setting will allow you to override the dialplan agent search method and force one only for this campaign. LB will search for the next agent on any server to send the answered call to. LO will first search on the originating server then search for agents on other servers. SO will only search on the originating server for an agent to send the answered call to. Default is blank for disabled. WARNING, setting this to -SO- can result in a much higher number of dropped calls.</QXZ>
|
||||||
campaigns-am_message_exten Answering Machine Message <QXZ>This field is for entering the prompt to play when the agent gets an answering machine and clicks on the Answering Machine Message button in the transfer conference frame. You must set this to either an audio file in the audio store or a TTS prompt if TTS is enabled on your system. You can also use lead fields to generate audio filenames using the DYN flag, for instance using DYN--A--user--B-- for agent 1234 would look for a file named 1234.wav in your audio store to play. If you need more space to build your message with files, you can put them into a Settings Container and the use STC and then the container ID to use that settings container as your answering machine message. Another advanced option is LTT, if you have custom programming on your system to construct answering maching messages on a per-call basis. If you will be using the Agent API function vm_message, you will want to put LTTagent in this field.</QXZ>
|
campaigns-am_message_exten Answering Machine Message <QXZ>This field is for entering the prompt to play when the agent gets an answering machine and clicks on the Answering Machine Message button in the transfer conference frame. You must set this to either an audio file in the audio store or a TTS prompt if TTS is enabled on your system. You can also use lead fields to generate audio filenames using the DYN flag, for instance using DYN--A--user--B-- for agent 1234 would look for a file named 1234.wav in your audio store to play. If you need more space to build your message with files, you can put them into a Settings Container and the use STC and then the container ID to use that settings container as your answering machine message. Another advanced option is LTT, if you have custom programming on your system to construct answering maching messages on a per-call basis. If you will be using the Agent API function vm_message, you will want to put LTTagent in this field. Another advanced option is to use a prefix of FHG along with a URL to pull an audio file from a webserver, preferrably a local webserver. This FHG option can be used with a Text-to-Speech service to play recording generated on a per-call basis, possibly from a custom agent script. Here is an example using this prefix, FHGhttp//127.0.0.1/agc/tts/--A--lead_id--B--_TTS.wav</QXZ>
|
||||||
campaigns-vmm_daily_limit Voicemail Message Daily Limit <QXZ>This option allows you to limit the number of times a voicemail message plays to a lead for a single day. After the defined limit is reached, the call will be hung up instead of playing a message. If this feature is active then it will be in effect for all calls sent to play a voicemail message, even if an agent manually sends a call to a VM message. The default is 0, for disabled.</QXZ>
|
campaigns-vmm_daily_limit Voicemail Message Daily Limit <QXZ>This option allows you to limit the number of times a voicemail message plays to a lead for a single day. After the defined limit is reached, the call will be hung up instead of playing a message. If this feature is active then it will be in effect for all calls sent to play a voicemail message, even if an agent manually sends a call to a VM message. The default is 0, for disabled.</QXZ>
|
||||||
campaigns-waitforsilence_options WaitForSilence Options <QXZ>If Wait For Silence is desired on calls that are detected as Answering Machines then this field has those options. There are three settings separated by a comma, the first option is how long to detect silence in milliseconds, the second option is for how many times to detect that before playing the message, the third is the maximum number of seconds to wait before timing out and playing the message. Default is EMPTY for disabled. A standard value for this would be wait for 2 seconds of silence twice: 2000,2,30</QXZ>
|
campaigns-waitforsilence_options WaitForSilence Options <QXZ>If Wait For Silence is desired on calls that are detected as Answering Machines then this field has those options. There are three settings separated by a comma, the first option is how long to detect silence in milliseconds, the second option is for how many times to detect that before playing the message, the third is the maximum number of seconds to wait before timing out and playing the message. Default is EMPTY for disabled. A standard value for this would be wait for 2 seconds of silence twice: 2000,2,30</QXZ>
|
||||||
campaigns-am_message_wildcards AM Message Wildcards <QXZ>This option, if enabled, allows you to go to the AM Message Wildcard administration page where you can define wildcards that can match data in a default lead field and can play a different message based upon the data in a specific lead. Default is N for disabled.</QXZ>
|
campaigns-am_message_wildcards AM Message Wildcards <QXZ>This option, if enabled, allows you to go to the AM Message Wildcard administration page where you can define wildcards that can match data in a default lead field and can play a different message based upon the data in a specific lead. Default is N for disabled.</QXZ>
|
||||||
|
|||||||
Reference in New Issue
Block a user