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_verbose=true" . ",";
$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'";
}
else {
$dial_string .= "api_hangup_hook='lua fax_retry.lua'";
}
$dial_string .= "api_hangup_hook='lua app/fax/resources/scripts/hangup_tx.lua'";
$dial_string = "{" . $dial_string . "}" . $fax_uri." &txfax('".$fax_file."')";
//add fax to the fax queue or send it directly
if ($_SESSION['fax_queue']['enabled']['boolean']) {
//build an array to add the fax to the queue
$array['fax_queue'][0]['fax_queue_uuid'] = $fax_queue_uuid;
$array['fax_queue'][0]['domain_uuid'] = $_SESSION['domain_uuid'];
$array['fax_queue'][0]['fax_uuid'] = $fax_uuid;
$array['fax_queue'][0]['fax_date'] = 'now()';
$array['fax_queue'][0]['hostname'] = gethostname();
$array['fax_queue'][0]['fax_caller_id_name'] = $fax_caller_id_name;
$array['fax_queue'][0]['fax_caller_id_number'] = $fax_caller_id_number;
$array['fax_queue'][0]['fax_number'] = $fax_number;
$array['fax_queue'][0]['fax_prefix'] = $fax_prefix;
$array['fax_queue'][0]['fax_email_address'] = $mail_to_address;
$array['fax_queue'][0]['fax_file'] = $fax_file;
$array['fax_queue'][0]['fax_status'] = 'waiting';
//$array['fax_queue'][0]['fax_retry_date'] = $fax_retry_date;
$array['fax_queue'][0]['fax_retry_count'] = 0;
$array['fax_queue'][0]['fax_accountcode'] = $fax_accountcode;
$array['fax_queue'][0]['fax_command'] = 'originate '.$dial_string;
//build an array to add the fax to the queue
$array['fax_queue'][0]['fax_queue_uuid'] = $fax_queue_uuid;
$array['fax_queue'][0]['domain_uuid'] = $_SESSION['domain_uuid'];
$array['fax_queue'][0]['fax_uuid'] = $fax_uuid;
$array['fax_queue'][0]['fax_date'] = 'now()';
$array['fax_queue'][0]['hostname'] = gethostname();
$array['fax_queue'][0]['fax_caller_id_name'] = $fax_caller_id_name;
$array['fax_queue'][0]['fax_caller_id_number'] = $fax_caller_id_number;
$array['fax_queue'][0]['fax_number'] = $fax_number;
$array['fax_queue'][0]['fax_prefix'] = $fax_prefix;
$array['fax_queue'][0]['fax_email_address'] = $mail_to_address;
$array['fax_queue'][0]['fax_file'] = $fax_file;
$array['fax_queue'][0]['fax_status'] = 'waiting';
//$array['fax_queue'][0]['fax_retry_date'] = $fax_retry_date;
$array['fax_queue'][0]['fax_retry_count'] = 0;
$array['fax_queue'][0]['fax_accountcode'] = $fax_accountcode;
$array['fax_queue'][0]['fax_command'] = 'originate '.$dial_string;
//add temporary permisison
$p = new permissions;
$p->add('fax_queue_add', 'temp');
//add temporary permisison
$p = new permissions;
$p->add('fax_queue_add', 'temp');
//save the data
$database = new database;
$database->app_name = 'fax queue';
$database->app_uuid = '3656287f-4b22-4cf1-91f6-00386bf488f4';
$database->save($array);
//save the data
$database = new database;
$database->app_name = 'fax queue';
$database->app_uuid = '3656287f-4b22-4cf1-91f6-00386bf488f4';
$database->save($array);
//remove temporary permisison
$p->delete('fax_queue_add', 'temp');
//add message to show in the browser
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);
}
//remove temporary permisison
$p->delete('fax_queue_add', 'temp');
//add message to show in the browser
message::add($text['confirm-queued']);
}
//redirect the browser
if (!$included && is_uuid($fax_uuid)) {
if ($_SESSION['fax_queue']['enabled']['boolean']) {
//header("Location: ".PROJECT_PATH."/app/fax_queue/fax_queue.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);
}
header("Location: fax_files.php?id=".$fax_uuid."&box=sent");
//header("Location: fax_outbox.php?id=".$fax_uuid);
exit;
}

View File

@ -36,14 +36,6 @@
//default settings
$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_category'] = "fax_queue";
$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "limit";

View File

@ -1,448 +1,446 @@
--
-- 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) 2015-2022
-- the Initial Developer. All Rights Reserved.
--
-- Contributor(s):
-- Mark J. Crane
--set the debug options
debug["sql"] = true;
--create the api object
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";
--check if windows
local IS_WINDOWS = (package.config:sub(1,1) == '\\')
--define function quote
local function quote(s)
local q = IS_WINDOWS and '"' or "'"
if s:find('%s') or s:find(q, nil, true) then
s = q .. s:gsub(q, q..q) .. q
end
return s
end
--escape shell arguments to prevent command injection
local function shell_esc(x)
return (x:gsub('\\', '\\\\')
:gsub('\'', '\\\''))
end
--create the api object
api = freeswitch.API();
--set channel variables to lua variables
domain_uuid = env:getHeader("domain_uuid");
domain_name = env:getHeader("domain_name");
--get the domain_uuid using the domain name required for multi-tenant
if (domain_name ~= nil) then
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
end
--show all channel variables
serialized = env:serialize()
freeswitch.consoleLog("INFO","[fax]\n" .. serialized .. "\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");
fax_uuid = env:getHeader("fax_uuid");
fax_queue_uuid = env:getHeader("fax_queue_uuid");
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_uri = env:getHeader("fax_uri");
fax_extension_number = env:getHeader("fax_extension_number");
caller_id_name = env:getHeader("caller_id_name");
caller_id_number = env:getHeader("caller_id_number");
fax_bad_rows = env:getHeader("fax_bad_rows");
fax_transfer_rate = env:getHeader("fax_transfer_rate");
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_remote_station_id = env:getHeader("fax_remote_station_id");
fax_document_total_pages = env:getHeader("fax_document_total_pages");
hangup_cause_q850 = tonumber(env:getHeader("hangup_cause_q850"));
fax_file = env:getHeader("fax_file");
--prevent nil errors
if (fax_file == nil) then
fax_file = env:getHeader("fax_filename");
end
if (fax_uri == nil) then
fax_uri = "";
end
if (fax_remote_station_id == nil) then
fax_remote_station_id = "";
end
if (caller_id_name == nil) then
caller_id_name = env:getHeader("Caller-Caller-ID-Name");
end
if (caller_id_number == nil) then
caller_id_number = env:getHeader("Caller-Caller-ID-Number");
end
if (document_root == nil) then
document_root = '';
end
--set default values
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 fax settings from the database
local sql = [[SELECT * FROM v_fax
WHERE fax_uuid = :fax_uuid
AND domain_uuid = :domain_uuid]];
local params = {fax_uuid = fax_uuid, domain_uuid = domain_uuid};
if (debug["sql"]) then
freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n");
end
dbh:query(sql, params, function(row)
dialplan_uuid = row["dialplan_uuid"];
fax_extension = row["fax_extension"];
fax_accountcode = row["accountcode"];
fax_destination_number = row["fax_destination_number"];
fax_name = row["fax_name"];
fax_prefix = row["fax_prefix"];
fax_email = row["fax_email"];
fax_email_connection_type = row["fax_email_connection_type"];
fax_email_connection_host = row["fax_email_connection_host"];
fax_email_connection_port = row["fax_email_connection_port"];
fax_email_connection_security = row["fax_email_connection_security"];
fax_email_connection_validate = row["fax_email_connection_validate"];
fax_email_connection_username = row["fax_email_connection_username"];
fax_email_connection_password = row["fax_email_connection_password"];
fax_email_connection_mailbox = row["fax_email_connection_mailbox"];
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_authorized_senders = row["fax_email_outbound_authorized_senders"];
fax_caller_id_name = row["fax_caller_id_name"];
fax_caller_id_number = row["fax_caller_id_number"];
fax_forward_number = row["fax_forward_number"];
fax_description = row["fax_description"];
end);
--get the values from the fax file
if (fax_file ~= nil) then
array = explode("/", fax_file);
fax_file_name = array[count(array)];
end
--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 = cmd .. "email="..quote(shell_esc(fax_email)).." ";
cmd = cmd .. "extension="..quote(shell_esc(fax_extension)).." ";
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 .. "domain="..quote(shell_esc(domain_name)).." ";
cmd = cmd .. "caller_id_name=" .. quote(shell_esc(caller_id_name) or '') .. " ";
cmd = cmd .. "caller_id_number=" .. quote(shell_esc(caller_id_number) or '') .. " ";
if #fax_forward_number > 0 then
cmd = cmd .. "fax_relay=true ";
else
cmd = cmd .. "fax_relay=false ";
end
if #fax_prefix > 0 then
cmd = cmd .. "fax_prefix=true ";
else
cmd = cmd .. "fax_prefix=false ";
end
freeswitch.consoleLog("notice", "[fax] command: " .. cmd .. "\n");
os.execute(cmd);
--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_uri ~= nil) then
sql = sql .. "fax_uri, ";
end
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_uri ~= nil) then
sql = sql .. ":fax_uri, ";
end
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_uri = fax_uri;
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");
end
dbh:query(sql, params);
--add the fax files
if (fax_success ~= nil) then
if (fax_success =="1") then
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, ");
table.insert(sql, "fax_file_type, ");
table.insert(sql, "fax_file_path, ");
if (caller_id_name ~= nil) then
table.insert(sql, "fax_caller_id_name, ");
end
if (caller_id_number ~= nil) then
table.insert(sql, "fax_caller_id_number, ");
end
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, "'rx', ");
table.insert(sql, "'tif', ");
table.insert(sql, ":fax_file, ");
if (caller_id_name ~= nil) then
table.insert(sql, ":caller_id_name, ");
end
if (caller_id_number ~= nil) then
table.insert(sql, ":caller_id_number, ");
end
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;
domain_uuid = domain_uuid;
fax_uuid = fax_uuid;
fax_file = fax_file;
caller_id_name = caller_id_name;
caller_id_number = caller_id_number;
fax_base64 = fax_base64;
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");
end
if (storage_type == "base64") then
local dbh = Database.new('system', 'base64');
dbh:query(sql, params);
dbh:release();
else
result = 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","domain_uuid: '" .. domain_uuid .. "'\n");
freeswitch.consoleLog("INFO","domain_name: '" .. domain_name .. "'\n");
freeswitch.consoleLog("INFO","fax_uuid: '" .. fax_uuid .. "'\n");
freeswitch.consoleLog("INFO","fax_extension: '" .. fax_extension .. "'\n");
freeswitch.consoleLog("INFO","fax_result_text: '" .. fax_result_text .. "'\n");
freeswitch.consoleLog("INFO","fax_file: '" .. fax_file .. "'\n");
freeswitch.consoleLog("INFO","uuid: '" .. uuid .. "'\n");
--freeswitch.consoleLog("INFO","fax_ecm_used: '" .. fax_ecm_used .. "'\n");
freeswitch.consoleLog("INFO","fax_uri: '" .. fax_uri.. "'\n");
if (caller_id_name ~= nil) then
freeswitch.consoleLog("INFO","caller_id_name: " .. caller_id_name .. "\n");
end
if (caller_id_number ~= nil) then
freeswitch.consoleLog("INFO","caller_id_number: " .. caller_id_number .. "\n");
end
freeswitch.consoleLog("INFO","fax_result_code: ".. fax_result_code .."\n");
--freeswitch.consoleLog("INFO","mailfrom_address: ".. from_address .."\n");
--freeswitch.consoleLog("INFO","mailto_address: ".. email_address .."\n");
freeswitch.consoleLog("INFO","hangup_cause_q850: '" .. hangup_cause_q850 .. "'\n");
--
-- 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) 2015-2023
-- the Initial Developer. All Rights Reserved.
--
-- Contributor(s):
-- Mark J. Crane
--set the debug options
debug["sql"] = true;
--create the api object
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";
--check if windows
local IS_WINDOWS = (package.config:sub(1,1) == '\\')
--define function quote
local function quote(s)
local q = IS_WINDOWS and '"' or "'"
if s:find('%s') or s:find(q, nil, true) then
s = q .. s:gsub(q, q..q) .. q
end
return s
end
--escape shell arguments to prevent command injection
local function shell_esc(x)
return (x:gsub('\\', '\\\\')
:gsub('\'', '\\\''))
end
--create the api object
api = freeswitch.API();
--set channel variables to lua variables
domain_uuid = env:getHeader("domain_uuid");
domain_name = env:getHeader("domain_name");
--get the domain_uuid using the domain name required for multi-tenant
if (domain_name ~= nil) then
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
end
--show all channel variables
serialized = env:serialize()
freeswitch.consoleLog("INFO","[fax]\n" .. serialized .. "\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");
fax_uuid = env:getHeader("fax_uuid");
fax_queue_uuid = env:getHeader("fax_queue_uuid");
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_uri = env:getHeader("fax_uri");
fax_extension_number = env:getHeader("fax_extension_number");
caller_id_name = env:getHeader("caller_id_name");
caller_id_number = env:getHeader("caller_id_number");
fax_bad_rows = env:getHeader("fax_bad_rows");
fax_transfer_rate = env:getHeader("fax_transfer_rate");
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_remote_station_id = env:getHeader("fax_remote_station_id");
fax_document_total_pages = env:getHeader("fax_document_total_pages");
hangup_cause_q850 = tonumber(env:getHeader("hangup_cause_q850"));
fax_file = env:getHeader("fax_file");
--prevent nil errors
if (fax_file == nil) then
fax_file = env:getHeader("fax_filename");
end
if (fax_uri == nil) then
fax_uri = "";
end
if (fax_remote_station_id == nil) then
fax_remote_station_id = "";
end
if (caller_id_name == nil) then
caller_id_name = env:getHeader("Caller-Caller-ID-Name");
end
if (caller_id_number == nil) then
caller_id_number = env:getHeader("Caller-Caller-ID-Number");
end
if (document_root == nil) then
document_root = '';
end
--set default values
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 fax settings from the database
local sql = [[SELECT * FROM v_fax
WHERE fax_uuid = :fax_uuid
AND domain_uuid = :domain_uuid]];
local params = {fax_uuid = fax_uuid, domain_uuid = domain_uuid};
if (debug["sql"]) then
freeswitch.consoleLog("notice", "[fax] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n");
end
dbh:query(sql, params, function(row)
dialplan_uuid = row["dialplan_uuid"];
fax_extension = row["fax_extension"];
fax_accountcode = row["accountcode"];
fax_destination_number = row["fax_destination_number"];
fax_name = row["fax_name"];
fax_prefix = row["fax_prefix"];
fax_email = row["fax_email"];
fax_email_connection_type = row["fax_email_connection_type"];
fax_email_connection_host = row["fax_email_connection_host"];
fax_email_connection_port = row["fax_email_connection_port"];
fax_email_connection_security = row["fax_email_connection_security"];
fax_email_connection_validate = row["fax_email_connection_validate"];
fax_email_connection_username = row["fax_email_connection_username"];
fax_email_connection_password = row["fax_email_connection_password"];
fax_email_connection_mailbox = row["fax_email_connection_mailbox"];
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_authorized_senders = row["fax_email_outbound_authorized_senders"];
fax_caller_id_name = row["fax_caller_id_name"];
fax_caller_id_number = row["fax_caller_id_number"];
fax_forward_number = row["fax_forward_number"];
fax_description = row["fax_description"];
end);
--get the values from the fax file
if (fax_file ~= nil) then
array = explode("/", fax_file);
fax_file_name = array[count(array)];
end
--fax to email
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 .. "extension="..quote(shell_esc(fax_extension)).." ";
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 .. "domain="..quote(shell_esc(domain_name)).." ";
cmd = cmd .. "caller_id_name=" .. quote(shell_esc(caller_id_name) or '') .. " ";
cmd = cmd .. "caller_id_number=" .. quote(shell_esc(caller_id_number) or '') .. " ";
if #fax_forward_number > 0 then
cmd = cmd .. "fax_relay=true ";
else
cmd = cmd .. "fax_relay=false ";
end
if #fax_prefix > 0 then
cmd = cmd .. "fax_prefix=true ";
else
cmd = cmd .. "fax_prefix=false ";
end
freeswitch.consoleLog("notice", "[fax] command: " .. cmd .. "\n");
os.execute(cmd);
--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_uri ~= nil) then
sql = sql .. "fax_uri, ";
end
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_uri ~= nil) then
sql = sql .. ":fax_uri, ";
end
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_uri = fax_uri;
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");
end
dbh:query(sql, params);
--add the fax files
if (fax_success ~= nil) then
if (fax_success =="1") then
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, ");
table.insert(sql, "fax_file_type, ");
table.insert(sql, "fax_file_path, ");
if (caller_id_name ~= nil) then
table.insert(sql, "fax_caller_id_name, ");
end
if (caller_id_number ~= nil) then
table.insert(sql, "fax_caller_id_number, ");
end
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, "'rx', ");
table.insert(sql, "'tif', ");
table.insert(sql, ":fax_file, ");
if (caller_id_name ~= nil) then
table.insert(sql, ":caller_id_name, ");
end
if (caller_id_number ~= nil) then
table.insert(sql, ":caller_id_number, ");
end
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;
domain_uuid = domain_uuid;
fax_uuid = fax_uuid;
fax_file = fax_file;
caller_id_name = caller_id_name;
caller_id_number = caller_id_number;
fax_base64 = fax_base64;
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");
end
if (storage_type == "base64") then
local dbh = Database.new('system', 'base64');
dbh:query(sql, params);
dbh:release();
else
result = 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","domain_uuid: '" .. domain_uuid .. "'\n");
freeswitch.consoleLog("INFO","domain_name: '" .. domain_name .. "'\n");
freeswitch.consoleLog("INFO","fax_uuid: '" .. fax_uuid .. "'\n");
freeswitch.consoleLog("INFO","fax_extension: '" .. fax_extension .. "'\n");
freeswitch.consoleLog("INFO","fax_result_text: '" .. fax_result_text .. "'\n");
freeswitch.consoleLog("INFO","fax_file: '" .. fax_file .. "'\n");
freeswitch.consoleLog("INFO","uuid: '" .. uuid .. "'\n");
--freeswitch.consoleLog("INFO","fax_ecm_used: '" .. fax_ecm_used .. "'\n");
freeswitch.consoleLog("INFO","fax_uri: '" .. fax_uri.. "'\n");
if (caller_id_name ~= nil) then
freeswitch.consoleLog("INFO","caller_id_name: " .. caller_id_name .. "\n");
end
if (caller_id_number ~= nil) then
freeswitch.consoleLog("INFO","caller_id_number: " .. caller_id_number .. "\n");
end
freeswitch.consoleLog("INFO","fax_result_code: ".. fax_result_code .."\n");
--freeswitch.consoleLog("INFO","mailfrom_address: ".. from_address .."\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
-- local settings = Settings.new('system')
-- print(settings:get('switch', 'base', 'dir'))
--
-- Domain settings (to `fax_retry.lua`)
-- local Settings = require "resources.functions.settings"
-- local settings = Settings.new(dbh, domain_name, domain_uuid)
-- storage_type = settings:get('fax', 'storage_type', 'text') or ''
-- storage_path = settings:get('fax', 'storage_path', 'text') or ''
-- storage_path = storage_path
-- :gsub("${domain_name}", domain_name)
-- :gsub("${voicemail_id}", voicemail_id)
-- :gsub("${voicemail_dir}", voicemail_dir)
local Database = require "resources.functions.database"
local cache = require "resources.functions.cache"
require "resources.functions.split"
-----------------------------------------------------------
local Settings = {} do
Settings.__index = Settings
local NONE = '15783958-912c-4893-8866-4ccd1ca73c6e'
local function append(t, v)
t[#t+1] = v
return t
end
local function append_setting(array, category, subcategory, name, value)
--add the category array
if not array[category] then
array[category] = {}
end
--add the subcategory array
if not array[category][subcategory] then
array[category][subcategory] = {}
end
--set the name and value
if (name == "array") then
if not array[category][subcategory][name] then
array[category][subcategory][name] = {}
end
append(array[category][subcategory][name], value);
elseif value ~= nil then
array[category][subcategory][name] = value;
end
end
function Settings.new(db, domain_name, domain_uuid, user_uuid)
local self = setmetatable({}, Settings)
self._array = {}
self._db = db
self._domain_name = domain_name
self._domain_uuid = domain_uuid
self._user_uuid = user_uuid
self._use_cache = not cache.settings
return self
end
function Settings:_cache_key(category, subcategory, name)
return 'setting:' .. (self._domain_name or '') .. ':' .. category .. ':' .. subcategory .. ':' .. name
end
function Settings:set(category, subcategory, name, value)
append_setting(self._array, category, subcategory, name, value)
return self
end
function Settings:get(category, subcategory, name)
local a = self._array
local v = a[category] and a[category][subcategory] and a[category][subcategory][name]
if v == NONE then return nil end
if v ~= nil then return v end
if self._use_cache then
local key = self:_cache_key(category, subcategory, name)
v = cache.get(key)
if v then
if v ~= NONE and name == 'array' then
v = split(v, '/+/', true)
end
self:set(category, subcategory, name, v)
if v == NONE then return nil end
return v
end
end
return self:_load(category, subcategory, name)
end
function Settings:_load(category, subcategory, name)
local user_uuid = self._user_uuid
local domain_uuid = self._domain_uuid
local db = self._db
if type(self._db) == 'string' then
db = Database.new(self._db)
end
local found = false
--get the user settings
if user_uuid then
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 .. "WHERE user_uuid = :user_uuid ";
sql = sql .. "AND user_setting_enabled = 'true' ";
sql = sql .. "AND user_setting_category = :category ";
sql = sql .. "AND user_setting_subcategory = :subcategory ";
sql = sql .. "AND user_setting_name = :name ";
sql = sql .. "AND user_setting_value is not null ";
sql = sql .. "ORDER BY user_setting_category, user_setting_subcategory ASC ";
local params = {
user_uuid = user_uuid,
category = category,
subcategory = subcategory,
name = name,
};
db:query(sql, params, function(row)
found = true;
self:set(
row.user_setting_category,
row.user_setting_subcategory,
row.user_setting_name,
row.user_setting_value
)
end)
end
--get the domain settings
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 "
sql = sql .. "FROM v_domain_settings ";
sql = sql .. "WHERE domain_uuid = :domain_uuid ";
sql = sql .. "AND domain_setting_enabled = 'true' ";
sql = sql .. "AND domain_setting_category = :category ";
sql = sql .. "AND domain_setting_subcategory = :subcategory ";
sql = sql .. "AND domain_setting_name = :name ";
sql = sql .. "AND domain_setting_value is not null ";
sql = sql .. "ORDER BY domain_setting_category, domain_setting_subcategory ASC ";
local params = {
domain_uuid = domain_uuid,
category = category,
subcategory = subcategory,
name = name,
};
db:query(sql, params, function(row)
found = true;
self:set(
row.domain_setting_category,
row.domain_setting_subcategory,
row.domain_setting_name,
row.domain_setting_value
)
end)
end
--get default settings
if not found then
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 .. "WHERE default_setting_enabled = 'true' ";
sql = sql .. "AND default_setting_category = :category ";
sql = sql .. "AND default_setting_subcategory = :subcategory ";
sql = sql .. "AND default_setting_name = :name ";
sql = sql .. "AND default_setting_value is not null ";
sql = sql .. "ORDER BY default_setting_category, default_setting_subcategory ASC";
local params = {
category = category,
subcategory = subcategory,
name = name,
};
db:query(sql, params, function(row)
found = true;
self:set(
row.default_setting_category,
row.default_setting_subcategory,
row.default_setting_name,
row.default_setting_value
)
end)
end
if type(self._db) == 'string' then
db:release()
end
--set empty value for unknown setting
if not found then
self:set(category, subcategory, name, NONE)
end
local a = self._array
local v = a[category] and a[category][subcategory] and a[category][subcategory][name]
--store settings in cache
if self._use_cache and cache.support() then
local key = self:_cache_key(category, subcategory, name)
local value = v
if v ~= NONE and name == 'array' then
value = table.concat(v, '/+/')
end
local exp = expire and expire["settings"] or 3600
cache.set(key, value, exp)
end
if v == NONE then return nil end
return v
end
end
-----------------------------------------------------------
return Settings
-- -- Global settings
-- local settings = Settings.new('system')
-- print(settings:get('switch', 'base', 'dir'))
--
-- Domain settings
-- local Settings = require "resources.functions.settings"
-- local settings = Settings.new(dbh, domain_name, domain_uuid)
-- storage_type = settings:get('fax', 'storage_type', 'text') or ''
-- storage_path = settings:get('fax', 'storage_path', 'text') or ''
-- storage_path = storage_path
-- :gsub("${domain_name}", domain_name)
-- :gsub("${voicemail_id}", voicemail_id)
-- :gsub("${voicemail_dir}", voicemail_dir)
local Database = require "resources.functions.database"
local cache = require "resources.functions.cache"
require "resources.functions.split"
-----------------------------------------------------------
local Settings = {} do
Settings.__index = Settings
local NONE = '15783958-912c-4893-8866-4ccd1ca73c6e'
local function append(t, v)
t[#t+1] = v
return t
end
local function append_setting(array, category, subcategory, name, value)
--add the category array
if not array[category] then
array[category] = {}
end
--add the subcategory array
if not array[category][subcategory] then
array[category][subcategory] = {}
end
--set the name and value
if (name == "array") then
if not array[category][subcategory][name] then
array[category][subcategory][name] = {}
end
append(array[category][subcategory][name], value);
elseif value ~= nil then
array[category][subcategory][name] = value;
end
end
function Settings.new(db, domain_name, domain_uuid, user_uuid)
local self = setmetatable({}, Settings)
self._array = {}
self._db = db
self._domain_name = domain_name
self._domain_uuid = domain_uuid
self._user_uuid = user_uuid
self._use_cache = not cache.settings
return self
end
function Settings:_cache_key(category, subcategory, name)
return 'setting:' .. (self._domain_name or '') .. ':' .. category .. ':' .. subcategory .. ':' .. name
end
function Settings:set(category, subcategory, name, value)
append_setting(self._array, category, subcategory, name, value)
return self
end
function Settings:get(category, subcategory, name)
local a = self._array
local v = a[category] and a[category][subcategory] and a[category][subcategory][name]
if v == NONE then return nil end
if v ~= nil then return v end
if self._use_cache then
local key = self:_cache_key(category, subcategory, name)
v = cache.get(key)
if v then
if v ~= NONE and name == 'array' then
v = split(v, '/+/', true)
end
self:set(category, subcategory, name, v)
if v == NONE then return nil end
return v
end
end
return self:_load(category, subcategory, name)
end
function Settings:_load(category, subcategory, name)
local user_uuid = self._user_uuid
local domain_uuid = self._domain_uuid
local db = self._db
if type(self._db) == 'string' then
db = Database.new(self._db)
end
local found = false
--get the user settings
if user_uuid then
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 .. "WHERE user_uuid = :user_uuid ";
sql = sql .. "AND user_setting_enabled = 'true' ";
sql = sql .. "AND user_setting_category = :category ";
sql = sql .. "AND user_setting_subcategory = :subcategory ";
sql = sql .. "AND user_setting_name = :name ";
sql = sql .. "AND user_setting_value is not null ";
sql = sql .. "ORDER BY user_setting_category, user_setting_subcategory ASC ";
local params = {
user_uuid = user_uuid,
category = category,
subcategory = subcategory,
name = name,
};
db:query(sql, params, function(row)
found = true;
self:set(
row.user_setting_category,
row.user_setting_subcategory,
row.user_setting_name,
row.user_setting_value
)
end)
end
--get the domain settings
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 "
sql = sql .. "FROM v_domain_settings ";
sql = sql .. "WHERE domain_uuid = :domain_uuid ";
sql = sql .. "AND domain_setting_enabled = 'true' ";
sql = sql .. "AND domain_setting_category = :category ";
sql = sql .. "AND domain_setting_subcategory = :subcategory ";
sql = sql .. "AND domain_setting_name = :name ";
sql = sql .. "AND domain_setting_value is not null ";
sql = sql .. "ORDER BY domain_setting_category, domain_setting_subcategory ASC ";
local params = {
domain_uuid = domain_uuid,
category = category,
subcategory = subcategory,
name = name,
};
db:query(sql, params, function(row)
found = true;
self:set(
row.domain_setting_category,
row.domain_setting_subcategory,
row.domain_setting_name,
row.domain_setting_value
)
end)
end
--get default settings
if not found then
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 .. "WHERE default_setting_enabled = 'true' ";
sql = sql .. "AND default_setting_category = :category ";
sql = sql .. "AND default_setting_subcategory = :subcategory ";
sql = sql .. "AND default_setting_name = :name ";
sql = sql .. "AND default_setting_value is not null ";
sql = sql .. "ORDER BY default_setting_category, default_setting_subcategory ASC";
local params = {
category = category,
subcategory = subcategory,
name = name,
};
db:query(sql, params, function(row)
found = true;
self:set(
row.default_setting_category,
row.default_setting_subcategory,
row.default_setting_name,
row.default_setting_value
)
end)
end
if type(self._db) == 'string' then
db:release()
end
--set empty value for unknown setting
if not found then
self:set(category, subcategory, name, NONE)
end
local a = self._array
local v = a[category] and a[category][subcategory] and a[category][subcategory][name]
--store settings in cache
if self._use_cache and cache.support() then
local key = self:_cache_key(category, subcategory, name)
local value = v
if v ~= NONE and name == 'array' then
value = table.concat(v, '/+/')
end
local exp = expire and expire["settings"] or 3600
cache.set(key, value, exp)
end
if v == NONE then return nil end
return v
end
end
-----------------------------------------------------------
return Settings

View File

@ -17,7 +17,7 @@
The Initial Developer of the Original Code is
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.
Contributor(s):
@ -386,7 +386,6 @@ if (!function_exists('fax_split_dtmf')) {
echo "fax_forward_number: $fax_forward_number\n";
//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
$array['fax_queue'][0]['fax_queue_uuid'] = 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
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
if ($output_type == "file") {
//open the file