Files
fusionpbx/resources/install/scripts/intercept_group.lua
Alexey Melnichuk ce9e2cc4d1 Fix. Allow intercept only outbound calls.
Now it is possible intercept call from local extension to the world.

Fix. intercept channels also in EARLY state.

One of my softphones return 180 Ringing with SDP (no 183 Progress).
And FreeSWITCH shows such channel as `EARLY` not as `RINGING`)
2015-08-12 10:09:56 +04:00

223 lines
7.1 KiB
Lua

--
-- 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 - 2014
-- the Initial Developer. All Rights Reserved.
--
-- Contributor(s):
-- Mark J Crane <markjcrane@fusionpbx.com>
--user defined variables
max_tries = "3";
digit_timeout = "5000";
extension = argv[1];
--set the debug options
debug["sql"] = false;
--include config.lua
require "resources.functions.config";
--add the function
require "resources.functions.explode";
--connect to the database
require "resources.functions.database_handle";
dbh = database_handle('system');
--check if the session is ready
if ( session:ready() ) then
--answer the session
session:answer();
--get session variables
domain_uuid = session:getVariable("domain_uuid");
domain_name = session:getVariable("domain_name");
pin_number = session:getVariable("pin_number");
sounds_dir = session:getVariable("sounds_dir");
context = session:getVariable("context");
caller_id_number = session:getVariable("caller_id_number");
sofia_profile_name = session:getVariable("sofia_profile_name");
--set the sounds path for the language, dialect and voice
default_language = session:getVariable("default_language");
default_dialect = session:getVariable("default_dialect");
default_voice = session:getVariable("default_voice");
if (not default_language) then default_language = 'en'; end
if (not default_dialect) then default_dialect = 'us'; end
if (not default_voice) then default_voice = 'callie'; end
--set defaults
if (digit_min_length) then
--do nothing
else
digit_min_length = "2";
end
if (digit_max_length) then
--do nothing
else
digit_max_length = "11";
end
--if the pin number is provided then require it
if (pin_number) then
--sleep
session:sleep(500);
--get the user pin number
min_digits = 2;
max_digits = 20;
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_pass:#", "", "\\d+");
--validate the user pin number
pin_number_table = explode(",",pin_number);
for index,pin_number in pairs(pin_number_table) do
if (digits == pin_number) then
--set the variable to true
auth = true;
--set the authorized pin number that was used
session:setVariable("pin_number", pin_number);
--end the loop
break;
end
end
--if not authorized play a message and then hangup
if (not auth) then
session:streamFile("phrase:voicemail_fail_auth:#");
session:hangup("NORMAL_CLEARING");
return;
end
end
--get the call groups the extension is a member of
sql = "SELECT call_group FROM v_extensions ";
sql = sql .. "WHERE domain_uuid = '"..domain_uuid.."' ";
sql = sql .. "AND (extension = '"..caller_id_number.."'";
sql = sql .. "OR number_alias = '"..caller_id_number.."')";
status = dbh:query(sql, function(row)
call_group = row.call_group;
freeswitch.consoleLog("NOTICE", "[intercept_group] call_group: "..call_group.."\n");
end);
call_groups = explode(",", call_group);
--get the extensions in the call groups
sql = "SELECT extension, number_alias FROM v_extensions ";
sql = sql .. "WHERE domain_uuid = '"..domain_uuid.."' ";
sql = sql .. "AND (";
x = 0;
for key,call_group in pairs(call_groups) do
if (x == 0) then
if (string.len(call_group) > 0) then
sql = sql .. "call_group like '%"..call_group.."%' ";
else
sql = sql .. "call_group = '' ";
end
else
if (string.len(call_group) > 0) then
sql = sql .. "OR call_group like '%"..call_group.."%' ";
end
end
x = x + 1;
end
x = 0;
sql = sql .. ") ";
if (debug["sql"]) then
freeswitch.consoleLog("NOTICE", "[intercept_group] sql "..sql.."\n");
end
extensions = {}
status = dbh:query(sql, function(row)
local member = row.extension
if row.number_alias and #row.number_alias > 0 then
member = row.number_alias
end
extensions[x] = member
freeswitch.consoleLog("NOTICE", "[intercept_group] member "..extensions[x].."\n");
x = x + 1;
end);
--connect to the database
if (file_exists(database_dir.."/core.db")) then
--dbh = freeswitch.Dbh("core:core"); -- when using sqlite
dbh = freeswitch.Dbh("sqlite://"..database_dir.."/core.db");
else
require "resources.functions.database_handle";
dbh = database_handle('switch');
end
--exits the script if we didn't connect properly
assert(dbh:connected());
--check the database to get the uuid of a ringing call
call_hostname = "";
sql = "SELECT call_uuid AS uuid, hostname, ip_addr FROM channels ";
sql = sql .. "WHERE callstate in ('RINGING', 'EARLY') ";
sql = sql .. "AND direction = 'outbound' ";
sql = sql .. "AND (";
x = 0;
for key,extension in pairs(extensions) do
if (x == 0) then
sql = sql .. " presence_id = '"..extension.."@"..domain_name.."' ";
else
sql = sql .. "OR presence_id = '"..extension.."@"..domain_name.."' ";
end
x = x + 1;
end
sql = sql .. ") ";
sql = sql .. "and call_uuid is not null ";
--if (domain_count > 1) then
-- sql = sql .. "and context = '"..context.."' ";
--end
sql = sql .. "limit 1 ";
if (debug["sql"]) then
freeswitch.consoleLog("NOTICE", "[intercept_group] sql "..sql.."\n");
end
dbh:query(sql, function(row)
--for key, val in pairs(row) do
-- freeswitch.consoleLog("NOTICE", "row "..key.." "..val.."\n");
--end
uuid = row.uuid;
call_hostname = row.hostname;
ip_addr = row.ip_addr;
end);
end
--get the hostname
hostname = freeswitch.getGlobalVariable("hostname");
freeswitch.consoleLog("NOTICE", "Hostname:"..hostname.." Call Hostname:"..call_hostname.."\n");
--intercept a call that is ringing
if (uuid ~= nil) then
if (session:getVariable("billmsec") == nil) then
if (hostname == call_hostname) then
session:execute("intercept", uuid);
else
session:execute("export", "sip_h_X-intercept_uuid="..uuid);
session:execute("export", "sip_h_X-domain_uuid="..domain_uuid);
session:execute("export", "sip_h_X-domain_name="..domain_name);
port = freeswitch.getGlobalVariable(sofia_profile_name.."_sip_port");
session:execute("bridge", "sofia/"..sofia_profile_name.."/*8@"..call_hostname..":"..port);
freeswitch.consoleLog("NOTICE", "Send call to other host.... \n");
end
end
end
--notes
--originate a call
--cmd = "originate user/1007@voip.example.com &intercept("..uuid..")";
--api = freeswitch.API();
--result = api:executeString(cmd);