From 261f36fd90aa50ad674077c55aa697fda7c5f486 Mon Sep 17 00:00:00 2001 From: mattf Date: Thu, 3 Dec 2015 12:18:56 +0000 Subject: [PATCH] Added AST_DNCcom_filter.pl script which allows for direct batch filtering of lists within vicidial with the DNC.COM dnc filtering service git-svn-id: svn://192.168.202.10@2419 3d104415-ff17-0410-8863-d5cf3c621b8a --- UPGRADE | 4 + bin/AST_DNCcom_filter.pl | 485 +++++++++++++++++++++++++++++ docs/DNC-dot-COM_integration.txt | 185 +++++++++++ extras/MySQL_AST_CREATE_tables.sql | 16 +- extras/upgrade_2.12.sql | 16 + 5 files changed, 705 insertions(+), 1 deletion(-) create mode 100644 bin/AST_DNCcom_filter.pl create mode 100644 docs/DNC-dot-COM_integration.txt diff --git a/UPGRADE b/UPGRADE index d2d9c30a..0dec42fb 100644 --- a/UPGRADE +++ b/UPGRADE @@ -195,6 +195,10 @@ OTHER CHANGES: 47. Added option to several reports to search the archived logs. +48. Added AST_DNCcom_filter.pl script which allows for direct batch filtering of + lists within vicidial with the DNC.COM dnc filtering service. For more + info, see the DNC-dot-COM_integration.txt document. + diff --git a/bin/AST_DNCcom_filter.pl b/bin/AST_DNCcom_filter.pl new file mode 100644 index 00000000..3469bb36 --- /dev/null +++ b/bin/AST_DNCcom_filter.pl @@ -0,0 +1,485 @@ +#!/usr/bin/perl +# +# AST_DNCcom_filter.pl version 2.12 +# +# This script filters lists against dnc.com +# +# !!! REQUIRES A SETTINGS CONTAINER CALLED "DNCDOTCOM" TO BE SET UP TO USE !!! +# +# Copyright (C) 2015 Matt Florell LICENSE: AGPLv2 +# +# 151004-1606 - Initial Build +# 151005-1256 - Added logging +# 151019-1456 - Reorganzied to reduce vicidial_list locks and improve dnc.com response +# 151022-1900 - Code clean up +# 151202-1435 - Added URL option for settings container +# + +# constants +$DB=0; # Debug flag, set to 0 for no debug messages per minute + +### begin parsing run-time options ### +if (length($ARGV[0])>1) + { + $i=0; + while ($#ARGV >= $i) + { + $args = "$args $ARGV[$i]"; + $i++; + } + + if ($args =~ /--help/i) + { + print "allowed run time options:\n"; + print " [--debug] = verbose debug messages\n"; + print " [--lists=LISTID1-LISTID2] = the list ids to be filters\n"; + print "\n"; + exit; + } + else + { + if ($args =~ /--debug/i) + { + $DB=1; # Debug flag + print "-- DEBUGGING ENABLED --\n\n"; + } + if ($args =~ /--lists=/i) + { + @data_in = split(/--lists=/,$args); + $CLIlists = $data_in[1]; + $CLIlists =~ s/ .*$//gi; + if ($CLIlists =~ /-/) + { + $CLIlists =~ s/-/,/gi; + } + } + if (length($CLIlists)<2) + { + print "no lists defined, exiting.\n"; + exit; + } + if ($DB) {print "|$CLIlists|\n";} + } + } +else + { + print "no command line options set\n"; + exit; + } +### end parsing run-time options ### + +# default path to astguiclient configuration file: +$PATHconf = '/etc/astguiclient.conf'; + +open(conf, "$PATHconf") || die "can't open $PATHconf: $!\n"; +@conf = ; +close(conf); +$i=0; +foreach(@conf) + { + $line = $conf[$i]; + $line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi; + if ( ($line =~ /^PATHhome/) && ($CLIhome < 1) ) + {$PATHhome = $line; $PATHhome =~ s/.*=//gi;} + if ( ($line =~ /^PATHlogs/) && ($CLIlogs < 1) ) + {$PATHlogs = $line; $PATHlogs =~ s/.*=//gi;} + if ( ($line =~ /^PATHagi/) && ($CLIagi < 1) ) + {$PATHagi = $line; $PATHagi =~ s/.*=//gi;} + if ( ($line =~ /^PATHweb/) && ($CLIweb < 1) ) + {$PATHweb = $line; $PATHweb =~ s/.*=//gi;} + if ( ($line =~ /^PATHsounds/) && ($CLIsounds < 1) ) + {$PATHsounds = $line; $PATHsounds =~ s/.*=//gi;} + if ( ($line =~ /^PATHmonitor/) && ($CLImonitor < 1) ) + {$PATHmonitor = $line; $PATHmonitor =~ s/.*=//gi;} + if ( ($line =~ /^VARserver_ip/) && ($CLIserver_ip < 1) ) + {$VARserver_ip = $line; $VARserver_ip =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_server/) && ($CLIDB_server < 1) ) + {$VARDB_server = $line; $VARDB_server =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_database/) && ($CLIDB_database < 1) ) + {$VARDB_database = $line; $VARDB_database =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_user/) && ($CLIDB_user < 1) ) + {$VARDB_user = $line; $VARDB_user =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_pass/) && ($CLIDB_pass < 1) ) + {$VARDB_pass = $line; $VARDB_pass =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_port/) && ($CLIDB_port < 1) ) + {$VARDB_port = $line; $VARDB_port =~ s/.*=//gi;} + $i++; + } + +# Customized Variables +$server_ip = $VARserver_ip; # Asterisk server IP + +if (!$VARDB_port) {$VARDB_port='3306';} + +use DBI; +use Time::HiRes qw( gettimeofday ); +use WWW::Curl::Easy; +use WWW::Curl::Form; + +$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass") + or die "Couldn't connect to database: " . DBI->errstr; + +$stmtA = "SELECT container_entry FROM vicidial_settings_containers WHERE container_id = 'DNCDOTCOM';"; +if ($DB) {print "|$stmtA|\n";} +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; +$rec_count=0; +if ($sthArows > 0) + { + + # log to the vicidial_admin_log the scrub + foreach $list_id (split /,/ ,$CLIlists) + { + $now = get_mysql_date_string(time()); + $stmtA = "INSERT INTO vicidial_admin_log SET event_date = '$now', user = 'VDAD', ip_address = '1.1.1.1', event_section = 'LISTS', event_type = 'OTHER', record_id = '$list_id', event_sql='', event_code='DNC.com SCRUB STARTED', event_notes='DNC.com scrub of list $list_id started at $now';"; + if ($DB) { print "|$stmtA|\n"; } + $dbhA->do($stmtA) or die "executing: $stmtA ", $dbhA->errstr; + } + + + @aryA = $sthA->fetchrow_array; + $container_entry = $aryA[0]; + %dnccom_settings = get_container_settings($container_entry); + + if ( + exists($dnccom_settings{'LOGIN_ID'}) && + exists($dnccom_settings{'CAMPAIGN_ID'}) && + exists($dnccom_settings{'PROJ_ID'}) && + exists($dnccom_settings{'VERSION'}) + ) + { + # $base_url = "http://www.dncscrub.com/app/main/rpc/scrub"; + $base_url = $dnccom_settings{"DNC_DOT_COM_URL"}; + $url = "$base_url?loginId=$dnccom_settings{'LOGIN_ID'}&version=$dnccom_settings{'VERSION'}&projId=$dnccom_settings{'PROJ_ID'}&campaignId=$dnccom_settings{'CAMPAIGN_ID'}&phoneList="; + + if ($DB) {print "|$url|\n";} + + $skip_statuses = $dnccom_settings{'VICI_STATUS_SKIP'}; + $skip_statuses = "'$skip_statuses'"; + $skip_statuses =~ s/-/','/gi; + + if ($DB) {print "|$skip_statuses|\n";} + + + $lead_id_pos = 0; + $lead_grab = 1000; # number of leads to grab at a time + $scrub_grab = 50000; # number of leads to send to DNC.com + $scrub_attempts = 5; # number of times to attempt to connect to DNC.com before erroring out + $loop = 1; + $scrub_count = 0; + + $x_count=0; + $c_count=0; + $o_count=0; + $e_count=0; + $r_count=0; + $w_count=0; + $g_count=0; + $h_count=0; + $l_count=0; + $f_count=0; + $v_count=0; + $i_count=0; + $m_count=0; + $b_count=0; + $p_count=0; + $d_count=0; + $s_count=0; + $t_count=0; + $y_count=0; + + + while ( $loop > 0 ) + { + $scrub_success = 0; + $good_num_count = 0; + $phone_string = ''; + + my @leads; + + # Grab leads till we have enough to call the DNC.com URL + $grabbed_leads = 0; + while (( $good_num_count < $scrub_grab ) && ( $loop > 0 )) + { + # grab a chuck of leads + $stmtA = "SELECT lead_id, phone_number, status, list_id FROM vicidial_list WHERE list_id IN ($CLIlists) AND status NOT IN ($skip_statuses) AND lead_id > $lead_id_pos ORDER BY lead_id LIMIT $lead_grab;" ; + if ($DB) {print "|$stmtA|\n";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + + # if we got results + if ( $sthArows > 0 ) + { + $grabbed_leads = 1; + $rec_count=0; + + while ( $sthArows > $rec_count ) + { + @aryA = $sthA->fetchrow_array; + $lead_id = $aryA[0]; + $phone_number = $aryA[1]; + $status = $aryA[2]; + $list_id = $aryA[3]; + + # verify the lead is 10 digits + if ( $phone_number =~ /^\d\d\d\d\d\d\d\d\d\d$/ ) + { + # if ($DB) { print "$good_num_count|$phone_number is in NANPA\n"; } + if ( $good_num_count == 0 ) { $phone_string = "$phone_number"; } + else { $phone_string = "$phone_string,$phone_number"; } + + # add the numbers to our array + $leads[$good_num_count][0] = $lead_id; + $leads[$good_num_count][1] = $phone_number; + $leads[$good_num_count][2] = $status; + $leads[$good_num_count][3] = $list_id; + + $good_num_count++; + $scrub_count++; + } + else + { + if ($DB) { print "$phone_number is not 10 digits\n"; } + } + + # keep track of the last lead we grabbed + $lead_id_pos = $lead_id; + $rec_count++; + } + + } + # if not stop looping + else + { + $loop = 0; + } + + } + + + while ( ($scrub_attempts > 0) && ($scrub_success != 1) && ($grabbed_leads == 1) ) + { + + # scrub the leads + if ($DB) {print "|$phone_string|\n";} + + my $dnccom_body; # string to hold their response + + # prepare the curl object + my $curl = WWW::Curl::Easy->new; + $curl->setopt(CURLOPT_HEADER,0); + $curl->setopt(CURLOPT_URL, "$base_url"); + $curl->setopt(CURLOPT_WRITEDATA,\$dnccom_body); + + # set the form data + my $curlf = WWW::Curl::Form->new; + $curlf->formadd("loginId", "$dnccom_settings{'LOGIN_ID'}"); + $curlf->formadd("version", "$dnccom_settings{'VERSION'}"); + $curlf->formadd("projId", "$dnccom_settings{'PROJ_ID'}"); + $curlf->formadd("campaignId", "$dnccom_settings{'CAMPAIGN_ID'}"); + $curlf->formadd("phoneList", "$phone_string"); + + # attach the form data + $curl->setopt(CURLOPT_HTTPPOST, $curlf); + + # time before URL + ($before_seconds, $before_microseconds) = gettimeofday(); + + # call the URL + my $retcode = $curl->perform; + + # time after URL + ($after_seconds, $after_microseconds) = gettimeofday(); + + # calculate their response time + $url_seconds = $after_seconds - $before_seconds; + + if ($DB) {print "$before_seconds|$after_seconds|request time = $url_seconds\n";} + + if ( $retcode == 0 ) + { + $scrub_success = 1; + $result_count = 0; + + # split their response into single lines + if ($DB) {print "Spliting\n";} + foreach $line (split /\n/ ,$dnccom_body) + { + #if ($DB) {print "$line\n";} + @line_results = split /,/, $line; + + $dnccom_pn = $line_results[0]; + $dnccom_rc = $line_results[1]; + + # verify that the result phone number matches the one in the leads array + if ( $dnccom_pn eq $leads[$result_count][1] ) + { + # keep track of how many we got of each + if ( $dnccom_rc eq 'X' ) { $x_count++; $up_status=$dnccom_settings{"STATUS_X"};} + if ( $dnccom_rc eq 'C' ) { $c_count++; $up_status=$dnccom_settings{"STATUS_C"};} + if ( $dnccom_rc eq 'O' ) { $o_count++; $up_status=$dnccom_settings{"STATUS_O"};} + if ( $dnccom_rc eq 'E' ) { $e_count++; $up_status=$dnccom_settings{"STATUS_E"};} + if ( $dnccom_rc eq 'R' ) { $r_count++; $up_status=$dnccom_settings{"STATUS_R"};} + if ( $dnccom_rc eq 'W' ) { $w_count++; $up_status=$dnccom_settings{"STATUS_W"};} + if ( $dnccom_rc eq 'G' ) { $g_count++; $up_status=$dnccom_settings{"STATUS_G"};} + if ( $dnccom_rc eq 'H' ) { $h_count++; $up_status=$dnccom_settings{"STATUS_H"};} + if ( $dnccom_rc eq 'L' ) { $l_count++; $up_status=$dnccom_settings{"STATUS_L"};} + if ( $dnccom_rc eq 'F' ) { $f_count++; $up_status=$dnccom_settings{"STATUS_F"};} + if ( $dnccom_rc eq 'V' ) { $v_count++; $up_status=$dnccom_settings{"STATUS_V"};} + if ( $dnccom_rc eq 'I' ) { $i_count++; $up_status=$dnccom_settings{"STATUS_I"};} + if ( $dnccom_rc eq 'M' ) { $m_count++; $up_status=$dnccom_settings{"STATUS_M"};} + if ( $dnccom_rc eq 'B' ) { $b_count++; $up_status=$dnccom_settings{"STATUS_B"};} + if ( $dnccom_rc eq 'P' ) { $p_count++; $up_status=$dnccom_settings{"STATUS_P"};} + if ( $dnccom_rc eq 'D' ) { $d_count++; $up_status=$dnccom_settings{"STATUS_D"};} + if ( $dnccom_rc eq 'S' ) { $s_count++; $up_status=$dnccom_settings{"STATUS_S"};} + if ( $dnccom_rc eq 'T' ) { $t_count++; $up_status=$dnccom_settings{"STATUS_T"};} + if ( $dnccom_rc eq 'Y' ) { $y_count++; $up_status=$dnccom_settings{"STATUS_Y"};} + + + # update the lead + if ( $dnccom_settings{'ADD_INFO_TO_COMMENTS'} eq 'YES' ) + { + $stmtA = "UPDATE vicidial_list SET status = '$up_status', comments = CONCAT(comments,'!N$leads[$result_count][2]!N$line') where lead_id=$leads[$result_count][0] and phone_number='$leads[$result_count][1]';"; + } + else + { + $stmtA = "UPDATE vicidial_list SET status = '$up_status' where lead_id=$leads[$result_count][0] and phone_number='$leads[$result_count][1]';"; + } + if ($DB) { print "|$stmtA|\n"; } + $dbhA->do($stmtA) or die "executing: $stmtA ", $dbhA->errstr; + + + # insert a log record + $now = get_mysql_date_string(time()); + $stmtA = "INSERT INTO vicidial_dnccom_filter_log SET lead_id = $leads[$result_count][0], list_id = $leads[$result_count][3], filter_date = '$now', new_status = '$up_status', old_status= '$leads[$result_count][2]', phone_number = '$leads[$result_count][1]', dnccom_data = '$line';"; + if ($DB) { print "|$stmtA|\n"; } + $dbhA->do($stmtA) or die "executing: $stmtA ", $dbhA->errstr; + + + } + else + { + # something went very wrong with the code. This should not happen + print "leads phone_number doesnt match DNC.com. Exiting.\n"; + exit(); + } + + $result_count++; + } + + } + else + { + # Error code, type of error, error message + $error = "An error happened: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf; + $scrub_attempts--; + if ($DB) { print("$error\n"); } + + # log the error to the vicidial_admin_log + foreach $list_id (split /,/ ,$CLIlists) + { + $now = get_mysql_date_string(time()); + $stmtA = "INSERT INTO vicidial_admin_log SET event_date = '$now', user = 'VDAD', ip_address = '1.1.1.1', event_section = 'LISTS', event_type = 'OTHER', record_id = '$list_id', event_sql='', event_code='DNC.com SCRUB ERROR', event_notes='DNC.com scrub of lists $CLIlists had an error: \'$error\' after processing $scrub_count leads.';"; + if ($DB) { print "|$stmtA|\n"; } + $dbhA->do($stmtA) or die "executing: $stmtA ", $dbhA->errstr; + } + + + } + } + + if ( $scrub_attempts == 0 ) + { + # log the error to the vicidial_admin_log + foreach $list_id (split /,/ ,$CLIlists) + { + $now = get_mysql_date_string(time()); + $stmtA = "INSERT INTO vicidial_admin_log SET event_date = '$now', user = 'VDAD', ip_address = '1.1.1.1', event_section = 'LISTS', event_type = 'OTHER', record_id = '$list_id', event_sql='', event_code='DNC.com SCRUB FAILED', event_notes='DNC.com scrub of lists $CLIlists failed after processing $scrub_count leads due to connection errors.';"; + if ($DB) { print "|$stmtA|\n"; } + $dbhA->do($stmtA) or die "executing: $stmtA ", $dbhA->errstr; + } + } + + } + + $result_str = "|X$x_count|C$c_count|O$o_count|E$e_count|R$r_count|W$w_count|G$g_count|H$h_count|L$l_count|F$f_count|V$v_count|I$i_count|M$m_count|B$b_count|P$p_count|D$d_count|S$s_count|T$t_count|Y$y_count|"; + if ($DB) { print "$result_str\n"; } + + # log the error to the vicidial_admin_log + foreach $list_id (split /,/ ,$CLIlists) + { + $now = get_mysql_date_string(time()); + $stmtA = "INSERT INTO vicidial_admin_log SET event_date = '$now', user = 'VDAD', ip_address = '1.1.1.1', event_section = 'LISTS', event_type = 'OTHER', record_id = '$list_id', event_sql='', event_code='DNC.com SCRUB FINISHED', event_notes='DNC.com scrub of lists $CLIlists finished after processing $scrub_count leads with the following results:\n$result_str';"; + if ($DB) { print "|$stmtA|\n"; } + $dbhA->do($stmtA) or die "executing: $stmtA ", $dbhA->errstr; + } + + } + else + { + print "DNC.com support not setup properly. Exiting."; + exit(); + } + } +else + { + print "DNC.com support not setup properly. You must have a Settings Container called 'DNCDOTCOM' set up on your Vicidial System. Exiting."; + exit(); + } + + +sub get_container_settings +{ + my %settings_hash; + + # the container entry from the DB + my $container_entry = $_[0]; + + # loop through the container + foreach $line (split /\n/ ,$container_entry) { + + $line =~ s/[#;].*$//gi; # remove comment + $line =~ s/^\s+//gi; # remove leading whitespace + $line =~ s/\s+$//gi; # remove trailing whitespace + + if ( $line ne "" ) + { + my @setting_parts = split( /=>/ , $line ); + $setting_parts[0] =~ s/^\s+//gi; + $setting_parts[0] =~ s/\s+$//gi; + $setting_parts[1] =~ s/^\s+//gi; + $setting_parts[1] =~ s/\s+$//gi; + $settings_hash{"$setting_parts[0]"} = $setting_parts[1] ; + } + + } + + if ($DB) + { + foreach (sort keys %settings_hash) { + print "$_ : $settings_hash{$_}\n"; + } + } + + return %settings_hash; +} + +sub get_mysql_date_string +{ + my $time = $_[0]; + + ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time); + $year = ($year + 1900); + $mon++; + if ($mon < 10) {$mon = "0$mon";} + if ($mday < 10) {$mday = "0$mday";} + if ($hour < 10) {$hour = "0$hour";} + if ($min < 10) {$min = "0$min";} + if ($sec < 10) {$sec = "0$sec";} + + $mysql_date = "$year-$mon-$mday $hour:$min:$sec"; + + return $mysql_date; +} diff --git a/docs/DNC-dot-COM_integration.txt b/docs/DNC-dot-COM_integration.txt new file mode 100644 index 00000000..a2919bff --- /dev/null +++ b/docs/DNC-dot-COM_integration.txt @@ -0,0 +1,185 @@ +DNC.COM INTEGRATION Started: 2015-12-02 Updated: 2015-12-03 + +NOTE: for DNC.COM integration of batch cellphone filtering, see this document: + 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 direct with DNC.COM + +The script that allows for this must be run from the Linux command-line(CLI): + AST_DNCcom_filter.pl + + +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. + + +Below is an example Settings Container for DNC.COM: + +############################################################################### + +# DNC_DOT_COM_URL is the URL to connect to DNC.com. You will probably +# never have to change this unless DNC.com completely redoes their API +DNC_DOT_COM_URL => http://www.dncscrub.com/app/main/rpc/scrub + +# LOGIN_ID is your DNC.com API ID +LOGIN_ID => 1234567890QWERTYUIOP1234567890QWERTYUIOP + +# PROJ_ID denotes the project whose settings you wish to use for +# scrubbing; if both projId and campaignId are omitted we use +# the Master Project +PROJ_ID => + +# CAMPAIGN_ID denotes the campaignId you wish to scrub-in – if you +# specify this you may omit projId; if omitted we assume Default +# Campaign of projId, or if both are omitted, the Default Campaign of +# your Master Project +CAMPAIGN_ID => + +# VERSION a value of 2 or higher will enable the new Version 2.0 +# features; a value of 3 or higher will enable the new Version 3.0 +# features which introduce a new result code of Y for VoIP. VoIP +# numbers, if VoIP scrubbing is enabled, prior to Version 3 will be +# returned as W +VERSION => 3 + +# VICI_STATUS_SKIP are the statuses within lists you do not want +# scrubbed. Multiple statuses should be separated by a hyphen '-' +VICI_STATUS_SKIP => SALE-DNC + +# STATUS_X is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of X. X is and +# Industry eXemption applied to an otherwise Do Not Call number – +# number can be called +STATUS_X => XDNCCM + +# STATUS_C is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of C. C means it is a +# Clean number and can be called +STATUS_C => CDNCCM + +# STATUS_O is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of O. O means ebr +# Override was applied to an otherwise Do Not Call number (including +# an explicit EBR overriding a number in Project DNC) – number can +# be called +STATUS_O => ODNCCM + +# STATUS_E is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of E. E means Ebr – +# currently valid, not on a Do Not Call list – number can be called +STATUS_E => EDNCCM + +# STATUS_R is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of R. R means expiRed +# ebr - number used to be a valid EBR, not on a Do Not Call list – +# number can be called (this ResultCode will be available in the near +# future) +STATUS_R => RDNCCM + +# STATUS_W is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of W. W means US +# Wireless number – number is not in any DNC database (or it is but +# has been overridden by an industry exemption) but it cannot be called +# from a predictive dialer. (Note: in version 1, WY, NJ, TX, LA and AZ +# wireless numbers are always reported as D as long as you choose to +# scrub against Wireless as these states don’t allow any wireless +# telemarketing calls regardless of Aggressive vs. Conservative +# settings in Scrub Options.) +STATUS_W => WDNCCM + +# STATUS_G is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of G. G means Valid +# EBR and US Wireless Number or VoIP Number, not on any DNC database +# (version 2+) – still cannot be called from a predictive dialer as +# EBRs do not constitute an exemption to those rules. +STATUS_G => GDNCCM + +# STATUS_H is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of H. H means US +# Wireless Number or VoIP Number that is also a Valid EBR overriding +# an otherwise DNC number (version 2+) – still cannot be called from +# a predictive dialer as EBRs do not constitute an exemption to those +# rules. +STATUS_H => HDNCCM + +# STATUS_L is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of L. L means +# Wireless number in a US state that does not allow telemarketing +# to wireless numbers even if manually dialed (see W for more details) +# not on any DNC list not an EBR. (version 2+) +STATUS_L => LDNCCM + +# STATUS_F is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of F. F means valid +# EBR and Wireless number in a US state that does not allow +# telemarketing to wireless numbers even if manually dialed (see W for +# more details) not on any DNC list. (version 2+) +STATUS_F => FDNCCM + +# STATUS_V is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of V. V mean Valid +# EBR overriding otherwise DNC number that is also a Wireless number +# in a US state that does not allow telemarketing to wireless numbers +# even if manually dialed (These states are WY, NJ, TX, LA, and AZ.) +# (version 2+) +STATUS_V => VDNCCM + +# STATUS_I is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of I. I means Invalid +# area code not active or reserved/special use phone number pattern +# (i.e. 555-5555)) +STATUS_I => IDNCCM + +# STATUS_M is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of M. M means +# Malformed (number is not 10 digits, etc.) – this actually never +# shows up in scrub results from the DNC Compliance Network +# Enterprise Edition – instead an error response will be returned +STATUS_M => MDNCCM + +# STATUS_B is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of B. B means +# Blocked (number is in an area code not covered by the National +# Subscription on this project or is in a configured no-call area code +# or no exemption was available in a pre-recorded call campaign) +STATUS_B => BDNCCM + +# STATUS_P is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of P. P means +# Project DNC or DNF database match (No further checks are performed. +# The choice to scrub against DNC vs. DNF (Do Not Fax) needs to be +# made previously at the Campaign level.) +STATUS_P => PDNCCM + +# STATUS_D is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of D. D means Do not +# call database match; Reason field provides additional details. +STATUS_D => DDNCCM + +# STATUS_S is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of S. S is a +# diSconnected – number matched a disconnected numbers database +# (DNC.com future service) +STATUS_S => SDNCCM + +# STATUS_T is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of T. T is a Tier C +# phone company (i.e. call may be more expensive) (future service) +STATUS_T => TDNCCM + +# STATUS_Y is what the status field in the vicidial_list will be +# updated to when DNC.com returns a Result Code of Y. Y is a VoIP +# number not in any DNC databases (or it has been overridden by an +# industry exemption). Note: This result code will only be returned if +# version=3 and the project has VoIP scrubbing enabled. If VoIP +# scrubbing is enabled and the version is less than 3, the phone number +# will be returned a W. +STATUS_Y => YDNCCM + +# ADD_INFO_TO_COMMENTS - Whether to overwrite the vicidial_list +# comments field with the additional information provided by DNC.com +# such as DateField, Reason, RegionAbbrev, etc. For more information +# about what what these fields mean refer to your DNC.com +# documentation. The additional fields will be comma separated. +# Values are YES or NO. +ADD_INFO_TO_COMMENTS => NO diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index 4c16685d..7c741be8 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -3381,6 +3381,20 @@ stats_html MEDIUMTEXT, UNIQUE KEY vicidial_html_cache_stats_key (stats_type,stats_id) ) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_unicode_ci; +CREATE TABLE vicidial_dnccom_filter_log ( +filter_log_id INT(9) UNSIGNED NOT NULL AUTO_INCREMENT, +lead_id INT(9) UNSIGNED NOT NULL, +list_id BIGINT(14) UNSIGNED DEFAULT NULL, +filter_date DATETIME DEFAULT NULL, +new_status VARCHAR(6) COLLATE utf8_unicode_ci DEFAULT NULL, +old_status VARCHAR(6) COLLATE utf8_unicode_ci DEFAULT NULL, +phone_number VARCHAR(18) COLLATE utf8_unicode_ci DEFAULT NULL, +dnccom_data VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL, +PRIMARY KEY (filter_log_id), +KEY lead_id (lead_id), +KEY filter_date (filter_date) +) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_unicode_ci; + ALTER TABLE vicidial_email_list MODIFY message text character set utf8; @@ -3630,4 +3644,4 @@ UPDATE vicidial_configuration set value='1766' where name='qc_database_version'; UPDATE system_settings set vdc_agent_api_active='1'; -UPDATE system_settings SET db_schema_version='1437',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1438',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/extras/upgrade_2.12.sql b/extras/upgrade_2.12.sql index 83f9888e..69978def 100644 --- a/extras/upgrade_2.12.sql +++ b/extras/upgrade_2.12.sql @@ -379,3 +379,19 @@ UPDATE system_settings SET db_schema_version='1436',db_schema_update_date=NOW() ALTER TABLE system_settings ADD oldest_logs_date DATETIME; UPDATE system_settings SET db_schema_version='1437',db_schema_update_date=NOW() where db_schema_version < 1437; + +CREATE TABLE vicidial_dnccom_filter_log ( +filter_log_id INT(9) UNSIGNED NOT NULL AUTO_INCREMENT, +lead_id INT(9) UNSIGNED NOT NULL, +list_id BIGINT(14) UNSIGNED DEFAULT NULL, +filter_date DATETIME DEFAULT NULL, +new_status VARCHAR(6) COLLATE utf8_unicode_ci DEFAULT NULL, +old_status VARCHAR(6) COLLATE utf8_unicode_ci DEFAULT NULL, +phone_number VARCHAR(18) COLLATE utf8_unicode_ci DEFAULT NULL, +dnccom_data VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL, +PRIMARY KEY (filter_log_id), +KEY lead_id (lead_id), +KEY filter_date (filter_date) +) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_unicode_ci; + +UPDATE system_settings SET db_schema_version='1438',db_schema_update_date=NOW() where db_schema_version < 1438;