Calculate timeout for Follow-me (#4528)
* Calculate timeout for Follow-me Need to calculate the timeout for Enterprise RG members that have extensions with follow-me. The RG timeout should always take precedence over a follow-me timeout value. What we do is take the delay of the follow-me destination and subtract that from the ring group timeout to give us the total timeout of the destination. Example: RG 1: x1000 (Delay=0, Timeout=10) RG 2: x2000 (Delay=10, Timeout=10) x2000 has follow-me enabled FM 1: x2000 (Delay=0, Timeout=15) FM 2: x3000 (Delay=5, Timeout=20) In this example we would want x2000 ring for 10 seconds and x3000 to ring for 5 seconds. What if we changed this... FM 2: x3000 (Delay 15, Timeout=20) In this example we wouldn't want x3000 to ring at all because it would start to ring after the RG timeout has expired. Our calculated value would be a negative value, -5. These negative values don't work as leg_timeouts in the dialstring, so we need to test for them. * Update index.lua * Update index.lua
This commit is contained in:
parent
a4661f196a
commit
f174a9f5af
|
|
@ -546,6 +546,15 @@
|
|||
else
|
||||
new_key = #destinations + 1;
|
||||
end
|
||||
|
||||
--Calculate the destination_timeout for follow-me destinations.
|
||||
--The call should honor ring group timeouts with rg delays, follow-me timeouts and follow-me delays factored in.
|
||||
--Destinations with a timeout of 0 or negative numbers should be ignored.
|
||||
if (tonumber(field.destination_timeout) < (tonumber(row.destination_timeout) - tonumber(field.destination_delay))) then
|
||||
new_destination_timeout = field.destination_timeout;
|
||||
else
|
||||
new_destination_timeout = row.destination_timeout - field.destination_delay;
|
||||
end
|
||||
|
||||
--add to the destinations array
|
||||
destinations[new_key] = {}
|
||||
|
|
@ -561,7 +570,7 @@
|
|||
destinations[new_key]['domain_name'] = field.domain_name;
|
||||
destinations[new_key]['destination_number'] = field.destination_number;
|
||||
destinations[new_key]['destination_delay'] = field.destination_delay + row.destination_delay;
|
||||
destinations[new_key]['destination_timeout'] = field.destination_timeout;
|
||||
destinations[new_key]['destination_timeout'] = new_destination_timeout;
|
||||
destinations[new_key]['destination_prompt'] = field.destination_prompt;
|
||||
destinations[new_key]['group_confirm_key'] = row.group_confirm_key;
|
||||
destinations[new_key]['group_confirm_file'] = row.group_confirm_file;
|
||||
|
|
@ -613,210 +622,212 @@
|
|||
--process the destinations
|
||||
x = 1;
|
||||
for key, row in pairs(destinations) do
|
||||
--set the values from the database as variables
|
||||
ring_group_strategy = row.ring_group_strategy;
|
||||
ring_group_timeout_app = row.ring_group_timeout_app;
|
||||
ring_group_timeout_data = row.ring_group_timeout_data;
|
||||
ring_group_caller_id_name = row.ring_group_caller_id_name;
|
||||
ring_group_caller_id_number = row.ring_group_caller_id_number;
|
||||
ring_group_cid_name_prefix = row.ring_group_cid_name_prefix;
|
||||
ring_group_cid_number_prefix = row.ring_group_cid_number_prefix;
|
||||
ring_group_distinctive_ring = row.ring_group_distinctive_ring;
|
||||
ring_group_ringback = row.ring_group_ringback;
|
||||
destination_number = row.destination_number;
|
||||
destination_delay = row.destination_delay;
|
||||
destination_timeout = row.destination_timeout;
|
||||
destination_prompt = row.destination_prompt;
|
||||
group_confirm_key = row.group_confirm_key;
|
||||
group_confirm_file = row.group_confirm_file;
|
||||
toll_allow = row.toll_allow;
|
||||
user_exists = row.user_exists;
|
||||
if (tonumber(row.destination_timeout) > 0) then
|
||||
--set the values from the database as variables
|
||||
ring_group_strategy = row.ring_group_strategy;
|
||||
ring_group_timeout_app = row.ring_group_timeout_app;
|
||||
ring_group_timeout_data = row.ring_group_timeout_data;
|
||||
ring_group_caller_id_name = row.ring_group_caller_id_name;
|
||||
ring_group_caller_id_number = row.ring_group_caller_id_number;
|
||||
ring_group_cid_name_prefix = row.ring_group_cid_name_prefix;
|
||||
ring_group_cid_number_prefix = row.ring_group_cid_number_prefix;
|
||||
ring_group_distinctive_ring = row.ring_group_distinctive_ring;
|
||||
ring_group_ringback = row.ring_group_ringback;
|
||||
destination_number = row.destination_number;
|
||||
destination_delay = row.destination_delay;
|
||||
destination_timeout = row.destination_timeout;
|
||||
destination_prompt = row.destination_prompt;
|
||||
group_confirm_key = row.group_confirm_key;
|
||||
group_confirm_file = row.group_confirm_file;
|
||||
toll_allow = row.toll_allow;
|
||||
user_exists = row.user_exists;
|
||||
|
||||
--follow the forwards
|
||||
count, destination_number = get_forward_all(0, destination_number, leg_domain_name);
|
||||
--follow the forwards
|
||||
count, destination_number = get_forward_all(0, destination_number, leg_domain_name);
|
||||
|
||||
--check if the user exists
|
||||
cmd = "user_exists id ".. destination_number .." "..domain_name;
|
||||
user_exists = api:executeString(cmd);
|
||||
--check if the user exists
|
||||
cmd = "user_exists id ".. destination_number .." "..domain_name;
|
||||
user_exists = api:executeString(cmd);
|
||||
|
||||
--set ringback
|
||||
ring_group_ringback = format_ringback(ring_group_ringback);
|
||||
session:setVariable("ringback", ring_group_ringback);
|
||||
session:setVariable("transfer_ringback", ring_group_ringback);
|
||||
--set ringback
|
||||
ring_group_ringback = format_ringback(ring_group_ringback);
|
||||
session:setVariable("ringback", ring_group_ringback);
|
||||
session:setVariable("transfer_ringback", ring_group_ringback);
|
||||
|
||||
--set the timeout if there is only one destination
|
||||
if (#destinations == 1) then
|
||||
session:execute("set", "call_timeout="..row.destination_timeout);
|
||||
end
|
||||
--set the timeout if there is only one destination
|
||||
if (#destinations == 1) then
|
||||
session:execute("set", "call_timeout="..row.destination_timeout);
|
||||
end
|
||||
|
||||
--setup the delimiter
|
||||
delimiter = ",";
|
||||
if (ring_group_strategy == "rollover") then
|
||||
delimiter = "|";
|
||||
end
|
||||
if (ring_group_strategy == "sequence") then
|
||||
delimiter = "|";
|
||||
end
|
||||
if (ring_group_strategy == "random") then
|
||||
delimiter = "|";
|
||||
end
|
||||
if (ring_group_strategy == "simultaneous") then
|
||||
--setup the delimiter
|
||||
delimiter = ",";
|
||||
end
|
||||
if (ring_group_strategy == "enterprise") then
|
||||
delimiter = ":_:";
|
||||
end
|
||||
|
||||
--leg delay settings
|
||||
if (ring_group_strategy == "enterprise") then
|
||||
delay_name = "originate_delay_start";
|
||||
destination_delay = destination_delay * 500;
|
||||
else
|
||||
delay_name = "leg_delay_start";
|
||||
end
|
||||
|
||||
--create a new uuid and add it to the uuid list
|
||||
new_uuid = api:executeString("create_uuid");
|
||||
if (string.len(uuids) == 0) then
|
||||
uuids = new_uuid;
|
||||
else
|
||||
uuids = uuids ..",".. new_uuid;
|
||||
end
|
||||
session:execute("set", "uuids="..uuids);
|
||||
|
||||
--export the ringback
|
||||
if (ring_group_distinctive_ring ~= nil) then
|
||||
if (local_ip_v4 ~= nil) then
|
||||
ring_group_distinctive_ring = ring_group_distinctive_ring:gsub("${local_ip_v4}", local_ip_v4);
|
||||
if (ring_group_strategy == "rollover") then
|
||||
delimiter = "|";
|
||||
end
|
||||
if (domain_name ~= nil) then
|
||||
ring_group_distinctive_ring = ring_group_distinctive_ring:gsub("${domain_name}", domain_name);
|
||||
if (ring_group_strategy == "sequence") then
|
||||
delimiter = "|";
|
||||
end
|
||||
if (ring_group_strategy == "random") then
|
||||
delimiter = "|";
|
||||
end
|
||||
if (ring_group_strategy == "simultaneous") then
|
||||
delimiter = ",";
|
||||
end
|
||||
if (ring_group_strategy == "enterprise") then
|
||||
delimiter = ":_:";
|
||||
end
|
||||
session:execute("export", "sip_h_Alert-Info="..ring_group_distinctive_ring);
|
||||
end
|
||||
|
||||
--set confirm
|
||||
if (ring_group_strategy == "simultaneous"
|
||||
or ring_group_strategy == "sequence"
|
||||
or ring_group_strategy == "rollover") then
|
||||
session:execute("set", "group_confirm_key=exec");
|
||||
session:execute("set", "group_confirm_file=lua ".. scripts_dir:gsub('\\','/') .."/confirm.lua");
|
||||
end
|
||||
|
||||
--determine confirm prompt
|
||||
if (destination_prompt == nil) then
|
||||
group_confirm = "confirm=false,";
|
||||
elseif (destination_prompt == "1") then
|
||||
group_confirm = "group_confirm_key=exec,group_confirm_file=lua ".. scripts_dir:gsub('\\','/') .."/confirm.lua,confirm=true,";
|
||||
elseif (destination_prompt == "2") then
|
||||
group_confirm = "group_confirm_key=exec,group_confirm_file=lua ".. scripts_dir:gsub('\\','/') .."/confirm.lua,confirm=true,";
|
||||
else
|
||||
group_confirm = "confirm=false,";
|
||||
end
|
||||
|
||||
--get user_record value and determine whether to record the session
|
||||
cmd = "user_data ".. destination_number .."@"..domain_name.." var user_record";
|
||||
user_record = trim(api:executeString(cmd));
|
||||
--set the record_session variable
|
||||
record_session = false;
|
||||
if (user_record == "all") then
|
||||
record_session = true;
|
||||
end
|
||||
if (user_record == "inbound" and call_direction == "inbound") then
|
||||
record_session = true;
|
||||
end
|
||||
if (user_record == "outbound" and call_direction == "outbound") then
|
||||
record_session = true;
|
||||
end
|
||||
if (user_record == "local" and call_direction == "local") then
|
||||
record_session = true;
|
||||
end
|
||||
|
||||
--record the session
|
||||
if (record_session) then
|
||||
record_session = ",api_on_answer='uuid_record "..uuid.." start ".. record_path .. "/" .. record_name .. "',record_path='".. record_path .."',record_name="..record_name;
|
||||
else
|
||||
record_session = ""
|
||||
end
|
||||
row.record_session = record_session
|
||||
|
||||
--process according to user_exists, sip_uri, external number
|
||||
if (user_exists == "true") then
|
||||
--get the extension_uuid
|
||||
cmd = "user_data ".. destination_number .."@"..domain_name.." var extension_uuid";
|
||||
extension_uuid = trim(api:executeString(cmd));
|
||||
--send to user
|
||||
local dial_string_to_user = "[sip_invite_domain="..domain_name..",call_direction="..call_direction..","..group_confirm.."leg_timeout="..destination_timeout..","..delay_name.."="..destination_delay..",dialed_extension=" .. row.destination_number .. ",extension_uuid="..extension_uuid .. row.record_session .. "]user/" .. row.destination_number .. "@" .. domain_name;
|
||||
dial_string = dial_string_to_user;
|
||||
elseif (tonumber(destination_number) == nil) then
|
||||
--sip uri
|
||||
dial_string = "[sip_invite_domain="..domain_name..",call_direction="..call_direction..","..group_confirm.."leg_timeout="..destination_timeout..","..delay_name.."="..destination_delay.."]" .. row.destination_number;
|
||||
else
|
||||
--external number
|
||||
-- have to double destination_delay here due a FS bug requiring a 50% delay value for internal externsions, but not external calls.
|
||||
destination_delay = destination_delay * 2;
|
||||
|
||||
route_bridge = 'loopback/'..destination_number;
|
||||
if (extension_toll_allow ~= nil) then
|
||||
toll_allow = extension_toll_allow:gsub(",", ":");
|
||||
end
|
||||
|
||||
--set the toll allow to an empty string
|
||||
if (toll_allow == nil) then
|
||||
toll_allow = '';
|
||||
end
|
||||
|
||||
--check if the user exists
|
||||
if tonumber(caller_id_number) ~= nil then
|
||||
cmd = "user_exists id ".. caller_id_number .." "..domain_name;
|
||||
caller_is_local = api:executeString(cmd);
|
||||
end
|
||||
|
||||
--set the caller id
|
||||
caller_id = '';
|
||||
|
||||
--set the outbound caller id
|
||||
if (caller_is_local == 'true' and outbound_caller_id_name ~= nil) then
|
||||
caller_id = ",origination_caller_id_name='"..outbound_caller_id_name.."'";
|
||||
end
|
||||
if (caller_is_local == 'true' and outbound_caller_id_number ~= nil) then
|
||||
caller_id = caller_id .. ",origination_caller_id_number='"..outbound_caller_id_number.."'";
|
||||
end
|
||||
if (ring_group_caller_id_name ~= nil and ring_group_caller_id_name ~= '') then
|
||||
caller_id = ",origination_caller_id_name='"..ring_group_caller_id_name.."'";
|
||||
end
|
||||
if (ring_group_caller_id_number ~= nil and ring_group_caller_id_number ~= '') then
|
||||
caller_id = caller_id .. ",origination_caller_id_number="..ring_group_caller_id_number..",";
|
||||
end
|
||||
|
||||
--set the destination dial string
|
||||
dial_string = "[ignore_early_media=true,toll_allow=".. toll_allow ..",".. caller_id .."sip_invite_domain="..domain_name..",call_direction="..call_direction..","..group_confirm.."leg_timeout="..destination_timeout..","..delay_name.."="..destination_delay.."]"..route_bridge
|
||||
end
|
||||
|
||||
--add a delimiter between destinations
|
||||
if (dial_string ~= nil) then
|
||||
--freeswitch.consoleLog("notice", "[ring group] dial_string: " .. dial_string .. "\n");
|
||||
if (x == 1) then
|
||||
if (ring_group_strategy == "enterprise") then
|
||||
app_data = dial_string;
|
||||
else
|
||||
app_data = "{ignore_early_media=true}"..dial_string;
|
||||
end
|
||||
--leg delay settings
|
||||
if (ring_group_strategy == "enterprise") then
|
||||
delay_name = "originate_delay_start";
|
||||
destination_delay = destination_delay * 500;
|
||||
else
|
||||
if (app_data == nil) then
|
||||
delay_name = "leg_delay_start";
|
||||
end
|
||||
|
||||
--create a new uuid and add it to the uuid list
|
||||
new_uuid = api:executeString("create_uuid");
|
||||
if (string.len(uuids) == 0) then
|
||||
uuids = new_uuid;
|
||||
else
|
||||
uuids = uuids ..",".. new_uuid;
|
||||
end
|
||||
session:execute("set", "uuids="..uuids);
|
||||
|
||||
--export the ringback
|
||||
if (ring_group_distinctive_ring ~= nil) then
|
||||
if (local_ip_v4 ~= nil) then
|
||||
ring_group_distinctive_ring = ring_group_distinctive_ring:gsub("${local_ip_v4}", local_ip_v4);
|
||||
end
|
||||
if (domain_name ~= nil) then
|
||||
ring_group_distinctive_ring = ring_group_distinctive_ring:gsub("${domain_name}", domain_name);
|
||||
end
|
||||
session:execute("export", "sip_h_Alert-Info="..ring_group_distinctive_ring);
|
||||
end
|
||||
|
||||
--set confirm
|
||||
if (ring_group_strategy == "simultaneous"
|
||||
or ring_group_strategy == "sequence"
|
||||
or ring_group_strategy == "rollover") then
|
||||
session:execute("set", "group_confirm_key=exec");
|
||||
session:execute("set", "group_confirm_file=lua ".. scripts_dir:gsub('\\','/') .."/confirm.lua");
|
||||
end
|
||||
|
||||
--determine confirm prompt
|
||||
if (destination_prompt == nil) then
|
||||
group_confirm = "confirm=false,";
|
||||
elseif (destination_prompt == "1") then
|
||||
group_confirm = "group_confirm_key=exec,group_confirm_file=lua ".. scripts_dir:gsub('\\','/') .."/confirm.lua,confirm=true,";
|
||||
elseif (destination_prompt == "2") then
|
||||
group_confirm = "group_confirm_key=exec,group_confirm_file=lua ".. scripts_dir:gsub('\\','/') .."/confirm.lua,confirm=true,";
|
||||
else
|
||||
group_confirm = "confirm=false,";
|
||||
end
|
||||
|
||||
--get user_record value and determine whether to record the session
|
||||
cmd = "user_data ".. destination_number .."@"..domain_name.." var user_record";
|
||||
user_record = trim(api:executeString(cmd));
|
||||
--set the record_session variable
|
||||
record_session = false;
|
||||
if (user_record == "all") then
|
||||
record_session = true;
|
||||
end
|
||||
if (user_record == "inbound" and call_direction == "inbound") then
|
||||
record_session = true;
|
||||
end
|
||||
if (user_record == "outbound" and call_direction == "outbound") then
|
||||
record_session = true;
|
||||
end
|
||||
if (user_record == "local" and call_direction == "local") then
|
||||
record_session = true;
|
||||
end
|
||||
|
||||
--record the session
|
||||
if (record_session) then
|
||||
record_session = ",api_on_answer='uuid_record "..uuid.." start ".. record_path .. "/" .. record_name .. "',record_path='".. record_path .."',record_name="..record_name;
|
||||
else
|
||||
record_session = ""
|
||||
end
|
||||
row.record_session = record_session
|
||||
|
||||
--process according to user_exists, sip_uri, external number
|
||||
if (user_exists == "true") then
|
||||
--get the extension_uuid
|
||||
cmd = "user_data ".. destination_number .."@"..domain_name.." var extension_uuid";
|
||||
extension_uuid = trim(api:executeString(cmd));
|
||||
--send to user
|
||||
local dial_string_to_user = "[sip_invite_domain="..domain_name..",call_direction="..call_direction..","..group_confirm.."leg_timeout="..destination_timeout..","..delay_name.."="..destination_delay..",dialed_extension=" .. row.destination_number .. ",extension_uuid="..extension_uuid .. row.record_session .. "]user/" .. row.destination_number .. "@" .. domain_name;
|
||||
dial_string = dial_string_to_user;
|
||||
elseif (tonumber(destination_number) == nil) then
|
||||
--sip uri
|
||||
dial_string = "[sip_invite_domain="..domain_name..",call_direction="..call_direction..","..group_confirm.."leg_timeout="..destination_timeout..","..delay_name.."="..destination_delay.."]" .. row.destination_number;
|
||||
else
|
||||
--external number
|
||||
-- have to double destination_delay here due a FS bug requiring a 50% delay value for internal externsions, but not external calls.
|
||||
destination_delay = destination_delay * 2;
|
||||
|
||||
route_bridge = 'loopback/'..destination_number;
|
||||
if (extension_toll_allow ~= nil) then
|
||||
toll_allow = extension_toll_allow:gsub(",", ":");
|
||||
end
|
||||
|
||||
--set the toll allow to an empty string
|
||||
if (toll_allow == nil) then
|
||||
toll_allow = '';
|
||||
end
|
||||
|
||||
--check if the user exists
|
||||
if tonumber(caller_id_number) ~= nil then
|
||||
cmd = "user_exists id ".. caller_id_number .." "..domain_name;
|
||||
caller_is_local = api:executeString(cmd);
|
||||
end
|
||||
|
||||
--set the caller id
|
||||
caller_id = '';
|
||||
|
||||
--set the outbound caller id
|
||||
if (caller_is_local == 'true' and outbound_caller_id_name ~= nil) then
|
||||
caller_id = ",origination_caller_id_name='"..outbound_caller_id_name.."'";
|
||||
end
|
||||
if (caller_is_local == 'true' and outbound_caller_id_number ~= nil) then
|
||||
caller_id = caller_id .. ",origination_caller_id_number='"..outbound_caller_id_number.."'";
|
||||
end
|
||||
if (ring_group_caller_id_name ~= nil and ring_group_caller_id_name ~= '') then
|
||||
caller_id = ",origination_caller_id_name='"..ring_group_caller_id_name.."'";
|
||||
end
|
||||
if (ring_group_caller_id_number ~= nil and ring_group_caller_id_number ~= '') then
|
||||
caller_id = caller_id .. ",origination_caller_id_number="..ring_group_caller_id_number..",";
|
||||
end
|
||||
|
||||
--set the destination dial string
|
||||
dial_string = "[ignore_early_media=true,toll_allow=".. toll_allow ..",".. caller_id .."sip_invite_domain="..domain_name..",call_direction="..call_direction..","..group_confirm.."leg_timeout="..destination_timeout..","..delay_name.."="..destination_delay.."]"..route_bridge
|
||||
end
|
||||
|
||||
--add a delimiter between destinations
|
||||
if (dial_string ~= nil) then
|
||||
--freeswitch.consoleLog("notice", "[ring group] dial_string: " .. dial_string .. "\n");
|
||||
if (x == 1) then
|
||||
if (ring_group_strategy == "enterprise") then
|
||||
app_data = dial_string;
|
||||
else
|
||||
app_data = "{ignore_early_media=true}"..dial_string;
|
||||
end
|
||||
else
|
||||
app_data = app_data .. delimiter .. dial_string;
|
||||
if (app_data == nil) then
|
||||
if (ring_group_strategy == "enterprise") then
|
||||
app_data = dial_string;
|
||||
else
|
||||
app_data = "{ignore_early_media=true}"..dial_string;
|
||||
end
|
||||
else
|
||||
app_data = app_data .. delimiter .. dial_string;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--increment the value of x
|
||||
x = x + 1;
|
||||
--increment the value of x
|
||||
x = x + 1;
|
||||
end
|
||||
end
|
||||
|
||||
--session execute
|
||||
|
|
|
|||
Loading…
Reference in New Issue