diff --git a/app/dialplan_outbound/dialplan_outbound_add.php b/app/dialplan_outbound/dialplan_outbound_add.php
index 12ff896054..98022a5702 100644
--- a/app/dialplan_outbound/dialplan_outbound_add.php
+++ b/app/dialplan_outbound/dialplan_outbound_add.php
@@ -613,6 +613,7 @@
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_type'] = 'set';
if ($dialplan_expression == '(^911$|^933$)') {
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_data'] = 'effective_caller_id_number=${emergency_caller_id_number}';
+ $array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_data'] = 'call_date=${strftime(%d-%b-%Y %r)}';
}
else {
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_data'] = 'effective_caller_id_number=${outbound_caller_id_number}';
@@ -628,7 +629,7 @@
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_uuid'] = $dialplan_uuid;
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_tag'] = 'action';
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_type'] = 'lua';
- $array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_data'] = "email.lua \${email_to} \${email_from} '' 'Emergency Call' '\${sip_from_user}@\${domain_name} has called 911 emergency'";
+ $array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_data'] = "app.lua emergency 1";
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_order'] = $y * 10;
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_group'] = '0';
$array['dialplans'][$x]['dialplan_details'][$y]['dialplan_detail_enabled'] = 'false';
diff --git a/app/email_templates/app_defaults.php b/app/email_templates/app_defaults.php
index 93682c51c5..9008dff2af 100644
--- a/app/email_templates/app_defaults.php
+++ b/app/email_templates/app_defaults.php
@@ -504,6 +504,46 @@
$array['email_templates'][$x]['template_type'] = 'html';
$array['email_templates'][$x]['template_enabled'] = 'true';
$array['email_templates'][$x]['template_description'] = '';
+ $x++;
+
+ $array['email_templates'][$x]['email_template_uuid'] = '814c08da-78ff-11ee-b73f-005056a27559';
+ $array['email_templates'][$x]['template_language'] = 'en-gb';
+ $array['email_templates'][$x]['template_category'] = 'plugin';
+ $array['email_templates'][$x]['template_subcategory'] = 'emergency';
+ $array['email_templates'][$x]['template_subject'] = '911 Emergency Call';
+ $array['email_templates'][$x]['template_body'] = "\n";
+ $array['email_templates'][$x]['template_body'] .= "
\n";
+ $array['email_templates'][$x]['template_body'] .= "From \${caller_id_name} \${caller_id_number}
\n";
+ $array['email_templates'][$x]['template_body'] .= "
\n";
+ $array['email_templates'][$x]['template_body'] .= "Emergency Name \${emergency_caller_id_name}"
\n";
+ $array['email_templates'][$x]['template_body'] .= "Emergency Name \${emergency_caller_id_number}"
\n";
+ $array['email_templates'][$x]['template_body'] .= "Received \${message_date}
\n";
+ $array['email_templates'][$x]['template_body'] .= "Event \${event}
\n";
+ $array['email_templates'][$x]['template_body'] .= "\n";
+ $array['email_templates'][$x]['template_body'] .= "\n";
+ $array['email_templates'][$x]['template_type'] = 'html';
+ $array['email_templates'][$x]['template_enabled'] = 'true';
+ $array['email_templates'][$x]['template_description'] = '';
+ $x++;
+
+ $array['email_templates'][$x]['email_template_uuid'] = '8928e8d4-78ff-11ee-ac06-005056a27559';
+ $array['email_templates'][$x]['template_language'] = 'en-us';
+ $array['email_templates'][$x]['template_category'] = 'plugin';
+ $array['email_templates'][$x]['template_subcategory'] = 'emergency';
+ $array['email_templates'][$x]['template_subject'] = '911 Emergency Call';
+ $array['email_templates'][$x]['template_body'] = "\n";
+ $array['email_templates'][$x]['template_body'] .= "\n";
+ $array['email_templates'][$x]['template_body'] .= "From \${caller_id_name} \${caller_id_number}
\n";
+ $array['email_templates'][$x]['template_body'] .= "
\n";
+ $array['email_templates'][$x]['template_body'] .= "Emergency Name \${emergency_caller_id_name}"
\n";
+ array['email_templates'][$x]['template_body'] .= "Emergency Name \${emergency_caller_id_number}"
\n";
+ $array['email_templates'][$x]['template_body'] .= "Received \${message_date}
\n";
+ $array['email_templates'][$x]['template_body'] .= "Event \${event}
\n";
+ $array['email_templates'][$x]['template_body'] .= "\n";
+ $array['email_templates'][$x]['template_body'] .= "\n";
+ $array['email_templates'][$x]['template_type'] = 'html';
+ $array['email_templates'][$x]['template_enabled'] = 'true';
+ $array['email_templates'][$x]['template_description'] = '';
//build array of email template uuids
diff --git a/app/emergency/app_config.php b/app/emergency/app_config.php
new file mode 100644
index 0000000000..53f7f09e0a
--- /dev/null
+++ b/app/emergency/app_config.php
@@ -0,0 +1,96 @@
+
diff --git a/app/emergency/app_menu.php b/app/emergency/app_menu.php
new file mode 100644
index 0000000000..08e0e253e2
--- /dev/null
+++ b/app/emergency/app_menu.php
@@ -0,0 +1,35 @@
+
diff --git a/app/emergency/emergency.php b/app/emergency/emergency.php
new file mode 100644
index 0000000000..03dbaaa698
--- /dev/null
+++ b/app/emergency/emergency.php
@@ -0,0 +1,213 @@
+get();
+
+//get the http post data
+if (!empty($_POST['emergency_logs']) && is_array($_POST['emergency_logs'])) {
+ $action = $_POST['action'];
+ $search = $_POST['search'];
+ $emergency_logs = $_POST['emergency_logs'];
+}
+
+//process the http post data by action
+if (!empty($action) && !empty($emergency_logs) && is_array($emergency_logs) && @sizeof($emergency_logs) != 0) {
+
+ //validate the token
+ $token = new token;
+ if (!$token->validate($_SERVER['PHP_SELF'])) {
+ message::add($text['message-invalid_token'],'negative');
+ header('Location: emergency.php');
+ exit;
+ }
+
+ //prepare the array
+ if (!empty($emergency_logs)) {
+ foreach ($emergency_logs as $row) {
+ $array['emergency_logs'][$x]['checked'] = $row['checked'];
+ $array['emergency_logs'][$x]['emergency_log_uuid'] = $row['emergency_log_uuid'];
+ $x++;
+ }
+ }
+
+ //prepare the database object
+ $database = new database;
+ $database->app_name = 'emergency_logs';
+ $database->app_uuid = 'de63b1ae-7750-11ee-b3a5-005056a27559';
+
+ //send the array to the database class
+ if (!empty($action) && $action == 'delete') {
+ $database->delete($array);
+ }
+
+ //redirect the user
+ header('Location: emergency.php'.($search != '' ? '?search='.urlencode($search) : null));
+ exit;
+}
+
+//get order and order by
+$order_by = $_GET["order_by"] ?? null;
+$order = $_GET["order"] ?? null;
+
+//define the variables
+$search = '';
+$show = '';
+
+//add the search variable
+if (!empty($_GET["search"])) {
+ $search = strtolower($_GET["search"]);
+}
+
+//add the show variable
+if (!empty($_GET["show"])) {
+ $show = $_GET["show"];
+}
+
+
+//get the count
+$sql = "select count(log_uuid) ";
+$sql .= "from v_emergency_logs ";
+if ($show == 'all') {
+ $sql .= "where true ";
+}
+else {
+ $sql .= "where domain_uuid = :domain_uuid ";
+ $parameters['domain_uuid'] = $_SESSION['domain_uuid'];
+}
+if (!empty($search)) {
+ $sql .= "and ( ";
+ $sql .= " lower(event) like :search ";
+ $sql .= ") ";
+ $parameters['search'] = '%'.$search.'%';
+}
+$database = new database;
+$num_rows = $database->select($sql, $parameters ?? null, 'column');
+unset($sql, $parameters);
+
+//prepare to page the results
+$rows_per_page = ($_SESSION['domain']['paging']['numeric'] != '') ? $_SESSION['domain']['paging']['numeric'] : 50;
+$param = !empty($search) ? "&search=".$search : null;
+$param .= (!empty($_GET['page']) && $show == 'all' && permission_exists('user_log_all')) ? "&show=all" : null;
+$page = !empty($_GET['page']) && is_numeric($_GET['page']) ? $_GET['page'] : 0;
+list($paging_controls, $rows_per_page) = paging($num_rows, $param, $rows_per_page);
+list($paging_controls_mini, $rows_per_page) = paging($num_rows, $param, $rows_per_page, true);
+$offset = $rows_per_page * $page;
+
+//set the time zone
+if (isset($_SESSION['domain']['time_zone']['name'])) {
+ $time_zone = $_SESSION['domain']['time_zone']['name'];
+}
+else {
+ $time_zone = date_default_timezone_get();
+}
+
+//get the list
+$sql = "select * ";
+$sql .= "from v_emergency_logs ";
+if ($show == 'all') {
+ $sql .= "where true ";
+}
+else {
+ $sql .= "where domain_uuid = :domain_uuid ";
+ $parameters['domain_uuid'] = $_SESSION['domain_uuid'];
+}
+if (!empty($search)) {
+ $sql .= "and ( ";
+ $sql .= " lower(event) like :search ";
+ $sql .= ") ";
+ $parameters['search'] = '%'.$search.'%';
+}
+$sql .= limit_offset($rows_per_page, $offset);
+
+$database = new database;
+$emergency_logs = $database->select($sql, $parameters ?? null, 'all');
+unset($sql, $parameters);
+
+//create token
+$object = new token;
+$token = $object->create($_SERVER['PHP_SELF']);
+
+//additional includes
+$document['title'] = 'Emergency Logs';
+require_once "resources/header.php";
+
+//show the content
+echo "\n";
+echo "
Emergency Logs (".$num_rows.")
\n";
+echo "
\n";
+if ($emergency_logs) {
+ echo button::create(['type'=>'button','label'=>$text['button-delete'],'icon'=>$_SESSION['theme']['button_icon_delete'],'id'=>'btn_delete','name'=>'btn_delete','style'=>'display:none;','onclick'=>"modal_open('modal-delete','btn_delete');"]);
+}
+echo "\n";
+echo "
\n";
+echo "
\n";
+echo "
\n";
+
+if ($emergency_logs) {
+ echo modal::create(['id'=>'modal-delete','type'=>'delete','actions'=>button::create(['type'=>'button','label'=>$text['button-continue'],'icon'=>'check','id'=>'btn_delete','style'=>'float: right; margin-left: 15px;','collapse'=>'never','onclick'=>"modal_close(); list_action_set('delete'); list_form_submit('form_list');"])]);
+}
+
+echo $text['title_description-emergency_logs']."\n";
+echo "
\n";
+
+echo "\n";
+echo "\n";
+
+if (!empty($emergency_logs) && is_array($emergency_logs) && @sizeof($emergency_logs) != 0) {
+ $x = 0;
+ foreach ($emergency_logs as $row) {
+ echo "\n";
+ echo " | ".escape($row['time'])." | \n";
+ echo " ".escape($row['date'])." | \n";
+ echo " ".escape($row['extension'])." | \n";
+ echo " ".escape($row['event'])." | \n";
+ echo "
\n";
+ $x++;
+ }
+ unset($emergency_logs);
+}
+
+echo "
\n";
+echo "
\n";
+echo "".$paging_controls."
\n";
+echo "\n";
+echo "\n";
+
+//include the footer
+require_once "resources/footer.php";
+
+?>
diff --git a/app/switch/resources/scripts/app/emergency/index.lua b/app/switch/resources/scripts/app/emergency/index.lua
new file mode 100644
index 0000000000..fd1a694ede
--- /dev/null
+++ b/app/switch/resources/scripts/app/emergency/index.lua
@@ -0,0 +1,278 @@
+-- emergency.lua
+-- Part of FusionPBX
+-- Copyright (C) 2010 - 2022 Mark J Crane
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- 1. Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+
+--Description:
+ --purpose: send an email queue or email for 911 calls
+ --freeswitch.email(to, from, headers, body, file, convert_cmd, convert_ext)
+ --to (mandatory) a valid email address
+ --from (mandatory) a valid email address
+ --headers (mandatory) for example "subject: you've got mail!\n"
+ --body (optional) your regular mail body
+ --file (optional) a file to attach to your mail
+ --convert_cmd (optional) convert file to a different format before sending
+ --convert_ext (optional) to replace the file's extension
+
+--Example
+ --luarun emergency.lua to@domain.com from@domain.com 'headers' 'subject' 'body'
+
+--load libraries
+ local send_mail = require 'resources.functions.send_mail'
+ local Database = require "resources.functions.database"
+ local Settings = require "resources.functions.lazy_settings"
+ local Utils = require "resources.functions.channel_utils";
+
+--define a function to send email
+ local db = dbh or Database.new('system')
+ local settings = Settings.new(db, domain_name, domain_uuid)
+ local email_queue_enabled = settings:get('email_queue', 'enabled', 'boolean') or "false";
+
+--get the argv values
+ script_name = argv[0];
+ delete = argv[1];
+
+--prepare the api object
+ api = freeswitch.API();
+
+--get sessions info
+if (session and session:ready()) then
+ domain_uuid = session:getVariable("domain_uuid");
+ domain_name = session:getVariable("domain_name");
+ call_uuid = session:getVariable("uuid");
+ headers = {
+ ["X-FusionPBX-Domain-UUID"] = domain_uuid;
+ ["X-FusionPBX-Domain-Name"] = domain_name;
+ ["X-FusionPBX-Email-Type"] = 'app';
+ ["X-FusionPBX-Call-UUID"] = call_uuid;
+ }
+else
+ headers = {}
+end
+
+function escapeCSV(s)
+ if string.find(s, '[,"]') then
+ s = '"' .. string.gsub(s, '"', '""') .. '"'
+ end
+ return s
+end
+
+function toCSV(tt)
+ local s = ""
+ for _,p in ipairs(tt) do
+ s = s .. "," .. escapeCSV(p)
+ end
+ return string.sub(s, 2)
+end
+
+--connect to the database
+local dbh = Database.new('system');
+
+--get the templates
+local sql = "SELECT * FROM v_email_templates ";
+ sql = sql .. "WHERE template_category = :category ";
+ sql = sql .. "AND template_subcategory = :subcategory ";
+ sql = sql .. "AND template_enabled = :status ";
+ local params = {category = 'plugins', subcategory = 'emergency', status = 'true'}
+ dbh:query(sql, params, function(row)
+ subject = row.template_subject;
+ body = row.template_body;
+ language = row.template_language;
+ end);
+ if (debug["sql"]) then
+ freeswitch.consoleLog("info", "[emergency] SQL: " .. sql .. "\n");
+ end
+ --freeswitch.consoleLog("info", "[template] SQL: " .. sql .. "body: " .. body .. "\n");
+
+--get email from
+local sql = "SELECT * FROM v_default_settings ";
+ sql = sql .. "WHERE default_setting_category = 'email' ";
+ sql = sql .. "AND (default_setting_subcategory = 'smtp_from' ";
+ sql = sql .. "OR default_setting_subcategory = 'smtp_from_name') ";
+
+ if (debug["sql"]) then
+ freeswitch.consoleLog("notice", "[emergency] SQL: " .. sql .. "\n");
+ end
+
+ dbh:query(sql, function(row)
+ if (row.default_setting_subcategory == "smtp_from") then
+ from = row.default_setting_value;
+ end
+ if (row.default_setting_subcategory == "smtp_from_name") then
+ from_name = row.default_setting_value;
+ end
+ end);
+
+
+
+-- get vars
+domain_uuid = session:getVariable("domain_uuid");
+call_date = session:getVariable("call_date");
+caller_id_name = session:getVariable("caller_id_name");
+caller_id_number = session:getVariable("caller_id_number");
+sip_from_user = session:getVariable("sip_from_user");
+emergency_caller_id_name = session:getVariable("emergency_caller_id_name");
+emergency_caller_id_number = session:getVariable("emergency_caller_id_number");
+call_duration = session:getVariable("call_duration");
+
+--domain level check
+ result = {}
+local sql = "SELECT count(domain_setting_value) ";
+ sql = sql .. "AS total ";
+ sql = sql .. "FROM v_domain_settings ";
+ sql = sql .. "WHERE domain_uuid = :domain_uuid ";
+ sql = sql .. "AND domain_setting_subcategory = :emergency_email_address ";
+ sql = sql .. "AND domain_setting_enabled = :status ";
+
+ local params = {domain_uuid = domain_uuid, emergency_email_address = 'emergency_email_address', status = 't'}
+
+ dbh:query(sql, params, function(result)
+ total = result.total;
+ --no emergency emails found under domain, using default
+ if (total == 0 or total == nil) then
+ to = {}
+ local sql = "SELECT default_setting_value ";
+ sql = sql .. "FROM v_default_settings ";
+ sql = sql .. "WHERE default_setting_category = :category ";
+ sql = sql .. "AND default_setting_subcategory = :emergency_email_address ";
+ sql = sql .. "AND default_setting_enabled = :status ";
+ sql = sql .. "LIMIT 5 ";
+ local params = {category = 'dialplan', emergency_email_address = 'emergency_email_address', status = 't'}
+ dbh:query(sql, params, function(result)
+ for key,row in pairs(result) do
+ table.insert(to, row);
+ freeswitch.consoleLog("info", "[emergency] Inserted into table from default settings " .. row .. "\n");
+ end
+ --add some details
+ if (debug["sql"]) then
+ freeswitch.consoleLog("notice", "[emergency] SQL: " .. sql .. " result " .. result .. "\n");
+ end
+ end);
+ --domain level emails max 5
+ else if (tonumber(total) <= 5) then
+ to = {}
+ local sql = "SELECT domain_setting_value ";
+ sql = sql .. "FROM v_domain_settings ";
+ sql = sql .. "WHERE domain_uuid = :domain_uuid ";
+ sql = sql .. "AND domain_setting_subcategory = :emergency_email_address ";
+ sql = sql .. "AND domain_setting_enabled = :status ";
+ local params = {domain_uuid = domain_uuid, emergency_email_address = 'emergency_email_address', status = 't'}
+ dbh:query(sql, params, function(result)
+ for key,row in pairs(result) do
+ table.insert(to, row);
+ freeswitch.consoleLog("info", "[template] Inserted into table " .. row .. "\n");
+ end
+ end);
+ end
+ end
+
+ end);
+
+dbh:release()
+
+if (#to > 0) then
+ --set event
+ destination_number = session:getVariable("destination_number");
+ if (tonumber(destination_number) == 933) then
+ event = '933 Emergency Address Validation Service';
+ else if (tonumber(destination_number) == 911) then
+ event = '911 Emergency Call';
+ end
+ end
+
+ --prepare the body
+ if (body ~= nil) then
+ body = body:gsub("${caller_id_name}", caller_id_name);
+ body = body:gsub("${caller_id_number}", caller_id_number);
+ body = body:gsub("${emergency_caller_id_name}", emergency_caller_id_name);
+ body = body:gsub("${emergency_caller_id_number}", emergency_caller_id_number);
+ body = body:gsub("${sip_from_user}", sip_from_user);
+ body = body:gsub("${caller_id_number}", caller_id_number);
+ body = body:gsub("${message_date}", call_date);
+ body = body:gsub("${event}", event);
+ body = trim(body);
+ end
+
+ for key,row in ipairs(to) do
+ freeswitch.consoleLog("info", "[emergency] Sending to row " .. row .. " key " .. key .. "\n");
+ --send the email
+ send_mail(headers,
+ from,
+ row,
+ {subject, body}
+ );
+ end
+end
+
+-- Insert into Emergency Logs
+emergency_logs_uuid = api:executeString("create_uuid");
+domain_uuid = session:getVariable("domain_uuid");
+
+-- Set time and date
+local delimiter = " ";
+local y = 0;
+local tab = {}
+
+while true do
+ local endindex = call_date:find(delimiter,y);
+ if not endindex then
+ break
+ end
+ table.insert(tab,call_date:sub(y,endindex-1))
+ y = endindex + 1;
+end
+
+table.insert(tab,call_date:sub(y));
+local time = tab[2] .. " " .. tab[3];
+
+freeswitch.consoleLog("info", "[emergency] Getting Date " .. tab[1] .. " Time " .. tab[2] .. " Format " .. tab[3] .. "\n");
+
+--connect to the database
+local dbh = Database.new('system');
+
+local sql = "INSERT INTO v_emergency_logs ( ";
+ sql = sql .. " log_uuid, ";
+ sql = sql .. " domain_uuid, ";
+ sql = sql .. " date, ";
+ sql = sql .. " time, ";
+ sql = sql .. " extension, ";
+ sql = sql .. " event ";
+ sql = sql .. ") ";
+ sql = sql .. "VALUES ( ";
+ sql = sql .. " :emergency_logs_uuid, ";
+ sql = sql .. " :domain_uuid, ";
+ sql = sql .. " :date, ";
+ sql = sql .. " :time, ";
+ sql = sql .. " :extension, ";
+ sql = sql .. " :event ";
+ sql = sql .. ") ";
+
+ local params = {emergency_logs_uuid = emergency_logs_uuid,domain_uuid = domain_uuid, date = tab[1], time = time, extension = caller_id_number, event = event}
+
+ if (debug["sql"]) then
+ freeswitch.consoleLog("info", "[emergency] SQL: " .. sql .. "\n");
+ end
+
+ dbh:query(sql, params);
+ dbh:release();