Remove fax_retry.lua supporting FAX Queue only

This commit is contained in:
markjcrane 2023-05-17 12:37:31 -06:00
parent 7d18e3eedc
commit 6cbf572512
6 changed files with 701 additions and 1620 deletions

View File

@ -729,76 +729,48 @@ else {
$dial_string .= "fax_retry_sleep=180" . ","; $dial_string .= "fax_retry_sleep=180" . ",";
//$dial_string .= "fax_verbose=true" . ","; //$dial_string .= "fax_verbose=true" . ",";
$dial_string .= "fax_use_ecm=off" . ","; $dial_string .= "fax_use_ecm=off" . ",";
if ($_SESSION['fax_queue']['enabled']['boolean']) { $dial_string .= "api_hangup_hook='lua app/fax/resources/scripts/hangup_tx.lua'";
$dial_string .= "api_hangup_hook='lua app/fax/resources/scripts/hangup_tx.lua'";
}
else {
$dial_string .= "api_hangup_hook='lua fax_retry.lua'";
}
$dial_string = "{" . $dial_string . "}" . $fax_uri." &txfax('".$fax_file."')"; $dial_string = "{" . $dial_string . "}" . $fax_uri." &txfax('".$fax_file."')";
//add fax to the fax queue or send it directly //build an array to add the fax to the queue
if ($_SESSION['fax_queue']['enabled']['boolean']) { $array['fax_queue'][0]['fax_queue_uuid'] = $fax_queue_uuid;
//build an array to add the fax to the queue $array['fax_queue'][0]['domain_uuid'] = $_SESSION['domain_uuid'];
$array['fax_queue'][0]['fax_queue_uuid'] = $fax_queue_uuid; $array['fax_queue'][0]['fax_uuid'] = $fax_uuid;
$array['fax_queue'][0]['domain_uuid'] = $_SESSION['domain_uuid']; $array['fax_queue'][0]['fax_date'] = 'now()';
$array['fax_queue'][0]['fax_uuid'] = $fax_uuid; $array['fax_queue'][0]['hostname'] = gethostname();
$array['fax_queue'][0]['fax_date'] = 'now()'; $array['fax_queue'][0]['fax_caller_id_name'] = $fax_caller_id_name;
$array['fax_queue'][0]['hostname'] = gethostname(); $array['fax_queue'][0]['fax_caller_id_number'] = $fax_caller_id_number;
$array['fax_queue'][0]['fax_caller_id_name'] = $fax_caller_id_name; $array['fax_queue'][0]['fax_number'] = $fax_number;
$array['fax_queue'][0]['fax_caller_id_number'] = $fax_caller_id_number; $array['fax_queue'][0]['fax_prefix'] = $fax_prefix;
$array['fax_queue'][0]['fax_number'] = $fax_number; $array['fax_queue'][0]['fax_email_address'] = $mail_to_address;
$array['fax_queue'][0]['fax_prefix'] = $fax_prefix; $array['fax_queue'][0]['fax_file'] = $fax_file;
$array['fax_queue'][0]['fax_email_address'] = $mail_to_address; $array['fax_queue'][0]['fax_status'] = 'waiting';
$array['fax_queue'][0]['fax_file'] = $fax_file; //$array['fax_queue'][0]['fax_retry_date'] = $fax_retry_date;
$array['fax_queue'][0]['fax_status'] = 'waiting'; $array['fax_queue'][0]['fax_retry_count'] = 0;
//$array['fax_queue'][0]['fax_retry_date'] = $fax_retry_date; $array['fax_queue'][0]['fax_accountcode'] = $fax_accountcode;
$array['fax_queue'][0]['fax_retry_count'] = 0; $array['fax_queue'][0]['fax_command'] = 'originate '.$dial_string;
$array['fax_queue'][0]['fax_accountcode'] = $fax_accountcode;
$array['fax_queue'][0]['fax_command'] = 'originate '.$dial_string;
//add temporary permisison //add temporary permisison
$p = new permissions; $p = new permissions;
$p->add('fax_queue_add', 'temp'); $p->add('fax_queue_add', 'temp');
//save the data //save the data
$database = new database; $database = new database;
$database->app_name = 'fax queue'; $database->app_name = 'fax queue';
$database->app_uuid = '3656287f-4b22-4cf1-91f6-00386bf488f4'; $database->app_uuid = '3656287f-4b22-4cf1-91f6-00386bf488f4';
$database->save($array); $database->save($array);
//remove temporary permisison //remove temporary permisison
$p->delete('fax_queue_add', 'temp'); $p->delete('fax_queue_add', 'temp');
//add message to show in the browser //add message to show in the browser
message::add($text['confirm-queued']); message::add($text['confirm-queued']);
}
else {
//send the fax directly
$fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']);
if ($fp) {
$cmd = "api originate " . $dial_string;
$response = event_socket_request($fp, $cmd);
$response = str_replace("\n", "", $response);
$uuid = str_replace("+OK ", "", $response);
}
fclose($fp);
//add message to show in the browser
message::add($text['confirm-sent']." ".$response);
}
} }
//redirect the browser //redirect the browser
if (!$included && is_uuid($fax_uuid)) { if (!$included && is_uuid($fax_uuid)) {
if ($_SESSION['fax_queue']['enabled']['boolean']) { header("Location: fax_files.php?id=".$fax_uuid."&box=sent");
//header("Location: ".PROJECT_PATH."/app/fax_queue/fax_queue.php?id=".$fax_uuid); //header("Location: fax_outbox.php?id=".$fax_uuid);
header("Location: ".PROJECT_PATH."fax.php");
}
else {
header("Location: fax_files.php?id=".$fax_uuid."&box=sent");
//header("Location: fax_outbox.php?id=".$fax_uuid);
}
exit; exit;
} }

View File

@ -36,14 +36,6 @@
//default settings //default settings
$y=0; $y=0;
$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "e63df592-9928-4cd3-85bc-afdec2f4cd1c";
$apps[$x]['default_settings'][$y]['default_setting_category'] = "fax_queue";
$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "enabled";
$apps[$x]['default_settings'][$y]['default_setting_name'] = "boolean";
$apps[$x]['default_settings'][$y]['default_setting_value'] = "true";
$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
$apps[$x]['default_settings'][$y]['default_setting_description'] = "Enable or disable the fax queue.";
$y++;
$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "84a6f2a8-4633-49d9-ad28-c9f96d630050"; $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "84a6f2a8-4633-49d9-ad28-c9f96d630050";
$apps[$x]['default_settings'][$y]['default_setting_category'] = "fax_queue"; $apps[$x]['default_settings'][$y]['default_setting_category'] = "fax_queue";
$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "limit"; $apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "limit";

View File

@ -1,448 +1,446 @@
-- --
-- FusionPBX -- FusionPBX
-- Version: MPL 1.1 -- Version: MPL 1.1
-- --
-- The contents of this file are subject to the Mozilla Public License Version -- The contents of this file are subject to the Mozilla Public License Version
-- 1.1 (the "License"); you may not use this file except in compliance with -- 1.1 (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at -- the License. You may obtain a copy of the License at
-- http://www.mozilla.org/MPL/ -- http://www.mozilla.org/MPL/
-- --
-- Software distributed under the License is distributed on an "AS IS" basis, -- Software distributed under the License is distributed on an "AS IS" basis,
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-- for the specific language governing rights and limitations under the -- for the specific language governing rights and limitations under the
-- License. -- License.
-- --
-- The Original Code is FusionPBX -- The Original Code is FusionPBX
-- --
-- The Initial Developer of the Original Code is -- The Initial Developer of the Original Code is
-- Mark J Crane <markjcrane@fusionpbx.com> -- Mark J Crane <markjcrane@fusionpbx.com>
-- Copyright (C) 2015-2022 -- Copyright (C) 2015-2023
-- the Initial Developer. All Rights Reserved. -- the Initial Developer. All Rights Reserved.
-- --
-- Contributor(s): -- Contributor(s):
-- Mark J. Crane -- Mark J. Crane
--set the debug options --set the debug options
debug["sql"] = true; debug["sql"] = true;
--create the api object --create the api object
api = freeswitch.API(); api = freeswitch.API();
--include config.lua --include config.lua
require "resources.functions.config"; require "resources.functions.config";
--connect to the database --connect to the database
local Database = require "resources.functions.database"; local Database = require "resources.functions.database";
dbh = Database.new('system'); dbh = Database.new('system');
--include json library --include json library
local json local json
if (debug["sql"]) then if (debug["sql"]) then
json = require "resources.functions.lunajson" json = require "resources.functions.lunajson"
end end
--additional includes --additional includes
require "resources.functions.explode"; require "resources.functions.explode";
require "resources.functions.count"; require "resources.functions.count";
require "resources.functions.send_mail"; require "resources.functions.send_mail";
--check if windows --check if windows
local IS_WINDOWS = (package.config:sub(1,1) == '\\') local IS_WINDOWS = (package.config:sub(1,1) == '\\')
--define function quote --define function quote
local function quote(s) local function quote(s)
local q = IS_WINDOWS and '"' or "'" local q = IS_WINDOWS and '"' or "'"
if s:find('%s') or s:find(q, nil, true) then if s:find('%s') or s:find(q, nil, true) then
s = q .. s:gsub(q, q..q) .. q s = q .. s:gsub(q, q..q) .. q
end end
return s return s
end end
--escape shell arguments to prevent command injection --escape shell arguments to prevent command injection
local function shell_esc(x) local function shell_esc(x)
return (x:gsub('\\', '\\\\') return (x:gsub('\\', '\\\\')
:gsub('\'', '\\\'')) :gsub('\'', '\\\''))
end end
--create the api object --create the api object
api = freeswitch.API(); api = freeswitch.API();
--set channel variables to lua variables --set channel variables to lua variables
domain_uuid = env:getHeader("domain_uuid"); domain_uuid = env:getHeader("domain_uuid");
domain_name = env:getHeader("domain_name"); domain_name = env:getHeader("domain_name");
--get the domain_uuid using the domain name required for multi-tenant --get the domain_uuid using the domain name required for multi-tenant
if (domain_name ~= nil) then if (domain_name ~= nil) then
sql = "SELECT domain_uuid FROM v_domains "; sql = "SELECT domain_uuid FROM v_domains ";
sql = sql .. "WHERE domain_name = :domain_name "; sql = sql .. "WHERE domain_name = :domain_name ";
dbh:query(sql, {domain_name = domain_name}, function(rows) dbh:query(sql, {domain_name = domain_name}, function(rows)
domain_uuid = rows["domain_uuid"]; domain_uuid = rows["domain_uuid"];
end); end);
end end
--settings --settings
require "resources.functions.settings"; require "resources.functions.settings";
settings = settings(domain_uuid); settings = settings(domain_uuid);
storage_type = ""; storage_type = "";
storage_path = ""; storage_path = "";
if (settings['fax'] ~= nil) then if (settings['fax'] ~= nil) then
if (settings['fax']['storage_type'] ~= nil) then if (settings['fax']['storage_type'] ~= nil) then
if (settings['fax']['storage_type']['text'] ~= nil) then if (settings['fax']['storage_type']['text'] ~= nil) then
storage_type = settings['fax']['storage_type']['text']; storage_type = settings['fax']['storage_type']['text'];
end end
end end
if (settings['fax']['storage_path'] ~= nil) then if (settings['fax']['storage_path'] ~= nil) then
if (settings['fax']['storage_path']['text'] ~= nil) then if (settings['fax']['storage_path']['text'] ~= nil) then
storage_path = settings['fax']['storage_path']['text']; storage_path = settings['fax']['storage_path']['text'];
storage_path = storage_path:gsub("${domain_name}", domain_name); storage_path = storage_path:gsub("${domain_name}", domain_name);
storage_path = storage_path:gsub("${voicemail_id}", voicemail_id); storage_path = storage_path:gsub("${voicemail_id}", voicemail_id);
storage_path = storage_path:gsub("${voicemail_dir}", voicemail_dir); storage_path = storage_path:gsub("${voicemail_dir}", voicemail_dir);
end end
end end
end end
--show all channel variables --show all channel variables
serialized = env:serialize() serialized = env:serialize()
freeswitch.consoleLog("INFO","[fax]\n" .. serialized .. "\n") freeswitch.consoleLog("INFO","[fax]\n" .. serialized .. "\n")
--example channel variables relating to fax --example channel variables relating to fax
--variable_fax_success: 0 --variable_fax_success: 0
--variable_fax_result_code: 49 --variable_fax_result_code: 49
--variable_fax_result_text: The%20call%20dropped%20prematurely --variable_fax_result_text: The%20call%20dropped%20prematurely
--variable_fax_ecm_used: off --variable_fax_ecm_used: off
--variable_fax_local_station_id: SpanDSP%20Fax%20Ident --variable_fax_local_station_id: SpanDSP%20Fax%20Ident
--variable_fax_document_transferred_pages: 0 --variable_fax_document_transferred_pages: 0
--variable_fax_document_total_pages: 0 --variable_fax_document_total_pages: 0
--variable_fax_image_resolution: 0x0 --variable_fax_image_resolution: 0x0
--variable_fax_image_size: 0 --variable_fax_image_size: 0
--variable_fax_bad_rows: 0 --variable_fax_bad_rows: 0
--variable_fax_transfer_rate: 14400 --variable_fax_transfer_rate: 14400
--set channel variables to lua variables --set channel variables to lua variables
uuid = env:getHeader("uuid"); uuid = env:getHeader("uuid");
fax_uuid = env:getHeader("fax_uuid"); fax_uuid = env:getHeader("fax_uuid");
fax_queue_uuid = env:getHeader("fax_queue_uuid"); fax_queue_uuid = env:getHeader("fax_queue_uuid");
fax_success = env:getHeader("fax_success"); fax_success = env:getHeader("fax_success");
fax_result_text = env:getHeader("fax_result_text"); fax_result_text = env:getHeader("fax_result_text");
fax_local_station_id = env:getHeader("fax_local_station_id"); fax_local_station_id = env:getHeader("fax_local_station_id");
fax_ecm_used = env:getHeader("fax_ecm_used"); fax_ecm_used = env:getHeader("fax_ecm_used");
fax_uri = env:getHeader("fax_uri"); fax_uri = env:getHeader("fax_uri");
fax_extension_number = env:getHeader("fax_extension_number"); fax_extension_number = env:getHeader("fax_extension_number");
caller_id_name = env:getHeader("caller_id_name"); caller_id_name = env:getHeader("caller_id_name");
caller_id_number = env:getHeader("caller_id_number"); caller_id_number = env:getHeader("caller_id_number");
fax_bad_rows = env:getHeader("fax_bad_rows"); fax_bad_rows = env:getHeader("fax_bad_rows");
fax_transfer_rate = env:getHeader("fax_transfer_rate"); fax_transfer_rate = env:getHeader("fax_transfer_rate");
sip_to_user = env:getHeader("sip_to_user"); sip_to_user = env:getHeader("sip_to_user");
bridge_hangup_cause = env:getHeader("bridge_hangup_cause"); bridge_hangup_cause = env:getHeader("bridge_hangup_cause");
fax_result_code = env:getHeader("fax_result_code"); fax_result_code = env:getHeader("fax_result_code");
fax_remote_station_id = env:getHeader("fax_remote_station_id"); fax_remote_station_id = env:getHeader("fax_remote_station_id");
fax_document_total_pages = env:getHeader("fax_document_total_pages"); fax_document_total_pages = env:getHeader("fax_document_total_pages");
hangup_cause_q850 = tonumber(env:getHeader("hangup_cause_q850")); hangup_cause_q850 = tonumber(env:getHeader("hangup_cause_q850"));
fax_file = env:getHeader("fax_file"); fax_file = env:getHeader("fax_file");
--prevent nil errors --prevent nil errors
if (fax_file == nil) then if (fax_file == nil) then
fax_file = env:getHeader("fax_filename"); fax_file = env:getHeader("fax_filename");
end end
if (fax_uri == nil) then if (fax_uri == nil) then
fax_uri = ""; fax_uri = "";
end end
if (fax_remote_station_id == nil) then if (fax_remote_station_id == nil) then
fax_remote_station_id = ""; fax_remote_station_id = "";
end end
if (caller_id_name == nil) then if (caller_id_name == nil) then
caller_id_name = env:getHeader("Caller-Caller-ID-Name"); caller_id_name = env:getHeader("Caller-Caller-ID-Name");
end end
if (caller_id_number == nil) then if (caller_id_number == nil) then
caller_id_number = env:getHeader("Caller-Caller-ID-Number"); caller_id_number = env:getHeader("Caller-Caller-ID-Number");
end end
if (document_root == nil) then if (document_root == nil) then
document_root = ''; document_root = '';
end end
--set default values --set default values
if (not fax_success) then if (not fax_success) then
fax_success = "0"; fax_success = "0";
end end
if (hangup_cause_q850 == "17") then if (hangup_cause_q850 == "17") then
fax_success = "0"; fax_success = "0";
fax_result_text = "USER_BUSY"; fax_result_text = "USER_BUSY";
end end
if (not fax_result_text) then if (not fax_result_text) then
fax_result_text = "FS_NOT_SET"; fax_result_text = "FS_NOT_SET";
end end
--get the fax settings from the database --get the fax settings from the database
local sql = [[SELECT * FROM v_fax local sql = [[SELECT * FROM v_fax
WHERE fax_uuid = :fax_uuid WHERE fax_uuid = :fax_uuid
AND domain_uuid = :domain_uuid]]; AND domain_uuid = :domain_uuid]];
local params = {fax_uuid = fax_uuid, domain_uuid = domain_uuid}; local params = {fax_uuid = fax_uuid, domain_uuid = domain_uuid};
if (debug["sql"]) then if (debug["sql"]) then
freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n");
end end
dbh:query(sql, params, function(row) dbh:query(sql, params, function(row)
dialplan_uuid = row["dialplan_uuid"]; dialplan_uuid = row["dialplan_uuid"];
fax_extension = row["fax_extension"]; fax_extension = row["fax_extension"];
fax_accountcode = row["accountcode"]; fax_accountcode = row["accountcode"];
fax_destination_number = row["fax_destination_number"]; fax_destination_number = row["fax_destination_number"];
fax_name = row["fax_name"]; fax_name = row["fax_name"];
fax_prefix = row["fax_prefix"]; fax_prefix = row["fax_prefix"];
fax_email = row["fax_email"]; fax_email = row["fax_email"];
fax_email_connection_type = row["fax_email_connection_type"]; fax_email_connection_type = row["fax_email_connection_type"];
fax_email_connection_host = row["fax_email_connection_host"]; fax_email_connection_host = row["fax_email_connection_host"];
fax_email_connection_port = row["fax_email_connection_port"]; fax_email_connection_port = row["fax_email_connection_port"];
fax_email_connection_security = row["fax_email_connection_security"]; fax_email_connection_security = row["fax_email_connection_security"];
fax_email_connection_validate = row["fax_email_connection_validate"]; fax_email_connection_validate = row["fax_email_connection_validate"];
fax_email_connection_username = row["fax_email_connection_username"]; fax_email_connection_username = row["fax_email_connection_username"];
fax_email_connection_password = row["fax_email_connection_password"]; fax_email_connection_password = row["fax_email_connection_password"];
fax_email_connection_mailbox = row["fax_email_connection_mailbox"]; fax_email_connection_mailbox = row["fax_email_connection_mailbox"];
fax_email_inbound_subject_tag = row["fax_email_inbound_subject_tag"]; fax_email_inbound_subject_tag = row["fax_email_inbound_subject_tag"];
fax_email_outbound_subject_tag = row["fax_email_outbound_subject_tag"]; fax_email_outbound_subject_tag = row["fax_email_outbound_subject_tag"];
fax_email_outbound_authorized_senders = row["fax_email_outbound_authorized_senders"]; fax_email_outbound_authorized_senders = row["fax_email_outbound_authorized_senders"];
fax_caller_id_name = row["fax_caller_id_name"]; fax_caller_id_name = row["fax_caller_id_name"];
fax_caller_id_number = row["fax_caller_id_number"]; fax_caller_id_number = row["fax_caller_id_number"];
fax_forward_number = row["fax_forward_number"]; fax_forward_number = row["fax_forward_number"];
fax_description = row["fax_description"]; fax_description = row["fax_description"];
end); end);
--get the values from the fax file --get the values from the fax file
if (fax_file ~= nil) then if (fax_file ~= nil) then
array = explode("/", fax_file); array = explode("/", fax_file);
fax_file_name = array[count(array)]; fax_file_name = array[count(array)];
end end
--fax to email --fax to email
cmd = "lua" .. " " .. quote(scripts_dir .. "/fax_to_email.lua") .. " "; cmd = quote(shell_esc(php_dir).."/"..shell_esc(php_bin)).." "..quote(shell_esc(document_root).."/secure/fax_to_email.php").." ";
cmd = quote(shell_esc(php_dir).."/"..shell_esc(php_bin)).." "..quote(shell_esc(document_root).."/secure/fax_to_email.php").." "; cmd = cmd .. "email="..quote(shell_esc(fax_email)).." ";
cmd = cmd .. "email="..quote(shell_esc(fax_email)).." "; cmd = cmd .. "extension="..quote(shell_esc(fax_extension)).." ";
cmd = cmd .. "extension="..quote(shell_esc(fax_extension)).." "; cmd = cmd .. "name="..quote(shell_esc(fax_file)).." ";
cmd = cmd .. "name="..quote(shell_esc(fax_file)).." "; cmd = cmd .. "messages=" .. quote("result:"..shell_esc(fax_result_text).." sender:"..shell_esc(fax_remote_station_id).." pages:"..shell_esc(fax_document_total_pages)).." ";
cmd = cmd .. "messages=" .. quote("result:"..shell_esc(fax_result_text).." sender:"..shell_esc(fax_remote_station_id).." pages:"..shell_esc(fax_document_total_pages)).." "; cmd = cmd .. "domain="..quote(shell_esc(domain_name)).." ";
cmd = cmd .. "domain="..quote(shell_esc(domain_name)).." "; cmd = cmd .. "caller_id_name=" .. quote(shell_esc(caller_id_name) or '') .. " ";
cmd = cmd .. "caller_id_name=" .. quote(shell_esc(caller_id_name) or '') .. " "; cmd = cmd .. "caller_id_number=" .. quote(shell_esc(caller_id_number) or '') .. " ";
cmd = cmd .. "caller_id_number=" .. quote(shell_esc(caller_id_number) or '') .. " "; if #fax_forward_number > 0 then
if #fax_forward_number > 0 then cmd = cmd .. "fax_relay=true ";
cmd = cmd .. "fax_relay=true "; else
else cmd = cmd .. "fax_relay=false ";
cmd = cmd .. "fax_relay=false "; end
end if #fax_prefix > 0 then
if #fax_prefix > 0 then cmd = cmd .. "fax_prefix=true ";
cmd = cmd .. "fax_prefix=true "; else
else cmd = cmd .. "fax_prefix=false ";
cmd = cmd .. "fax_prefix=false "; end
end freeswitch.consoleLog("notice", "[fax] command: " .. cmd .. "\n");
freeswitch.consoleLog("notice", "[fax] command: " .. cmd .. "\n"); os.execute(cmd);
os.execute(cmd);
--add to fax logs
sql = "insert into v_fax_logs ";
--add to fax logs sql = sql .. "(";
sql = "insert into v_fax_logs "; sql = sql .. "fax_log_uuid, ";
sql = sql .. "("; sql = sql .. "domain_uuid, ";
sql = sql .. "fax_log_uuid, "; if (fax_uuid ~= nil) then
sql = sql .. "domain_uuid, "; sql = sql .. "fax_uuid, ";
if (fax_uuid ~= nil) then end
sql = sql .. "fax_uuid, "; sql = sql .. "fax_success, ";
end sql = sql .. "fax_result_code, ";
sql = sql .. "fax_success, "; sql = sql .. "fax_result_text, ";
sql = sql .. "fax_result_code, "; sql = sql .. "fax_file, ";
sql = sql .. "fax_result_text, "; if (fax_ecm_used ~= nil) then
sql = sql .. "fax_file, "; sql = sql .. "fax_ecm_used, ";
if (fax_ecm_used ~= nil) then end
sql = sql .. "fax_ecm_used, "; if (fax_local_station_id ~= nil) then
end sql = sql .. "fax_local_station_id, ";
if (fax_local_station_id ~= nil) then end
sql = sql .. "fax_local_station_id, "; sql = sql .. "fax_document_transferred_pages, ";
end sql = sql .. "fax_document_total_pages, ";
sql = sql .. "fax_document_transferred_pages, "; if (fax_image_resolution ~= nil) then
sql = sql .. "fax_document_total_pages, "; sql = sql .. "fax_image_resolution, ";
if (fax_image_resolution ~= nil) then end
sql = sql .. "fax_image_resolution, "; if (fax_image_size ~= nil) then
end sql = sql .. "fax_image_size, ";
if (fax_image_size ~= nil) then end
sql = sql .. "fax_image_size, "; if (fax_bad_rows ~= nil) then
end sql = sql .. "fax_bad_rows, ";
if (fax_bad_rows ~= nil) then end
sql = sql .. "fax_bad_rows, "; if (fax_transfer_rate ~= nil) then
end sql = sql .. "fax_transfer_rate, ";
if (fax_transfer_rate ~= nil) then end
sql = sql .. "fax_transfer_rate, "; if (fax_uri ~= nil) then
end sql = sql .. "fax_uri, ";
if (fax_uri ~= nil) then end
sql = sql .. "fax_uri, "; sql = sql .. "fax_date, ";
end sql = sql .. "fax_epoch ";
sql = sql .. "fax_date, "; sql = sql .. ") ";
sql = sql .. "fax_epoch "; sql = sql .. "values ";
sql = sql .. ") "; sql = sql .. "(";
sql = sql .. "values "; sql = sql .. ":uuid, ";
sql = sql .. "("; sql = sql .. ":domain_uuid, ";
sql = sql .. ":uuid, "; if (fax_uuid ~= nil) then
sql = sql .. ":domain_uuid, "; sql = sql .. ":fax_uuid, ";
if (fax_uuid ~= nil) then end
sql = sql .. ":fax_uuid, "; sql = sql .. ":fax_success, ";
end sql = sql .. ":fax_result_code, ";
sql = sql .. ":fax_success, "; sql = sql .. ":fax_result_text, ";
sql = sql .. ":fax_result_code, "; sql = sql .. ":fax_file, ";
sql = sql .. ":fax_result_text, "; if (fax_ecm_used ~= nil) then
sql = sql .. ":fax_file, "; sql = sql .. ":fax_ecm_used, ";
if (fax_ecm_used ~= nil) then end
sql = sql .. ":fax_ecm_used, "; if (fax_local_station_id ~= nil) then
end sql = sql .. ":fax_local_station_id, ";
if (fax_local_station_id ~= nil) then end
sql = sql .. ":fax_local_station_id, "; sql = sql .. ":fax_document_transferred_pages, ";
end sql = sql .. ":fax_document_total_pages, ";
sql = sql .. ":fax_document_transferred_pages, "; if (fax_image_resolution ~= nil) then
sql = sql .. ":fax_document_total_pages, "; sql = sql .. ":fax_image_resolution, ";
if (fax_image_resolution ~= nil) then end
sql = sql .. ":fax_image_resolution, "; if (fax_image_size ~= nil) then
end sql = sql .. ":fax_image_size, ";
if (fax_image_size ~= nil) then end
sql = sql .. ":fax_image_size, "; if (fax_bad_rows ~= nil) then
end sql = sql .. ":fax_bad_rows, ";
if (fax_bad_rows ~= nil) then end
sql = sql .. ":fax_bad_rows, "; if (fax_transfer_rate ~= nil) then
end sql = sql .. ":fax_transfer_rate, ";
if (fax_transfer_rate ~= nil) then end
sql = sql .. ":fax_transfer_rate, "; if (fax_uri ~= nil) then
end sql = sql .. ":fax_uri, ";
if (fax_uri ~= nil) then end
sql = sql .. ":fax_uri, "; if (database["type"] == "sqlite") then
end sql = sql .. ":fax_date, ";
if (database["type"] == "sqlite") then else
sql = sql .. ":fax_date, "; sql = sql .. "now(), ";
else end
sql = sql .. "now(), "; sql = sql .. ":fax_time ";
end sql = sql .. ")";
sql = sql .. ":fax_time ";
sql = sql .. ")"; local params = {
uuid = uuid;
local params = { domain_uuid = domain_uuid;
uuid = uuid; fax_uuid = fax_uuid;
domain_uuid = domain_uuid; fax_success = fax_success;
fax_uuid = fax_uuid; fax_result_code = fax_result_code;
fax_success = fax_success; fax_result_text = fax_result_text;
fax_result_code = fax_result_code; fax_file = fax_file;
fax_result_text = fax_result_text; fax_ecm_used = fax_ecm_used;
fax_file = fax_file; fax_local_station_id = fax_local_station_id;
fax_ecm_used = fax_ecm_used; fax_document_transferred_pages = fax_document_transferred_pages or '0';
fax_local_station_id = fax_local_station_id; fax_document_total_pages = fax_document_total_pages or '0';
fax_document_transferred_pages = fax_document_transferred_pages or '0'; fax_image_resolution = fax_image_resolution;
fax_document_total_pages = fax_document_total_pages or '0'; fax_image_size = fax_image_size;
fax_image_resolution = fax_image_resolution; fax_bad_rows = fax_bad_rows;
fax_image_size = fax_image_size; fax_transfer_rate = fax_transfer_rate;
fax_bad_rows = fax_bad_rows; fax_uri = fax_uri;
fax_transfer_rate = fax_transfer_rate; fax_date = os.date("%Y-%m-%d %X");
fax_uri = fax_uri; fax_time = os.time();
fax_date = os.date("%Y-%m-%d %X"); };
fax_time = os.time();
}; if (debug["sql"]) then
freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n");
if (debug["sql"]) then end
freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n");
end dbh:query(sql, params);
dbh:query(sql, params); --add the fax files
if (fax_success ~= nil) then
--add the fax files if (fax_success =="1") then
if (fax_success ~= nil) then if (storage_type == "base64") then
if (fax_success =="1") then --include the file io
if (storage_type == "base64") then local file = require "resources.functions.file"
--include the file io
local file = require "resources.functions.file" --read file content as base64 string
fax_base64 = assert(file.read_base64(fax_file));
--read file content as base64 string end
fax_base64 = assert(file.read_base64(fax_file));
end local sql = {}
table.insert(sql, "insert into v_fax_files ");
local sql = {} table.insert(sql, "(");
table.insert(sql, "insert into v_fax_files "); table.insert(sql, "fax_file_uuid, ");
table.insert(sql, "("); table.insert(sql, "fax_uuid, ");
table.insert(sql, "fax_file_uuid, "); table.insert(sql, "fax_mode, ");
table.insert(sql, "fax_uuid, "); table.insert(sql, "fax_file_type, ");
table.insert(sql, "fax_mode, "); table.insert(sql, "fax_file_path, ");
table.insert(sql, "fax_file_type, "); if (caller_id_name ~= nil) then
table.insert(sql, "fax_file_path, "); table.insert(sql, "fax_caller_id_name, ");
if (caller_id_name ~= nil) then end
table.insert(sql, "fax_caller_id_name, "); if (caller_id_number ~= nil) then
end table.insert(sql, "fax_caller_id_number, ");
if (caller_id_number ~= nil) then end
table.insert(sql, "fax_caller_id_number, "); table.insert(sql, "fax_date, ");
end table.insert(sql, "fax_epoch, ");
table.insert(sql, "fax_date, "); if (storage_type == "base64") then
table.insert(sql, "fax_epoch, "); table.insert(sql, "fax_base64, ");
if (storage_type == "base64") then end
table.insert(sql, "fax_base64, "); table.insert(sql, "domain_uuid");
end table.insert(sql, ") ");
table.insert(sql, "domain_uuid"); table.insert(sql, "values ");
table.insert(sql, ") "); table.insert(sql, "(");
table.insert(sql, "values "); table.insert(sql, ":uuid, ");
table.insert(sql, "("); table.insert(sql, ":fax_uuid, ");
table.insert(sql, ":uuid, "); table.insert(sql, "'rx', ");
table.insert(sql, ":fax_uuid, "); table.insert(sql, "'tif', ");
table.insert(sql, "'rx', "); table.insert(sql, ":fax_file, ");
table.insert(sql, "'tif', "); if (caller_id_name ~= nil) then
table.insert(sql, ":fax_file, "); table.insert(sql, ":caller_id_name, ");
if (caller_id_name ~= nil) then end
table.insert(sql, ":caller_id_name, "); if (caller_id_number ~= nil) then
end table.insert(sql, ":caller_id_number, ");
if (caller_id_number ~= nil) then end
table.insert(sql, ":caller_id_number, "); if (database["type"] == "sqlite") then
end table.insert(sql, ":fax_date, ");
if (database["type"] == "sqlite") then else
table.insert(sql, ":fax_date, "); table.insert(sql, "now(), ");
else end
table.insert(sql, "now(), "); table.insert(sql, ":fax_time, ");
end if (storage_type == "base64") then
table.insert(sql, ":fax_time, "); table.insert(sql, ":fax_base64, ");
if (storage_type == "base64") then end
table.insert(sql, ":fax_base64, "); table.insert(sql, ":domain_uuid");
end table.insert(sql, ")");
table.insert(sql, ":domain_uuid"); sql = table.concat(sql, "\n");
table.insert(sql, ")"); local params = {
sql = table.concat(sql, "\n"); uuid = uuid;
local params = { domain_uuid = domain_uuid;
uuid = uuid; fax_uuid = fax_uuid;
domain_uuid = domain_uuid; fax_file = fax_file;
fax_uuid = fax_uuid; caller_id_name = caller_id_name;
fax_file = fax_file; caller_id_number = caller_id_number;
caller_id_name = caller_id_name; fax_base64 = fax_base64;
caller_id_number = caller_id_number; fax_date = os.date("%Y-%m-%d %X");
fax_base64 = fax_base64; fax_time = os.time();
fax_date = os.date("%Y-%m-%d %X"); };
fax_time = os.time(); if (debug["sql"]) then
}; freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n");
if (debug["sql"]) then end
freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); if (storage_type == "base64") then
end local dbh = Database.new('system', 'base64');
if (storage_type == "base64") then dbh:query(sql, params);
local dbh = Database.new('system', 'base64'); dbh:release();
dbh:query(sql, params); else
dbh:release(); result = dbh:query(sql, params);
else end
result = dbh:query(sql, params); end
end end
end
end --send the selected variables to the console
if (fax_success ~= nil) then
--send the selected variables to the console freeswitch.consoleLog("INFO","fax_success: '" .. fax_success .. "'\n");
if (fax_success ~= nil) then end
freeswitch.consoleLog("INFO","fax_success: '" .. fax_success .. "'\n"); freeswitch.consoleLog("INFO","domain_uuid: '" .. domain_uuid .. "'\n");
end freeswitch.consoleLog("INFO","domain_name: '" .. domain_name .. "'\n");
freeswitch.consoleLog("INFO","domain_uuid: '" .. domain_uuid .. "'\n"); freeswitch.consoleLog("INFO","fax_uuid: '" .. fax_uuid .. "'\n");
freeswitch.consoleLog("INFO","domain_name: '" .. domain_name .. "'\n"); freeswitch.consoleLog("INFO","fax_extension: '" .. fax_extension .. "'\n");
freeswitch.consoleLog("INFO","fax_uuid: '" .. fax_uuid .. "'\n"); freeswitch.consoleLog("INFO","fax_result_text: '" .. fax_result_text .. "'\n");
freeswitch.consoleLog("INFO","fax_extension: '" .. fax_extension .. "'\n"); freeswitch.consoleLog("INFO","fax_file: '" .. fax_file .. "'\n");
freeswitch.consoleLog("INFO","fax_result_text: '" .. fax_result_text .. "'\n"); freeswitch.consoleLog("INFO","uuid: '" .. uuid .. "'\n");
freeswitch.consoleLog("INFO","fax_file: '" .. fax_file .. "'\n"); --freeswitch.consoleLog("INFO","fax_ecm_used: '" .. fax_ecm_used .. "'\n");
freeswitch.consoleLog("INFO","uuid: '" .. uuid .. "'\n"); freeswitch.consoleLog("INFO","fax_uri: '" .. fax_uri.. "'\n");
--freeswitch.consoleLog("INFO","fax_ecm_used: '" .. fax_ecm_used .. "'\n"); if (caller_id_name ~= nil) then
freeswitch.consoleLog("INFO","fax_uri: '" .. fax_uri.. "'\n"); freeswitch.consoleLog("INFO","caller_id_name: " .. caller_id_name .. "\n");
if (caller_id_name ~= nil) then end
freeswitch.consoleLog("INFO","caller_id_name: " .. caller_id_name .. "\n"); if (caller_id_number ~= nil) then
end freeswitch.consoleLog("INFO","caller_id_number: " .. caller_id_number .. "\n");
if (caller_id_number ~= nil) then end
freeswitch.consoleLog("INFO","caller_id_number: " .. caller_id_number .. "\n"); freeswitch.consoleLog("INFO","fax_result_code: ".. fax_result_code .."\n");
end --freeswitch.consoleLog("INFO","mailfrom_address: ".. from_address .."\n");
freeswitch.consoleLog("INFO","fax_result_code: ".. fax_result_code .."\n"); --freeswitch.consoleLog("INFO","mailto_address: ".. email_address .."\n");
--freeswitch.consoleLog("INFO","mailfrom_address: ".. from_address .."\n"); freeswitch.consoleLog("INFO","hangup_cause_q850: '" .. hangup_cause_q850 .. "'\n");
--freeswitch.consoleLog("INFO","mailto_address: ".. email_address .."\n");
freeswitch.consoleLog("INFO","hangup_cause_q850: '" .. hangup_cause_q850 .. "'\n");

View File

@ -1,771 +0,0 @@
--
-- FusionPBX
-- Version: MPL 1.1
--
-- The contents of this file are subject to the Mozilla Public License Version
-- 1.1 (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
-- http://www.mozilla.org/MPL/
--
-- Software distributed under the License is distributed on an "AS IS" basis,
-- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-- for the specific language governing rights and limitations under the
-- License.
--
-- The Original Code is FusionPBX
--
-- The Initial Developer of the Original Code is
-- Mark J Crane <markjcrane@fusionpbx.com>
-- Copyright (C) 2010 - 2022
-- the Initial Developer. All Rights Reserved.
--
-- Contributor(s):
-- Mark J. Crane
-- James O. Rose
-- Luis Daniel Lucio Quiroz
--set default variables
fax_retry_sleep = 30;
fax_retry_limit = 4;
fax_busy_limit = 5;
api = freeswitch.API();
--include config.lua
require "resources.functions.config";
--connect to the database
local Database = require "resources.functions.database";
dbh = Database.new('system');
--include json library
local json
if (debug["sql"]) then
json = require "resources.functions.lunajson"
end
--additional includes
require "resources.functions.explode";
require "resources.functions.count";
require "resources.functions.send_mail";
--show all channel variables
--dat = env:serialize()
--freeswitch.consoleLog("INFO","[FAX] info:\n" .. dat .. "\n")
--example channel variables relating to fax
--variable_fax_success: 0
--variable_fax_result_code: 49
--variable_fax_result_text: The%20call%20dropped%20prematurely
--variable_fax_ecm_used: off
--variable_fax_local_station_id: SpanDSP%20Fax%20Ident
--variable_fax_document_transferred_pages: 0
--variable_fax_document_total_pages: 0
--variable_fax_image_resolution: 0x0
--variable_fax_image_size: 0
--variable_fax_bad_rows: 0
--variable_fax_transfer_rate: 14400
--set channel variables to lua variables
uuid = env:getHeader("uuid");
domain_uuid = env:getHeader("domain_uuid");
domain_name = env:getHeader("domain_name");
fax_success = env:getHeader("fax_success");
fax_result_text = env:getHeader("fax_result_text");
fax_local_station_id = env:getHeader("fax_local_station_id");
fax_ecm_used = env:getHeader("fax_ecm_used");
fax_retry_attempts = tonumber(env:getHeader("fax_retry_attempts"));
fax_retry_limit = tonumber(env:getHeader("fax_retry_limit"));
--fax_retry_sleep = tonumber(env:getHeader("fax_retry_sleep"));
fax_uri = env:getHeader("fax_uri");
fax_file = env:getHeader("fax_file");
fax_extension_number = env:getHeader("fax_extension_number");
origination_caller_id_name = env:getHeader("origination_caller_id_name");
origination_caller_id_number = env:getHeader("origination_caller_id_number");
fax_bad_rows = env:getHeader("fax_bad_rows");
fax_transfer_rate = env:getHeader("fax_transfer_rate");
accountcode = env:getHeader("accountcode");
sip_to_user = env:getHeader("sip_to_user");
bridge_hangup_cause = env:getHeader("bridge_hangup_cause");
fax_result_code = env:getHeader("fax_result_code");
fax_busy_attempts = tonumber(env:getHeader("fax_busy_attempts"));
hangup_cause_q850 = tonumber(env:getHeader("hangup_cause_q850"));
fax_document_transferred_pages = env:getHeader("fax_document_transferred_pages");
fax_document_total_pages = env:getHeader("fax_document_total_pages");
fax_image_resolution = env:getHeader("fax_image_resolution");
fax_duration = env:getHeader("billsec");
--set default values
default_language = 'en';
default_dialect = 'us';
if (not origination_caller_id_name) then
origination_caller_id_name = '000000000000000';
end
if (not origination_caller_id_number) then
origination_caller_id_number = '000000000000000';
end
if (not fax_busy_attempts) then
fax_busy_attempts = 0;
end
--we got a busy signal.... may want to check the sip_term_cause
if (not fax_success) then
fax_success = "0";
end
if (hangup_cause_q850 == "17") then
fax_success = "0";
fax_result_text = "USER_BUSY";
end
if (not fax_result_text) then
fax_result_text = "FS_NOT_SET";
end
--get the values from the fax file
array = explode("/", fax_file);
domain_name = array[count(array)-3];
fax_extension = array[count(array)-2];
file_name = array[count(array)];
--get the domain_uuid using the domain name required for multi-tenant
if (domain_uuid == nil and domain_name ~= nil) then
local sql = "SELECT domain_uuid FROM v_domains ";
sql = sql .. "WHERE domain_name = :domain_name ";
dbh:query(sql, {domain_name = domain_name}, function(rows)
domain_uuid = rows["domain_uuid"];
end);
end
--settings
require "resources.functions.settings";
settings = settings(domain_uuid);
storage_type = "";
storage_path = "";
if (settings['fax'] ~= nil) then
if (settings['fax']['storage_type'] ~= nil) then
if (settings['fax']['storage_type']['text'] ~= nil) then
storage_type = settings['fax']['storage_type']['text'];
end
end
if (settings['fax']['storage_path'] ~= nil) then
if (settings['fax']['storage_path']['text'] ~= nil) then
storage_path = settings['fax']['storage_path']['text'];
storage_path = storage_path:gsub("${domain_name}", domain_name);
storage_path = storage_path:gsub("${voicemail_id}", voicemail_id);
storage_path = storage_path:gsub("${voicemail_dir}", voicemail_dir);
end
end
ignore_early_media = "false";
if (settings['fax']['variable'] ~= nil) then
for i, var in ipairs(settings.fax.variable) do
--freeswitch.consoleLog("notice", "variable #" .. i .. ": " .. var .. "\n");
if (var == "ignore_early_media=true") then
ignore_early_media = "true";
end
end
end
end
--be sure accountcode is not empty
if (accountcode == nil) then
accountcode = domain_name;
end
--get the domain_uuid using the domain name required for multi-tenant
if (domain_uuid ~= nil and fax_extension ~= nil) then
local sql = "SELECT fax_uuid FROM v_fax ";
sql = sql .. "WHERE domain_uuid = :domain_uuid ";
sql = sql .. "AND fax_extension = :fax_extension ";
local params = {domain_uuid = domain_uuid, fax_extension = fax_extension}
dbh:query(sql, params, function(rows)
fax_uuid = rows["fax_uuid"];
end);
end
--add to fax logs
sql = "insert into v_fax_logs ";
sql = sql .. "(";
sql = sql .. "fax_log_uuid, ";
sql = sql .. "domain_uuid, ";
if (fax_uuid ~= nil) then
sql = sql .. "fax_uuid, ";
end
sql = sql .. "fax_success, ";
sql = sql .. "fax_result_code, ";
sql = sql .. "fax_result_text, ";
sql = sql .. "fax_file, ";
if (fax_ecm_used ~= nil) then
sql = sql .. "fax_ecm_used, ";
end
if (fax_local_station_id ~= nil) then
sql = sql .. "fax_local_station_id, ";
end
sql = sql .. "fax_document_transferred_pages, ";
sql = sql .. "fax_document_total_pages, ";
if (fax_image_resolution ~= nil) then
sql = sql .. "fax_image_resolution, ";
end
if (fax_image_size ~= nil) then
sql = sql .. "fax_image_size, ";
end
if (fax_bad_rows ~= nil) then
sql = sql .. "fax_bad_rows, ";
end
if (fax_transfer_rate ~= nil) then
sql = sql .. "fax_transfer_rate, ";
end
if (fax_retry_attempts ~= nil) then
sql = sql .. "fax_retry_attempts, ";
end
if (fax_retry_limit ~= nil) then
sql = sql .. "fax_retry_limit, ";
end
if (fax_retry_sleep ~= nil) then
sql = sql .. "fax_retry_sleep, ";
end
sql = sql .. "fax_uri, ";
sql = sql .. "fax_date, ";
sql = sql .. "fax_epoch ";
sql = sql .. ") ";
sql = sql .. "values ";
sql = sql .. "(";
sql = sql .. ":uuid, ";
sql = sql .. ":domain_uuid, ";
if (fax_uuid ~= nil) then
sql = sql .. ":fax_uuid, ";
end
sql = sql .. ":fax_success, ";
sql = sql .. ":fax_result_code, ";
sql = sql .. ":fax_result_text, ";
sql = sql .. ":fax_file, ";
if (fax_ecm_used ~= nil) then
sql = sql .. ":fax_ecm_used, ";
end
if (fax_local_station_id ~= nil) then
sql = sql .. ":fax_local_station_id, ";
end
sql = sql .. ":fax_document_transferred_pages, ";
sql = sql .. ":fax_document_total_pages, ";
if (fax_image_resolution ~= nil) then
sql = sql .. ":fax_image_resolution, ";
end
if (fax_image_size ~= nil) then
sql = sql .. ":fax_image_size, ";
end
if (fax_bad_rows ~= nil) then
sql = sql .. ":fax_bad_rows, ";
end
if (fax_transfer_rate ~= nil) then
sql = sql .. ":fax_transfer_rate, ";
end
if (fax_retry_attempts ~= nil) then
sql = sql .. ":fax_retry_attempts, ";
end
if (fax_retry_limit ~= nil) then
sql = sql .. ":fax_retry_limit, ";
end
if (fax_retry_sleep ~= nil) then
sql = sql .. ":fax_retry_sleep, ";
end
sql = sql .. ":fax_uri, ";
if (database["type"] == "sqlite") then
sql = sql .. ":fax_date, ";
else
sql = sql .. "now(), ";
end
sql = sql .. ":fax_time ";
sql = sql .. ")";
local params = {
uuid = uuid;
domain_uuid = domain_uuid;
fax_uuid = fax_uuid;
fax_success = fax_success;
fax_result_code = fax_result_code;
fax_result_text = fax_result_text;
fax_file = fax_file;
fax_ecm_used = fax_ecm_used;
fax_local_station_id = fax_local_station_id;
fax_document_transferred_pages = fax_document_transferred_pages or '0';
fax_document_total_pages = fax_document_total_pages or '0';
fax_image_resolution = fax_image_resolution;
fax_image_size = fax_image_size;
fax_bad_rows = fax_bad_rows;
fax_transfer_rate = fax_transfer_rate;
fax_retry_attempts = fax_retry_attempts;
fax_retry_limit = fax_retry_limit;
fax_retry_sleep = fax_retry_sleep;
fax_uri = fax_uri;
fax_date = os.date("%Y-%m-%d %X");
fax_time = os.time();
};
if (debug["sql"]) then
freeswitch.consoleLog("notice", "[FAX] retry: " .. sql .. "; params:" .. json.encode(params) .. "\n");
end
dbh:query(sql, params);
--for email
email_address = env:getHeader("mailto_address");
--email_address = api:execute("system", "/bin/echo -n "..email_address.." | /bin/sed -e s/\,/\\\\,/g");
if (email_address == nil) then
email_address = '';
else
email_address = email_address:gsub(",", "\\,");
end
from_address = env:getHeader("mailfrom_address");
if (from_address == nil) then
from_address = email_address;
end
uri_array = explode("/",fax_uri);
number_dialed = uri_array[4];
if (number_dialed == nil) then
number_dialed = uri_array[3];
if (number_dialed == nil) then
number_dialed = '0';
end
end
--do not use apostrophies in message, they are not escaped and the mail will fail.
--get the from address
if (from_address == nil) then
if (settings['fax'] ~= nil) then
if (settings['fax']['smtp_from'] ~= nil) then
if (settings['fax']['smtp_from']['text'] ~= nil) then
smtp_from = settings['fax']['smtp_from']['text'];
end
end
end
if (from_address == nil) then
if (settings['email'] ~= nil) then
if (settings['email']['smtp_from'] ~= nil) then
if (settings['email']['smtp_from']['text'] ~= nil) then
smtp_from = settings['email']['smtp_from']['text'];
end
end
end
end
end
--get the templates
local sql = "SELECT * FROM v_email_templates ";
sql = sql .. "WHERE (domain_uuid = :domain_uuid or domain_uuid is null) ";
sql = sql .. "AND template_language = :template_language ";
sql = sql .. "AND template_category = 'fax' "
sql = sql .. "AND ( ";
sql = sql .. " template_subcategory = 'success_default' ";
sql = sql .. " OR template_subcategory = 'fail_default' ";
sql = sql .. " OR template_subcategory = 'fail_busy' ";
sql = sql .. " OR template_subcategory = 'fail_invalid' ";
sql = sql .. ") "
sql = sql .. "AND template_enabled = 'true' "
local params = {domain_uuid = domain_uuid, template_language = default_language.."-"..default_dialect};
if (debug["sql"]) then
freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n");
end
--function to format time in templates
function format_time(seconds)
local seconds = tonumber(seconds)
if (seconds <= 0) then
return "00:00:00";
else
hours = string.format("%02.f", math.floor(seconds/3600));
mins = string.format("%02.f", math.floor(seconds/60 - (hours*60)));
secs = string.format("%02.f", math.floor(seconds - hours*3600 - mins *60));
if (hours == '00' and mins == '00') then
time_formatted = secs.."s";
elseif (hours == '00' and mins ~= '00') then
time_formatted = mins.."m "..secs.."s";
else
time_formatted = hours.."h "..mins.."m "..secs.."s";
end
end
return time_formatted;
end
--perform variable replacements in email templates
dbh:query(sql, params, function(row)
if (row["template_subcategory"] == 'success_default') then
email_subject_success_default = row["template_subject"];
email_body_success_default = row["template_body"];
email_subject_success_default = email_subject_success_default:gsub("${number_dialed}", number_dialed);
email_subject_success_default = email_subject_success_default:gsub("${fax_busy_attempts}", fax_busy_attempts);
email_subject_success_default = email_subject_success_default:gsub("${fax_time}", os.date("%Y-%m-%d %X"));
email_subject_success_default = email_subject_success_default:gsub("${fax_document_transferred_pages}", fax_document_transferred_pages);
email_subject_success_default = email_subject_success_default:gsub("${fax_document_total_pages}", fax_document_total_pages);
email_subject_success_default = email_subject_success_default:gsub("${fax_local_caller_id_number}", fax_local_station_id);
email_subject_success_default = email_subject_success_default:gsub("${fax_image_resolution}", fax_image_resolution);
email_subject_success_default = email_subject_success_default:gsub("${fax_duration}", format_time(fax_duration));
email_body_success_default = email_body_success_default:gsub("${number_dialed}", number_dialed);
email_body_success_default = email_body_success_default:gsub("${fax_busy_attempts}", fax_busy_attempts);
email_body_success_default = email_body_success_default:gsub("${fax_time}", os.date("%Y-%m-%d %X"));
email_body_success_default = email_body_success_default:gsub("${fax_document_transferred_pages}", fax_document_transferred_pages);
email_body_success_default = email_body_success_default:gsub("${fax_document_total_pages}", fax_document_total_pages);
email_body_success_default = email_body_success_default:gsub("${fax_local_caller_id_number}", fax_local_station_id);
email_body_success_default = email_body_success_default:gsub("${fax_image_resolution}", fax_image_resolution);
email_body_success_default = email_body_success_default:gsub("${fax_duration}", format_time(fax_duration));
end
if (row["template_subcategory"] == 'fail_default') then
email_subject_fail_default = row["template_subject"];
email_body_fail_default = row["template_body"];
email_subject_fail_default = email_subject_fail_default:gsub("${number_dialed}", number_dialed);
email_subject_fail_default = email_subject_fail_default:gsub("${fax_busy_attempts}", fax_busy_attempts);
email_subject_fail_default = email_subject_fail_default:gsub("${fax_time}", os.date("%Y-%m-%d %X"));
email_subject_fail_default = email_subject_fail_default:gsub("${fax_document_transferred_pages}", fax_document_transferred_pages);
email_subject_fail_default = email_subject_fail_default:gsub("${fax_document_total_pages}", fax_document_total_pages);
email_subject_fail_default = email_subject_fail_default:gsub("${fax_local_caller_id_number}", fax_local_station_id);
email_subject_fail_default = email_subject_fail_default:gsub("${fax_image_resolution}", fax_image_resolution);
email_subject_fail_default = email_subject_fail_default:gsub("${fax_duration}", format_time(fax_duration));
email_body_fail_default = email_body_fail_default:gsub("${number_dialed}", number_dialed);
email_body_fail_default = email_body_fail_default:gsub("${fax_busy_attempts}", fax_busy_attempts);
email_body_fail_default = email_body_fail_default:gsub("${fax_time}", os.date("%Y-%m-%d %X"));
email_body_fail_default = email_body_fail_default:gsub("${fax_document_transferred_pages}", fax_document_transferred_pages);
email_body_fail_default = email_body_fail_default:gsub("${fax_document_total_pages}", fax_document_total_pages);
email_body_fail_default = email_body_fail_default:gsub("${fax_local_caller_id_number}", fax_local_station_id);
email_body_fail_default = email_body_fail_default:gsub("${fax_image_resolution}", fax_image_resolution);
email_body_fail_default = email_body_fail_default:gsub("${fax_duration}", format_time(fax_duration));
end
if (row["template_subcategory"] == 'fail_busy') then
email_subject_fail_busy = row["template_subject"];
email_body_fail_busy = row["template_body"];
email_subject_fail_busy = email_subject_fail_busy:gsub("${number_dialed}", number_dialed);
email_subject_fail_busy = email_subject_fail_busy:gsub("${fax_busy_attempts}", fax_busy_attempts);
email_subject_fail_busy = email_subject_fail_busy:gsub("${fax_time}", os.date("%Y-%m-%d %X"));
email_subject_fail_busy = email_subject_fail_busy:gsub("${fax_document_transferred_pages}", fax_document_transferred_pages);
email_subject_fail_busy = email_subject_fail_busy:gsub("${fax_document_total_pages}", fax_document_total_pages);
email_subject_fail_busy = email_subject_fail_busy:gsub("${fax_local_caller_id_number}", fax_local_station_id);
email_subject_fail_busy = email_subject_fail_busy:gsub("${fax_image_resolution}", fax_image_resolution);
email_subject_fail_busy = email_subject_fail_busy:gsub("${fax_duration}", format_time(fax_duration));
email_body_fail_busy = email_body_fail_busy:gsub("${number_dialed}", number_dialed);
email_body_fail_busy = email_body_fail_busy:gsub("${fax_busy_attempts}", fax_busy_attempts);
email_body_fail_busy = email_body_fail_busy:gsub("${fax_time}", os.date("%Y-%m-%d %X"));
email_body_fail_busy = email_body_fail_busy:gsub("${fax_document_transferred_pages}", fax_document_transferred_pages);
email_body_fail_busy = email_body_fail_busy:gsub("${fax_document_total_pages}", fax_document_total_pages);
email_body_fail_busy = email_body_fail_busy:gsub("${fax_local_caller_id_number}", fax_local_station_id);
email_body_fail_busy = email_body_fail_busy:gsub("${fax_image_resolution}", fax_image_resolution);
email_body_fail_busy = email_body_fail_busy:gsub("${fax_duration}", format_time(fax_duration));
end
if (row["template_subcategory"] == 'fail_invalid') then
email_subject_fail_invalid = row["template_subject"];
email_body_fail_invalid = row["template_body"];
email_subject_fail_invalid = email_subject_fail_invalid:gsub("${number_dialed}", number_dialed);
email_subject_fail_invalid = email_subject_fail_invalid:gsub("${fax_busy_attempts}", fax_busy_attempts);
email_subject_fail_invalid = email_subject_fail_invalid:gsub("${fax_time}", os.date("%Y-%m-%d %X"));
email_subject_fail_invalid = email_subject_fail_invalid:gsub("${fax_document_transferred_pages}", fax_document_transferred_pages);
email_subject_fail_invalid = email_subject_fail_invalid:gsub("${fax_document_total_pages}", fax_document_total_pages);
email_subject_fail_invalid = email_subject_fail_invalid:gsub("${fax_local_caller_id_number}", fax_local_station_id);
email_subject_fail_invalid = email_subject_fail_invalid:gsub("${fax_image_resolution}", fax_image_resolution);
email_subject_fail_invalid = email_subject_fail_invalid:gsub("${fax_duration}", format_time(fax_duration));
email_body_fail_invalid = email_body_fail_invalid:gsub("${number_dialed}", number_dialed);
email_body_fail_invalid = email_body_fail_invalid:gsub("${fax_busy_attempts}", fax_busy_attempts);
email_body_fail_invalid = email_body_fail_invalid:gsub("${fax_time}", os.date("%Y-%m-%d %X"));
email_body_fail_invalid = email_body_fail_invalid:gsub("${fax_document_transferred_pages}", fax_document_transferred_pages);
email_body_fail_invalid = email_body_fail_invalid:gsub("${fax_document_total_pages}", fax_document_total_pages);
email_body_fail_invalid = email_body_fail_invalid:gsub("${fax_local_caller_id_number}", fax_local_station_id);
email_body_fail_invalid = email_body_fail_invalid:gsub("${fax_image_resolution}", fax_image_resolution);
email_body_fail_invalid = email_body_fail_invalid:gsub("${fax_duration}", format_time(fax_duration));
end
end);
--add the fax files
if (fax_success ~= nil) then
if (fax_success =="1") then
if (settings['fax']['keep_local']['boolean'] ~= "nil") then
if (settings['fax']['keep_local']['boolean'] == "false") then
storage_type = "";
end
end
local fax_base64
if (storage_type == "base64") then
--include the file io
local file = require "resources.functions.file"
--read file content as base64 string
fax_base64 = assert(file.read_base64(fax_file));
end
local sql = {}
table.insert(sql, "insert into v_fax_files ");
table.insert(sql, "(");
table.insert(sql, "fax_file_uuid, ");
table.insert(sql, "fax_uuid, ");
table.insert(sql, "fax_mode, ");
if (sip_to_user ~= nil) then
table.insert(sql, "fax_destination, ");
end
table.insert(sql, "fax_file_type, ");
table.insert(sql, "fax_file_path, ");
table.insert(sql, "fax_caller_id_name, ");
table.insert(sql, "fax_caller_id_number, ");
table.insert(sql, "fax_date, ");
table.insert(sql, "fax_epoch, ");
if (storage_type == "base64") then
table.insert(sql, "fax_base64, ");
end
table.insert(sql, "domain_uuid");
table.insert(sql, ") ");
table.insert(sql, "values ");
table.insert(sql, "(");
table.insert(sql, ":uuid, ");
table.insert(sql, ":fax_uuid, ");
table.insert(sql, "'tx', ");
if (sip_to_user ~= nil) then
table.insert(sql, ":sip_to_user, ");
end
table.insert(sql, "'tif', ");
table.insert(sql, ":fax_file, ");
table.insert(sql, ":origination_caller_id_name, ");
table.insert(sql, ":origination_caller_id_number, ");
if (database["type"] == "sqlite") then
table.insert(sql, ":fax_date, ");
else
table.insert(sql, "now(), ");
end
table.insert(sql, ":fax_time, ");
if (storage_type == "base64") then
table.insert(sql, ":fax_base64, ");
end
table.insert(sql, ":domain_uuid ");
table.insert(sql, ")");
sql = table.concat(sql, "\n");
local params = {
uuid = uuid;
fax_uuid = fax_uuid;
sip_to_user = sip_to_user;
fax_file = string.gsub(fax_file, '/temp/', '/sent/');
origination_caller_id_name = origination_caller_id_name;
origination_caller_id_number = origination_caller_id_number;
fax_date = os.date("%Y-%m-%d %X");
fax_time = os.time();
fax_base64 = fax_base64;
domain_uuid = domain_uuid;
}
if (debug["sql"]) then
freeswitch.consoleLog("notice", "[FAX] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n");
end
if (storage_type == "base64") then
local dbh = Database.new('system', 'base64');
dbh:query(sql, params);
dbh:release();
else
dbh:query(sql, params);
end
end
end
--send the selected variables to the console
if (fax_success ~= nil) then
freeswitch.consoleLog("INFO","[FAX] Success: '" .. fax_success .. "'\n");
end
freeswitch.consoleLog("INFO","[FAX] fax_result_text: '" .. fax_result_text .. "'\n");
freeswitch.consoleLog("INFO","[FAX] fax_file: '" .. fax_file .. "'\n");
freeswitch.consoleLog("INFO","[FAX] uuid: '" .. uuid .. "'\n");
--freeswitch.consoleLog("INFO","fax_ecm_used: '" .. fax_ecm_used .. "'\n");
freeswitch.consoleLog("INFO","[FAX] fax_retry_attempts: " .. fax_retry_attempts.. "\n");
freeswitch.consoleLog("INFO","[FAX] fax_retry_limit: " .. fax_retry_limit.. "\n");
freeswitch.consoleLog("INFO","[FAX] fax_retry_sleep: " .. fax_retry_sleep.. "\n");
freeswitch.consoleLog("INFO","[FAX] fax_uri: '" .. fax_uri.. "'\n");
freeswitch.consoleLog("INFO","[FAX] accountcode: '" .. accountcode .. "'\n");
freeswitch.consoleLog("INFO","[FAX] origination_caller_id_name: " .. origination_caller_id_name .. "\n");
freeswitch.consoleLog("INFO","[FAX] origination_caller_id_number: " .. origination_caller_id_number .. "\n");
freeswitch.consoleLog("INFO","[FAX] fax_result_code: ".. fax_result_code .."\n");
freeswitch.consoleLog("INFO","[FAX] mailfrom_address: ".. from_address .."\n");
freeswitch.consoleLog("INFO","[FAX] mailto_address: ".. email_address .."\n");
freeswitch.consoleLog("INFO","[FAX] hangup_cause_q850: '" .. hangup_cause_q850 .. "'\n");
--set the type
email_type = "email2fax";
--prepare the headers
headers = {}
headers["X-FusionPBX-Domain-UUID"] = domain_uuid;
headers["X-FusionPBX-Domain-Name"] = domain_name;
headers["X-FusionPBX-Email-Type"] = email_type;
headers["X-FusionPBX-Email-From"] = from_address;
headers["X-FusionPBX-Call-UUID"] = uuid;
--if the fax failed then try again
if (fax_success == "0") then
--DEBUG
--email_cmd = "/bin/echo '"..email_subject_fail.."' | /usr/bin/mail -s 'Fax to: "..number_dialed.." FAILED' -r "..from_address.." -a '"..fax_file.."' "..email_address;
--to keep the originate command shorter these are things we always send. One place to adjust for all.
--originate_same = "for_fax=1,accountcode='"..accountcode.."',domain_uuid="..domain_uuid..",domain_name="..domain_name..",mailto_address='"..email_address.."',mailfrom_address='"..from_address.."',origination_caller_id_name='"..origination_caller_id_name.. "',origination_caller_id_number="..origination_caller_id_number..",fax_uri="..fax_uri..",fax_retry_limit="..fax_retry_limit..",fax_retry_sleep="..fax_retry_sleep..",fax_verbose=true,fax_file='"..fax_file.."'";
originate_same = "for_fax=1,accountcode='"..accountcode.."',domain_uuid="..domain_uuid..",domain_name="..domain_name..",mailto_address='"..email_address.."',mailfrom_address='"..from_address.."',origination_caller_id_name='"..origination_caller_id_name.. "',origination_caller_id_number="..origination_caller_id_number..",fax_uri="..fax_uri..",fax_retry_limit="..fax_retry_limit..",fax_retry_sleep="..fax_retry_sleep..",fax_verbose=true,fax_file='"..fax_file.."',fax_ident='"..origination_caller_id_number.."',fax_header='"..origination_caller_id_name.."'";
if (fax_retry_attempts < fax_retry_limit) then
--timed out waitng for comm or on first message, or busy code
if (fax_result_code == "2" or fax_result_code == "3" or hangup_cause_q850 == 17) then
--do nothing. don't want to increment
freeswitch.consoleLog("INFO","[FAX] Last Fax was probably Busy, don't increment retry_attempts. \n");
fax_busy_attempts = fax_busy_attempts + 1;
if (fax_busy_attempts > fax_busy_limit) then
fax_retry_attempts = 17;
else
freeswitch.msleep(fax_retry_sleep * 1000);
end
--unallocated number
elseif (hangup_cause_q850 == 1 ) then
fax_retry_attempts = 10;
elseif (fax_retry_attempts < 5 ) then
freeswitch.consoleLog("INFO","[FAX] Last Fax Failed, try a different way. Wait first.\n");
freeswitch.msleep(fax_retry_sleep * 500);
else
freeswitch.consoleLog("INFO","[FAX] All attempts to send fax to "..number_dialed.."FAILED\n");
end
if (fax_retry_attempts == 1) then
--send t38 on ECM on
freeswitch.consoleLog("INFO","[FAX] TRYING ["..fax_retry_attempts.."] of [4] to: "..number_dialed.." with: t38 ON ECM ON, Fast\n");
if (hangup_cause_q850 ~= 17) then
fax_retry_attempts = fax_retry_attempts + 1;
end
if (ignore_early_media == "true") then
cmd = "originate {accountcode='"..accountcode.."',fax_retry_attempts="..fax_retry_attempts..","..originate_same..",fax_use_ecm=true,fax_enable_t38=true,fax_enable_t38_request=true,ignore_early_media=true,fax_disable_v17=false,fax_busy_attempts='"..fax_busy_attempts.."',api_hangup_hook='lua fax_retry.lua'}"..fax_uri.." &txfax('"..fax_file.."')";
else
cmd = "originate {accountcode='"..accountcode.."',fax_retry_attempts="..fax_retry_attempts..","..originate_same..",fax_use_ecm=true,fax_enable_t38=true,fax_enable_t38_request=true,fax_disable_v17=false,fax_busy_attempts='"..fax_busy_attempts.."',api_hangup_hook='lua fax_retry.lua'}"..fax_uri.." &txfax('"..fax_file.."')";
end
elseif (fax_retry_attempts == 2) then
--send t38 off, ECM on
freeswitch.consoleLog("INFO","[FAX] TRYING ["..fax_retry_attempts.."] of [4] to: "..number_dialed.." with: t38 OFF ECM ON, Fast\n");
if (hangup_cause_q850 ~= 17) then
fax_retry_attempts = fax_retry_attempts + 1;
end
cmd = "originate {accountcode='"..accountcode.."',fax_retry_attempts="..fax_retry_attempts..","..originate_same..",fax_use_ecm=true,fax_enable_t38=false,fax_enable_t38_request=false,fax_disable_v17=false,fax_busy_attempts='"..fax_busy_attempts.."',api_hangup_hook='lua fax_retry.lua'}"..fax_uri.." &txfax('"..fax_file.."')";
elseif (fax_retry_attempts == 3) then
--send t38 on v17 [slow] on ECM off
freeswitch.consoleLog("INFO","[FAX] TRYING ["..fax_retry_attempts.."] of [4] to: "..number_dialed.." with: t38 ON ECM OFF, SLOW\n");
if (hangup_cause_q850 ~= 17) then
fax_retry_attempts = fax_retry_attempts + 1;
end
if (ignore_early_media == "true") then
cmd = "originate {accountcode='"..accountcode.."',fax_retry_attempts="..fax_retry_attempts..","..originate_same..",fax_use_ecm=false,fax_enable_t38=true,fax_enable_t38_request=true,ignore_early_media=true,fax_disable_v17=true,fax_busy_attempts='"..fax_busy_attempts.."',api_hangup_hook='lua fax_retry.lua'}"..fax_uri.." &txfax('"..fax_file.."')";
else
cmd = "originate {accountcode='"..accountcode.."',fax_retry_attempts="..fax_retry_attempts..","..originate_same..",fax_use_ecm=false,fax_enable_t38=true,fax_enable_t38_request=true,fax_disable_v17=true,fax_busy_attempts='"..fax_busy_attempts.."',api_hangup_hook='lua fax_retry.lua'}"..fax_uri.." &txfax('"..fax_file.."')";
end
elseif (fax_retry_attempts == 4) then
--send t38 off v17 [slow] on ECM off
freeswitch.consoleLog("INFO","[FAX] TRYING ["..fax_retry_attempts.."] of [4] to: "..number_dialed.." with: t38 OFF ECM OFF, SLOW\n");
if (hangup_cause_q850 ~= 17) then
fax_retry_attempts = fax_retry_attempts + 1;
end
cmd = "originate {accountcode='"..accountcode.."',fax_retry_attempts="..fax_retry_attempts..","..originate_same..",fax_use_ecm=false,fax_enable_t38=false,fax_enable_t38_request=false,fax_disable_v17=true,fax_busy_attempts='"..fax_busy_attempts.."',api_hangup_hook='lua fax_retry.lua'}"..fax_uri.." &txfax('"..fax_file.."')";
--bad number
elseif (fax_retry_attempts == 10) then
freeswitch.consoleLog("INFO","[FAX] RETRY FAILED: BAD NUMBER\n");
freeswitch.consoleLog("INFO", "[FAX] RETRY_STATS FAILURE BAD NUMBER: GATEWAY[".. fax_uri .."]");
email_address = email_address:gsub("\\,", ",");
--send the email
send_mail(headers,
from_address,
email_address,
{email_subject_fail_invalid, email_body_fail_invalid},
fax_file
);
--busy number
elseif (fax_retry_attempts == 17) then
freeswitch.consoleLog("INFO","[FAX] RETRY FAILED: TRIED ["..fax_busy_attempts.."] of [4]: BUSY NUMBER\n");
freeswitch.consoleLog("INFO", "[FAX] RETRY STATS FAILURE BUSY: GATEWAY[".. fax_uri .."], BUSY NUMBER");
email_address = email_address:gsub("\\,", ",");
--send the email
send_mail(headers,
from_address,
email_address,
{email_subject_fail_busy, email_body_fail_busy},
fax_file
);
else
--the fax failed completely. send a message
freeswitch.consoleLog("INFO","[FAX] RETRY FAILED: tried ["..fax_retry_attempts.."] of [4]: GIVING UP\n");
freeswitch.consoleLog("INFO", "[FAX] RETRY STATS FAILURE: GATEWAY[".. fax_uri .."], tried 5 combinations without success");
email_address = email_address:gsub("\\,", ",");
--send the email
send_mail(headers,
from_address,
email_address,
{email_subject_fail_default, email_body_fail_default},
fax_file
);
fax_retry_attempts = fax_retry_attempts + 1;
end
api = freeswitch.API();
if ( not cmd ) then
freeswitch.consoleLog("INFO","[FAX] Last Attempt (5th) of fax_retry.lua: \n");
else
freeswitch.consoleLog("INFO","[FAX] Retry Command: " .. cmd .. "\n");
reply = api:executeString(cmd);
end
end
else
--Success
if (fax_retry_attempts == 0) then
if (ignore_early_media == "true") then
fax_trial = "fax_use_ecm=false,fax_enable_t38=true,fax_enable_t38_request=true,ignore_early_media=true,fax_disable_v17=default";
else
fax_trial = "fax_use_ecm=false,fax_enable_t38=true,fax_enable_t38_request=true,fax_disable_v17=default";
end
elseif (fax_retry_attempts == 1) then
if (ignore_early_media == "true") then
fax_trial = "fax_use_ecm=true,fax_enable_t38=true,fax_enable_t38_request=true,ignore_early_media=true,fax_disable_v17=false";
else
fax_trial = "fax_use_ecm=true,fax_enable_t38=true,fax_enable_t38_request=true,fax_disable_v17=false";
end
elseif (fax_retry_attempts == 2) then
fax_trial = "fax_use_ecm=true,fax_enable_t38=false,fax_enable_t38_request=false,fax_disable_v17=false";
elseif (fax_retry_attempts == 3) then
if (ignore_early_media == "true") then
fax_trial = "fax_use_ecm=true,fax_enable_t38=true,fax_enable_t38_request=true,ignore_early_media=true,fax_disable_v17=true";
else
fax_trial = "fax_use_ecm=true,fax_enable_t38=true,fax_enable_t38_request=true,fax_disable_v17=true";
end
elseif (fax_retry_attempts == 4) then
fax_trial = "fax_use_ecm=false,fax_enable_t38=false,fax_enable_t38_request=false,fax_disable_v17=false";
else
fax_trial = "fax_retry had an issue and tried more than 5 times"
end
freeswitch.consoleLog("INFO", "[FAX] RETRY STATS SUCCESS: GATEWAY[".. fax_uri .."] VARS[" .. fax_trial .. "]");
email_address = email_address:gsub("\\,", ",");
--send the email
send_mail(headers,
from_address,
email_address,
{email_subject_success_default, email_body_success_default},
fax_file:gsub(".tif",".pdf")
);
if (settings['fax']['keep_local']['boolean'] ~= "nil") then
if (settings['fax']['keep_local']['boolean'] == "false") then
os.remove(fax_file);
end
end
end

View File

@ -1,221 +1,221 @@
-- -- Global settings -- -- Global settings
-- local settings = Settings.new('system') -- local settings = Settings.new('system')
-- print(settings:get('switch', 'base', 'dir')) -- print(settings:get('switch', 'base', 'dir'))
-- --
-- Domain settings (to `fax_retry.lua`) -- Domain settings
-- local Settings = require "resources.functions.settings" -- local Settings = require "resources.functions.settings"
-- local settings = Settings.new(dbh, domain_name, domain_uuid) -- local settings = Settings.new(dbh, domain_name, domain_uuid)
-- storage_type = settings:get('fax', 'storage_type', 'text') or '' -- storage_type = settings:get('fax', 'storage_type', 'text') or ''
-- storage_path = settings:get('fax', 'storage_path', 'text') or '' -- storage_path = settings:get('fax', 'storage_path', 'text') or ''
-- storage_path = storage_path -- storage_path = storage_path
-- :gsub("${domain_name}", domain_name) -- :gsub("${domain_name}", domain_name)
-- :gsub("${voicemail_id}", voicemail_id) -- :gsub("${voicemail_id}", voicemail_id)
-- :gsub("${voicemail_dir}", voicemail_dir) -- :gsub("${voicemail_dir}", voicemail_dir)
local Database = require "resources.functions.database" local Database = require "resources.functions.database"
local cache = require "resources.functions.cache" local cache = require "resources.functions.cache"
require "resources.functions.split" require "resources.functions.split"
----------------------------------------------------------- -----------------------------------------------------------
local Settings = {} do local Settings = {} do
Settings.__index = Settings Settings.__index = Settings
local NONE = '15783958-912c-4893-8866-4ccd1ca73c6e' local NONE = '15783958-912c-4893-8866-4ccd1ca73c6e'
local function append(t, v) local function append(t, v)
t[#t+1] = v t[#t+1] = v
return t return t
end end
local function append_setting(array, category, subcategory, name, value) local function append_setting(array, category, subcategory, name, value)
--add the category array --add the category array
if not array[category] then if not array[category] then
array[category] = {} array[category] = {}
end end
--add the subcategory array --add the subcategory array
if not array[category][subcategory] then if not array[category][subcategory] then
array[category][subcategory] = {} array[category][subcategory] = {}
end end
--set the name and value --set the name and value
if (name == "array") then if (name == "array") then
if not array[category][subcategory][name] then if not array[category][subcategory][name] then
array[category][subcategory][name] = {} array[category][subcategory][name] = {}
end end
append(array[category][subcategory][name], value); append(array[category][subcategory][name], value);
elseif value ~= nil then elseif value ~= nil then
array[category][subcategory][name] = value; array[category][subcategory][name] = value;
end end
end end
function Settings.new(db, domain_name, domain_uuid, user_uuid) function Settings.new(db, domain_name, domain_uuid, user_uuid)
local self = setmetatable({}, Settings) local self = setmetatable({}, Settings)
self._array = {} self._array = {}
self._db = db self._db = db
self._domain_name = domain_name self._domain_name = domain_name
self._domain_uuid = domain_uuid self._domain_uuid = domain_uuid
self._user_uuid = user_uuid self._user_uuid = user_uuid
self._use_cache = not cache.settings self._use_cache = not cache.settings
return self return self
end end
function Settings:_cache_key(category, subcategory, name) function Settings:_cache_key(category, subcategory, name)
return 'setting:' .. (self._domain_name or '') .. ':' .. category .. ':' .. subcategory .. ':' .. name return 'setting:' .. (self._domain_name or '') .. ':' .. category .. ':' .. subcategory .. ':' .. name
end end
function Settings:set(category, subcategory, name, value) function Settings:set(category, subcategory, name, value)
append_setting(self._array, category, subcategory, name, value) append_setting(self._array, category, subcategory, name, value)
return self return self
end end
function Settings:get(category, subcategory, name) function Settings:get(category, subcategory, name)
local a = self._array local a = self._array
local v = a[category] and a[category][subcategory] and a[category][subcategory][name] local v = a[category] and a[category][subcategory] and a[category][subcategory][name]
if v == NONE then return nil end if v == NONE then return nil end
if v ~= nil then return v end if v ~= nil then return v end
if self._use_cache then if self._use_cache then
local key = self:_cache_key(category, subcategory, name) local key = self:_cache_key(category, subcategory, name)
v = cache.get(key) v = cache.get(key)
if v then if v then
if v ~= NONE and name == 'array' then if v ~= NONE and name == 'array' then
v = split(v, '/+/', true) v = split(v, '/+/', true)
end end
self:set(category, subcategory, name, v) self:set(category, subcategory, name, v)
if v == NONE then return nil end if v == NONE then return nil end
return v return v
end end
end end
return self:_load(category, subcategory, name) return self:_load(category, subcategory, name)
end end
function Settings:_load(category, subcategory, name) function Settings:_load(category, subcategory, name)
local user_uuid = self._user_uuid local user_uuid = self._user_uuid
local domain_uuid = self._domain_uuid local domain_uuid = self._domain_uuid
local db = self._db local db = self._db
if type(self._db) == 'string' then if type(self._db) == 'string' then
db = Database.new(self._db) db = Database.new(self._db)
end end
local found = false local found = false
--get the user settings --get the user settings
if user_uuid then if user_uuid then
local sql = "SELECT user_setting_uuid,user_setting_category,user_setting_subcategory,user_setting_name,user_setting_value " local sql = "SELECT user_setting_uuid,user_setting_category,user_setting_subcategory,user_setting_name,user_setting_value "
sql = sql .. "FROM v_user_settings "; sql = sql .. "FROM v_user_settings ";
sql = sql .. "WHERE user_uuid = :user_uuid "; sql = sql .. "WHERE user_uuid = :user_uuid ";
sql = sql .. "AND user_setting_enabled = 'true' "; sql = sql .. "AND user_setting_enabled = 'true' ";
sql = sql .. "AND user_setting_category = :category "; sql = sql .. "AND user_setting_category = :category ";
sql = sql .. "AND user_setting_subcategory = :subcategory "; sql = sql .. "AND user_setting_subcategory = :subcategory ";
sql = sql .. "AND user_setting_name = :name "; sql = sql .. "AND user_setting_name = :name ";
sql = sql .. "AND user_setting_value is not null "; sql = sql .. "AND user_setting_value is not null ";
sql = sql .. "ORDER BY user_setting_category, user_setting_subcategory ASC "; sql = sql .. "ORDER BY user_setting_category, user_setting_subcategory ASC ";
local params = { local params = {
user_uuid = user_uuid, user_uuid = user_uuid,
category = category, category = category,
subcategory = subcategory, subcategory = subcategory,
name = name, name = name,
}; };
db:query(sql, params, function(row) db:query(sql, params, function(row)
found = true; found = true;
self:set( self:set(
row.user_setting_category, row.user_setting_category,
row.user_setting_subcategory, row.user_setting_subcategory,
row.user_setting_name, row.user_setting_name,
row.user_setting_value row.user_setting_value
) )
end) end)
end end
--get the domain settings --get the domain settings
if not found and domain_uuid then if not found and domain_uuid then
local sql = "SELECT domain_setting_uuid,domain_setting_category,domain_setting_subcategory,domain_setting_name,domain_setting_value " local sql = "SELECT domain_setting_uuid,domain_setting_category,domain_setting_subcategory,domain_setting_name,domain_setting_value "
sql = sql .. "FROM v_domain_settings "; sql = sql .. "FROM v_domain_settings ";
sql = sql .. "WHERE domain_uuid = :domain_uuid "; sql = sql .. "WHERE domain_uuid = :domain_uuid ";
sql = sql .. "AND domain_setting_enabled = 'true' "; sql = sql .. "AND domain_setting_enabled = 'true' ";
sql = sql .. "AND domain_setting_category = :category "; sql = sql .. "AND domain_setting_category = :category ";
sql = sql .. "AND domain_setting_subcategory = :subcategory "; sql = sql .. "AND domain_setting_subcategory = :subcategory ";
sql = sql .. "AND domain_setting_name = :name "; sql = sql .. "AND domain_setting_name = :name ";
sql = sql .. "AND domain_setting_value is not null "; sql = sql .. "AND domain_setting_value is not null ";
sql = sql .. "ORDER BY domain_setting_category, domain_setting_subcategory ASC "; sql = sql .. "ORDER BY domain_setting_category, domain_setting_subcategory ASC ";
local params = { local params = {
domain_uuid = domain_uuid, domain_uuid = domain_uuid,
category = category, category = category,
subcategory = subcategory, subcategory = subcategory,
name = name, name = name,
}; };
db:query(sql, params, function(row) db:query(sql, params, function(row)
found = true; found = true;
self:set( self:set(
row.domain_setting_category, row.domain_setting_category,
row.domain_setting_subcategory, row.domain_setting_subcategory,
row.domain_setting_name, row.domain_setting_name,
row.domain_setting_value row.domain_setting_value
) )
end) end)
end end
--get default settings --get default settings
if not found then if not found then
local sql = "SELECT default_setting_uuid,default_setting_category,default_setting_subcategory,default_setting_name,default_setting_value " local sql = "SELECT default_setting_uuid,default_setting_category,default_setting_subcategory,default_setting_name,default_setting_value "
sql = sql .. "FROM v_default_settings "; sql = sql .. "FROM v_default_settings ";
sql = sql .. "WHERE default_setting_enabled = 'true' "; sql = sql .. "WHERE default_setting_enabled = 'true' ";
sql = sql .. "AND default_setting_category = :category "; sql = sql .. "AND default_setting_category = :category ";
sql = sql .. "AND default_setting_subcategory = :subcategory "; sql = sql .. "AND default_setting_subcategory = :subcategory ";
sql = sql .. "AND default_setting_name = :name "; sql = sql .. "AND default_setting_name = :name ";
sql = sql .. "AND default_setting_value is not null "; sql = sql .. "AND default_setting_value is not null ";
sql = sql .. "ORDER BY default_setting_category, default_setting_subcategory ASC"; sql = sql .. "ORDER BY default_setting_category, default_setting_subcategory ASC";
local params = { local params = {
category = category, category = category,
subcategory = subcategory, subcategory = subcategory,
name = name, name = name,
}; };
db:query(sql, params, function(row) db:query(sql, params, function(row)
found = true; found = true;
self:set( self:set(
row.default_setting_category, row.default_setting_category,
row.default_setting_subcategory, row.default_setting_subcategory,
row.default_setting_name, row.default_setting_name,
row.default_setting_value row.default_setting_value
) )
end) end)
end end
if type(self._db) == 'string' then if type(self._db) == 'string' then
db:release() db:release()
end end
--set empty value for unknown setting --set empty value for unknown setting
if not found then if not found then
self:set(category, subcategory, name, NONE) self:set(category, subcategory, name, NONE)
end end
local a = self._array local a = self._array
local v = a[category] and a[category][subcategory] and a[category][subcategory][name] local v = a[category] and a[category][subcategory] and a[category][subcategory][name]
--store settings in cache --store settings in cache
if self._use_cache and cache.support() then if self._use_cache and cache.support() then
local key = self:_cache_key(category, subcategory, name) local key = self:_cache_key(category, subcategory, name)
local value = v local value = v
if v ~= NONE and name == 'array' then if v ~= NONE and name == 'array' then
value = table.concat(v, '/+/') value = table.concat(v, '/+/')
end end
local exp = expire and expire["settings"] or 3600 local exp = expire and expire["settings"] or 3600
cache.set(key, value, exp) cache.set(key, value, exp)
end end
if v == NONE then return nil end if v == NONE then return nil end
return v return v
end end
end end
----------------------------------------------------------- -----------------------------------------------------------
return Settings return Settings

View File

@ -17,7 +17,7 @@
The Initial Developer of the Original Code is The Initial Developer of the Original Code is
Mark J Crane <markjcrane@fusionpbx.com> Mark J Crane <markjcrane@fusionpbx.com>
Portions created by the Initial Developer are Copyright (C) 2008-2022 Portions created by the Initial Developer are Copyright (C) 2008-2023
the Initial Developer. All Rights Reserved. the Initial Developer. All Rights Reserved.
Contributor(s): Contributor(s):
@ -386,7 +386,6 @@ if (!function_exists('fax_split_dtmf')) {
echo "fax_forward_number: $fax_forward_number\n"; echo "fax_forward_number: $fax_forward_number\n";
//add fax to the fax queue or send it directly //add fax to the fax queue or send it directly
if ($_SESSION['fax_queue']['enabled']['boolean'] == 'true') {
//build an array to add the fax to the queue //build an array to add the fax to the queue
$array['fax_queue'][0]['fax_queue_uuid'] = uuid(); $array['fax_queue'][0]['fax_queue_uuid'] = uuid();
$array['fax_queue'][0]['domain_uuid'] = $domain_uuid; $array['fax_queue'][0]['domain_uuid'] = $domain_uuid;
@ -418,89 +417,7 @@ if (!function_exists('fax_split_dtmf')) {
//add message to show in the browser //add message to show in the browser
message::add($text['confirm-queued']); message::add($text['confirm-queued']);
}
else {
fax_split_dtmf($fax_forward_number, $fax_dtmf);
$fax_send_mode = $_SESSION['fax']['send_mode']['text'];
if (empty($fax_send_mode)) {
$fax_send_mode = 'direct';
}
$route_array = outbound_route_to_bridge($domain_uuid, $fax_forward_number);
if (count($route_array) == 0) {
//send the internal call to the registered extension
$fax_uri = "user/".escapeshellarg($fax_forward_number)."@".escapeshellarg($domain_name);
$fax_variables = "";
}
else {
//send the external call
$fax_uri = $route_array[0];
$fax_variables = "";
foreach($_SESSION['fax']['variable'] as $variable) {
$fax_variables .= escapeshellarg($variable).",";
}
}
//build the dial string
$dial_string = "absolute_codec_string='PCMU,PCMA',";
$dial_string .= "accountcode='" . escapeshellarg($fax_accountcode) . "',";
$dial_string .= "sip_h_X-accountcode='" . escapeshellarg($fax_accountcode) . "',";
$dial_string .= "domain_uuid=" . escapeshellarg($domain_uuid) . ",";
$dial_string .= "domain_name=" . escapeshellarg($domain_name) . ",";
$dial_string .= "origination_caller_id_name='" . escapeshellarg($fax_caller_id_name) . "',";
$dial_string .= "origination_caller_id_number='" . escapeshellarg($fax_caller_id_number) . "',";
$dial_string .= "fax_ident='" . escapeshellarg($fax_caller_id_number) . "',";
$dial_string .= "fax_header='" . escapeshellarg($fax_caller_id_name) . "',";
$dial_string .= "fax_file='" . escapeshellarg($fax_file) . "',";
if ($fax_send_mode != 'queue') {
//add more ot the dial string
$dial_string .= $fax_variables;
$dial_string .= "mailto_address='" . escapeshellarg($mail_to_address) . "',";
$dial_string .= "mailfrom_address='" . escapeshellarg($mail_from_address) . "',";
$dial_string .= "fax_uri=" . escapeshellarg($fax_uri) . ",";
$dial_string .= "fax_retry_attempts=1" . ",";
$dial_string .= "fax_retry_limit=20" . ",";
$dial_string .= "fax_retry_sleep=180" . ",";
$dial_string .= "fax_verbose=true" . ",";
$dial_string .= "fax_use_ecm=off" . ",";
$dial_string .= "api_hangup_hook='lua fax_retry.lua'";
$dial_string = "{" . $dial_string . "}" . escapeshellarg($fax_uri)." &txfax('".escapeshellarg($fax_file)."')";
//get the event socket information
$sql = "select * from v_settings ";
$database = new database;
$row = $database->select($sql, $parameters, 'row');
if (is_array($row) && @sizeof($row) != 0) {
$event_socket_ip_address = $row["event_socket_ip_address"];
$event_socket_port = $row["event_socket_port"];
$event_socket_password = $row["event_socket_password"];
}
unset($sql);
//create the event socket connection
$fp = event_socket_create($event_socket_ip_address, $event_socket_port, $event_socket_password);
//send the command with event socket
if ($fp) {
//prepare the fax originate command
$cmd = "api originate ".$dial_string;
//send info to the log
echo "fax forward\n";
echo $cmd."\n";
//send the command to event socket
$response = event_socket_request($fp, $cmd);
$response = str_replace("\n", "", $response);
//send info to the log
echo "response: ".$response."\n";
//get the uuid
$uuid = str_replace("+OK ", "", $response);
//close event socket
fclose($fp);
}
}
}
} }
} }
@ -608,33 +525,6 @@ if (!function_exists('fax_split_dtmf')) {
} }
} }
//when sending an email the following files are created:
// /usr/local/freeswitch/storage/fax
// emailed_faxes.log - this is a log of all the faxes we have successfully emailed. (note that we need to work out how to rotate this log)
// failed_fax_emails.log - this is a log of all the faxes we have failed to email. This log is in the form of instructions that we can re-execute in order to retry.
// Whenever this exists there should be an at job present to run it sometime in the next 3 minutes (check with atq). If we succeed in sending the messages
// this file will be removed.
// /tmp
// fax_email_retry.sh - this is the renamed failed_fax_emails.log and is created only at the point in time that we are trying to re-send the emails. Note however
// that this will continue to exist even if we succeed as we do not delete it when finished.
// failed_fax_emails.sh - this is created when we have a email we need to re-send. At the time it is created, an at job is created to execute it in 3 minutes time,
// this allows us to try sending the email again at that time. If the file exists but there is no at job this is because there are no longer any emails queued
// as we have successfully sent them all.
if ($_SESSION['fax_queue']['enabled']['boolean'] != 'true' && !empty($fax_email) && file_exists($fax_file)) {
if (stristr(PHP_OS, 'WIN')) {
//not compatible with windows
}
else {
$fax_to_email_queue_dir = $_SESSION['switch']['storage']['dir']."/fax";
if ($email_status == 'ok') {
//log the success
$fp = fopen($fax_to_email_queue_dir."/emailed_faxes.log", "a");
fwrite($fp, $fax_file_name." received on ".$fax_extension." emailed to ".$fax_email." ".$fax_messages."\n");
fclose($fp);
}
}
}
//open the file for writing //open the file for writing
if ($output_type == "file") { if ($output_type == "file") {
//open the file //open the file