mirror of
https://github.com/fusionpbx/fusionpbx.git
synced 2026-02-22 19:06:37 +00:00
Move the includes/install to resources/install
This commit is contained in:
49
resources/install/scripts/app.lua
Normal file
49
resources/install/scripts/app.lua
Normal file
@@ -0,0 +1,49 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--get the argv values
|
||||
script_name = argv[0];
|
||||
app_name = argv[1];
|
||||
|
||||
--example use command
|
||||
--luarun app.lua name 'a' 'b 123' 'c'
|
||||
|
||||
--for loop through arguments
|
||||
arguments = "";
|
||||
for key,value in pairs(argv) do
|
||||
if (key > 1) then
|
||||
arguments = arguments .. " '" .. value .. "'";
|
||||
freeswitch.consoleLog("notice", "[voicemail] argv["..key.."]: " .. argv[key] .. "\n");
|
||||
end
|
||||
end
|
||||
|
||||
--route the request to the application
|
||||
--freeswitch.consoleLog("notice", "[app] lua route: ".. scripts_dir .. "/app/" .. app_name .. "/index.lua" .. arguments .."\n");
|
||||
dofile(scripts_dir .. "/app/" .. app_name .. "/index.lua" .. arguments);
|
||||
630
resources/install/scripts/app/conference_center/index.lua
Normal file
630
resources/install/scripts/app/conference_center/index.lua
Normal file
@@ -0,0 +1,630 @@
|
||||
-- conference.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set variables
|
||||
flags = "";
|
||||
max_tries = 3;
|
||||
digit_timeout = 5000;
|
||||
|
||||
--debug
|
||||
debug["sql"] = true;
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--prepare the api object
|
||||
api = freeswitch.API();
|
||||
|
||||
--general functions
|
||||
dofile(scripts_dir.."/resources/functions/base64.lua");
|
||||
dofile(scripts_dir.."/resources/functions/trim.lua");
|
||||
dofile(scripts_dir.."/resources/functions/file_exists.lua");
|
||||
dofile(scripts_dir.."/resources/functions/explode.lua");
|
||||
dofile(scripts_dir.."/resources/functions/format_seconds.lua");
|
||||
dofile(scripts_dir.."/resources/functions/mkdir.lua");
|
||||
|
||||
--get the session variables
|
||||
uuid = session:getVariable("uuid");
|
||||
|
||||
--answer the call
|
||||
session:answer();
|
||||
|
||||
--define a function to send email
|
||||
function send_email(email, attachment, default_language, default_dialect)
|
||||
|
||||
--require the email address to send the email
|
||||
if (string.len(email) > 2) then
|
||||
|
||||
--format the message length and date
|
||||
--message_length_formatted = format_seconds(message_length);
|
||||
--if (debug["info"]) then
|
||||
-- freeswitch.consoleLog("notice", "[conference_center] message length: " .. message_length .. "\n");
|
||||
--end
|
||||
local conference_date_end = os.date("%A, %d %b %Y %I:%M %p");
|
||||
--os.time();
|
||||
|
||||
--prepare the files
|
||||
file_subject = scripts_dir.."/app/conference_center/resources/templates/"..default_language.."/"..default_dialect.."email_subject.tpl";
|
||||
file_body = scripts_dir.."/app/conference_center/resources/templates/"..default_language.."/"..default_dialect.."/email_body.tpl";
|
||||
if (not file_exists(file_subject)) then
|
||||
file_subject = scripts_dir.."/app/conference_center/resources/templates/en/us/email_subject.tpl";
|
||||
file_body = scripts_dir.."/app/conference_center/resources/templates/en/us/email_body.tpl";
|
||||
end
|
||||
|
||||
--get the moderator_pin
|
||||
sql = [[SELECT moderator_pin FROM v_meetings
|
||||
WHERE meeting_uuid = ']] .. meeting_uuid ..[[']];
|
||||
freeswitch.consoleLog("notice", "[voicemail] sql: " .. sql .. "\n");
|
||||
status = dbh:query(sql, function(row)
|
||||
moderator_pin = string.lower(row["moderator_pin"]);
|
||||
end);
|
||||
|
||||
--prepare the subject
|
||||
local f = io.open(file_subject, "r");
|
||||
local subject = f:read("*all");
|
||||
f:close();
|
||||
subject = subject:gsub("${moderator_pin}", moderator_pin);
|
||||
subject = subject:gsub("${conference_date_end}", conference_date_end);
|
||||
--subject = subject:gsub("${conference_duration}", message_length_formatted);
|
||||
subject = subject:gsub("${domain_name}", domain_name);
|
||||
subject = trim(subject);
|
||||
subject = '=?utf-8?B?'..base64.enc(subject)..'?=';
|
||||
|
||||
--prepare the body
|
||||
local f = io.open(file_body, "r");
|
||||
local body = f:read("*all");
|
||||
f:close();
|
||||
body = body:gsub("${moderator_pin}", moderator_pin);
|
||||
body = body:gsub("${conference_date_end}", conference_date_end);
|
||||
body = body:gsub("${conference_uuid}", conference_session_uuid);
|
||||
--body = body:gsub("${conference_duration}", message_length_formatted);
|
||||
body = body:gsub("${domain_name}", domain_name);
|
||||
body = body:gsub(" ", " ");
|
||||
body = body:gsub("%s+", "");
|
||||
body = body:gsub(" ", " ");
|
||||
body = body:gsub("\n", "");
|
||||
body = body:gsub("\n", "");
|
||||
body = body:gsub("'", "'");
|
||||
body = body:gsub([["]], """);
|
||||
body = trim(body);
|
||||
|
||||
--send the email
|
||||
if (string.len(attachment) > 4) then
|
||||
cmd = "luarun email.lua "..email.." "..email.." '"..subject.."' '"..body.."' '"..attachment.."'";
|
||||
else
|
||||
cmd = "luarun email.lua "..email.." "..email.." '"..subject.."' '"..body.."'";
|
||||
end
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] cmd: " .. cmd .. "\n");
|
||||
end
|
||||
result = api:executeString(cmd);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--define the session hangup
|
||||
function session_hangup_hook()
|
||||
|
||||
--get the session variables
|
||||
conference_session_detail_uuid = api:executeString("create_uuid");
|
||||
--conference_name = session:getVariable("conference_name");
|
||||
conference_session_uuid = session:getVariable("conference_uuid");
|
||||
--conference_recording = session:getVariable("conference_recording");
|
||||
conference_moderator = session:getVariable("conference_moderator");
|
||||
default_language = session:getVariable("default_language");
|
||||
default_dialect = session:getVariable("default_dialect");
|
||||
--recording = session:getVariable("recording");
|
||||
|
||||
--set the end epoch
|
||||
end_epoch = os.time();
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--get the conference sessions
|
||||
if (conference_session_uuid) then
|
||||
sql = [[SELECT count(*) as num_rows
|
||||
FROM v_conference_sessions
|
||||
WHERE conference_session_uuid = ']] .. conference_session_uuid ..[[']];
|
||||
status = dbh:query(sql, function(row)
|
||||
num_rows = string.lower(row["num_rows"]);
|
||||
end);
|
||||
freeswitch.consoleLog("notice", "[conference] SQL: " .. sql .. " Rows:"..num_rows.."\n");
|
||||
if (tonumber(num_rows) == 0) then
|
||||
local sql = {}
|
||||
table.insert(sql, "INSERT INTO v_conference_sessions ");
|
||||
table.insert(sql, "(");
|
||||
table.insert(sql, "conference_session_uuid, ");
|
||||
table.insert(sql, "domain_uuid, ");
|
||||
table.insert(sql, "meeting_uuid, ");
|
||||
--if (conference_recording) then
|
||||
-- table.insert(sql, "recording, ");
|
||||
--end
|
||||
--if (wait_mod) then
|
||||
-- table.insert(sql, "wait_mod, ");
|
||||
--end
|
||||
--table.insert(sql, "start_epoch, ");
|
||||
table.insert(sql, "profile ");
|
||||
table.insert(sql, ") ");
|
||||
table.insert(sql, "VALUES ");
|
||||
table.insert(sql, "( ");
|
||||
table.insert(sql, "'".. conference_session_uuid .."', ");
|
||||
table.insert(sql, "'".. domain_uuid .."', ");
|
||||
table.insert(sql, "'".. meeting_uuid .."', ");
|
||||
--if (conference_recording) then
|
||||
-- table.insert(sql, "'".. conference_recording .."', ");
|
||||
--end
|
||||
--if (wait_mod) then
|
||||
-- table.insert(sql, "'".. wait_mod .."', ");
|
||||
--end
|
||||
--table.insert(sql, "'".. start_epoch .."', ");
|
||||
table.insert(sql, "'".. profile .."' ");
|
||||
table.insert(sql, ") ");
|
||||
SQL_STRING = table.concat(sql, "\n");
|
||||
dbh:query(SQL_STRING);
|
||||
freeswitch.consoleLog("notice", "[conference] SQL: " .. SQL_STRING .. "\n");
|
||||
end
|
||||
end
|
||||
|
||||
--add the conference sessions details
|
||||
if (conference_session_uuid) then
|
||||
local sql = {}
|
||||
table.insert(sql, "INSERT INTO v_conference_session_details ");
|
||||
table.insert(sql, "(");
|
||||
table.insert(sql, "conference_session_detail_uuid, ");
|
||||
table.insert(sql, "domain_uuid, ");
|
||||
table.insert(sql, "conference_session_uuid, ");
|
||||
table.insert(sql, "meeting_uuid, ");
|
||||
table.insert(sql, "username, ");
|
||||
table.insert(sql, "caller_id_name, ");
|
||||
table.insert(sql, "caller_id_number, ");
|
||||
table.insert(sql, "network_addr, ");
|
||||
table.insert(sql, "uuid, ");
|
||||
if (conference_moderator) then
|
||||
table.insert(sql, "moderator, ");
|
||||
end
|
||||
table.insert(sql, "start_epoch, ");
|
||||
table.insert(sql, "end_epoch ");
|
||||
table.insert(sql, ") ");
|
||||
table.insert(sql, "VALUES ");
|
||||
table.insert(sql, "( ");
|
||||
table.insert(sql, "'".. conference_session_detail_uuid .."', ");
|
||||
table.insert(sql, "'".. domain_uuid .."', ");
|
||||
table.insert(sql, "'".. conference_session_uuid .."', ");
|
||||
table.insert(sql, "'".. meeting_uuid .."', ");
|
||||
table.insert(sql, "'".. username .."', ");
|
||||
table.insert(sql, "'".. caller_id_name .."', ");
|
||||
table.insert(sql, "'".. caller_id_number .."', ");
|
||||
table.insert(sql, "'".. network_addr .."', ");
|
||||
table.insert(sql, "'".. uuid .."', ");
|
||||
if (conference_moderator) then
|
||||
table.insert(sql, "'".. conference_moderator .."', ");
|
||||
end
|
||||
table.insert(sql, "'".. start_epoch .."', ");
|
||||
table.insert(sql, "'".. end_epoch .."' ");
|
||||
table.insert(sql, ") ");
|
||||
SQL_STRING = table.concat(sql, "\n");
|
||||
dbh:query(SQL_STRING);
|
||||
end
|
||||
|
||||
--if the conference is empty
|
||||
if (conference_session_uuid) then
|
||||
cmd = "conference "..meeting_uuid.."-"..domain_name.." xml_list";
|
||||
result = trim(api:executeString(cmd));
|
||||
if (string.sub(result, -9) == "not found") then
|
||||
--get the conference start_epoch
|
||||
sql = [[SELECT start_epoch
|
||||
FROM v_conference_session_details
|
||||
WHERE conference_session_uuid = ']] .. conference_session_uuid ..[['
|
||||
ORDER BY start_epoch ASC
|
||||
LIMIT 1]];
|
||||
status = dbh:query(sql, function(row)
|
||||
start_epoch = string.lower(row["start_epoch"]);
|
||||
end);
|
||||
freeswitch.consoleLog("notice", "[conference] <conference_start_epoch> sql: " .. sql .. "\n");
|
||||
|
||||
--set the conference_recording
|
||||
conference_recording = recordings_dir.."/archive/"..os.date("%Y", start_epoch).."/"..os.date("%b", start_epoch).."/"..os.date("%d", start_epoch) .."/"..conference_session_uuid;
|
||||
|
||||
--conference has ended set the end_epoch
|
||||
local sql = {}
|
||||
table.insert(sql, "update v_conference_sessions set ");
|
||||
table.insert(sql, "recording = '".. conference_recording .."', ");
|
||||
table.insert(sql, "start_epoch = '".. start_epoch .."', ");
|
||||
table.insert(sql, "end_epoch = '".. end_epoch .."' ");
|
||||
table.insert(sql, "where conference_session_uuid = '"..conference_session_uuid.."' ");
|
||||
SQL_STRING = table.concat(sql, "\n");
|
||||
freeswitch.consoleLog("notice", "[conference] SQL: " .. SQL_STRING .. "\n");
|
||||
dbh:query(SQL_STRING);
|
||||
--convert the wav to an mp3
|
||||
if (record == "true") then
|
||||
--cmd = "sox "..conference_recording..".wav -r 16000 -c 1 "..conference_recording..".mp3";
|
||||
cmd = "/usr/bin/lame -b 32 --resample 8 -a "..conference_recording..".wav "..conference_recording..".mp3";
|
||||
freeswitch.consoleLog("notice", "[conference] cmd: " .. cmd .. "\n");
|
||||
os.execute(cmd);
|
||||
--if (file_exists(conference_recording..".mp3")) then
|
||||
-- cmd = "rm "..conference_recording..".wav";
|
||||
-- os.execute(cmd);
|
||||
--end
|
||||
end
|
||||
--send the email addresses
|
||||
sql = [[SELECT c.contact_email FROM v_users as u, v_meeting_users as m, v_contacts as c
|
||||
WHERE m.domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND u.user_uuid = m.user_uuid
|
||||
AND m.meeting_uuid = ']] .. meeting_uuid ..[['
|
||||
and u.contact_uuid = c.contact_uuid]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[conference] <email> SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
if (row["contact_email"] ~= nil) then
|
||||
contact_email = string.lower(row["contact_email"]);
|
||||
if (string.len(contact_email) > 3) then
|
||||
freeswitch.consoleLog("notice", "[conference] contact_email: " .. contact_email .. "\n");
|
||||
if (record == "true") then
|
||||
if (file_exists(conference_recording..".wav")) then
|
||||
send_email(contact_email, "", default_language, default_dialect);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end);
|
||||
end
|
||||
end
|
||||
|
||||
--close the database connection
|
||||
if (conference_session_uuid) then
|
||||
dbh:release();
|
||||
end
|
||||
end
|
||||
|
||||
--make sure the session is ready
|
||||
if (session:ready()) then
|
||||
--answer the call
|
||||
session:answer();
|
||||
|
||||
--set the hangup hook function
|
||||
session:setHangupHook("session_hangup_hook");
|
||||
|
||||
--get session variables
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
hold_music = session:getVariable("hold_music");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
pin_number = session:getVariable("pin_number");
|
||||
|
||||
--get the domain_uuid
|
||||
if (domain_name ~= nil) then
|
||||
sql = "SELECT domain_uuid FROM v_domains ";
|
||||
sql = sql .. "WHERE domain_name = '" .. domain_name .."' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[conference] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(rows)
|
||||
domain_uuid = string.lower(rows["domain_uuid"]);
|
||||
end);
|
||||
end
|
||||
|
||||
--add the domain to the recording directory
|
||||
if (domain_count > 1) then
|
||||
recordings_dir = recordings_dir.."/"..domain_name;
|
||||
end
|
||||
|
||||
--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
|
||||
|
||||
--sounds
|
||||
enter_sound = "tone_stream://v=-20;%(100,1000,100);v=-20;%(90,60,440);%(90,60,620)";
|
||||
exit_sound = "tone_stream://v=-20;%(90,60,620);/%(90,60,440)";
|
||||
|
||||
--get the variables
|
||||
username = session:getVariable("username");
|
||||
caller_id_name = session:getVariable("caller_id_name");
|
||||
caller_id_number = session:getVariable("caller_id_number");
|
||||
callee_id_name = session:getVariable("callee_id_name");
|
||||
callee_id_number = session:getVariable("callee_id_number");
|
||||
dialplan = session:getVariable("dialplan");
|
||||
network_addr = session:getVariable("network_addr");
|
||||
uuid = session:getVariable("uuid");
|
||||
--context = session:getVariable("context");
|
||||
chan_name = session:getVariable("chan_name");
|
||||
|
||||
--define the function get_pin_number
|
||||
function get_pin_number(domain_uuid)
|
||||
--if the pin number is provided then require it
|
||||
if (not pin_number) then
|
||||
min_digits = 3;
|
||||
max_digits = 12;
|
||||
max_tries = 1;
|
||||
digit_timeout = 5000;
|
||||
pin_number = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/conference/conf-pin.wav", "", "\\d+");
|
||||
end
|
||||
if (pin_number ~= "") then
|
||||
sql = [[SELECT * FROM v_conference_rooms as r, v_meetings as m
|
||||
WHERE r.domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND r.meeting_uuid = m.meeting_uuid
|
||||
AND m.domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND (m.moderator_pin = ']] .. pin_number ..[[' or m.participant_pin = ']] .. pin_number ..[[')
|
||||
AND r.enabled = 'true' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[conference] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
conference_room_uuid = string.lower(row["conference_room_uuid"]);
|
||||
end);
|
||||
end
|
||||
if (conference_room_uuid == nil) then
|
||||
return nil;
|
||||
else
|
||||
return pin_number;
|
||||
end
|
||||
end
|
||||
|
||||
--get the pin
|
||||
pin_number = session:getVariable("pin_number");
|
||||
if (not pin_number) then
|
||||
pin_number = nil;
|
||||
pin_number = get_pin_number(domain_uuid);
|
||||
end
|
||||
if (pin_number == nil) then
|
||||
pin_number = get_pin_number(domain_uuid);
|
||||
end
|
||||
if (pin_number == nil) then
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/conference/conf-bad-pin.wav");
|
||||
pin_number = get_pin_number(domain_uuid);
|
||||
end
|
||||
if (pin_number == nil) then
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/conference/conf-bad-pin.wav");
|
||||
pin_number = get_pin_number(domain_uuid);
|
||||
end
|
||||
if (pin_number ~= nil) then
|
||||
sql = [[SELECT * FROM v_conference_rooms as r, v_meetings as m
|
||||
WHERE r.domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND r.meeting_uuid = m.meeting_uuid
|
||||
AND m.domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND (m.moderator_pin = ']] .. pin_number ..[[' or m.participant_pin = ']] .. pin_number ..[[')
|
||||
AND r.enabled = 'true' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[conference] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
conference_room_uuid = string.lower(row["conference_room_uuid"]);
|
||||
conference_center_uuid = string.lower(row["conference_center_uuid"]);
|
||||
meeting_uuid = string.lower(row["meeting_uuid"]);
|
||||
record = string.lower(row["record"]);
|
||||
profile = string.lower(row["profile"]);
|
||||
max_members = row["max_members"];
|
||||
wait_mod = row["wait_mod"];
|
||||
moderator_pin = row["moderator_pin"];
|
||||
participant_pin = row["participant_pin"];
|
||||
announce = row["announce"];
|
||||
mute = row["mute"];
|
||||
sounds = row["sounds"];
|
||||
created = row["created"];
|
||||
created_by = row["created_by"];
|
||||
enabled = row["enabled"];
|
||||
description = row["description"];
|
||||
return pin_number;
|
||||
end);
|
||||
freeswitch.consoleLog("INFO","conference_room_uuid: " .. conference_room_uuid .. "\n");
|
||||
end
|
||||
|
||||
--set the member type
|
||||
if (pin_number == moderator_pin) then
|
||||
member_type = "moderator";
|
||||
end
|
||||
if (pin_number == participant_pin) then
|
||||
member_type = "participant";
|
||||
end
|
||||
|
||||
--close the database connection
|
||||
dbh:release();
|
||||
|
||||
--set the meeting uuid
|
||||
if (meeting_uuid) then
|
||||
session:setVariable("meeting_uuid", meeting_uuid);
|
||||
end
|
||||
|
||||
if (conference_center_uuid == nil) then
|
||||
--invalid pin number
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/conference/conf-bad-pin.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
else
|
||||
--check if the conference exists
|
||||
cmd = "conference "..meeting_uuid.."-"..domain_name.." xml_list";
|
||||
result = trim(api:executeString(cmd));
|
||||
if (string.sub(result, -9) == "not found") then
|
||||
conference_exists = false;
|
||||
else
|
||||
conference_exists = true;
|
||||
end
|
||||
|
||||
--check if the conference is locked
|
||||
if (string.find(result, [[locked="true"]]) == nil) then
|
||||
conference_locked = false;
|
||||
else
|
||||
conference_locked = true;
|
||||
end
|
||||
|
||||
--set a conference parameter
|
||||
if (max_members ~= nil) then
|
||||
if (tonumber(max_members) > 0) then
|
||||
--max members must be 2 or more
|
||||
session:execute("set","conference_max_members="..max_members);
|
||||
if (conference_exists) then
|
||||
cmd = "conference "..meeting_uuid.."-"..domain_name.." get count";
|
||||
count = trim(api:executeString(cmd));
|
||||
if (count ~= nil) then
|
||||
if (tonumber(count) >= tonumber(max_members)) then
|
||||
session:execute("playback", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/conference/conf-locked.wav");
|
||||
session:hangup("CALL_REJECTED");
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--announce the caller
|
||||
if (conference_locked) then
|
||||
announce = "false";
|
||||
end
|
||||
if (announce == "true") then
|
||||
--prompt for the name of the caller
|
||||
session:execute("playback", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-say_name.wav");
|
||||
session:execute("playback", "tone_stream://v=-7;%%(500,0,500.0)");
|
||||
--record the response
|
||||
max_len_seconds = 5;
|
||||
silence_threshold = "500";
|
||||
silence_secs = "3";
|
||||
session:recordFile("/tmp/conference-"..uuid..".wav", max_len_seconds, silence_threshold, silence_secs);
|
||||
end
|
||||
|
||||
--play a message that the conference is being a recorded
|
||||
--if (record == "true") then
|
||||
--session:execute("playback", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-recording_started.wav");
|
||||
--end
|
||||
|
||||
--wait for moderator
|
||||
if (wait_mod == "true") then
|
||||
if (conference_exists) then
|
||||
--continue
|
||||
else
|
||||
if (member_type == "participant") then
|
||||
profile = "wait_mod";
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--set the exit sound
|
||||
if (sounds == "true") then
|
||||
session:execute("set","conference_exit_sound="..exit_sound);
|
||||
end
|
||||
|
||||
--set flags and moderator controls
|
||||
if (wait_mod == "true") then
|
||||
if (member_type == "participant") then
|
||||
flags = flags .. "wait-mod";
|
||||
end
|
||||
end
|
||||
if (mute == "true") then
|
||||
if (member_type == "participant") then
|
||||
flags = flags .. "|mute";
|
||||
end
|
||||
end
|
||||
if (member_type == "moderator") then
|
||||
--set as the moderator
|
||||
flags = flags .. "|moderator";
|
||||
--when the moderator leaves end the conference
|
||||
--flags = flags .. "|endconf";
|
||||
--set the moderator controls
|
||||
session:execute("set","conference_controls=moderator");
|
||||
end
|
||||
|
||||
--get the conference xml_list
|
||||
cmd = "conference "..meeting_uuid.."-"..domain_name.." xml_list";
|
||||
freeswitch.consoleLog("INFO","" .. cmd .. "\n");
|
||||
result = trim(api:executeString(cmd));
|
||||
|
||||
--get the content to the <conference> tag
|
||||
result = string.match(result,[[<conference (.-)>]],1);
|
||||
|
||||
--get the uuid out of the xml tag contents
|
||||
if (result ~= nil) then
|
||||
conference_session_uuid = string.match(result,[[uuid="(.-)"]],1);
|
||||
end
|
||||
|
||||
--log entry
|
||||
if (conference_session_uuid ~= nil) then
|
||||
freeswitch.consoleLog("INFO","conference_session_uuid: " .. conference_session_uuid .. "\n");
|
||||
end
|
||||
|
||||
--set the start epoch
|
||||
start_epoch = os.time();
|
||||
|
||||
--set the recording variable
|
||||
if (conference_session_uuid ~= nil) then
|
||||
if (record == "true") then
|
||||
recordings_dir = recordings_dir.."/archive/"..os.date("%Y", start_epoch).."/"..os.date("%b", start_epoch).."/"..os.date("%d", start_epoch);
|
||||
mkdir(recordings_dir);
|
||||
recording = recordings_dir.."/"..conference_session_uuid;
|
||||
session:execute("set","recording="..recording);
|
||||
end
|
||||
end
|
||||
|
||||
--record the conference
|
||||
if (record == "true") then
|
||||
--play a message that the conference is being a recorded
|
||||
session:execute("playback", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-recording_started.wav");
|
||||
--play a message that the conference is being a recorded
|
||||
--cmd = "conference "..meeting_uuid.."-"..domain_name.." play "..sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-recording_started.wav";
|
||||
--freeswitch.consoleLog("notice", "[conference] ".. cmd .."\n");
|
||||
--response = api:executeString(cmd);
|
||||
--record the conference when it exists
|
||||
if (conference_exists) then
|
||||
--send a command to record the conference
|
||||
if (not file_exists(recording..".wav")) then
|
||||
cmd = "conference "..meeting_uuid.."-"..domain_name.." record "..recording..".wav";
|
||||
freeswitch.consoleLog("notice", "[conference] cmd: " .. cmd .. "\n");
|
||||
response = api:executeString(cmd);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--announce the caller
|
||||
if (announce == "true") then
|
||||
--announce the caller - play the recording
|
||||
cmd = "conference "..meeting_uuid.."-"..domain_name.." play /tmp/conference-"..uuid..".wav";
|
||||
freeswitch.consoleLog("notice", "[conference] ".. cmd .."\n");
|
||||
response = api:executeString(cmd);
|
||||
--play has entered the conference
|
||||
cmd = "conference "..meeting_uuid.."-"..domain_name.." play "..sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/conference/conf-has_joined.wav";
|
||||
freeswitch.consoleLog("notice", "[conference] ".. cmd .."\n");
|
||||
response = api:executeString(cmd);
|
||||
else
|
||||
if (not conference_locked) then
|
||||
if (sounds == "true") then
|
||||
cmd = "conference "..meeting_uuid.."-"..domain_name.." play "..enter_sound;
|
||||
response = api:executeString(cmd);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--close the database connection
|
||||
dbh:release();
|
||||
|
||||
--send the call to the conference
|
||||
profile = "default";
|
||||
cmd = meeting_uuid.."-"..domain_name.."@"..profile.."+flags{".. flags .."}";
|
||||
session:execute("conference", cmd);
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
<font face="arial">
|
||||
<p>The conference moderator pin is ${moderator_pin} and it ended on ${conference_date_end}.</p>
|
||||
<p>You can download your conference recording by clicking <a href='http://${domain_name}/app/conference_centers/conference_session_details.php?uuid=${conference_uuid}'>here</a>.</p>
|
||||
<hr noshade="noshade" size="1"/>
|
||||
Moderator PIN: ${moderator_pin}
|
||||
Ended: ${conference_date_end}<br/>
|
||||
</font>
|
||||
@@ -0,0 +1 @@
|
||||
New recording available for conference ${moderator_pin} ${conference_date_end}.
|
||||
328
resources/install/scripts/app/voicemail/index.lua
Normal file
328
resources/install/scripts/app/voicemail/index.lua
Normal file
@@ -0,0 +1,328 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set default values
|
||||
min_digits = 1;
|
||||
max_digits = 8;
|
||||
max_tries = 3;
|
||||
max_timeouts = 3;
|
||||
digit_timeout = 3000;
|
||||
|
||||
--direct dial
|
||||
direct_dial = {}
|
||||
direct_dial["enabled"] = "true";
|
||||
direct_dial["max_digits"] = 4;
|
||||
|
||||
--debug
|
||||
debug["info"] = false;
|
||||
debug["sql"] = false;
|
||||
|
||||
--get the argv values
|
||||
script_name = argv[0];
|
||||
voicemail_action = argv[1];
|
||||
|
||||
--starting values
|
||||
dtmf_digits = '';
|
||||
timeouts = 0;
|
||||
password_tries = 0;
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--set the api
|
||||
api = freeswitch.API();
|
||||
|
||||
--if the session exists
|
||||
if (session ~= nil) then
|
||||
--answer the session
|
||||
if (session:ready()) then
|
||||
session:answer();
|
||||
end
|
||||
|
||||
--unset bind meta app
|
||||
session:execute("unbind_meta_app", "");
|
||||
|
||||
--set the callback function
|
||||
if (session:ready()) then
|
||||
session:setVariable("playback_terminators", "#");
|
||||
session:setInputCallback("on_dtmf", "");
|
||||
end
|
||||
|
||||
--get session variables
|
||||
context = session:getVariable("context");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
uuid = session:getVariable("uuid");
|
||||
voicemail_id = session:getVariable("voicemail_id");
|
||||
voicemail_action = session:getVariable("voicemail_action");
|
||||
base_dir = session:getVariable("base_dir");
|
||||
destination_number = session:getVariable("destination_number");
|
||||
caller_id_name = session:getVariable("caller_id_name");
|
||||
caller_id_number = session:getVariable("caller_id_number");
|
||||
skip_instructions = session:getVariable("skip_instructions");
|
||||
skip_greeting = session:getVariable("skip_greeting");
|
||||
vm_message_ext = session:getVariable("vm_message_ext");
|
||||
if (not vm_message_ext) then vm_message_ext = 'wav'; end
|
||||
|
||||
--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
|
||||
|
||||
--get the domain_uuid
|
||||
domain_uuid = session:getVariable("domain_uuid");
|
||||
if (domain_count > 1) then
|
||||
if (domain_uuid == nil) then
|
||||
--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 .. "' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(rows)
|
||||
domain_uuid = rows["domain_uuid"];
|
||||
end);
|
||||
end
|
||||
end
|
||||
end
|
||||
if (domain_uuid ~= nil) then
|
||||
domain_uuid = string.lower(domain_uuid);
|
||||
end
|
||||
|
||||
--set the voicemail_dir
|
||||
voicemail_dir = base_dir.."/storage/voicemail/default/"..domain_name;
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] voicemail_dir: " .. voicemail_dir .. "\n");
|
||||
end
|
||||
|
||||
--get the voicemail settings
|
||||
if (voicemail_id ~= nil) then
|
||||
if (session:ready()) then
|
||||
--get the information from the database
|
||||
sql = [[SELECT * FROM v_voicemails
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_id = ']] .. voicemail_id ..[['
|
||||
AND voicemail_enabled = 'true' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
voicemail_uuid = string.lower(row["voicemail_uuid"]);
|
||||
voicemail_password = row["voicemail_password"];
|
||||
greeting_id = row["greeting_id"];
|
||||
voicemail_mail_to = row["voicemail_mail_to"];
|
||||
voicemail_attach_file = row["voicemail_attach_file"];
|
||||
voicemail_local_after_email = row["voicemail_local_after_email"];
|
||||
end);
|
||||
--set default values
|
||||
if (voicemail_local_after_email == nil) then
|
||||
voicemail_local_after_email = "true";
|
||||
end
|
||||
if (voicemail_attach_file == nil) then
|
||||
voicemail_attach_file = "true";
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--general functions
|
||||
dofile(scripts_dir.."/resources/functions/base64.lua");
|
||||
dofile(scripts_dir.."/resources/functions/trim.lua");
|
||||
dofile(scripts_dir.."/resources/functions/file_exists.lua");
|
||||
dofile(scripts_dir.."/resources/functions/explode.lua");
|
||||
dofile(scripts_dir.."/resources/functions/format_seconds.lua");
|
||||
dofile(scripts_dir.."/resources/functions/mkdir.lua");
|
||||
|
||||
--voicemail functions
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/on_dtmf.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/get_voicemail_id.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/check_password.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/change_password.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/macro.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/play_greeting.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/record_message.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/record_menu.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/forward_to_extension.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/main_menu.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/listen_to_recording.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/message_waiting.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/send_email.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/delete_recording.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/message_saved.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/return_call.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/menu_messages.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/advanced.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/record_greeting.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/choose_greeting.lua");
|
||||
dofile(scripts_dir.."/app/voicemail/resources/functions/record_name.lua");
|
||||
|
||||
--send a message waiting event
|
||||
if (voicemail_action == "mwi") then
|
||||
--get the mailbox info
|
||||
account = argv[2];
|
||||
array = explode("@", account);
|
||||
voicemail_id = array[1];
|
||||
domain_name = array[2];
|
||||
|
||||
--send information the console
|
||||
debug["info"] = "true";
|
||||
|
||||
--get voicemail message details
|
||||
sql = [[SELECT * FROM v_domains WHERE domain_name = ']] .. domain_name ..[[']]
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
domain_uuid = string.lower(row["domain_uuid"]);
|
||||
end);
|
||||
|
||||
--get the message count and send the mwi event
|
||||
message_waiting(voicemail_id, domain_uuid);
|
||||
end
|
||||
|
||||
--check messages
|
||||
if (voicemail_action == "check") then
|
||||
if (session:ready()) then
|
||||
--check the voicemail password
|
||||
check_password(voicemail_id, password_tries);
|
||||
--send to the main menu
|
||||
timeouts = 0;
|
||||
main_menu();
|
||||
end
|
||||
end
|
||||
|
||||
--leave a message
|
||||
if (voicemail_action == "save") then
|
||||
|
||||
--valid voicemail
|
||||
if (voicemail_uuid ~= nil) then
|
||||
|
||||
--save the recording
|
||||
timeouts = 0;
|
||||
play_greeting();
|
||||
record_message();
|
||||
|
||||
--save the message to the voicemail messages
|
||||
if (message_length > 2) then
|
||||
local sql = {}
|
||||
table.insert(sql, "INSERT INTO v_voicemail_messages ");
|
||||
table.insert(sql, "(");
|
||||
table.insert(sql, "voicemail_message_uuid, ");
|
||||
table.insert(sql, "domain_uuid, ");
|
||||
table.insert(sql, "voicemail_uuid, ");
|
||||
table.insert(sql, "created_epoch, ");
|
||||
table.insert(sql, "caller_id_name, ");
|
||||
table.insert(sql, "caller_id_number, ");
|
||||
table.insert(sql, "message_length ");
|
||||
--table.insert(sql, "message_status, ");
|
||||
--table.insert(sql, "message_priority, ");
|
||||
table.insert(sql, ") ");
|
||||
table.insert(sql, "VALUES ");
|
||||
table.insert(sql, "( ");
|
||||
table.insert(sql, "'".. uuid .."', ");
|
||||
table.insert(sql, "'".. domain_uuid .."', ");
|
||||
table.insert(sql, "'".. voicemail_uuid .."', ");
|
||||
table.insert(sql, "'".. start_epoch .."', ");
|
||||
table.insert(sql, "'".. caller_id_name .."', ");
|
||||
table.insert(sql, "'".. caller_id_number .."', ");
|
||||
table.insert(sql, "'".. message_length .."' ");
|
||||
--table.insert(sql, "'".. message_status .."', ");
|
||||
--table.insert(sql, "'".. message_priority .."' ");
|
||||
table.insert(sql, ") ");
|
||||
sql = table.concat(sql, "\n");
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
end
|
||||
|
||||
--set the message waiting event
|
||||
if (message_length > 2) then
|
||||
local event = freeswitch.Event("message_waiting");
|
||||
event:addHeader("MWI-Messages-Waiting", "yes");
|
||||
event:addHeader("MWI-Message-Account", "sip:"..voicemail_id.."@"..domain_name);
|
||||
event:fire();
|
||||
end
|
||||
|
||||
--send the email with the voicemail recording attached
|
||||
if (message_length > 2) then
|
||||
send_email(voicemail_id, uuid);
|
||||
end
|
||||
else
|
||||
--voicemail not enabled or does not exist
|
||||
referred_by = session:getVariable("sip_h_Referred-By");
|
||||
if (referred_by) then
|
||||
referred_by = referred_by:match('[%d]+');
|
||||
session:transfer(referred_by, "XML", context);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--close the database connection
|
||||
dbh:release();
|
||||
|
||||
--notes
|
||||
--record the video
|
||||
--records audio only
|
||||
--result = session:execute("set", "enable_file_write_buffering=false");
|
||||
--mkdir(voicemail_dir.."/"..voicemail_id);
|
||||
--session:recordFile("/tmp/recording.fsv", 200, 200, 200);
|
||||
--records audio and video
|
||||
--result = session:execute("record_fsv", "file.fsv");
|
||||
--freeswitch.consoleLog("notice", "[voicemail] SQL: " .. result .. "\n");
|
||||
|
||||
--play the video recording
|
||||
--plays the video
|
||||
--result = session:execute("play_fsv", "/tmp/recording.fsv");
|
||||
--plays the file but without the video
|
||||
--dtmf = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "/tmp/recording.fsv", "", "\\d+");
|
||||
--freeswitch.consoleLog("notice", "[voicemail] SQL: " .. result .. "\n");
|
||||
|
||||
--callback (works with DTMF)
|
||||
--http://wiki.freeswitch.org/wiki/Mod_fsv
|
||||
--mkdir(voicemail_dir.."/"..voicemail_id);
|
||||
--session:recordFile(file_name, max_len_secs, silence_threshold, silence_secs)
|
||||
--session:sayPhrase(macro_name [,macro_data] [,language]);
|
||||
--session:sayPhrase("voicemail_menu", "1:2:3:#", default_language);
|
||||
--session:streamFile("directory/dir-to_select_entry.wav"); --works with setInputCallback
|
||||
--session:streamFile("tone_stream://L=1;%(1000, 0, 640)");
|
||||
--session:say("12345", default_language, "number", "pronounced");
|
||||
|
||||
--speak
|
||||
--session:set_tts_parms("flite", "kal");
|
||||
--session:speak("Please say the name of the person you're trying to contact");
|
||||
|
||||
--callback (execute and executeString does not work with DTMF)
|
||||
--session:execute(api_string);
|
||||
--session:executeString("playback "..mySound);
|
||||
|
||||
--uuid_video_refresh
|
||||
--uuid_video_refresh,<uuid>,Send video refresh.,mod_commands
|
||||
--may be used to clear video buffer before using record_fsv
|
||||
@@ -0,0 +1,90 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define a function for the advanced menu
|
||||
function advanced ()
|
||||
--clear the dtmf
|
||||
dtmf_digits = '';
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
--To record a greeting press 1
|
||||
if (session:ready()) then
|
||||
dtmf_digits = macro(session, "to_record_greeting", 1, 100, '');
|
||||
end
|
||||
--To choose greeting press 2
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "choose_greeting", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--To record your name 3
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "to_record_name", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--To change your password press 6
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "change_password", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--For the main menu press 0
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "main_menu", 1, 5000, '');
|
||||
end
|
||||
end
|
||||
--process the dtmf
|
||||
if (session:ready()) then
|
||||
if (dtmf_digits == "1") then
|
||||
--To record a greeting press 1
|
||||
timeouts = 0;
|
||||
record_greeting();
|
||||
elseif (dtmf_digits == "2") then
|
||||
--To choose greeting press 2
|
||||
timeouts = 0;
|
||||
choose_greeting();
|
||||
elseif (dtmf_digits == "3") then
|
||||
--To record your name 3
|
||||
record_name();
|
||||
elseif (dtmf_digits == "6") then
|
||||
--To change your password press 6
|
||||
change_password(voicemail_id);
|
||||
elseif (dtmf_digits == "0") then
|
||||
--For the main menu press 0
|
||||
timeouts = 0;
|
||||
main_menu();
|
||||
else
|
||||
timeouts = timeouts + 1;
|
||||
if (timeouts <= max_timeouts) then
|
||||
advanced();
|
||||
else
|
||||
macro(session, "goodbye", 1, 1000, '');
|
||||
session:hangup();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--check the voicemail password
|
||||
function change_password(voicemail_id)
|
||||
if (session:ready()) then
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
--please enter your password followed by pound
|
||||
dtmf_digits = '';
|
||||
password = macro(session, "password_new", 20, 5000, '');
|
||||
--update the voicemail password
|
||||
sql = [[UPDATE v_voicemails
|
||||
set voicemail_password = ']] .. password ..[['
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_id = ']] .. voicemail_id ..[['
|
||||
AND voicemail_enabled = 'true' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
--has been changed to
|
||||
dtmf_digits = '';
|
||||
macro(session, "password_changed", 20, 3000, password);
|
||||
--advanced menu
|
||||
timeouts = 0;
|
||||
advanced();
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,85 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--check the voicemail password
|
||||
function check_password(voicemail_id, password_tries)
|
||||
if (session:ready()) then
|
||||
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
|
||||
--please enter your id followed by pound
|
||||
if (voicemail_id) then
|
||||
--do nothing
|
||||
else
|
||||
timeouts = 0;
|
||||
voicemail_id = get_voicemail_id();
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] voicemail id: " .. voicemail_id .. "\n");
|
||||
end
|
||||
end
|
||||
|
||||
--get the voicemail settings from the database
|
||||
if (voicemail_id) then
|
||||
if (session:ready()) then
|
||||
sql = [[SELECT * FROM v_voicemails
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_id = ']] .. voicemail_id ..[['
|
||||
AND voicemail_enabled = 'true' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
voicemail_uuid = string.lower(row["voicemail_uuid"]);
|
||||
voicemail_password = row["voicemail_password"];
|
||||
greeting_id = row["greeting_id"];
|
||||
voicemail_mail_to = row["voicemail_mail_to"];
|
||||
voicemail_attach_file = row["voicemail_attach_file"];
|
||||
voicemail_local_after_email = row["voicemail_local_after_email"];
|
||||
end);
|
||||
end
|
||||
end
|
||||
--please enter your password followed by pound
|
||||
dtmf_digits = '';
|
||||
password = macro(session, "voicemail_password", 20, 5000, '');
|
||||
--freeswitch.consoleLog("notice", "[voicemail] password: " .. password .. "\n");
|
||||
--compare the password from the database with the password provided by the user
|
||||
if (voicemail_password ~= password) then
|
||||
--incorrect password
|
||||
dtmf_digits = '';
|
||||
macro(session, "password_not_valid", 1, 1000, '');
|
||||
if (session:ready()) then
|
||||
password_tries = password_tries + 1;
|
||||
if (password_tries < max_tries) then
|
||||
check_password(voicemail_id, password_tries);
|
||||
else
|
||||
macro(session, "goodbye", 1, 1000, '');
|
||||
session:hangup();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--dofile(scripts_dir.."/app/voicemail/resources/functions/check_password.lua");
|
||||
@@ -0,0 +1,110 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define a function to choose the greeting
|
||||
function choose_greeting()
|
||||
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
|
||||
--select the greeting
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
greeting_id = macro(session, "choose_greeting_choose", 1, 5000, '');
|
||||
end
|
||||
|
||||
--check to see if the greeting file exists
|
||||
if (greeting_id ~= "0") then
|
||||
if (not file_exists(voicemail_dir.."/"..voicemail_id.."/greeting_"..greeting_id..".wav")) then
|
||||
--invalid greeting_id file does not exist
|
||||
greeting_id = "invalid";
|
||||
end
|
||||
end
|
||||
|
||||
--validate the greeting_id
|
||||
if (greeting_id == "0"
|
||||
or greeting_id == "1"
|
||||
or greeting_id == "2"
|
||||
or greeting_id == "3"
|
||||
or greeting_id == "4"
|
||||
or greeting_id == "5"
|
||||
or greeting_id == "6"
|
||||
or greeting_id == "7"
|
||||
or greeting_id == "8"
|
||||
or greeting_id == "9") then
|
||||
|
||||
--valid greeting_id update the database
|
||||
if (session:ready()) then
|
||||
if (greeting_id == "0") then
|
||||
sql = [[UPDATE v_voicemails SET greeting_id = null ]];
|
||||
else
|
||||
sql = [[UPDATE v_voicemails SET greeting_id = ']]..greeting_id..[[' ]];
|
||||
end
|
||||
sql = sql ..[[WHERE domain_uuid = ']] .. domain_uuid ..[[' ]]
|
||||
sql = sql ..[[AND voicemail_uuid = ']] .. voicemail_uuid ..[[' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
end
|
||||
|
||||
--play the greeting
|
||||
if (session:ready()) then
|
||||
if (file_exists(voicemail_dir.."/"..voicemail_id.."/greeting_"..greeting_id..".wav")) then
|
||||
session:streamFile(voicemail_dir.."/"..voicemail_id.."/greeting_"..greeting_id..".wav");
|
||||
end
|
||||
end
|
||||
|
||||
--greeting selected
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
macro(session, "greeting_selected", 1, 100, greeting_id);
|
||||
end
|
||||
|
||||
--advanced menu
|
||||
if (session:ready()) then
|
||||
timeouts = 0;
|
||||
advanced();
|
||||
end
|
||||
else
|
||||
--invalid greeting_id
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
greeting_id = macro(session, "choose_greeting_fail", 1, 100, '');
|
||||
end
|
||||
|
||||
--send back to choose the greeting
|
||||
if (session:ready()) then
|
||||
timeouts = timeouts + 1;
|
||||
if (timeouts < max_timeouts) then
|
||||
choose_greeting();
|
||||
else
|
||||
timeouts = 0;
|
||||
advanced();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--delete the message
|
||||
function delete_recording(voicemail_id, uuid)
|
||||
--message deleted
|
||||
if (session ~= nil) then
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
macro(session, "message_deleted", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--get the voicemail_uuid
|
||||
sql = [[SELECT * FROM v_voicemails
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_id = ']] .. voicemail_id ..[[']];
|
||||
status = dbh:query(sql, function(row)
|
||||
db_voicemail_uuid = row["voicemail_uuid"];
|
||||
end);
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
--delete the file
|
||||
os.remove(voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext);
|
||||
--delete from the database
|
||||
sql = [[DELETE FROM v_voicemail_messages
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_uuid = ']] .. db_voicemail_uuid ..[['
|
||||
AND voicemail_message_uuid = ']] .. uuid ..[[']];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
--log to console
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail][deleted] message: " .. uuid .. "\n");
|
||||
end
|
||||
--clear the variable
|
||||
db_voicemail_uuid = '';
|
||||
end
|
||||
@@ -0,0 +1,133 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define a function to forward a message to an extension
|
||||
function forward_to_extension(voicemail_id, uuid)
|
||||
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
|
||||
--save the voicemail message
|
||||
message_saved(voicemail_id, uuid);
|
||||
|
||||
--request the forward_voicemail_id
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
forward_voicemail_id = macro(session, "forward_enter_extension", 20, 5000, '');
|
||||
if (session:ready()) then
|
||||
if (string.len(forward_voicemail_id) == 0) then
|
||||
dtmf_digits = '';
|
||||
forward_voicemail_id = macro(session, "forward_enter_extension", 20, 5000, '');
|
||||
end
|
||||
end
|
||||
end
|
||||
if (session:ready()) then
|
||||
if (string.len(forward_voicemail_id) == 0) then
|
||||
dtmf_digits = '';
|
||||
forward_voicemail_id = macro(session, "forward_enter_extension", 20, 5000, '');
|
||||
end
|
||||
end
|
||||
|
||||
--get voicemail message details
|
||||
if (session:ready()) then
|
||||
sql = [[SELECT * FROM v_voicemail_messages
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_uuid = ']] .. voicemail_uuid ..[['
|
||||
AND voicemail_message_uuid = ']] .. uuid ..[[']]
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
--get the values from the database
|
||||
created_epoch = row["created_epoch"];
|
||||
caller_id_name = row["caller_id_name"];
|
||||
caller_id_number = row["caller_id_number"];
|
||||
message_length = row["message_length"];
|
||||
message_status = row["message_status"];
|
||||
message_priority = row["message_priority"];
|
||||
end);
|
||||
end
|
||||
|
||||
--get the voicemail settings
|
||||
sql = [[SELECT * FROM v_voicemails
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_id = ']] .. forward_voicemail_id ..[['
|
||||
AND voicemail_enabled = 'true' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
forward_voicemail_uuid = string.lower(row["voicemail_uuid"]);
|
||||
forward_voicemail_mail_to = row["voicemail_mail_to"];
|
||||
forward_voicemail_attach_file = row["voicemail_attach_file"];
|
||||
forward_voicemail_local_after_email = row["voicemail_local_after_email"];
|
||||
end);
|
||||
|
||||
--save the message to the voicemail messages
|
||||
local sql = {}
|
||||
table.insert(sql, "INSERT INTO v_voicemail_messages ");
|
||||
table.insert(sql, "(");
|
||||
table.insert(sql, "voicemail_message_uuid, ");
|
||||
table.insert(sql, "domain_uuid, ");
|
||||
table.insert(sql, "voicemail_uuid, ");
|
||||
table.insert(sql, "created_epoch, ");
|
||||
table.insert(sql, "caller_id_name, ");
|
||||
table.insert(sql, "caller_id_number, ");
|
||||
table.insert(sql, "message_length ");
|
||||
--table.insert(sql, "message_status, ");
|
||||
--table.insert(sql, "message_priority, ");
|
||||
table.insert(sql, ") ");
|
||||
table.insert(sql, "VALUES ");
|
||||
table.insert(sql, "( ");
|
||||
table.insert(sql, "'".. uuid .."', ");
|
||||
table.insert(sql, "'".. domain_uuid .."', ");
|
||||
table.insert(sql, "'".. forward_voicemail_uuid .."', ");
|
||||
table.insert(sql, "'".. created_epoch .."', ");
|
||||
table.insert(sql, "'".. caller_id_name .."', ");
|
||||
table.insert(sql, "'".. caller_id_number .."', ");
|
||||
table.insert(sql, "'".. message_length .."' ");
|
||||
--table.insert(sql, "'".. message_status .."', ");
|
||||
--table.insert(sql, "'".. message_priority .."' ");
|
||||
table.insert(sql, ") ");
|
||||
sql = table.concat(sql, "\n");
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
|
||||
--set the message waiting event
|
||||
local event = freeswitch.Event("message_waiting");
|
||||
event:addHeader("MWI-Messages-Waiting", "yes");
|
||||
event:addHeader("MWI-Message-Account", "sip:"..forward_voicemail_id.."@"..domain_name);
|
||||
event:fire();
|
||||
|
||||
--if local after email is true then copy the recording file
|
||||
mkdir(voicemail_dir.."/"..forward_voicemail_id);
|
||||
os.execute("cp "..voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext.." "..voicemail_dir.."/"..forward_voicemail_id.."/msg_"..uuid.."."..vm_message_ext);
|
||||
|
||||
--send the email with the voicemail recording attached
|
||||
send_email(forward_voicemail_id, uuid);
|
||||
|
||||
end
|
||||
@@ -0,0 +1,43 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--get the voicemail id
|
||||
function get_voicemail_id()
|
||||
session:flushDigits();
|
||||
dtmf_digits = '';
|
||||
voicemail_id = macro(session, "voicemail_id", 20, 5000, '');
|
||||
if (string.len(voicemail_id) == 0) then
|
||||
if (session:ready()) then
|
||||
timeouts = timeouts + 1;
|
||||
if (timeouts < max_timeouts) then
|
||||
voicemail_id = get_voicemail_id();
|
||||
else
|
||||
macro(session, "goodbye", 1, 1000, '');
|
||||
session:hangup();
|
||||
end
|
||||
end
|
||||
end
|
||||
return voicemail_id;
|
||||
end
|
||||
@@ -0,0 +1,137 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define function to listen to the recording
|
||||
function listen_to_recording (message_number, uuid, created_epoch, caller_id_name, caller_id_number)
|
||||
|
||||
--set default values
|
||||
dtmf_digits = '';
|
||||
max_digits = 1;
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
--set the display
|
||||
if (session:ready()) then
|
||||
reply = api:executeString("uuid_display "..session:get_uuid().." "..caller_id_number);
|
||||
end
|
||||
--say the message number
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "message_number", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--say the number
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
session:say(message_number, default_language, "NUMBER", "pronounced");
|
||||
end
|
||||
end
|
||||
--say the message date
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
session:say(created_epoch, default_language, "CURRENT_DATE_TIME", "pronounced");
|
||||
end
|
||||
end
|
||||
--play the message
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
session:streamFile(voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext);
|
||||
session:streamFile("silence_stream://1000");
|
||||
end
|
||||
end
|
||||
--to listen to the recording press 1
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "listen_to_recording", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to save the recording press 2
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "save_recording", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to return the call now press 5
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "return_call", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to delete the recording press 7
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "delete_recording", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to forward this message press 8
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "to_forward_message", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to forward this recording to your email press 9
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "forward_to_email", 1, 3000, '');
|
||||
end
|
||||
end
|
||||
--wait for more digits
|
||||
--if (session:ready()) then
|
||||
-- if (string.len(dtmf_digits) == 0) then
|
||||
-- dtmf_digits = session:getDigits(max_digits, "#", 1, 3000);
|
||||
-- end
|
||||
--end
|
||||
--process the dtmf
|
||||
if (session:ready()) then
|
||||
if (dtmf_digits == "1") then
|
||||
listen_to_recording(message_number, uuid, created_epoch, caller_id_name, caller_id_number);
|
||||
elseif (dtmf_digits == "2") then
|
||||
message_saved(voicemail_id, uuid);
|
||||
macro(session, "message_saved", 1, 100, '');
|
||||
elseif (dtmf_digits == "5") then
|
||||
message_saved(voicemail_id, uuid);
|
||||
return_call(caller_id_number);
|
||||
elseif (dtmf_digits == "7") then
|
||||
delete_recording(voicemail_id, uuid);
|
||||
message_waiting(voicemail_id, domain_uuid);
|
||||
elseif (dtmf_digits == "8") then
|
||||
forward_to_extension(voicemail_id, uuid);
|
||||
dtmf_digits = '';
|
||||
macro(session, "message_saved", 1, 100, '');
|
||||
elseif (dtmf_digits == "9") then
|
||||
send_email(voicemail_id, uuid);
|
||||
dtmf_digits = '';
|
||||
macro(session, "emailed", 1, 100, '');
|
||||
elseif (dtmf_digits == "*") then
|
||||
timeouts = 0;
|
||||
main_menu();
|
||||
elseif (dtmf_digits == "0") then
|
||||
message_saved(voicemail_id, uuid);
|
||||
session:transfer("0", "XML", context);
|
||||
else
|
||||
message_saved(voicemail_id, uuid);
|
||||
macro(session, "message_saved", 1, 100, '');
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,319 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define the macro function
|
||||
function macro(session, name, max_digits, max_timeout, param)
|
||||
if (session:ready()) then
|
||||
--create an empty table
|
||||
actions = {}
|
||||
|
||||
--Please enter your id followed by
|
||||
if (name == "voicemail_id") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-enter_id.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/pound.wav"});
|
||||
end
|
||||
--Please enter your id followed by
|
||||
if (name == "voicemail_password") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-enter_pass.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/pound.wav"});
|
||||
end
|
||||
--the person at extension 101 is not available record your message at the tone press any key or stop talking to end the recording
|
||||
if (name == "person_not_available_record_message") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-person.wav"});
|
||||
--pronounce the voicemail_id
|
||||
table.insert(actions, {app="say.number.iterated",data=voicemail_id});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-not_available.wav"});
|
||||
end
|
||||
--record your message at the tone press any key or stop talking to end the recording
|
||||
if (name == "record_message") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-record_message.wav"});
|
||||
end
|
||||
--beep
|
||||
if (name == "record_beep") then
|
||||
table.insert(actions, {app="tone_stream",data="L=1;%(1000, 0, 640)"});
|
||||
end
|
||||
--to listen to the recording press 1
|
||||
if (name == "to_listen_to_recording") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-listen_to_recording.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/1.wav"});
|
||||
end
|
||||
--to save the recording press 2
|
||||
if (name == "to_save_recording") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-save_recording.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/2.wav"});
|
||||
end
|
||||
--to rerecord press 3
|
||||
if (name == "to_rerecord") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-rerecord.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/3.wav"});
|
||||
end
|
||||
--You have zero new messages
|
||||
if (name == "new_messages") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-you_have.wav"});
|
||||
table.insert(actions, {app="say.number.pronounced",data=param});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-new.wav"});
|
||||
if (param == "1") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-message.wav"});
|
||||
else
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-messages.wav"});
|
||||
end
|
||||
end
|
||||
--You have zero saved messages
|
||||
if (name == "saved_messages") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-you_have.wav"});
|
||||
table.insert(actions, {app="say.number.pronounced",data=param});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-saved.wav"});
|
||||
if (param == "1") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-message.wav"});
|
||||
else
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-messages.wav"});
|
||||
end
|
||||
end
|
||||
--To listen to new messages press 1
|
||||
if (name == "listen_to_new_messages") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-listen_new.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/1.wav"});
|
||||
end
|
||||
--To listen to saved messages press 2
|
||||
if (name == "listen_to_saved_messages") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-listen_saved.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/2.wav"});
|
||||
end
|
||||
|
||||
--For advanced options press 5
|
||||
if (name == "advanced") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-advanced.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/5.wav"});
|
||||
end
|
||||
--Advanced Options Menu
|
||||
--To record a greeting press 1
|
||||
if (name == "to_record_greeting") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-to_record_greeting.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/1.wav"});
|
||||
end
|
||||
--Choose a greeting between 1 and 9
|
||||
if (name == "choose_greeting_choose") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-choose_greeting_choose.wav"});
|
||||
end
|
||||
--Greeting invalid value
|
||||
if (name == "choose_greeting_fail") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-choose_greeting_fail.wav"});
|
||||
end
|
||||
--Record your greeting at the tone press any key or stop talking to end the recording
|
||||
if (name == "record_greeting") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-record_greeting.wav"});
|
||||
table.insert(actions, {app="tone_stream",data="L=1;%(1000, 0, 640)"});
|
||||
end
|
||||
--To choose greeting press 2
|
||||
if (name == "choose_greeting") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-choose_greeting.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/2.wav"});
|
||||
end
|
||||
--Greeting 1 selected
|
||||
if (name == "greeting_selected") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-greeting.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/"..param..".wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-selected.wav"});
|
||||
end
|
||||
|
||||
--To record your name 3
|
||||
if (name == "to_record_name") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-record_name2.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/3.wav"});
|
||||
end
|
||||
--At the tone please record your name press any key or stop talking to end the recording
|
||||
if (name == "record_name") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-record_name1.wav"});
|
||||
table.insert(actions, {app="tone_stream",data="L=1;%(1000, 0, 640)"});
|
||||
end
|
||||
--To change your password press 6
|
||||
if (name == "change_password") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-change_password.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/6.wav"});
|
||||
end
|
||||
--For the main menu press 0
|
||||
if (name == "main_menu") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-main_menu.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/0.wav"});
|
||||
end
|
||||
--To exit press *
|
||||
if (name == "to_exit_press") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-to_exit.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/star.wav"});
|
||||
end
|
||||
--Additional Macros
|
||||
--Please enter your new password then press the # key #
|
||||
if (name == "password_new") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-enter_new_pin.wav"});
|
||||
end
|
||||
--Has been changed to
|
||||
if (name == "password_changed") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-has_been_changed_to.wav"});
|
||||
table.insert(actions, {app="say.number.iterated",data=param});
|
||||
end
|
||||
--Login Incorrect
|
||||
--if (name == "password_not_valid") then
|
||||
-- table.insert(actions, {app="streamFile",data="voicemail/vm-password_not_valid.wav"});
|
||||
--end
|
||||
--Login Incorrect
|
||||
if (name == "password_not_valid") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-fail_auth.wav"});
|
||||
end
|
||||
--Too many failed attempts
|
||||
if (name == "too_many_failed_attempts") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-abort.wav"});
|
||||
end
|
||||
--Message number
|
||||
if (name == "message_number") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-message_number.wav"});
|
||||
end
|
||||
--To listen to the recording press 1
|
||||
if (name == "listen_to_recording") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-listen_to_recording.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/1.wav"});
|
||||
end
|
||||
--To save the recording press 2
|
||||
if (name == "save_recording") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-save_recording.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/2.wav"});
|
||||
end
|
||||
--To delete the recording press 7
|
||||
if (name == "delete_recording") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-delete_recording.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/7.wav"});
|
||||
end
|
||||
--Message deleted
|
||||
if (name == "message_deleted") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-message.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-deleted.wav"});
|
||||
end
|
||||
--To return the call now press 5
|
||||
if (name == "return_call") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-return_call.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/5.wav"});
|
||||
end
|
||||
--To forward this message press 8
|
||||
if (name == "to_forward_message") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-to_forward.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/8.wav"});
|
||||
end
|
||||
--Please enter the extension to forward this message to followed by #
|
||||
if (name == "forward_enter_extension") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-forward_enter_ext.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-followed_by_pound.wav"});
|
||||
end
|
||||
--To forward this recording to your email press 9
|
||||
if (name == "forward_to_email") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-forward_to_email.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-press.wav"});
|
||||
table.insert(actions, {app="streamFile",data="digits/9.wav"});
|
||||
end
|
||||
--Emailed
|
||||
if (name == "emailed") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-emailed.wav"});
|
||||
end
|
||||
--Please enter the extension to send this message to followed by #
|
||||
--if (name == "send_message_to_extension") then
|
||||
-- table.insert(actions, {app="streamFile",data="voicemail/vm-zzz.wav"});
|
||||
--end
|
||||
--Message saved
|
||||
if (name == "message_saved") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-message.wav"});
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-saved.wav"});
|
||||
end
|
||||
--Your recording is below the minimal acceptable length, please try again.
|
||||
if (name == "too_small") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-too-small.wav"});
|
||||
end
|
||||
--Goodbye
|
||||
if (name == "goodbye") then
|
||||
table.insert(actions, {app="streamFile",data="voicemail/vm-goodbye.wav"});
|
||||
end
|
||||
|
||||
--if actions table exists then process it
|
||||
if (actions) then
|
||||
--set default values
|
||||
tries = 1;
|
||||
timeout = 100;
|
||||
--loop through the action and data
|
||||
for key, row in pairs(actions) do
|
||||
--freeswitch.consoleLog("notice", "[voicemail] app: " .. row.app .. " data: " .. row.data .. "\n");
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
if (row.app == "streamFile") then
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/"..row.data);
|
||||
elseif (row.app == "playback") then
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/"..row.data);
|
||||
elseif (row.app == "tone_stream") then
|
||||
session:streamFile("tone_stream://"..row.data);
|
||||
elseif (row.app == "silence_stream") then
|
||||
session:streamFile("silence_stream://100"..row.data);
|
||||
elseif (row.app == "playAndGetDigits") then
|
||||
--playAndGetDigits <min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp> <digit_timeout>
|
||||
if (not file_exists(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/"..row.data)) then
|
||||
dtmf_digits = session:playAndGetDigits(min_digits, max_digits, tries, timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/"..row.data, "", "\\d+", max_timeout);
|
||||
else
|
||||
dtmf_digits = session:playAndGetDigits(min_digits, max_digits, tries, timeout, "#", row.data, "", "\\d+", max_timeout);
|
||||
end
|
||||
elseif (row.app == "say.number.pronounced") then
|
||||
session:say(row.data, default_language, "number", "pronounced");
|
||||
elseif (row.app == "say.number.iterated") then
|
||||
session:say(row.data, default_language, "number", "iterated");
|
||||
end
|
||||
session:streamFile("silence_stream://100");
|
||||
end --if
|
||||
end --session:ready
|
||||
end --for
|
||||
--get the remaining digits
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) < max_digits) then
|
||||
dtmf_digits = dtmf_digits .. session:getDigits(max_digits, "#", max_timeout);
|
||||
end
|
||||
end
|
||||
--return dtmf the digits
|
||||
return dtmf_digits;
|
||||
else
|
||||
--no dtmf digits to return
|
||||
return '';
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,115 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define function main menu
|
||||
function main_menu ()
|
||||
if (voicemail_uuid) then
|
||||
--clear the value
|
||||
dtmf_digits = '';
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
--new voicemail count
|
||||
if (session:ready()) then
|
||||
sql = [[SELECT count(*) as new_messages FROM v_voicemail_messages
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_uuid = ']] .. voicemail_uuid ..[['
|
||||
AND (message_status is null or message_status = '') ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
new_messages = row["new_messages"];
|
||||
end);
|
||||
dtmf_digits = macro(session, "new_messages", 1, 100, new_messages);
|
||||
end
|
||||
--saved voicemail count
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
sql = [[SELECT count(*) as saved_messages FROM v_voicemail_messages
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_uuid = ']] .. voicemail_uuid ..[['
|
||||
AND message_status = 'saved' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
saved_messages = row["saved_messages"];
|
||||
end);
|
||||
dtmf_digits = macro(session, "saved_messages", 1, 100, saved_messages);
|
||||
end
|
||||
end
|
||||
--to listen to new message
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "listen_to_new_messages", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to listen to saved message
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "listen_to_saved_messages", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--for advanced options
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "advanced", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to exit press #
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "to_exit_press", 1, 3000, '');
|
||||
end
|
||||
end
|
||||
--process the dtmf
|
||||
if (session:ready()) then
|
||||
if (dtmf_digits == "1") then
|
||||
menu_messages("new");
|
||||
elseif (dtmf_digits == "2") then
|
||||
menu_messages("saved");
|
||||
elseif (dtmf_digits == "5") then
|
||||
timeouts = 0;
|
||||
advanced();
|
||||
elseif (dtmf_digits == "0") then
|
||||
main_menu();
|
||||
elseif (dtmf_digits == "*") then
|
||||
dtmf_digits = '';
|
||||
macro(session, "goodbye", 1, 100, '');
|
||||
session:hangup();
|
||||
else
|
||||
if (session:ready()) then
|
||||
timeouts = timeouts + 1;
|
||||
if (timeouts < max_timeouts) then
|
||||
main_menu();
|
||||
else
|
||||
macro(session, "goodbye", 1, 1000, '');
|
||||
session:hangup();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,111 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define function for messages menu
|
||||
function menu_messages (message_status)
|
||||
|
||||
--set default values
|
||||
max_timeout = 2000;
|
||||
min_digits = 1;
|
||||
max_digits = 1;
|
||||
tries = 1;
|
||||
timeout = 2000;
|
||||
--clear the dtmf
|
||||
dtmf_digits = '';
|
||||
--flush dtmf digits from the input buffer
|
||||
--session:flushDigits();
|
||||
--set the message number
|
||||
message_number = 0;
|
||||
--message_status new,saved
|
||||
if (session:ready()) then
|
||||
if (voicemail_id ~= nil) then
|
||||
sql = [[SELECT * FROM v_voicemail_messages
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_uuid = ']] .. voicemail_uuid ..[[']]
|
||||
if (message_status == "new") then
|
||||
sql = sql .. [[AND (message_status is null or message_status = '') ]];
|
||||
elseif (message_status == "saved") then
|
||||
sql = sql .. [[AND message_status = 'saved' ]];
|
||||
end
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
--get the values from the database
|
||||
--row["voicemail_message_uuid"];
|
||||
--row["created_epoch"];
|
||||
--row["caller_id_name"];
|
||||
--row["caller_id_number"];
|
||||
--row["message_length"];
|
||||
--row["message_status"];
|
||||
--row["message_priority"];
|
||||
--increment the message count
|
||||
message_number = message_number + 1;
|
||||
--listen to the message
|
||||
if (session:ready()) then
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", message_number.." "..string.lower(row["voicemail_message_uuid"]).." "..row["created_epoch"]);
|
||||
end
|
||||
listen_to_recording(message_number, string.lower(row["voicemail_message_uuid"]), row["created_epoch"], row["caller_id_name"], row["caller_id_number"]);
|
||||
end
|
||||
end);
|
||||
end
|
||||
end
|
||||
|
||||
--voicemail count if zero new messages set the mwi to no
|
||||
if (session:ready()) then
|
||||
if (voicemail_id ~= nil) then
|
||||
sql = [[SELECT count(*) as new_messages FROM v_voicemail_messages
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_uuid = ']] .. voicemail_uuid ..[['
|
||||
AND (message_status is null or message_status = '') ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
--send the message waiting event
|
||||
local event = freeswitch.Event("message_waiting");
|
||||
if (row["new_messages"] == "0") then
|
||||
event:addHeader("MWI-Messages-Waiting", "no");
|
||||
else
|
||||
event:addHeader("MWI-Messages-Waiting", "yes");
|
||||
end
|
||||
event:addHeader("MWI-Message-Account", "sip:"..voicemail_id.."@"..domain_name);
|
||||
event:fire();
|
||||
end);
|
||||
end
|
||||
end
|
||||
|
||||
--set the display
|
||||
if (session:ready()) then
|
||||
reply = api:executeString("uuid_display "..session:get_uuid().." "..destination_number);
|
||||
end
|
||||
|
||||
--send back to the main menu
|
||||
if (session:ready()) then
|
||||
timeouts = 0;
|
||||
main_menu();
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--save the message
|
||||
function message_saved(voicemail_id, uuid)
|
||||
--clear the dtmf
|
||||
dtmf_digits = '';
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
--get the voicemail_uuid
|
||||
sql = [[SELECT * FROM v_voicemails
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_id = ']] .. voicemail_id ..[[']];
|
||||
status = dbh:query(sql, function(row)
|
||||
db_voicemail_uuid = row["voicemail_uuid"];
|
||||
end);
|
||||
--delete from the database
|
||||
sql = [[UPDATE v_voicemail_messages SET message_status = 'saved'
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_uuid = ']] .. db_voicemail_uuid ..[['
|
||||
AND voicemail_message_uuid = ']] .. uuid ..[[']];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
--log to console
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail][saved] id: " .. voicemail_id .. " message: "..uuid.."\n");
|
||||
end
|
||||
--check the message waiting status
|
||||
message_waiting(voicemail_id, domain_uuid);
|
||||
--clear the variable
|
||||
db_voicemail_uuid = '';
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--voicemail count if zero new messages set the mwi to no
|
||||
function message_waiting(voicemail_id, domain_uuid)
|
||||
sql = [[SELECT count(*) as message_count FROM v_voicemail_messages as m, v_voicemails as v
|
||||
WHERE v.domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND v.voicemail_uuid = m.voicemail_uuid
|
||||
AND v.voicemail_id = ']] .. voicemail_id ..[['
|
||||
AND (m.message_status is null or m.message_status = '') ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
--send the message waiting event
|
||||
local event = freeswitch.Event("message_waiting");
|
||||
if (row["message_count"] == "0") then
|
||||
--freeswitch.consoleLog("notice", "[voicemail] mailbox: "..voicemail_id.."@"..domain_name.." messages: " .. row["message_count"] .. " no messages\n");
|
||||
event:addHeader("MWI-Messages-Waiting", "no");
|
||||
else
|
||||
event:addHeader("MWI-Messages-Waiting", "yes");
|
||||
end
|
||||
event:addHeader("MWI-Message-Account", "sip:"..voicemail_id.."@"..domain_name);
|
||||
event:fire();
|
||||
--log to console
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] mailbox: "..voicemail_id.."@"..domain_name.." messages: " .. row["message_count"] .. " \n");
|
||||
end
|
||||
end);
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define on_dtmf call back function
|
||||
function on_dtmf(s, type, obj, arg)
|
||||
if (type == "dtmf") then
|
||||
freeswitch.console_log("info", "[voicemail] dtmf digit: " .. obj['digit'] .. ", duration: " .. obj['duration'] .. "\n");
|
||||
if (obj['digit'] == "#") then
|
||||
return 0;
|
||||
else
|
||||
dtmf_digits = dtmf_digits .. obj['digit'];
|
||||
if (debug["info"]) then
|
||||
freeswitch.console_log("info", "[voicemail] dtmf digits: " .. dtmf_digits .. ", length: ".. string.len(dtmf_digits) .." max_digits: " .. max_digits .. "\n");
|
||||
end
|
||||
if (string.len(dtmf_digits) >= max_digits) then
|
||||
if (debug["info"]) then
|
||||
freeswitch.console_log("info", "[voicemail] max_digits reached\n");
|
||||
end
|
||||
return 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
return 0;
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--play the greeting
|
||||
function play_greeting()
|
||||
--voicemail prompt
|
||||
if (skip_greeting == "true") then
|
||||
--skip the greeting
|
||||
else
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
if (string.len(greeting_id) > 0) then
|
||||
--play the custom greeting
|
||||
session:streamFile(voicemail_dir.."/"..voicemail_id.."/greeting_"..greeting_id..".wav");
|
||||
session:streamFile("silence_stream://200");
|
||||
else
|
||||
--play the default greeting
|
||||
dtmf_digits = macro(session, "person_not_available_record_message", 1, 200);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,96 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define a function to record the greeting
|
||||
function record_greeting()
|
||||
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
|
||||
--Choose a greeting between 1 and 9
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
greeting_id = macro(session, "choose_greeting_choose", 1, 5000, '');
|
||||
freeswitch.consoleLog("notice", "[voicemail] greeting_id: " .. greeting_id .. "\n");
|
||||
end
|
||||
|
||||
--validate the greeting_id
|
||||
if (greeting_id == "1"
|
||||
or greeting_id == "2"
|
||||
or greeting_id == "3"
|
||||
or greeting_id == "4"
|
||||
or greeting_id == "5"
|
||||
or greeting_id == "6"
|
||||
or greeting_id == "7"
|
||||
or greeting_id == "8"
|
||||
or greeting_id == "9") then
|
||||
--record your greeting at the tone press any key or stop talking to end the recording
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
macro(session, "record_greeting", 1, 100, '');
|
||||
end
|
||||
|
||||
--record the greeting
|
||||
if (session:ready()) then
|
||||
max_len_seconds = 30;
|
||||
silence_threshold = 30;
|
||||
silence_seconds = 5;
|
||||
mkdir(voicemail_dir.."/"..voicemail_id);
|
||||
-- syntax is session:recordFile(file_name, max_len_secs, silence_threshold, silence_secs)
|
||||
result = session:recordFile(voicemail_dir.."/"..voicemail_id.."/greeting_"..greeting_id..".wav", max_len_seconds, silence_threshold, silence_seconds);
|
||||
--session:execute("record", voicemail_dir.."/"..uuid.." 180 200");
|
||||
end
|
||||
|
||||
--play the greeting
|
||||
--if (session:ready()) then
|
||||
-- if (file_exists(voicemail_dir.."/"..voicemail_id.."/greeting_"..greeting_id..".wav")) then
|
||||
-- session:streamFile(voicemail_dir.."/"..voicemail_id.."/greeting_"..greeting_id..".wav");
|
||||
-- end
|
||||
--end
|
||||
|
||||
--option to play, save, and re-record the greeting
|
||||
if (session:ready()) then
|
||||
timeouts = 0;
|
||||
record_menu("greeting", voicemail_dir.."/"..voicemail_id.."/greeting_"..greeting_id..".wav");
|
||||
end
|
||||
else
|
||||
--invalid greeting_id
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
macro(session, "choose_greeting_fail", 1, 100, '');
|
||||
end
|
||||
|
||||
--send back to choose the greeting
|
||||
if (session:ready()) then
|
||||
timeouts = timeouts + 1;
|
||||
if (timeouts < max_timeouts) then
|
||||
record_greeting();
|
||||
else
|
||||
timeouts = 0;
|
||||
advanced();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,116 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--record message menu
|
||||
function record_menu(type, file)
|
||||
if (session:ready()) then
|
||||
--clear the dtmf digits variable
|
||||
dtmf_digits = '';
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
--to listen to the recording press 1
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "to_listen_to_recording", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to save the recording press 2
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "to_save_recording", 1, 100, '');
|
||||
end
|
||||
end
|
||||
--to re-record press 3
|
||||
if (session:ready()) then
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "to_rerecord", 1, 3000, '');
|
||||
end
|
||||
end
|
||||
--process the dtmf
|
||||
if (session:ready()) then
|
||||
if (dtmf_digits == "1") then
|
||||
--listen to the recording
|
||||
session:streamFile(file);
|
||||
--session:streamFile(voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext);
|
||||
--record menu 1 listen to the recording, 2 save the recording, 3 re-record
|
||||
record_menu(type, file);
|
||||
elseif (dtmf_digits == "2") then
|
||||
--save the message
|
||||
dtmf_digits = '';
|
||||
macro(session, "message_saved", 1, 100, '');
|
||||
if (type == "message") then
|
||||
--goodbye
|
||||
macro(session, "goodbye", 1, 100, '');
|
||||
--hangup the call
|
||||
session:hangup();
|
||||
end
|
||||
if (type == "greeting") then
|
||||
advanced();
|
||||
end
|
||||
if (type == "name") then
|
||||
advanced();
|
||||
end
|
||||
elseif (dtmf_digits == "3") then
|
||||
--re-record the message
|
||||
timeouts = 0;
|
||||
dtmf_digits = '';
|
||||
if (type == "message") then
|
||||
record_message();
|
||||
end
|
||||
if (type == "greeting") then
|
||||
record_greeting();
|
||||
end
|
||||
if (type == "name") then
|
||||
record_name();
|
||||
end
|
||||
elseif (dtmf_digits == "*") then
|
||||
--hangup
|
||||
if (session:ready()) then
|
||||
dtmf_digits = '';
|
||||
macro(session, "goodbye", 1, 100, '');
|
||||
session:hangup();
|
||||
end
|
||||
else
|
||||
if (session:ready()) then
|
||||
timeouts = timeouts + 1;
|
||||
if (timeouts < max_timeouts) then
|
||||
record_menu(type, file);
|
||||
else
|
||||
if (type == "message") then
|
||||
macro(session, "goodbye", 1, 1000, '');
|
||||
session:hangup();
|
||||
end
|
||||
if (type == "greeting") then
|
||||
advanced();
|
||||
end
|
||||
if (type == "name") then
|
||||
advanced();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,122 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--save the recording
|
||||
function record_message()
|
||||
|
||||
--record your message at the tone press any key or stop talking to end the recording
|
||||
if (skip_greeting == "true") then
|
||||
--skip the greeting
|
||||
else
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = macro(session, "record_message", 1, 100);
|
||||
end
|
||||
end
|
||||
|
||||
--direct dial
|
||||
if (dtmf_digits) then
|
||||
if (string.len(dtmf_digits) > 0) then
|
||||
if (session:ready()) then
|
||||
if (direct_dial["enabled"] == "true") then
|
||||
if (string.len(dtmf_digits) < max_digits) then
|
||||
dtmf_digits = dtmf_digits .. session:getDigits(direct_dial["max_digits"], "#", 5000);
|
||||
end
|
||||
end
|
||||
end
|
||||
if (session:ready()) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] dtmf_digits: " .. string.sub(dtmf_digits, 0, 1) .. "\n");
|
||||
if (dtmf_digits == "*") then
|
||||
--check the voicemail password
|
||||
check_password(voicemail_id, password_tries);
|
||||
--send to the main menu
|
||||
timeouts = 0;
|
||||
main_menu();
|
||||
elseif (string.sub(dtmf_digits, 0, 1) == "*") then
|
||||
--do not allow dialing numbers prefixed with *
|
||||
session:hangup();
|
||||
else
|
||||
session:transfer(dtmf_digits, "XML", context);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--play the beep
|
||||
dtmf_digits = '';
|
||||
result = macro(session, "record_beep", 1, 100);
|
||||
|
||||
--start epoch
|
||||
start_epoch = os.time();
|
||||
|
||||
--save the recording
|
||||
-- syntax is session:recordFile(file_name, max_len_secs, silence_threshold, silence_secs)
|
||||
max_len_seconds = 300;
|
||||
silence_threshold = 30;
|
||||
silence_seconds = 5;
|
||||
mkdir(voicemail_dir.."/"..voicemail_id);
|
||||
result = session:recordFile(voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext, max_len_seconds, silence_threshold, silence_seconds);
|
||||
--session:execute("record", voicemail_dir.."/"..uuid.." 180 200");
|
||||
|
||||
--stop epoch
|
||||
stop_epoch = os.time();
|
||||
|
||||
--calculate the message length
|
||||
message_length = stop_epoch - start_epoch;
|
||||
message_length_formatted = format_seconds(message_length);
|
||||
|
||||
--if the recording is below the minimal length then re-record the message
|
||||
if (message_length > 2) then
|
||||
--continue
|
||||
else
|
||||
if (session:ready()) then
|
||||
--your recording is below the minimal acceptable length, please try again
|
||||
dtmf_digits = '';
|
||||
macro(session, "too_small", 1, 100);
|
||||
--record your message at the tone
|
||||
timeouts = timeouts + 1;
|
||||
if (timeouts < max_timeouts) then
|
||||
record_message();
|
||||
else
|
||||
timeouts = 0;
|
||||
record_menu("message", voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--instructions press 1 to listen to the recording, press 2 to save the recording, press 3 to re-record
|
||||
if (session:ready()) then
|
||||
if (skip_instructions == "true") then
|
||||
--save the message
|
||||
dtmf_digits = '';
|
||||
macro(session, "message_saved", 1, 100, '');
|
||||
macro(session, "goodbye", 1, 100, '');
|
||||
--hangup the call
|
||||
session:hangup();
|
||||
else
|
||||
timeouts = 0;
|
||||
record_menu("message", voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext);
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define a function to record the name
|
||||
function record_name()
|
||||
if (session:ready()) then
|
||||
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
|
||||
--play the name record
|
||||
dtmf_digits = '';
|
||||
macro(session, "record_name", 1, 100, '');
|
||||
|
||||
--save the recording
|
||||
-- syntax is session:recordFile(file_name, max_len_secs, silence_threshold, silence_secs)
|
||||
max_len_seconds = 30;
|
||||
silence_threshold = 30;
|
||||
silence_seconds = 5;
|
||||
mkdir(voicemail_dir.."/"..voicemail_id);
|
||||
result = session:recordFile(voicemail_dir.."/"..voicemail_id.."/recorded_name.wav", max_len_seconds, silence_threshold, silence_seconds);
|
||||
--session:execute("record", voicemail_dir.."/"..uuid.." 180 200");
|
||||
|
||||
--play the name
|
||||
--session:streamFile(voicemail_dir.."/"..voicemail_id.."/recorded_name.wav");
|
||||
|
||||
--option to play, save, and re-record the name
|
||||
if (session:ready()) then
|
||||
timeouts = 0;
|
||||
record_menu("name", voicemail_dir.."/"..voicemail_id.."/recorded_name.wav");
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define a function to return the call
|
||||
function return_call(destination)
|
||||
if (session:ready()) then
|
||||
--clear the dtmf
|
||||
dtmf_digits = '';
|
||||
--flush dtmf digits from the input buffer
|
||||
session:flushDigits();
|
||||
--transfer the call
|
||||
session:transfer(destination, "XML", context);
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,156 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define a function to send email
|
||||
function send_email(id, uuid)
|
||||
--get voicemail message details
|
||||
sql = [[SELECT * FROM v_voicemails
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_id = ']] .. id ..[[']]
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
db_voicemail_uuid = string.lower(row["voicemail_uuid"]);
|
||||
--voicemail_password = row["voicemail_password"];
|
||||
--greeting_id = row["greeting_id"];
|
||||
voicemail_mail_to = row["voicemail_mail_to"];
|
||||
voicemail_attach_file = row["voicemail_attach_file"];
|
||||
voicemail_local_after_email = row["voicemail_local_after_email"];
|
||||
end);
|
||||
|
||||
--set default values
|
||||
if (voicemail_local_after_email == nil) then
|
||||
voicemail_local_after_email = "true";
|
||||
end
|
||||
if (voicemail_attach_file == nil) then
|
||||
voicemail_attach_file = "true";
|
||||
end
|
||||
|
||||
--require the email address to send the email
|
||||
if (string.len(voicemail_mail_to) > 2) then
|
||||
--get voicemail message details
|
||||
sql = [[SELECT * FROM v_voicemail_messages
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_message_uuid = ']] .. uuid ..[[']]
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
--get the values from the database
|
||||
--uuid = row["voicemail_message_uuid"];
|
||||
created_epoch = row["created_epoch"];
|
||||
caller_id_name = row["caller_id_name"];
|
||||
caller_id_number = row["caller_id_number"];
|
||||
message_length = row["message_length"];
|
||||
--message_status = row["message_status"];
|
||||
--message_priority = row["message_priority"];
|
||||
end);
|
||||
|
||||
--format the message length and date
|
||||
message_length_formatted = format_seconds(message_length);
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] message length: " .. message_length .. "\n");
|
||||
end
|
||||
local message_date = os.date("%A, %d %b %Y %I:%M %p", created_epoch)
|
||||
|
||||
--prepare the files
|
||||
file_subject = scripts_dir.."/app/voicemail/resources/templates/"..default_language.."/"..default_dialect.."email_subject.tpl";
|
||||
file_body = scripts_dir.."/app/voicemail/resources/templates/"..default_language.."/"..default_dialect.."/email_body.tpl";
|
||||
if (not file_exists(file_subject)) then
|
||||
file_subject = scripts_dir.."/app/voicemail/resources/templates/en/us/email_subject.tpl";
|
||||
file_body = scripts_dir.."/app/voicemail/resources/templates/en/us/email_body.tpl";
|
||||
end
|
||||
|
||||
--prepare the subject
|
||||
local f = io.open(file_subject, "r");
|
||||
local subject = f:read("*all");
|
||||
f:close();
|
||||
subject = subject:gsub("${caller_id_name}", caller_id_name);
|
||||
subject = subject:gsub("${caller_id_number}", caller_id_number);
|
||||
subject = subject:gsub("${message_date}", message_date);
|
||||
subject = subject:gsub("${message_duration}", message_length_formatted);
|
||||
subject = subject:gsub("${account}", id);
|
||||
subject = subject:gsub("${domain_name}", domain_name);
|
||||
subject = trim(subject);
|
||||
subject = '=?utf-8?B?'..base64.enc(subject)..'?=';
|
||||
|
||||
--prepare the body
|
||||
local f = io.open(file_body, "r");
|
||||
body = f:read("*all");
|
||||
f:close();
|
||||
body = body:gsub("${caller_id_name}", caller_id_name);
|
||||
body = body:gsub("${caller_id_number}", caller_id_number);
|
||||
body = body:gsub("${message_date}", message_date);
|
||||
body = body:gsub("${message_duration}", message_length_formatted);
|
||||
body = body:gsub("${account}", id);
|
||||
body = body:gsub("${domain_name}", domain_name);
|
||||
body = body:gsub(" ", " ");
|
||||
body = body:gsub("%s+", "");
|
||||
body = body:gsub(" ", " ");
|
||||
body = body:gsub("\n", "");
|
||||
body = body:gsub("\n", "");
|
||||
body = body:gsub("'", "'");
|
||||
body = body:gsub([["]], """);
|
||||
body = trim(body);
|
||||
|
||||
--send the email
|
||||
if (voicemail_attach_file == "true") then
|
||||
if (voicemail_local_after_email == "false") then
|
||||
delete = "true";
|
||||
else
|
||||
delete = "false";
|
||||
end
|
||||
file = voicemail_dir.."/"..id.."/msg_"..uuid.."."..vm_message_ext;
|
||||
cmd = "luarun email.lua "..voicemail_mail_to.." "..voicemail_mail_to.." '"..subject.."' '"..body.."' '"..file.."' "..delete;
|
||||
else
|
||||
cmd = "luarun email.lua "..voicemail_mail_to.." "..voicemail_mail_to.." '"..subject.."' '"..body.."'";
|
||||
end
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] cmd: " .. cmd .. "\n");
|
||||
end
|
||||
result = api:executeString(cmd);
|
||||
|
||||
end
|
||||
|
||||
--whether to keep the voicemail message and details local after email
|
||||
if (voicemail_mail_to) then
|
||||
if (voicemail_local_after_email == "false" and string.len(voicemail_mail_to) > 0) then
|
||||
--delete the voicemail message details
|
||||
sql = [[DELETE FROM v_voicemail_messages
|
||||
WHERE domain_uuid = ']] .. domain_uuid ..[['
|
||||
AND voicemail_uuid = ']] .. db_voicemail_uuid ..[['
|
||||
AND voicemail_message_uuid = ']] .. uuid ..[[']]
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql);
|
||||
--set message waiting indicator
|
||||
message_waiting(id, domain_uuid);
|
||||
--clear the variable
|
||||
db_voicemail_uuid = '';
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,100 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--include the lua script
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--define general settings
|
||||
tmp_file = "/usr/local/freeswitch/log/mwi.tmp";
|
||||
sleep = 300;
|
||||
|
||||
--debug
|
||||
debug["sql"] = false;
|
||||
debug["info"] = false;
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--used to stop the lua service
|
||||
local file = assert(io.open(tmp_file, "w"));
|
||||
file:write("remove this file to stop the script");
|
||||
|
||||
--add the trim function
|
||||
function trim(s)
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
--check if a file exists
|
||||
function file_exists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
end
|
||||
|
||||
--create the api object
|
||||
api = freeswitch.API();
|
||||
|
||||
--run lua as a service
|
||||
while true do
|
||||
|
||||
--exit the loop when the file does not exist
|
||||
if (not file_exists(tmp_file)) then
|
||||
freeswitch.consoleLog("NOTICE", tmp_file.." not found\n");
|
||||
break;
|
||||
end
|
||||
|
||||
--Send MWI events for voicemail boxes with messages
|
||||
sql = [[SELECT v.voicemail_id, v.voicemail_uuid, v.domain_uuid, d.domain_name, COUNT(*) AS message_count
|
||||
FROM v_voicemail_messages as m, v_voicemails as v, v_domains as d
|
||||
WHERE v.voicemail_uuid = m.voicemail_uuid
|
||||
AND v.domain_uuid = d.domain_uuid
|
||||
GROUP BY v.voicemail_id, v.voicemail_uuid, v.domain_uuid, d.domain_name;]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
--send the message waiting event
|
||||
local event = freeswitch.Event("message_waiting");
|
||||
if (row["message_count"] == "0") then
|
||||
event:addHeader("MWI-Messages-Waiting", "no");
|
||||
else
|
||||
event:addHeader("MWI-Messages-Waiting", "yes");
|
||||
end
|
||||
event:addHeader("MWI-Message-Account", "sip:"..row["voicemail_id"].."@"..row["domain_name"]);
|
||||
event:fire();
|
||||
--log to console
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[voicemail] mailbox: "..row["voicemail_id"].."@"..row["domain_name"].." messages: " .. row["message_count"] .. " \n");
|
||||
end
|
||||
end);
|
||||
|
||||
--slow the loop down
|
||||
os.execute("sleep "..sleep);
|
||||
|
||||
--testing exit immediately
|
||||
--break;
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
<font face="arial">
|
||||
<b>Message From "${caller_id_name}" <a href="tel:${caller_id_number}">${caller_id_number}</a></b><br/>
|
||||
<hr noshade="noshade" size="1"/>
|
||||
Created: ${message_date}<br/>
|
||||
Duration: ${message_duration}<br/>
|
||||
Account: ${account}@${domain_name}<br/>
|
||||
</font>
|
||||
@@ -0,0 +1 @@
|
||||
Voicemail from ${caller_id_name} <${caller_id_number}> ${message_duration}
|
||||
@@ -0,0 +1,7 @@
|
||||
<font face="arial">
|
||||
<b>Message From "${caller_id_name}" <a href="tel:${caller_id_number}">${caller_id_number}</a></b><br/>
|
||||
<hr noshade="noshade" size="1"/>
|
||||
Created: ${message_date}<br/>
|
||||
Duration: ${message_duration}<br/>
|
||||
Account: ${account}@${domain_name}<br/>
|
||||
</font>
|
||||
@@ -0,0 +1 @@
|
||||
Voicemail from ${caller_id_name} <${caller_id_number}> ${message_duration}
|
||||
138
resources/install/scripts/app/xml_handler/index.lua
Normal file
138
resources/install/scripts/app/xml_handler/index.lua
Normal file
@@ -0,0 +1,138 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set defaults
|
||||
expire = {}
|
||||
expire["directory"] = "3600";
|
||||
expire["dialplan"] = "300";
|
||||
expire["sofia.conf"] = "3600";
|
||||
|
||||
--set the debug options
|
||||
debug["params"] = false;
|
||||
debug["sql"] = false;
|
||||
debug["xml_request"] = false;
|
||||
debug["xml_string"] = false;
|
||||
debug["cache"] = false;
|
||||
|
||||
--general functions
|
||||
dofile(scripts_dir.."/resources/functions/trim.lua");
|
||||
dofile(scripts_dir.."/resources/functions/file_exists.lua");
|
||||
dofile(scripts_dir.."/resources/functions/explode.lua");
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--exits the script if we didn't connect properly
|
||||
assert(dbh:connected());
|
||||
|
||||
--if the params class and methods do not exist then add them to prevent errors
|
||||
if (not params) then
|
||||
params = {}
|
||||
function params:getHeader(name)
|
||||
self.name = name;
|
||||
end
|
||||
function params:serialize(name)
|
||||
self.name = name;
|
||||
end
|
||||
end
|
||||
|
||||
--show the params in the console
|
||||
if (debug["params"]) then
|
||||
if (params:serialize() ~= nil) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] Params:\n" .. params:serialize() .. "\n");
|
||||
end
|
||||
end
|
||||
|
||||
--show the xml request in the console
|
||||
if (debug["xml_request"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] Section: " .. XML_REQUEST["section"] .. "\n");
|
||||
freeswitch.consoleLog("notice", "[xml_handler] Tag Name: " .. XML_REQUEST["tag_name"] .. "\n");
|
||||
freeswitch.consoleLog("notice", "[xml_handler] Key Name: " .. XML_REQUEST["key_name"] .. "\n");
|
||||
freeswitch.consoleLog("notice", "[xml_handler] Key Value: " .. XML_REQUEST["key_value"] .. "\n");
|
||||
end
|
||||
|
||||
--get the params and set them as variables
|
||||
domain_name = params:getHeader("sip_from_host");
|
||||
if (domain_uuid == nil) then
|
||||
domain_uuid = params:getHeader("domain_uuid");
|
||||
end
|
||||
domain_name = params:getHeader("domain");
|
||||
if (domain_name == nil) then
|
||||
domain_name = params:getHeader("domain_name");
|
||||
end
|
||||
if (domain_name == nil) then
|
||||
domain_name = params:getHeader("variable_domain_name");
|
||||
end
|
||||
purpose = params:getHeader("purpose");
|
||||
profile = params:getHeader("profile");
|
||||
key = params:getHeader("key");
|
||||
user = params:getHeader("user");
|
||||
user_context = params:getHeader("variable_user_context");
|
||||
call_context = params:getHeader("Caller-Context");
|
||||
destination_number = params:getHeader("Caller-Destination-Number");
|
||||
caller_id_number = params:getHeader("Caller-Caller-ID-Number");
|
||||
hunt_context = params:getHeader("Hunt-Context");
|
||||
if (hunt_context ~= nil) then
|
||||
call_context = hunt_context;
|
||||
end
|
||||
|
||||
--prepare the api object
|
||||
api = freeswitch.API();
|
||||
|
||||
--get the domain_uuid
|
||||
if (domain_uuid == nil) then
|
||||
--get the domain_uuid
|
||||
if (domain_name ~= nil) then
|
||||
sql = "SELECT domain_uuid FROM v_domains ";
|
||||
sql = sql .. "WHERE domain_name = '" .. domain_name .."' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(rows)
|
||||
domain_uuid = rows["domain_uuid"];
|
||||
end);
|
||||
end
|
||||
end
|
||||
|
||||
--process the sections
|
||||
if (XML_REQUEST["section"] == "configuration") then
|
||||
configuration = scripts_dir.."/app/xml_handler/resources/scripts/configuration/"..XML_REQUEST["key_value"]..".lua";
|
||||
if (debug["xml_request"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] " .. configuration .. "\n");
|
||||
end
|
||||
if (file_exists(configuration)) then
|
||||
dofile(configuration);
|
||||
end
|
||||
end
|
||||
if (XML_REQUEST["section"] == "directory") then
|
||||
dofile(scripts_dir.."/app/xml_handler/resources/scripts/directory/directory.lua");
|
||||
end
|
||||
if (XML_REQUEST["section"] == "dialplan") then
|
||||
dofile(scripts_dir.."/app/xml_handler/resources/scripts/dialplan/dialplan.lua");
|
||||
end
|
||||
|
||||
--close the database connection
|
||||
dbh:release();
|
||||
@@ -0,0 +1,103 @@
|
||||
-- xml_handler.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set the xml array
|
||||
local xml = {}
|
||||
table.insert(xml, [[<?xml version="1.0" encoding="UTF-8" standalone="no"?>]]);
|
||||
table.insert(xml, [[<document type="freeswitch/xml">]]);
|
||||
table.insert(xml, [[ <section name="configuration">]]);
|
||||
table.insert(xml, [[ <configuration name="conference.conf" description="Audio Conference">]]);
|
||||
table.insert(xml, [[ <caller-controls>]]);
|
||||
table.insert(xml, [[ <group name="default">]]);
|
||||
table.insert(xml, [[ <control action="mute" digits=""/>]]);
|
||||
table.insert(xml, [[ <control action="deaf mute" digits=""/>]]);
|
||||
table.insert(xml, [[ <control action="energy up" digits="9"/>]]);
|
||||
table.insert(xml, [[ <control action="energy equ" digits="8"/>]]);
|
||||
table.insert(xml, [[ <control action="energy dn" digits="7"/>]]);
|
||||
table.insert(xml, [[ <control action="vol talk up" digits="3"/>]]);
|
||||
table.insert(xml, [[ <control action="vol talk zero" digits="2"/>]]);
|
||||
table.insert(xml, [[ <control action="vol talk dn" digits="1"/>]]);
|
||||
table.insert(xml, [[ <control action="vol listen up" digits="6"/>]]);
|
||||
table.insert(xml, [[ <control action="vol listen zero" digits="5"/>]]);
|
||||
table.insert(xml, [[ <control action="vol listen dn" digits="4"/>]]);
|
||||
table.insert(xml, [[ <control action="hangup" digits=""/>]]);
|
||||
table.insert(xml, [[ </group>]]);
|
||||
table.insert(xml, [[ <group name="moderator">]]);
|
||||
table.insert(xml, [[ <control action="mute" digits="#"/>]]);
|
||||
table.insert(xml, [[ <control action="deaf mute" digits=""/>]]);
|
||||
table.insert(xml, [[ <control action="energy up" digits="9"/>]]);
|
||||
table.insert(xml, [[ <control action="energy equ" digits="8"/>]]);
|
||||
table.insert(xml, [[ <control action="energy dn" digits="7"/>]]);
|
||||
table.insert(xml, [[ <control action="vol talk up" digits="3"/>]]);
|
||||
table.insert(xml, [[ <control action="vol talk zero" digits="2"/>]]);
|
||||
table.insert(xml, [[ <control action="vol talk dn" digits="1"/>]]);
|
||||
table.insert(xml, [[ <control action="vol listen up" digits="6"/>]]);
|
||||
table.insert(xml, [[ <control action="vol listen zero" digits="5"/>]]);
|
||||
table.insert(xml, [[ <control action="vol listen dn" digits="4"/>]]);
|
||||
table.insert(xml, [[ <control action="hangup" digits=""/>]]);
|
||||
table.insert(xml, [[ </group>]]);
|
||||
table.insert(xml, [[ </caller-controls>]]);
|
||||
table.insert(xml, "");
|
||||
table.insert(xml, [[ <profile name="default">]]);
|
||||
table.insert(xml, [[ <param name="cdr-log-dir" value="auto"/>]]);
|
||||
table.insert(xml, [[ <param name="conference-flags" value="wait-mod" />]]);
|
||||
table.insert(xml, [[ <param name="domain" value="$${domain}"/>]]);
|
||||
table.insert(xml, [[ <param name="rate" value="16000"/>]]);
|
||||
table.insert(xml, [[ <param name="interval" value="20"/>]]);
|
||||
table.insert(xml, [[ <param name="energy-level" value="15"/>]]);
|
||||
table.insert(xml, [[ <param name="auto-gain-level" value="50"/>]]);
|
||||
table.insert(xml, [[ <param name="caller-controls" value="default"/>]]);
|
||||
table.insert(xml, [[ <param name="moderator-controls" value="default"/>]]);
|
||||
table.insert(xml, [[ <param name="muted-sound" value="conference/conf-muted.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="unmuted-sound" value="conference/conf-unmuted.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="alone-sound" value="conference/conf-alone.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="moh-sound" value="$${hold_music}"/>]]);
|
||||
table.insert(xml, [[ <param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>]]);
|
||||
table.insert(xml, [[ <param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>]]);
|
||||
table.insert(xml, [[ <param name="kicked-sound" value="conference/conf-kicked.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="locked-sound" value="conference/conf-locked.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="is-locked-sound" value="conference/conf-is-locked.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="pin-sound" value="conference/conf-pin.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>]]);
|
||||
table.insert(xml, [[ <param name="caller-id-name" value="$${outbound_caller_name}"/>]]);
|
||||
table.insert(xml, [[ <param name="caller-id-number" value="$${outbound_caller_id}"/>]]);
|
||||
table.insert(xml, [[ <param name="comfort-noise" value="true"/>]]);
|
||||
table.insert(xml, [[ <param name="auto-record" value="/tmp/test.wav"/>]]);
|
||||
table.insert(xml, [[ </profile>]]);
|
||||
|
||||
--set the xml array and then concatenate the array to a string
|
||||
table.insert(xml, [[ </configuration>]]);
|
||||
table.insert(xml, [[ </section>]]);
|
||||
table.insert(xml, [[</document>]]);
|
||||
XML_STRING = table.concat(xml, "\n");
|
||||
|
||||
--send the xml to the console
|
||||
if (debug["xml_string"]) then
|
||||
local file = assert(io.open("/tmp/conference.conf.xml", "w"));
|
||||
file:write(XML_STRING);
|
||||
file:close();
|
||||
end
|
||||
@@ -0,0 +1,265 @@
|
||||
-- xml_handler.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--get the cache
|
||||
if (trim(api:execute("module_exists", "mod_memcache")) == "true") then
|
||||
XML_STRING = trim(api:execute("memcache", "get configuration:sofia.conf"));
|
||||
else
|
||||
XML_STRING = "-ERR NOT FOUND";
|
||||
end
|
||||
|
||||
--set the cache
|
||||
if (XML_STRING == "-ERR NOT FOUND") then
|
||||
|
||||
--get the variables
|
||||
vars = trim(api:execute("global_getvar", ""));
|
||||
|
||||
--start the xml array
|
||||
local xml = {}
|
||||
table.insert(xml, [[<?xml version="1.0" encoding="UTF-8" standalone="no"?>]]);
|
||||
table.insert(xml, [[<document type="freeswitch/xml">]]);
|
||||
table.insert(xml, [[ <section name="configuration">]]);
|
||||
table.insert(xml, [[ <configuration name="sofia.conf" description="sofia Endpoint">]]);
|
||||
table.insert(xml, [[ <global_settings>]]);
|
||||
table.insert(xml, [[ <param name="log-level" value="0"/>]]);
|
||||
--table.insert(xml, [[ <param name="auto-restart" value="false"/>]]);
|
||||
table.insert(xml, [[ <param name="debug-presence" value="0"/>]]);
|
||||
--table.insert(xml, [[ <param name="capture-server" value="udp:homer.domain.com:5060"/>]]);
|
||||
table.insert(xml, [[ </global_settings>]]);
|
||||
table.insert(xml, [[ <profiles>]]);
|
||||
|
||||
--set defaults
|
||||
previous_sip_profile_name = "";
|
||||
profile_tag_status = "closed";
|
||||
|
||||
--run the query
|
||||
sql = "select p.sip_profile_name, p.sip_profile_description, s.sip_profile_setting_name, s.sip_profile_setting_value ";
|
||||
sql = sql .. "from v_sip_profiles as p, v_sip_profile_settings as s ";
|
||||
sql = sql .. "where p.sip_profile_uuid = s.sip_profile_uuid ";
|
||||
sql = sql .. "and s.sip_profile_setting_enabled = 'true' ";
|
||||
sql = sql .. "order by p.sip_profile_name asc ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n");
|
||||
end
|
||||
x = 0;
|
||||
dbh:query(sql, function(row)
|
||||
--set as variables
|
||||
sip_profile_name = row.sip_profile_name;
|
||||
--sip_profile_description = row.sip_profile_description;
|
||||
sip_profile_setting_name = row.sip_profile_setting_name;
|
||||
sip_profile_setting_value = row.sip_profile_setting_value;
|
||||
|
||||
--open xml tag
|
||||
if (sip_profile_name ~= previous_sip_profile_name) then
|
||||
if (x > 1) then
|
||||
table.insert(xml, [[ </settings>]]);
|
||||
table.insert(xml, [[ </profile>]]);
|
||||
end
|
||||
table.insert(xml, [[ <profile name="]]..sip_profile_name..[[">]]);
|
||||
table.insert(xml, [[ <aliases>]]);
|
||||
table.insert(xml, [[ </aliases>]]);
|
||||
table.insert(xml, [[ <gateways>]]);
|
||||
--table.insert(xml, [[ <X-PRE-PROCESS cmd="include" data="]]..sip_profile_name..[[/*.xml"/>]]);
|
||||
|
||||
--get the gateways
|
||||
if (domain_count > 1) then
|
||||
sql = "select * from v_gateways as g, v_domains as d ";
|
||||
sql = sql .. "where g.profile = '"..sip_profile_name.."' ";
|
||||
sql = sql .. "and g.enabled = 'true' ";
|
||||
sql = sql .. "and g.domain_uuid = d.domain_uuid ";
|
||||
else
|
||||
sql = "select * from v_gateways ";
|
||||
sql = sql .. "where profile = '"..sip_profile_name.."' and enabled = 'true' ";
|
||||
end
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n");
|
||||
end
|
||||
x = 0;
|
||||
dbh:query(sql, function(field)
|
||||
--set as variables
|
||||
gateway = field.gateway;
|
||||
gateway = gateway:gsub(" ", "_");
|
||||
|
||||
if (domain_count > 1) then
|
||||
table.insert(xml, [[ <gateway name="]] .. field.domain_name .."-".. gateway .. [[">]]);
|
||||
else
|
||||
table.insert(xml, [[ <gateway name="]] .. gateway .. [[">]]);
|
||||
end
|
||||
|
||||
if (string.len(field.username) > 0) then
|
||||
table.insert(xml, [[ <param name="username" value="]] .. field.username .. [["/>]]);
|
||||
else
|
||||
table.insert(xml, [[ <param name="username" value="register:false"/>]]);
|
||||
end
|
||||
if (string.len(field.distinct_to) > 0) then
|
||||
table.insert(xml, [[ <param name="distinct-to" value="]] .. field.distinct_to .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.auth_username) > 0) then
|
||||
table.insert(xml, [[ <param name="auth-username" value="]] .. field.auth_username .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.password) > 0) then
|
||||
table.insert(xml, [[ <param name="password" value="]] .. field.password .. [["/>]]);
|
||||
else
|
||||
table.insert(xml, [[ <param name="password" value="register:false"/>]]);
|
||||
end
|
||||
if (string.len(field.realm) > 0) then
|
||||
table.insert(xml, [[ <param name="realm" value="]] .. field.realm .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.from_user) > 0) then
|
||||
table.insert(xml, [[ <param name="from-user" value="]] .. field.from_user .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.from_domain) > 0) then
|
||||
table.insert(xml, [[ <param name="from-domain" value="]] .. field.from_domain .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.proxy) > 0) then
|
||||
table.insert(xml, [[ <param name="proxy" value="]] .. field.proxy .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.register_proxy) > 0) then
|
||||
table.insert(xml, [[ <param name="register-proxy" value="]] .. field.register_proxy .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.outbound_proxy) > 0) then
|
||||
table.insert(xml, [[ <param name="outbound-proxy" value="]] .. field.outbound_proxy .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.expire_seconds) > 0) then
|
||||
table.insert(xml, [[ <param name="expire-seconds" value="]] .. field.expire_seconds .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.register) > 0) then
|
||||
table.insert(xml, [[ <param name="register" value="]] .. field.register .. [["/>]]);
|
||||
end
|
||||
|
||||
if (field.register_transport) then
|
||||
if (field.register_transport == "udp") then
|
||||
table.insert(xml, [[ <param name="register-transport" value="udp"/>]]);
|
||||
elseif (field.register_transport == "tcp") then
|
||||
table.insert(xml, [[ <param name="register-transport" value="tcp"/>]]);
|
||||
elseif (field.register_transport == "tls") then
|
||||
table.insert(xml, [[ <param name="register-transport" value="tls"/>]]);
|
||||
table.insert(xml, [[ <param name="contact-params" value="transport=tls"/>]]);
|
||||
else
|
||||
table.insert(xml, [[ <param name="register-transport" value="udp"/>]]);
|
||||
end
|
||||
end
|
||||
|
||||
if (string.len(field.retry_seconds) > 0) then
|
||||
table.insert(xml, [[ <param name="retry-seconds" value="]] .. field.retry_seconds .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.extension) > 0) then
|
||||
table.insert(xml, [[ <param name="extension" value="]] .. field.extension .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.ping) > 0) then
|
||||
table.insert(xml, [[ <param name="ping" value="]] .. field.ping .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.context) > 0) then
|
||||
table.insert(xml, [[ <param name="context" value="]] .. field.context .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.caller_id_in_from) > 0) then
|
||||
table.insert(xml, [[ <param name="caller-id-in-from" value="]] .. field.caller_id_in_from .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.supress_cng) > 0) then
|
||||
table.insert(xml, [[ <param name="supress-cng" value="]] .. field.supress_cng .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.sip_cid_type) > 0) then
|
||||
table.insert(xml, [[ <param name="sip_cid_type" value="]] .. field.sip_cid_type .. [["/>]]);
|
||||
end
|
||||
if (string.len(field.extension_in_contact) > 0) then
|
||||
table.insert(xml, [[ <param name="extension-in-contact" value="]] .. field.extension_in_contact .. [["/>]]);
|
||||
end
|
||||
table.insert(xml, [[ </gateway>]]);
|
||||
end)
|
||||
|
||||
table.insert(xml, [[ </gateways>]]);
|
||||
table.insert(xml, [[ <domains>]]);
|
||||
table.insert(xml, [[ <domain name="all" alias="false" parse="true"/>]]);
|
||||
table.insert(xml, [[ </domains>]]);
|
||||
table.insert(xml, [[ <settings>]]);
|
||||
profile_tag_status = "open";
|
||||
end
|
||||
|
||||
--loop through the var array
|
||||
for line in (vars.."\n"):gmatch"(.-)\n" do
|
||||
if (line) then
|
||||
pos = string.find(line, "=", 0, true);
|
||||
--name = string.sub( line, 0, pos-1);
|
||||
--value = string.sub( line, pos+1);
|
||||
sip_profile_setting_value = sip_profile_setting_value:gsub("%$%${"..string.sub( line, 0, pos-1).."}", string.sub( line, pos+1));
|
||||
end
|
||||
end
|
||||
|
||||
--remove $ and replace with ""
|
||||
--if (sip_profile_setting_value) then
|
||||
-- sip_profile_setting_value = sip_profile_setting_value:gsub("%$", "");
|
||||
--end
|
||||
|
||||
--set the parameters
|
||||
if (sip_profile_setting_name) then
|
||||
table.insert(xml, [[ <param name="]]..sip_profile_setting_name..[[" value="]]..sip_profile_setting_value..[["/>]]);
|
||||
end
|
||||
|
||||
--set the previous value
|
||||
previous_sip_profile_name = sip_profile_name;
|
||||
|
||||
--increment the value of x
|
||||
x = x + 1;
|
||||
end)
|
||||
|
||||
--close the extension tag if it was left open
|
||||
if (profile_tag_status == "open") then
|
||||
table.insert(xml, [[ </settings>]]);
|
||||
table.insert(xml, [[ </profile>]]);
|
||||
profile_tag_status = "close";
|
||||
end
|
||||
table.insert(xml, [[ </profiles>]]);
|
||||
table.insert(xml, [[ </configuration>]]);
|
||||
table.insert(xml, [[ </section>]]);
|
||||
table.insert(xml, [[</document>]]);
|
||||
XML_STRING = table.concat(xml, "\n");
|
||||
if (debug["xml_string"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] XML_STRING: " .. XML_STRING .. "\n");
|
||||
end
|
||||
|
||||
--set the cache
|
||||
result = trim(api:execute("memcache", "set configuration:sofia.conf '"..XML_STRING:gsub("'", "'").."' "..expire["sofia.conf"]));
|
||||
|
||||
--send the xml to the console
|
||||
if (debug["xml_string"]) then
|
||||
local file = assert(io.open("/tmp/sofia.conf.xml", "w"));
|
||||
file:write(XML_STRING);
|
||||
file:close();
|
||||
end
|
||||
|
||||
--send to the console
|
||||
if (debug["cache"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] configuration:sofia.conf source: database\n");
|
||||
end
|
||||
else
|
||||
--replace the ' back to a single quote
|
||||
XML_STRING = XML_STRING:gsub("'", "'");
|
||||
|
||||
--send to the console
|
||||
if (debug["cache"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] configuration:sofia.conf source: memcache\n");
|
||||
end
|
||||
end --if XML_STRING
|
||||
@@ -0,0 +1,264 @@
|
||||
-- xml_handler.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--get the cache
|
||||
if (trim(api:execute("module_exists", "mod_memcache")) == "true") then
|
||||
XML_STRING = trim(api:execute("memcache", "get dialplan:" .. call_context));
|
||||
else
|
||||
XML_STRING = "-ERR NOT FOUND";
|
||||
end
|
||||
|
||||
--set the cache
|
||||
if (XML_STRING == "-ERR NOT FOUND") then
|
||||
--set the xml array and then concatenate the array to a string
|
||||
local xml = {}
|
||||
table.insert(xml, [[<?xml version="1.0" encoding="UTF-8" standalone="no"?>]]);
|
||||
table.insert(xml, [[<document type="freeswitch/xml">]]);
|
||||
table.insert(xml, [[ <section name="dialplan" description="">]]);
|
||||
table.insert(xml, [[ <context name="]] .. call_context .. [[">]]);
|
||||
|
||||
--set defaults
|
||||
previous_dialplan_uuid = "";
|
||||
previous_dialplan_detail_group = "";
|
||||
previous_dialplan_detail_tag = "";
|
||||
previous_dialplan_detail_type = "";
|
||||
previous_dialplan_detail_data = "";
|
||||
dialplan_tag_status = "closed";
|
||||
condition_tag_status = "closed";
|
||||
|
||||
--get the dialplan and related details
|
||||
sql = "select * from v_dialplans as d, v_dialplan_details as s ";
|
||||
sql = sql .. "where d.dialplan_context = '" .. call_context .. "' ";
|
||||
sql = sql .. "and d.dialplan_enabled = 'true' ";
|
||||
sql = sql .. "and d.dialplan_uuid = s.dialplan_uuid ";
|
||||
--if (call_context ~= "public") then
|
||||
-- sql = sql .. "and d.domain_uuid = '" .. domain_uuid .. "' ";
|
||||
--end
|
||||
sql = sql .. "order by ";
|
||||
sql = sql .. "d.dialplan_order asc, ";
|
||||
sql = sql .. "d.dialplan_name asc, ";
|
||||
sql = sql .. "d.dialplan_uuid asc, ";
|
||||
sql = sql .. "s.dialplan_detail_group asc, ";
|
||||
sql = sql .. "CASE s.dialplan_detail_tag ";
|
||||
sql = sql .. "WHEN 'condition' THEN 1 ";
|
||||
sql = sql .. "WHEN 'action' THEN 2 ";
|
||||
sql = sql .. "WHEN 'anti-action' THEN 3 ";
|
||||
sql = sql .. "ELSE 100 END, ";
|
||||
sql = sql .. "s.dialplan_detail_order asc ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n");
|
||||
end
|
||||
x = 0;
|
||||
dbh:query(sql, function(row)
|
||||
--get the dialplan
|
||||
--domain_uuid = row.domain_uuid;
|
||||
dialplan_uuid = row.dialplan_uuid;
|
||||
--app_uuid = row.app_uuid;
|
||||
--dialplan_context = row.dialplan_context;
|
||||
dialplan_name = row.dialplan_name;
|
||||
--dialplan_number = row.dialplan_number;
|
||||
dialplan_continue = row.dialplan_continue;
|
||||
--dialplan_order = row.dialplan_order;
|
||||
--dialplan_enabled = row.dialplan_enabled;
|
||||
--dialplan_description = row.dialplan_description;
|
||||
--get the dialplan details
|
||||
--dialplan_detail_uuid = row.dialplan_detail_uuid;
|
||||
dialplan_detail_tag = row.dialplan_detail_tag;
|
||||
dialplan_detail_type = row.dialplan_detail_type;
|
||||
dialplan_detail_data = row.dialplan_detail_data;
|
||||
dialplan_detail_break = row.dialplan_detail_break;
|
||||
dialplan_detail_inline = row.dialplan_detail_inline;
|
||||
dialplan_detail_group = row.dialplan_detail_group;
|
||||
--dialplan_detail_order = row.dialplan_detail_order;
|
||||
|
||||
--remove $$ and replace with $
|
||||
dialplan_detail_data = dialplan_detail_data:gsub("%$%$", "$");
|
||||
|
||||
--get the dialplan detail inline
|
||||
detail_inline = "";
|
||||
if (dialplan_detail_inline) then
|
||||
if (string.len(dialplan_detail_inline) > 0) then
|
||||
detail_inline = [[ inline="]] .. dialplan_detail_inline .. [["]];
|
||||
end
|
||||
end
|
||||
|
||||
--close the tags
|
||||
if (condition_tag_status ~= "closed") then
|
||||
if (previous_dialplan_uuid ~= dialplan_uuid) then
|
||||
table.insert(xml, [[ </condition>]]);
|
||||
table.insert(xml, [[ </extension>]]);
|
||||
dialplan_tag_status = "closed";
|
||||
condition_tag_status = "closed";
|
||||
else
|
||||
if (previous_dialplan_detail_group ~= dialplan_detail_group and previous_dialplan_detail_tag == "condition") then
|
||||
table.insert(xml, [[ </condition>]]);
|
||||
condition_tag_status = "closed";
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--open the tags
|
||||
if (dialplan_tag_status == "closed") then
|
||||
table.insert(xml, [[ <extension name="]] .. dialplan_name .. [[" continue="]] .. dialplan_continue .. [[" uuid="]] .. dialplan_uuid .. [[">]]);
|
||||
dialplan_tag_status = "open";
|
||||
end
|
||||
if (dialplan_detail_tag == "condition") then
|
||||
--determine the type of condition
|
||||
if (dialplan_detail_type == "hour") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "minute") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "minute-of-day") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "mday") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "mweek") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "mon") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "yday") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "year") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "wday") then
|
||||
condition_type = 'time';
|
||||
elseif (dialplan_detail_type == "week") then
|
||||
condition_type = 'time';
|
||||
else
|
||||
condition_type = 'default';
|
||||
end
|
||||
|
||||
--get the condition break attribute
|
||||
condition_break = "";
|
||||
if (dialplan_detail_break) then
|
||||
if (string.len(dialplan_detail_break) > 0) then
|
||||
condition_break = [[ break="]] .. dialplan_detail_break .. [["]];
|
||||
end
|
||||
end
|
||||
|
||||
if (condition_tag_status == "open") then
|
||||
if (previous_dialplan_detail_tag == "condition") then
|
||||
--add the condition self closing tag
|
||||
if (condition) then
|
||||
if (string.len(condition) > 0) then
|
||||
table.insert(xml, condition .. [[/>]]);
|
||||
end
|
||||
end
|
||||
end
|
||||
if (previous_dialplan_detail_tag == "action" or previous_dialplan_detail_tag == "anti-action") then
|
||||
table.insert(xml, [[ </condition>]]);
|
||||
condition_tag_status = "closed";
|
||||
condition_type = "";
|
||||
condition_attribute = "";
|
||||
condition_expression = "";
|
||||
end
|
||||
end
|
||||
|
||||
--condition tag but leave off the ending
|
||||
if (condition_type == "default") then
|
||||
condition = [[ <condition field="]] .. dialplan_detail_type .. [[" expression="]] .. dialplan_detail_data .. [["]] .. condition_break;
|
||||
elseif (condition_type == "time") then
|
||||
if (condition_attribute) then
|
||||
condition_attribute = condition_attribute .. dialplan_detail_type .. [[="]] .. dialplan_detail_data .. [[" ]];
|
||||
else
|
||||
condition_attribute = dialplan_detail_type .. [[="]] .. dialplan_detail_data .. [[" ]];
|
||||
end
|
||||
condition_expression = "";
|
||||
condition = ""; --prevents a duplicate time condition
|
||||
else
|
||||
condition = [[ <condition field="]] .. dialplan_detail_type .. [[" expression="]] .. dialplan_detail_data .. [["]] .. condition_break;
|
||||
end
|
||||
condition_tag_status = "open";
|
||||
end
|
||||
if (dialplan_detail_tag == "action" or dialplan_detail_tag == "anti-action") then
|
||||
if (previous_dialplan_detail_tag == "condition") then
|
||||
--add the condition ending
|
||||
if (condition_type == "time") then
|
||||
condition = [[ <condition ]] .. condition_attribute .. condition_break;
|
||||
condition_attribute = ""; --prevents the condition attribute from being used on every condition
|
||||
else
|
||||
if (previous_dialplan_detail_type) then
|
||||
condition = [[ <condition field="]] .. previous_dialplan_detail_type .. [[" expression="]] .. previous_dialplan_detail_data .. [["]] .. condition_break;
|
||||
end
|
||||
end
|
||||
table.insert(xml, condition .. [[>]]);
|
||||
condition = ""; --prevents duplicate time conditions
|
||||
end
|
||||
end
|
||||
if (dialplan_detail_tag == "action") then
|
||||
table.insert(xml, [[ <action application="]] .. dialplan_detail_type .. [[" data="]] .. dialplan_detail_data .. [["]] .. detail_inline .. [[/>]]);
|
||||
end
|
||||
if (dialplan_detail_tag == "anti-action") then
|
||||
table.insert(xml, [[ <anti-action application="]] .. dialplan_detail_type .. [[" data="]] .. dialplan_detail_data .. [["]] .. detail_inline .. [[/>]]);
|
||||
end
|
||||
|
||||
--save the previous values
|
||||
previous_dialplan_uuid = dialplan_uuid;
|
||||
previous_dialplan_detail_group = dialplan_detail_group;
|
||||
previous_dialplan_detail_tag = dialplan_detail_tag;
|
||||
previous_dialplan_detail_type = dialplan_detail_type;
|
||||
previous_dialplan_detail_data = dialplan_detail_data;
|
||||
|
||||
--increment the x
|
||||
x = x + 1;
|
||||
end);
|
||||
|
||||
--close the extension tag if it was left open
|
||||
if (dialplan_tag_status == "open") then
|
||||
table.insert(xml, [[ </condition>]]);
|
||||
table.insert(xml, [[ </extension>]]);
|
||||
end
|
||||
|
||||
--set the xml array and then concatenate the array to a string
|
||||
table.insert(xml, [[ </context>]]);
|
||||
table.insert(xml, [[ </section>]]);
|
||||
table.insert(xml, [[</document>]]);
|
||||
XML_STRING = table.concat(xml, "\n");
|
||||
|
||||
--set the cache
|
||||
tmp = XML_STRING:gsub("\\", "\\\\");
|
||||
result = trim(api:execute("memcache", "set dialplan:" .. call_context .. " '"..tmp:gsub("'", "'").."' "..expire["dialplan"]));
|
||||
|
||||
--send the xml to the console
|
||||
if (debug["xml_string"]) then
|
||||
local file = assert(io.open("/tmp/dialplan-" .. call_context .. ".xml", "w"));
|
||||
file:write(XML_STRING);
|
||||
file:close();
|
||||
end
|
||||
|
||||
--send to the console
|
||||
if (debug["cache"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: database\n");
|
||||
end
|
||||
else
|
||||
--replace the ' back to a single quote
|
||||
XML_STRING = XML_STRING:gsub("'", "'");
|
||||
|
||||
--send to the console
|
||||
if (debug["cache"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: memcache\n");
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,124 @@
|
||||
-- xml_handler.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--get the cache
|
||||
if (trim(api:execute("module_exists", "mod_memcache")) == "true") then
|
||||
XML_STRING = trim(api:execute("memcache", "get directory:groups:"..domain_name));
|
||||
else
|
||||
XML_STRING = "-ERR NOT FOUND";
|
||||
end
|
||||
|
||||
--set the cache
|
||||
if (XML_STRING == "-ERR NOT FOUND") then
|
||||
--build the call group array
|
||||
sql = [[
|
||||
select * from v_extensions
|
||||
where domain_uuid = ']]..domain_uuid..[['
|
||||
order by call_group asc
|
||||
]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n");
|
||||
end
|
||||
call_group_array = {};
|
||||
status = dbh:query(sql, function(row)
|
||||
call_group = row['call_group'];
|
||||
--call_group = str_replace(";", ",", call_group);
|
||||
tmp_array = explode(",", call_group);
|
||||
for key,value in pairs(tmp_array) do
|
||||
value = trim(value);
|
||||
--freeswitch.consoleLog("notice", "[directory] Key: " .. key .. " Value: " .. value .. " " ..row['extension'] .."\n");
|
||||
if (string.len(value) == 0) then
|
||||
--do nothing
|
||||
else
|
||||
if (call_group_array[value] == nil) then
|
||||
call_group_array[value] = row['extension'];
|
||||
else
|
||||
call_group_array[value] = call_group_array[value]..','..row['extension'];
|
||||
end
|
||||
end
|
||||
end
|
||||
end);
|
||||
--for key,value in pairs(call_group_array) do
|
||||
-- freeswitch.consoleLog("notice", "[directory] Key: " .. key .. " Value: " .. value .. "\n");
|
||||
--end
|
||||
|
||||
--build the xml array
|
||||
local xml = {}
|
||||
table.insert(xml, [[<?xml version="1.0" encoding="UTF-8" standalone="no"?>]]);
|
||||
table.insert(xml, [[<document type="freeswitch/xml">]]);
|
||||
table.insert(xml, [[ <section name="directory">]]);
|
||||
table.insert(xml, [[ <domain name="]] .. domain_name .. [[">]]);
|
||||
table.insert(xml, [[ <groups>]]);
|
||||
previous_call_group = "";
|
||||
for key, value in pairs(call_group_array) do
|
||||
call_group = trim(key);
|
||||
extension_list = trim(value);
|
||||
if (string.len(call_group) > 0) then
|
||||
freeswitch.consoleLog("notice", "[directory] call_group: " .. call_group .. "\n");
|
||||
freeswitch.consoleLog("notice", "[directory] extension_list: " .. extension_list .. "\n");
|
||||
if (previous_call_group ~= call_group) then
|
||||
table.insert(xml, [[ <group name="]]..call_group..[[">]]);
|
||||
table.insert(xml, [[ <users>]]);
|
||||
extension_array = explode(",", extension_list);
|
||||
for index,tmp_extension in pairs(extension_array) do
|
||||
table.insert(xml, [[ <user id="]]..tmp_extension..[[" type="pointer"/>]]);
|
||||
end
|
||||
table.insert(xml, [[ </users>]]);
|
||||
table.insert(xml, [[ </group>]]);
|
||||
end
|
||||
previous_call_group = call_group;
|
||||
end
|
||||
end
|
||||
table.insert(xml, [[ </groups>]]);
|
||||
table.insert(xml, [[ </domain>]]);
|
||||
table.insert(xml, [[ </section>]]);
|
||||
table.insert(xml, [[</document>]]);
|
||||
XML_STRING = table.concat(xml, "\n");
|
||||
|
||||
--set the cache
|
||||
result = trim(api:execute("memcache", "set directory:groups:"..domain_name.." '"..XML_STRING:gsub("'", "'").."' "..expire["directory"]));
|
||||
|
||||
--send to the console
|
||||
if (debug["cache"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] directory:groups:"..domain_name.." source: database\n");
|
||||
end
|
||||
|
||||
else
|
||||
--replace the ' back to a single quote
|
||||
XML_STRING = XML_STRING:gsub("'", "'");
|
||||
|
||||
--send to the console
|
||||
if (debug["cache"]) then
|
||||
if (XML_STRING) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] directory:groups:"..domain_name.." source: memcache\n");
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--send the xml to the console
|
||||
if (debug["xml_string"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] directory:groups:"..domain_name.." XML_STRING: \n" .. XML_STRING .. "\n");
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
--params
|
||||
--Event-Calling-Line-Number: 102
|
||||
--Event-Sequence: 4173
|
||||
--action: message-count
|
||||
--key: id
|
||||
--user: *98
|
||||
--domain: example.com
|
||||
@@ -0,0 +1,379 @@
|
||||
-- xml_handler.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set the default
|
||||
continue = true;
|
||||
|
||||
--get the action
|
||||
action = params:getHeader("action");
|
||||
purpose = params:getHeader("purpose");
|
||||
--sip_auth - registration
|
||||
--group_call - call group has been called
|
||||
--user_call - user has been called
|
||||
|
||||
--additional information
|
||||
--event_calling_function = params:getHeader("Event-Calling-Function");
|
||||
|
||||
--determine the correction action to perform
|
||||
if (purpose == "gateways") then
|
||||
if (params:getHeader("profile") == "internal") then
|
||||
--process when the sip profile is rescanned or sofia is reloaded
|
||||
local xml = {}
|
||||
table.insert(xml, [[<?xml version="1.0" encoding="UTF-8" standalone="no"?>]]);
|
||||
table.insert(xml, [[<document type="freeswitch/xml">]]);
|
||||
table.insert(xml, [[ <section name="directory">]]);
|
||||
sql = "SELECT * FROM v_domains ";
|
||||
dbh:query(sql, function(row)
|
||||
table.insert(xml, [[ <domain name="]]..row.domain_name..[[" />]]);
|
||||
end);
|
||||
table.insert(xml, [[ </section>]]);
|
||||
table.insert(xml, [[</document>]]);
|
||||
XML_STRING = table.concat(xml, "\n");
|
||||
end
|
||||
elseif (action == "message-count") then
|
||||
dofile(scripts_dir.."/app/xml_handler/resources/scripts/directory/action/message-count.lua");
|
||||
elseif (action == "group_call") then
|
||||
dofile(scripts_dir.."/app/xml_handler/resources/scripts/directory/action/group_call.lua");
|
||||
else
|
||||
--handle action
|
||||
--all other directory actions: sip_auth, user_call
|
||||
--except for the action: group_call
|
||||
|
||||
--get the cache
|
||||
if (trim(api:execute("module_exists", "mod_memcache")) == "true") then
|
||||
if (user == nil) then
|
||||
user = "";
|
||||
end
|
||||
if (domain_name) then
|
||||
XML_STRING = trim(api:execute("memcache", "get directory:" .. user .. "@" .. domain_name));
|
||||
end
|
||||
if (XML_STRING == "-ERR NOT FOUND") then
|
||||
continue = true;
|
||||
else
|
||||
continue = false;
|
||||
end
|
||||
else
|
||||
XML_STRING = "";
|
||||
continue = true;
|
||||
end
|
||||
|
||||
--prevent processing for invalid user
|
||||
if (user == "*97") then
|
||||
continue = false;
|
||||
end
|
||||
|
||||
--prevent processing for invalid domains
|
||||
if (domain_uuid == nil) then
|
||||
continue = false;
|
||||
end
|
||||
|
||||
--get the extension from the database
|
||||
if (continue) then
|
||||
sql = "SELECT * FROM v_extensions WHERE domain_uuid = '" .. domain_uuid .. "' and extension = '" .. user .. "' and enabled = 'true' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql, function(row)
|
||||
--general
|
||||
domain_uuid = row.domain_uuid;
|
||||
extension_uuid = row.extension_uuid;
|
||||
extension = row.extension;
|
||||
cidr = "";
|
||||
if (string.len(row.cidr) > 0) then
|
||||
cidr = [[ cidr="]] .. row.cidr .. [["]];
|
||||
end
|
||||
number_alias = "";
|
||||
if (string.len(row.number_alias) > 0) then
|
||||
number_alias = [[ number-alias="]] .. row.number_alias .. [["]];
|
||||
end
|
||||
--params
|
||||
password = row.password;
|
||||
vm_enabled = "true";
|
||||
if (string.len(row.vm_enabled) > 0) then
|
||||
vm_enabled = row.vm_enabled;
|
||||
end
|
||||
vm_password = row.vm_password;
|
||||
vm_attach_file = "true";
|
||||
if (string.len(row.vm_attach_file) > 0) then
|
||||
vm_attach_file = row.vm_attach_file;
|
||||
end
|
||||
vm_keep_local_after_email = "true";
|
||||
if (string.len(row.vm_keep_local_after_email) > 0) then
|
||||
vm_keep_local_after_email = row.vm_keep_local_after_email;
|
||||
end
|
||||
if (string.len(row.vm_mailto) > 0) then
|
||||
vm_mailto = row.vm_mailto;
|
||||
else
|
||||
vm_mailto = "";
|
||||
end
|
||||
mwi_account = row.mwi_account;
|
||||
auth_acl = row.auth_acl;
|
||||
--variables
|
||||
sip_from_user = row.extension;
|
||||
call_group = row.call_group;
|
||||
hold_music = row.hold_music;
|
||||
toll_allow = row.toll_allow;
|
||||
accountcode = row.accountcode;
|
||||
user_context = row.user_context;
|
||||
effective_caller_id_name = row.effective_caller_id_name;
|
||||
effective_caller_id_number = row.effective_caller_id_number;
|
||||
outbound_caller_id_name = row.outbound_caller_id_name;
|
||||
outbound_caller_id_number = row.outbound_caller_id_number;
|
||||
emergency_caller_id_number = row.emergency_caller_id_number;
|
||||
directory_full_name = row.directory_full_name;
|
||||
directory_visible = row.directory_visible;
|
||||
directory_exten_visible = row.directory_exten_visible;
|
||||
limit_max = row.limit_max;
|
||||
call_timeout = row.call_timeout;
|
||||
limit_destination = row.limit_destination;
|
||||
sip_force_contact = row.sip_force_contact;
|
||||
sip_force_expires = row.sip_force_expires;
|
||||
nibble_account = row.nibble_account;
|
||||
sip_bypass_media = row.sip_bypass_media;
|
||||
|
||||
--set the dial_string
|
||||
if (string.len(row.dial_string) > 0) then
|
||||
dial_string = row.dial_string;
|
||||
else
|
||||
dial_string = "{sip_invite_domain=" .. domain_name .. ",leg_timeout=" .. call_timeout .. ",presence_id=" .. user .. "@" .. domain_name .. "}${sofia_contact(" .. user .. "@" .. domain_name .. ")}";
|
||||
end
|
||||
end);
|
||||
end
|
||||
|
||||
--if the extension does not exist set continue to false;
|
||||
if (extension_uuid == nil) then
|
||||
continue = false;
|
||||
end
|
||||
|
||||
--outbound hot desking - get the extension variables
|
||||
if (continue) then
|
||||
sql = "SELECT * FROM v_extensions WHERE dial_domain = '" .. domain_name .. "' and dial_user = '" .. user .. "' and enabled = 'true' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql, function(row)
|
||||
--get the values from the database
|
||||
extension_uuid = row.extension_uuid;
|
||||
domain_uuid = row.domain_uuid;
|
||||
sip_from_user = row.extension;
|
||||
call_group = row.call_group;
|
||||
hold_music = row.hold_music;
|
||||
toll_allow = row.toll_allow;
|
||||
accountcode = row.accountcode;
|
||||
user_context = row.user_context;
|
||||
effective_caller_id_name = row.effective_caller_id_name;
|
||||
effective_caller_id_number = row.effective_caller_id_number;
|
||||
outbound_caller_id_name = row.outbound_caller_id_name;
|
||||
outbound_caller_id_number = row.outbound_caller_id_number;
|
||||
emergency_caller_id_number = row.emergency_caller_id_number;
|
||||
directory_full_name = row.directory_full_name;
|
||||
directory_visible = row.directory_visible;
|
||||
directory_exten_visible = row.directory_exten_visible;
|
||||
limit_max = row.limit_max;
|
||||
--call_timeout = row.call_timeout;
|
||||
limit_destination = row.limit_destination;
|
||||
sip_force_contact = row.sip_force_contact;
|
||||
sip_force_expires = row.sip_force_expires;
|
||||
nibble_account = row.nibble_account;
|
||||
sip_bypass_media = row.sip_bypass_media;
|
||||
end);
|
||||
end
|
||||
|
||||
--set the xml array and then concatenate the array to a string
|
||||
if (continue and password) then
|
||||
--build the xml
|
||||
local xml = {}
|
||||
table.insert(xml, [[<?xml version="1.0" encoding="UTF-8" standalone="no"?>]]);
|
||||
table.insert(xml, [[<document type="freeswitch/xml">]]);
|
||||
table.insert(xml, [[ <section name="directory">]]);
|
||||
table.insert(xml, [[ <domain name="]] .. domain_name .. [[" alias="true">]]);
|
||||
table.insert(xml, [[ <groups>]]);
|
||||
table.insert(xml, [[ <group name="default">]]);
|
||||
table.insert(xml, [[ <users>]]);
|
||||
if (number_alias) then
|
||||
if (cidr) then
|
||||
table.insert(xml, [[ <user id="]] .. extension .. [["]] .. cidr .. number_alias .. [[ type=>]]);
|
||||
else
|
||||
table.insert(xml, [[ <user id="]] .. extension .. [["]] .. number_alias .. [[>]]);
|
||||
end
|
||||
else
|
||||
if (cidr) then
|
||||
table.insert(xml, [[ <user id="]] .. extension .. [["]] .. cidr .. [[>]]);
|
||||
else
|
||||
table.insert(xml, [[ <user id="]] .. extension .. [[">]]);
|
||||
end
|
||||
end
|
||||
table.insert(xml, [[ <params>]]);
|
||||
table.insert(xml, [[ <param name="password" value="]] .. password .. [["/>]]);
|
||||
table.insert(xml, [[ <param name="vm-enabled" value="]] .. vm_enabled .. [["/>]]);
|
||||
if (string.len(vm_mailto) > 0) then
|
||||
table.insert(xml, [[ <param name="vm-password" value="]] .. vm_password .. [["/>]]);
|
||||
table.insert(xml, [[ <param name="vm-email-all-messages" value="]] .. vm_enabled ..[["/>]]);
|
||||
table.insert(xml, [[ <param name="vm-attach-file" value="]] .. vm_attach_file .. [["/>]]);
|
||||
table.insert(xml, [[ <param name="vm-keep-local-after-email" value="]] .. vm_keep_local_after_email .. [["/>]]);
|
||||
table.insert(xml, [[ <param name="vm-mailto" value="]] .. vm_mailto .. [["/>]]);
|
||||
end
|
||||
if (string.len(mwi_account) > 0) then
|
||||
table.insert(xml, [[ <param name="MWI-Account" value="]] .. mwi_account .. [["/>]]);
|
||||
end
|
||||
if (string.len(auth_acl) > 0) then
|
||||
table.insert(xml, [[ <param name="auth-acl" value="]] .. auth_acl .. [["/>]]);
|
||||
end
|
||||
table.insert(xml, [[ <param name="dial-string" value="]] .. dial_string .. [["/>]]);
|
||||
table.insert(xml, [[ </params>]]);
|
||||
table.insert(xml, [[ <variables>]]);
|
||||
table.insert(xml, [[ <variable name="domain_uuid" value="]] .. domain_uuid .. [["/>]]);
|
||||
table.insert(xml, [[ <variable name="domain_name" value="]] .. domain_name .. [["/>]]);
|
||||
table.insert(xml, [[ <variable name="extension_uuid" value="]] .. extension_uuid .. [["/>]]);
|
||||
--table.insert(xml, [[ <variable name="call_timeout" value="]] .. call_timeout .. [["/>]]);
|
||||
table.insert(xml, [[ <variable name="caller_id_name" value="]] .. sip_from_user .. [["/>]]);
|
||||
table.insert(xml, [[ <variable name="caller_id_number" value="]] .. sip_from_user .. [["/>]]);
|
||||
if (string.len(call_group) > 0) then
|
||||
table.insert(xml, [[ <variable name="call_group" value="]] .. call_group .. [["/>]]);
|
||||
end
|
||||
if (string.len(hold_music) > 0) then
|
||||
table.insert(xml, [[ <variable name="hold_music" value="]] .. hold_music .. [["/>]]);
|
||||
end
|
||||
if (string.len(toll_allow) > 0) then
|
||||
table.insert(xml, [[ <variable name="toll_allow" value="]] .. toll_allow .. [["/>]]);
|
||||
end
|
||||
if (string.len(accountcode) > 0) then
|
||||
table.insert(xml, [[ <variable name="accountcode" value="]] .. accountcode .. [["/>]]);
|
||||
end
|
||||
table.insert(xml, [[ <variable name="user_context" value="]] .. user_context .. [["/>]]);
|
||||
if (string.len(effective_caller_id_name) > 0) then
|
||||
table.insert(xml, [[ <variable name="effective_caller_id_name" value="]] .. effective_caller_id_name.. [["/>]]);
|
||||
end
|
||||
if (string.len(effective_caller_id_number) > 0) then
|
||||
table.insert(xml, [[ <variable name="effective_caller_id_number" value="]] .. effective_caller_id_number.. [["/>]]);
|
||||
end
|
||||
if (string.len(outbound_caller_id_name) > 0) then
|
||||
table.insert(xml, [[ <variable name="outbound_caller_id_name" value="]] .. outbound_caller_id_name .. [["/>]]);
|
||||
end
|
||||
if (string.len(outbound_caller_id_number) > 0) then
|
||||
table.insert(xml, [[ <variable name="outbound_caller_id_number" value="]] .. outbound_caller_id_number .. [["/>]]);
|
||||
end
|
||||
if (string.len(emergency_caller_id_number) > 0) then
|
||||
table.insert(xml, [[ <variable name="emergency_caller_id_number" value="]] .. emergency_caller_id_number .. [["/>]]);
|
||||
end
|
||||
if (string.len(directory_full_name) > 0) then
|
||||
table.insert(xml, [[ <variable name="directory_full_name" value="]] .. directory_full_name .. [["/>]]);
|
||||
end
|
||||
if (string.len(directory_visible) > 0) then
|
||||
table.insert(xml, [[ <variable name="directory-visible" value="]] .. directory_visible .. [["/>]]);
|
||||
end
|
||||
if (string.len(directory_exten_visible) > 0) then
|
||||
table.insert(xml, [[ <variable name="directory-exten-visible" value="]] .. directory_exten_visible .. [["/>]]);
|
||||
end
|
||||
if (string.len(limit_max) > 0) then
|
||||
table.insert(xml, [[ <variable name="limit_max" value="]] .. limit_max .. [["/>]]);
|
||||
else
|
||||
table.insert(xml, [[ <variable name="limit_max" value="5"/>]]);
|
||||
end
|
||||
if (string.len(limit_destination) > 0) then
|
||||
table.insert(xml, [[ <variable name="limit_destination" value="]] .. limit_destination .. [["/>]]);
|
||||
end
|
||||
if (string.len(sip_force_contact) > 0) then
|
||||
table.insert(xml, [[ <variable name="sip_force_contact" value="]] .. sip_force_contact .. [["/>]]);
|
||||
end
|
||||
if (string.len(sip_force_expires) > 0) then
|
||||
table.insert(xml, [[ <variable name="sip-force-expires" value="]] .. sip_force_expires .. [["/>]]);
|
||||
end
|
||||
if (string.len(nibble_account) > 0) then
|
||||
table.insert(xml, [[ <variable name="nibble_account" value="]] .. nibble_account .. [["/>]]);
|
||||
end
|
||||
if (sip_bypass_media == "bypass-media") then
|
||||
table.insert(xml, [[ <variable name="bypass_media" value="true"/>]]);
|
||||
end
|
||||
if (sip_bypass_media == "bypass-media-after-bridge") then
|
||||
table.insert(xml, [[ <variable name="bypass_media_after_bridge" value="true"/>]]);
|
||||
end
|
||||
if (sip_bypass_media == "proxy-media") then
|
||||
table.insert(xml, [[ <variable name="proxy_media" value="true"/>]]);
|
||||
end
|
||||
table.insert(xml, [[ <variable name="record_stereo" value="true"/>]]);
|
||||
table.insert(xml, [[ <variable name="transfer_fallback_extension" value="operator"/>]]);
|
||||
table.insert(xml, [[ <variable name="export_vars" value="domain_name"/>]]);
|
||||
table.insert(xml, [[ </variables>]]);
|
||||
table.insert(xml, [[ </user>]]);
|
||||
table.insert(xml, [[ </users>]]);
|
||||
table.insert(xml, [[ </group>]]);
|
||||
table.insert(xml, [[ </groups>]]);
|
||||
table.insert(xml, [[ </domain>]]);
|
||||
table.insert(xml, [[ </section>]]);
|
||||
table.insert(xml, [[</document>]]);
|
||||
XML_STRING = table.concat(xml, "\n");
|
||||
|
||||
--set the cache
|
||||
if (user and domain_name) then
|
||||
result = trim(api:execute("memcache", "set directory:" .. user .. "@" .. domain_name .. " '"..XML_STRING:gsub("'", "'").."' "..expire["directory"]));
|
||||
end
|
||||
|
||||
--send the xml to the console
|
||||
if (debug["xml_string"]) then
|
||||
local file = assert(io.open("/tmp/" .. user .. "@" .. domain_name .. ".xml", "w"));
|
||||
file:write(XML_STRING);
|
||||
file:close();
|
||||
end
|
||||
|
||||
--send to the console
|
||||
if (debug["cache"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] directory:" .. user .. "@" .. domain_name .. " source: database\n");
|
||||
end
|
||||
else
|
||||
--replace the ' back to a single quote
|
||||
if (XML_STRING) then
|
||||
XML_STRING = XML_STRING:gsub("'", "'");
|
||||
end
|
||||
|
||||
--send to the console
|
||||
if (debug["cache"]) then
|
||||
if (XML_STRING) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] directory:" .. user .. "@" .. domain_name .. " source: memcache \n");
|
||||
end
|
||||
end
|
||||
end
|
||||
end --if action
|
||||
|
||||
--if the extension does not exist send "not found"
|
||||
if (trim(XML_STRING) == "-ERR NOT FOUND" or XML_STRING == nil) then
|
||||
--send not found
|
||||
XML_STRING = [[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="freeswitch/xml">
|
||||
<section name="result">
|
||||
<result status="not found" />
|
||||
</section>
|
||||
</document>]];
|
||||
--set the cache
|
||||
if (user and domain_name) then
|
||||
result = trim(api:execute("memcache", "set directory:" .. user .. "@" .. domain_name .. " '"..XML_STRING:gsub("'", "'").."' "..expire["directory"]));
|
||||
end
|
||||
end
|
||||
|
||||
--send the xml to the console
|
||||
if (debug["xml_string"]) then
|
||||
freeswitch.consoleLog("notice", "[xml_handler] XML_STRING: \n" .. XML_STRING .. "\n");
|
||||
end
|
||||
174
resources/install/scripts/call_flow.lua
Normal file
174
resources/install/scripts/call_flow.lua
Normal file
@@ -0,0 +1,174 @@
|
||||
-- intercom.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set the variables
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
if (session:ready()) then
|
||||
--get the variables
|
||||
domain_name = session:getVariable("domain_name");
|
||||
call_flow_uuid = session:getVariable("call_flow_uuid");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
feature_code = session:getVariable("feature_code");
|
||||
|
||||
--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
|
||||
|
||||
--get the extension list
|
||||
sql = [[SELECT * FROM v_call_flows
|
||||
where call_flow_uuid = ']]..call_flow_uuid..[[']]
|
||||
--and call_flow_enabled = 'true'
|
||||
--freeswitch.consoleLog("notice", "SQL:" .. sql .. "\n");
|
||||
app_data = "";
|
||||
|
||||
x = 0;
|
||||
dbh:query(sql, function(row)
|
||||
call_flow_name = row.call_flow_name;
|
||||
call_flow_extension = row.call_flow_extension;
|
||||
call_flow_feature_code = row.call_flow_feature_code;
|
||||
--call_flow_context = row.call_flow_context;
|
||||
call_flow_status = row.call_flow_status;
|
||||
pin_number = row.call_flow_pin_number;
|
||||
call_flow_label = row.call_flow_label;
|
||||
call_flow_anti_label = row.call_flow_anti_label;
|
||||
|
||||
if (string.len(call_flow_status) == 0) then
|
||||
app = row.call_flow_app;
|
||||
data = row.call_flow_data
|
||||
else
|
||||
if (call_flow_status == "true") then
|
||||
app = row.call_flow_app;
|
||||
data = row.call_flow_data
|
||||
else
|
||||
app = row.call_flow_anti_app;
|
||||
data = row.call_flow_anti_data
|
||||
end
|
||||
end
|
||||
end);
|
||||
|
||||
if (feature_code == "true") then
|
||||
--if the pin number is provided then require it
|
||||
if (string.len(pin_number) > 0) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
session:answer();
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_pass:#", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile("phrase:voicemail_fail_auth:#");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--feature code - toggle the status
|
||||
if (string.len(call_flow_status) == 0) then
|
||||
toggle = "false";
|
||||
else
|
||||
if (call_flow_status == "true") then
|
||||
toggle = "false";
|
||||
else
|
||||
toggle = "true";
|
||||
end
|
||||
end
|
||||
if (toggle == "true") then
|
||||
--set the presence to terminated - turn the lamp off:
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", call_flow_feature_code.."@"..domain_name);
|
||||
event:addHeader("login", call_flow_feature_code.."@"..domain_name);
|
||||
event:addHeader("unique-id", call_flow_uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
--answer and play a tone
|
||||
session:answer();
|
||||
if (string.len(call_flow_label) > 0) then
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString("uuid_display "..session:get_uuid().." "..call_flow_label);
|
||||
end
|
||||
session:execute("sleep", "2000");
|
||||
session:execute("playback", "tone_stream://%(200,0,500,600,700)");
|
||||
--show in the console
|
||||
freeswitch.consoleLog("notice", "Call Flow: label="..call_flow_label..",status=true,uuid="..call_flow_uuid.."\n");
|
||||
else
|
||||
--set presence in - turn lamp on
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("login", call_flow_feature_code.."@"..domain_name);
|
||||
event:addHeader("from", call_flow_feature_code.."@"..domain_name);
|
||||
event:addHeader("status", "Active (1 waiting)");
|
||||
event:addHeader("rpid", "unknown");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("event_count", "1");
|
||||
event:addHeader("unique-id", call_flow_uuid);
|
||||
event:addHeader("Presence-Call-Direction", "outbound")
|
||||
event:addHeader("answer-state", "confirmed");
|
||||
event:fire();
|
||||
--answer and play a tone
|
||||
session:answer();
|
||||
if (string.len(call_flow_anti_label) > 0) then
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString("uuid_display "..session:get_uuid().." "..call_flow_anti_label);
|
||||
end
|
||||
session:execute("sleep", "2000");
|
||||
session:execute("playback", "tone_stream://%(500,0,300,200,100,50,25)");
|
||||
--show in the console
|
||||
freeswitch.consoleLog("notice", "Call Flow: label="..call_flow_anti_label..",status=false,uuid="..call_flow_uuid.."\n");
|
||||
end
|
||||
dbh:query("UPDATE v_call_flows SET call_flow_status = '"..toggle.."' WHERE call_flow_uuid = '"..call_flow_uuid.."'");
|
||||
else
|
||||
--app_data
|
||||
freeswitch.consoleLog("notice", "Call Flow: " .. app .. " " .. data .. "\n");
|
||||
|
||||
--exucute the application
|
||||
session:execute(app, data);
|
||||
--timeout application
|
||||
--if (not session:answered()) then
|
||||
-- session:execute(ring_group_timeout_app, ring_group_timeout_data);
|
||||
--end
|
||||
end
|
||||
end
|
||||
137
resources/install/scripts/call_flow_monitor.lua
Normal file
137
resources/install/scripts/call_flow_monitor.lua
Normal file
@@ -0,0 +1,137 @@
|
||||
-- call_flow_monitor.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set the time between loops in seconds
|
||||
sleep = 300;
|
||||
|
||||
--set the debug level
|
||||
debug["log"] = false;
|
||||
debug["sql"] = false;
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--general functions
|
||||
dofile(scripts_dir.."/resources/functions/file_exists.lua");
|
||||
dofile(scripts_dir.."/resources/functions/mkdir.lua");
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--make sure the scripts/run dir exists
|
||||
mkdir(scripts_dir .. "/run");
|
||||
|
||||
--define the run file
|
||||
run_file = scripts_dir .. "/run/call_flow_monitor.tmp";
|
||||
|
||||
--define the functions
|
||||
--shell return results
|
||||
function shell(c)
|
||||
local o, h
|
||||
h = assert(io.popen(c,"r"))
|
||||
o = h:read("*all")
|
||||
h:close()
|
||||
return o
|
||||
end
|
||||
|
||||
--used to stop the lua service
|
||||
local file = assert(io.open(run_file, "w"));
|
||||
file:write("remove this file to stop the script");
|
||||
|
||||
--monitor the call flows status
|
||||
x = 0
|
||||
while true do
|
||||
--get the extension list
|
||||
sql = [[select d.domain_name, f.call_flow_uuid, f.call_flow_extension, f.call_flow_feature_code, f.call_flow_status, f.call_flow_label, f.call_flow_anti_label
|
||||
from v_call_flows as f, v_domains as d
|
||||
where f.domain_uuid = d.domain_uuid]]
|
||||
--and call_flow_enabled = 'true'
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "SQL:" .. sql .. "\n");
|
||||
end
|
||||
x = 0;
|
||||
dbh:query(sql, function(row)
|
||||
domain_name = row.domain_name;
|
||||
call_flow_uuid = row.call_flow_uuid;
|
||||
--call_flow_name = row.call_flow_name;
|
||||
call_flow_extension = row.call_flow_extension;
|
||||
call_flow_feature_code = row.call_flow_feature_code;
|
||||
--call_flow_context = row.call_flow_context;
|
||||
call_flow_status = row.call_flow_status;
|
||||
--pin_number = row.call_flow_pin_number;
|
||||
call_flow_label = row.call_flow_label;
|
||||
call_flow_anti_label = row.call_flow_anti_label;
|
||||
|
||||
if (call_flow_status == "true") then
|
||||
--set the presence to terminated - turn the lamp off:
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", call_flow_feature_code.."@"..domain_name);
|
||||
event:addHeader("login", call_flow_feature_code.."@"..domain_name);
|
||||
event:addHeader("unique-id", call_flow_uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
--show in the console
|
||||
if (debug["log"]) then
|
||||
freeswitch.consoleLog("notice", "Call Flow: label="..call_flow_label..",status=true,uuid="..call_flow_uuid.."\n");
|
||||
end
|
||||
else
|
||||
--set presence in - turn lamp on
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("login", call_flow_feature_code.."@"..domain_name);
|
||||
event:addHeader("from", call_flow_feature_code.."@"..domain_name);
|
||||
event:addHeader("status", "Active (1 waiting)");
|
||||
event:addHeader("rpid", "unknown");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("event_count", "1");
|
||||
event:addHeader("unique-id", call_flow_uuid);
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("answer-state", "confirmed");
|
||||
event:fire();
|
||||
--show in the console
|
||||
if (debug["log"]) then
|
||||
freeswitch.consoleLog("notice", "Call Flow: label="..call_flow_anti_label..",status=false,uuid="..call_flow_uuid.."\n");
|
||||
end
|
||||
end
|
||||
end);
|
||||
|
||||
--exit the loop when the file does not exist
|
||||
if (not file_exists(run_file)) then
|
||||
break;
|
||||
end
|
||||
|
||||
--sleep a moment to prevent using unecessary resources
|
||||
freeswitch.msleep(sleep*1000);
|
||||
end
|
||||
127
resources/install/scripts/call_forward.lua
Normal file
127
resources/install/scripts/call_forward.lua
Normal file
@@ -0,0 +1,127 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
|
||||
function file_exists(fname)
|
||||
local f = io.open(fname, "r")
|
||||
if (f and f:read()) then return true end
|
||||
end
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
--session:execute("info", "");
|
||||
extension = session:getVariable("user_name");
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
dialplan_default_dir = session:getVariable("dialplan_default_dir");
|
||||
call_forward_number = session:getVariable("call_forward_number");
|
||||
extension_required = session:getVariable("extension_required");
|
||||
context = session:getVariable("context");
|
||||
if (not context ) then context = 'default'; end
|
||||
|
||||
--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
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--if extension_requires is true then get the extension number
|
||||
if (extension_required) then
|
||||
if (extension_required == "true") then
|
||||
extension = session:playAndGetDigits(3, 6, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_extension_number.wav", "", "\\d+");
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (file_exists(dialplan_default_dir.."/000_call_forward_"..extension..".xml")) then
|
||||
--file exists
|
||||
|
||||
--remove the call forward dialplan entry
|
||||
os.remove (dialplan_default_dir.."/000_call_forward_"..extension..".xml");
|
||||
|
||||
--stream file
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/call_forward_has_been_deleted.wav");
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
session:sleep(1000);
|
||||
|
||||
else
|
||||
--file does not exist
|
||||
|
||||
dtmf = ""; --clear dtmf digits to prepare for next dtmf request
|
||||
if (call_forward_number) then
|
||||
-- do nothing
|
||||
else
|
||||
-- get the call forward number
|
||||
call_forward_number = session:playAndGetDigits(3, 15, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_phone_number.wav", "", "\\d+");
|
||||
end
|
||||
if (string.len(call_forward_number) > 0) then
|
||||
--write the xml file
|
||||
xml = "<extension name=\"call_forward_"..extension.."\" >\n";
|
||||
xml = xml .. " <condition field=\"destination_number\" expression=\"^"..extension.."$\">\n";
|
||||
xml = xml .. " <action application=\"transfer\" data=\""..call_forward_number.." XML "..context.."\"/>\n";
|
||||
xml = xml .. " </condition>\n";
|
||||
xml = xml .. "</extension>\n";
|
||||
session:execute("log", xml);
|
||||
local file = assert(io.open(dialplan_default_dir.."/000_call_forward_"..extension..".xml", "w"));
|
||||
file:write(xml);
|
||||
file:close();
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
--session:sleep(20000);
|
||||
|
||||
--stream file
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/call_forward_has_been_set.wav");
|
||||
end
|
||||
end
|
||||
|
||||
--reloadxml
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString("reloadxml");
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
session:sleep(1000);
|
||||
|
||||
session:hangup();
|
||||
|
||||
end
|
||||
78
resources/install/scripts/confirm.lua
Normal file
78
resources/install/scripts/confirm.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
context = session:getVariable("context");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
destination_number = session:getVariable("destination_number");
|
||||
|
||||
--prepare the api
|
||||
api = freeswitch.API();
|
||||
|
||||
--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
|
||||
|
||||
--confirm the calls
|
||||
--set the default
|
||||
prompt_for_digits = true;
|
||||
--if an extension answer the call
|
||||
-- user_exists id 1005 voip.fusionpbx.com
|
||||
cmd = "user_exists id ".. destination_number .." "..context;
|
||||
result = api:executeString(cmd);
|
||||
freeswitch.consoleLog("NOTICE", "[confirm] "..cmd.." --"..result.."--\n");
|
||||
if (result == "true") then
|
||||
prompt_for_digits = false;
|
||||
end
|
||||
--prompt for digits
|
||||
if (prompt_for_digits) then
|
||||
--get the digit
|
||||
min_digits = 1;
|
||||
max_digits = 1;
|
||||
digit = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-accept_reject_voicemail.wav", "", "\\d+");
|
||||
--process the response
|
||||
if (digit == "1") then
|
||||
--freeswitch.consoleLog("NOTICE", "[confirm] accept\n");
|
||||
elseif (digit == "2") then
|
||||
--freeswitch.consoleLog("NOTICE", "[confirm] reject\n");
|
||||
session:hangup("CALL_REJECTED"); --LOSE_RACE
|
||||
elseif (digit == "3") then
|
||||
--freeswitch.consoleLog("NOTICE", "[confirm] voicemail\n");
|
||||
session:hangup("NO_ANSWER");
|
||||
else
|
||||
--freeswitch.consoleLog("NOTICE", "[confirm] no answer\n");
|
||||
session:hangup("NO_ANSWER");
|
||||
end
|
||||
else
|
||||
--freeswitch.consoleLog("NOTICE", "[confirm] automatically accepted\n");
|
||||
end
|
||||
end
|
||||
70
resources/install/scripts/destination_caller_id.lua
Normal file
70
resources/install/scripts/destination_caller_id.lua
Normal file
@@ -0,0 +1,70 @@
|
||||
-- intercom.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--add a trim function
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
--get the variables
|
||||
domain_name = session:getVariable("domain_name");
|
||||
outbound_number = session:getVariable("destination_number");
|
||||
freeswitch.consoleLog("notice", "outbound_number: --" .. outbound_number .. "--\n");
|
||||
outbound_area_code = string.sub(outbound_number,3,5);
|
||||
freeswitch.consoleLog("notice", "Area Code: " .. outbound_area_code .. "\n");
|
||||
|
||||
--caller_id_name = session:getVariable("caller_id_name");
|
||||
--caller_id_number = session:getVariable("caller_id_number");
|
||||
|
||||
--get the destination_number
|
||||
sql = [[ SELECT * FROM v_destinations
|
||||
where destination_number like '1]].. outbound_area_code ..[[%']]
|
||||
freeswitch.consoleLog("notice", "SQL:" .. sql .. "\n");
|
||||
x = 0;
|
||||
dbh:query(sql, function(row)
|
||||
destination_number = row.destination_number;
|
||||
--destination_caller_id_name = row.destination_caller_id_name;
|
||||
--destination_caller_id_number = row.destination_caller_id_number;
|
||||
x = x + 1;
|
||||
end);
|
||||
|
||||
--session actions
|
||||
if (session:ready()) then
|
||||
if (destination_number) then
|
||||
freeswitch.consoleLog("notice", "effective_caller_id_number="..destination_number.."\n");
|
||||
session:execute("set", "effective_caller_id_number="..destination_number);
|
||||
end
|
||||
--session:hangup();
|
||||
end
|
||||
201
resources/install/scripts/dial_string.lua
Normal file
201
resources/install/scripts/dial_string.lua
Normal file
@@ -0,0 +1,201 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
--set default variables
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
--set the debug level
|
||||
debug["sql"] = false;
|
||||
debug["var"] = false;
|
||||
db_dial_string = "";
|
||||
db_extension_uuid = "";
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
domain_uuid = session:getVariable("domain_uuid");
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
sip_from_user = session:getVariable("sip_from_user");
|
||||
sip_from_host = session:getVariable("sip_from_host");
|
||||
direction = session:getVariable("direction"); --in, out, both
|
||||
extension = tostring(session:getVariable("extension")); --true, false
|
||||
dial_string = tostring(session:getVariable("dial_string"));
|
||||
if (dial_string == "nil") then dial_string = ""; end
|
||||
|
||||
--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
|
||||
|
||||
--get the unique_id
|
||||
min_digits = 1;
|
||||
max_digits = 15;
|
||||
unique_id = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_id:#", "", "\\d+");
|
||||
|
||||
--add the unique_id value to the dial_string
|
||||
if (string.len(dial_string) > 0) then
|
||||
dial_string = string.gsub(dial_string, '{v_unique_id}', unique_id);
|
||||
end
|
||||
|
||||
--authenticate the user
|
||||
if (pin_number) then
|
||||
--get the pin number from the caller
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
caller_pin_number = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_pass:#", "", "\\d+");
|
||||
else
|
||||
--get the vm_password
|
||||
min_digits = 1;
|
||||
max_digits = 12;
|
||||
vm_password = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_pass:#", "", "\\d+");
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("NOTICE", "unique_id ".. unique_id .. " vm_password " .. vm_password .. "\n");
|
||||
end
|
||||
end
|
||||
|
||||
--get the dial_string, and extension_uuid
|
||||
sql = "SELECT * FROM v_extensions as e, v_domains as d ";
|
||||
sql = sql .. "WHERE e.domain_uuid = d.domain_uuid ";
|
||||
if (extension == "true") then
|
||||
sql = sql .. "AND e.extension = '" .. unique_id .."' ";
|
||||
sql = sql .. "AND e.domain_uuid = '" .. domain_uuid .."' ";
|
||||
else
|
||||
sql = sql .. "AND e.unique_id = '" .. unique_id .."' ";
|
||||
end
|
||||
if (pin_number) then
|
||||
--do nothing
|
||||
else
|
||||
sql = sql .. "AND e.vm_password = '" .. vm_password .."' ";
|
||||
end
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("NOTICE", "sql: ".. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql, function(row)
|
||||
db_domain_uuid = row.domain_uuid;
|
||||
db_extension_uuid = row.extension_uuid;
|
||||
db_dial_string = row.dial_string;
|
||||
db_dial_user = row.dial_user;
|
||||
db_dial_domain = row.dial_domain;
|
||||
end);
|
||||
|
||||
--check to see if the pin number is correct
|
||||
if (pin_number) then
|
||||
if (pin_number ~= caller_pin_number) then
|
||||
--access denied
|
||||
db_extension_uuid = "";
|
||||
end
|
||||
end
|
||||
|
||||
if (string.len(db_extension_uuid) > 0) then
|
||||
--add the dial string
|
||||
if (direction == "in") then
|
||||
if (string.len(dial_string) == 0) then
|
||||
dial_string = [[{sip_invite_domain=]] .. sip_from_host .. [[,presence_id=]] .. sip_from_user .. [[@]] .. sip_from_host .. [[}${sofia_contact(]] .. sip_from_user .. [[@]] .. sip_from_host .. [[)}]];
|
||||
end
|
||||
sql = "UPDATE v_extensions SET ";
|
||||
sql = sql .. "dial_string = '" .. dial_string .."', ";
|
||||
sql = sql .. "dial_user = '" .. sip_from_user .."', ";
|
||||
sql = sql .. "dial_domain = '" .. sip_from_host .."' ";
|
||||
sql = sql .. "WHERE extension_uuid = '" .. db_extension_uuid .."' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("NOTICE", "[dial_string] sql: ".. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/voicemail/vm-saved.wav");
|
||||
end
|
||||
--remove the dialstring
|
||||
if (direction == "out") then
|
||||
--if the the dial_string has a value then clear the dial string
|
||||
sql = "UPDATE v_extensions SET ";
|
||||
sql = sql .. "dial_string = null, ";
|
||||
sql = sql .. "dial_user = null, ";
|
||||
sql = sql .. "dial_domain = null ";
|
||||
sql = sql .. "WHERE extension_uuid = '" .. db_extension_uuid .."' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("NOTICE", "[dial_string] sql: ".. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/voicemail/vm-deleted.wav");
|
||||
end
|
||||
--toggle the dial string
|
||||
if (direction == "both") then
|
||||
if (string.len(db_dial_string) > 1) then
|
||||
--if the the dial_string has a value then clear the dial string
|
||||
sql = "UPDATE v_extensions SET ";
|
||||
sql = sql .. "dial_string = null, ";
|
||||
sql = sql .. "dial_user = null, ";
|
||||
sql = sql .. "dial_domain = null ";
|
||||
sql = sql .. "WHERE extension_uuid = '" .. db_extension_uuid .."' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("NOTICE", "[dial_string] sql: ".. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/voicemail/vm-deleted.wav");
|
||||
else
|
||||
--if the dial string is empty then set the dial string
|
||||
if (string.len(dial_string) == 0) then
|
||||
dial_string = [[{sip_invite_domain=]] .. sip_from_host .. [[,presence_id=]] .. sip_from_user .. [[@]] .. sip_from_host .. [[}${sofia_contact(]] .. sip_from_user .. [[@]] .. sip_from_host .. [[)}]];
|
||||
end
|
||||
sql = "UPDATE v_extensions SET ";
|
||||
sql = sql .. "dial_string = '" .. dial_string .."', ";
|
||||
sql = sql .. "dial_user = '" .. sip_from_user .."', ";
|
||||
sql = sql .. "dial_domain = '" .. sip_from_host .."' ";
|
||||
sql = sql .. "WHERE extension_uuid = '" .. db_extension_uuid .."' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("NOTICE", "[dial_string] sql: ".. sql .. "\n");
|
||||
end
|
||||
dbh:query(sql);
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/voicemail/vm-saved.wav");
|
||||
end
|
||||
end
|
||||
else
|
||||
session:streamFile("phrase:voicemail_fail_auth:#");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
|
||||
--log to the console
|
||||
if (debug["var"]) then
|
||||
freeswitch.consoleLog("NOTICE", "sip_from_host: ".. sip_from_host .. "\n");
|
||||
freeswitch.consoleLog("NOTICE", "extension_uuid: ".. extension_uuid .. "\n");
|
||||
freeswitch.consoleLog("NOTICE", "dial_string: ".. dial_string .. "\n");
|
||||
end
|
||||
|
||||
--show call variables
|
||||
--session:execute("info", "");
|
||||
|
||||
end
|
||||
330
resources/install/scripts/directory.lua
Normal file
330
resources/install/scripts/directory.lua
Normal file
@@ -0,0 +1,330 @@
|
||||
-- directory.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2012 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set the defaults
|
||||
digit_max_length = 3;
|
||||
timeout_pin = 5000;
|
||||
timeout_transfer = 5000;
|
||||
max_tries = 3;
|
||||
digit_timeout = 5000;
|
||||
search_limit = 3;
|
||||
search_count = 0;
|
||||
|
||||
--debug
|
||||
debug["info"] = false;
|
||||
debug["sql"] = false;
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--prepare the api object
|
||||
api = freeswitch.API();
|
||||
|
||||
--get the session variables
|
||||
if ( session:ready() ) then
|
||||
--answer the session
|
||||
session:answer();
|
||||
|
||||
--give time for the call to be ready
|
||||
session:streamFile("silence_stream://1000");
|
||||
|
||||
--get the domain info
|
||||
domain_name = session:getVariable("domain_name");
|
||||
domain_uuid = session:getVariable("domain_uuid");
|
||||
|
||||
--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 the sounds path for the language, dialect and voice
|
||||
ringback = session:getVariable("ringback");
|
||||
if (ringback) then
|
||||
ringback = ringback:gsub("$", "");
|
||||
ringback = ringback:gsub("{", "");
|
||||
ringback = ringback:gsub("}", "");
|
||||
end
|
||||
session:setVariable("instant_ringback", "true");
|
||||
session:setVariable("ignore_early_media", "true");
|
||||
if (not ringback) then
|
||||
session:execute("set", "ringback=local_stream://default"); --set to ringtone
|
||||
session:execute("set", "transfer_ringback=local_stream://default"); --set to ringtone
|
||||
elseif (ringback == "uk-ring") then
|
||||
session:setVariable("ringback", "%(400,200,400,450);%(400,2200,400,450)");
|
||||
session:setVariable("transfer_ringback", "%(400,200,400,450);%(400,2200,400,450)");
|
||||
elseif (ringback == "us-ring") then
|
||||
session:setVariable("ringback", "%(2000, 4000, 440.0, 480.0)");
|
||||
session:setVariable("transfer_ringback", "%(2000, 4000, 440.0, 480.0)");
|
||||
elseif (ringback == "fr-ring") then
|
||||
session:setVariable("ringback", "%(1500, 3500, 440.0, 0.0)");
|
||||
session:setVariable("transfer_ringback", "%(1500, 3500, 440.0, 0.0)");
|
||||
elseif (ringback == "rs-ring") then
|
||||
session:setVariable("ringback", "%(1000, 4000, 425.0, 0.0)");
|
||||
session:setVariable("transfer_ringback", "%(1000, 4000, 425.0, 0.0)");
|
||||
else
|
||||
session:execute("set", "ringback=local_stream://default"); --set to ringtone
|
||||
session:execute("set", "transfer_ringback=local_stream://default"); --set to ringtone
|
||||
end
|
||||
|
||||
--define the sounds directory
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
sounds_dir = sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice;
|
||||
end
|
||||
|
||||
--get session variables
|
||||
base_dir = session:getVariable("base_dir");
|
||||
|
||||
--set the voicemail_dir
|
||||
voicemail_dir = base_dir.."/storage/voicemail/default/"..domain_name;
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[directory] voicemail_dir: " .. voicemail_dir .. "\n");
|
||||
end
|
||||
|
||||
--get the domain_uuid
|
||||
if (domain_uuid == nil) then
|
||||
if (domain_name ~= nil) then
|
||||
sql = "SELECT domain_uuid FROM v_domains ";
|
||||
sql = sql .. "WHERE domain_name = '" .. domain_name .."' ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[conference] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(rows)
|
||||
domain_uuid = string.lower(rows["domain_uuid"]);
|
||||
end);
|
||||
end
|
||||
end
|
||||
|
||||
--define explode
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
--define a function to convert dialpad letters to numbers
|
||||
function dialpad_to_digit(letter)
|
||||
letter = string.lower(letter);
|
||||
if (letter == "a" or letter == "b" or letter == "c") then
|
||||
digit = "2";
|
||||
elseif (letter == "d" or letter == "e" or letter == "f") then
|
||||
digit = "3";
|
||||
elseif (letter == "g" or letter == "h" or letter == "i") then
|
||||
digit = "4";
|
||||
elseif (letter == "j" or letter == "k" or letter == "l") then
|
||||
digit = "5";
|
||||
elseif (letter == "m" or letter == "n" or letter == "o") then
|
||||
digit = "6";
|
||||
elseif (letter == "p" or letter == "q" or letter == "r" or letter == "s") then
|
||||
digit = "7";
|
||||
elseif (letter == "t" or letter == "u" or letter == "v") then
|
||||
digit = "8";
|
||||
elseif (letter == "w" or letter == "x" or letter == "y" or letter == "z") then
|
||||
digit = "9";
|
||||
end
|
||||
return digit;
|
||||
end
|
||||
--print(dialpad_to_digit("m"));
|
||||
|
||||
--define table_count
|
||||
function table_count(T)
|
||||
local count = 0
|
||||
for _ in pairs(T) do count = count + 1 end
|
||||
return count
|
||||
end
|
||||
|
||||
--define trim
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
--check if a file exists
|
||||
function file_exists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
end
|
||||
|
||||
--define select_entry function
|
||||
function select_entry()
|
||||
dtmf_digits = "";
|
||||
digit_timeout = "500";
|
||||
max_digits = 1;
|
||||
max_tries = 1;
|
||||
dtmf_digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/directory/dir-to_select_entry.wav", "", "\\d+");
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
dtmf_digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/voicemail/vm-press.wav", "", "\\d+");
|
||||
end
|
||||
if (string.len(dtmf_digits) == 0) then
|
||||
digit_timeout = "3000";
|
||||
dtmf_digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/digits/1.wav", "", "\\d+");
|
||||
end
|
||||
return dtmf_digits;
|
||||
end
|
||||
|
||||
--define prompt_for_name function
|
||||
function prompt_for_name()
|
||||
dtmf_digits = "";
|
||||
min_digits=0; max_digits=3; max_tries=3; digit_timeout = "5000";
|
||||
dtmf_digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/directory/dir-enter_person_first_or_last.wav", "", "\\d+");
|
||||
return dtmf_digits;
|
||||
end
|
||||
|
||||
--define the directory_search function
|
||||
function directory_search()
|
||||
|
||||
--get the digits for the name
|
||||
dtmf_digits = prompt_for_name();
|
||||
|
||||
--show the dtmf digits
|
||||
freeswitch.consoleLog("notice", "[directory] first 3 letters of first or last name: " .. dtmf_digits .. "\n");
|
||||
|
||||
--loop through the extensions to find matches
|
||||
search_dtmf_digits = dtmf_digits;
|
||||
found = false;
|
||||
for key,row in pairs(directory) do
|
||||
|
||||
--if (row.first_name and row.last_name) then
|
||||
-- freeswitch.consoleLog("notice", "[directory] ext: " .. row.extension .. " context " .. row.context .. " name " .. row.first_name .. " "..row.first_name_digits.." ".. row.last_name .. " "..row.last_name_digits.." "..row.directory_exten_visible.."\n");
|
||||
--else
|
||||
-- freeswitch.consoleLog("notice", "[directory] ext: " .. row.extension .. " context " .. row.context .. "\n");
|
||||
--end
|
||||
|
||||
if (search_dtmf_digits == row.last_name_digits) or (search_dtmf_digits == row.first_name_digits) then
|
||||
if (row.first_name and row.last_name) then
|
||||
if (debug["info"]) then
|
||||
freeswitch.consoleLog("notice", "[directory] path: "..voicemail_dir.."/"..row.extension.."/recorded_name.wav\n");
|
||||
end
|
||||
if (file_exists(voicemail_dir.."/"..row.extension.."/recorded_name.wav")) then
|
||||
session:streamFile(voicemail_dir.."/"..row.extension.."/recorded_name.wav");
|
||||
else
|
||||
--announce the first and last names
|
||||
session:execute("say", "en name_spelled iterated "..row.first_name);
|
||||
--session:execute("sleep", "500");
|
||||
session:execute("say", "en name_spelled iterated "..row.last_name);
|
||||
end
|
||||
|
||||
--announce the extension number
|
||||
if (row.directory_exten_visible == "false") then
|
||||
--invisible extension number
|
||||
else
|
||||
session:streamFile(sounds_dir.."/directory/dir-at_extension.wav");
|
||||
session:execute("say", "en number iterated "..row.extension);
|
||||
end
|
||||
|
||||
--select this entry press 1
|
||||
dtmf_digits = select_entry();
|
||||
|
||||
--if 1 is pressed then transfer the call
|
||||
if (dtmf_digits == "1") then
|
||||
session:execute("transfer", row.extension.." XML "..row.context);
|
||||
end
|
||||
end
|
||||
found = true;
|
||||
end
|
||||
end
|
||||
if (found ~= true) then
|
||||
session:streamFile(sounds_dir.."/directory/dir-no_matching_results.wav");
|
||||
end
|
||||
search_count = search_count + 1;
|
||||
if (search_count < search_limit) then
|
||||
directory_search();
|
||||
end
|
||||
end
|
||||
|
||||
--get the extensions from the database
|
||||
sql = "SELECT * FROM v_extensions WHERE domain_uuid = '" .. domain_uuid .. "' AND enabled = 'true' AND (directory_visible is null or directory_visible = 'true'); ";
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[directory] SQL: " .. sql .. "\n");
|
||||
end
|
||||
x = 1;
|
||||
directory = {}
|
||||
dbh:query(sql, function(row)
|
||||
--show all key value pairs
|
||||
--for key, val in pairs(row) do
|
||||
-- freeswitch.consoleLog("notice", "[directory] Key: " .. key .. " Value: " .. val .. "\n");
|
||||
--end
|
||||
--add the entire row to the directory table array
|
||||
--directory[x] = row;
|
||||
--variables
|
||||
effective_caller_id_name = row.effective_caller_id_name;
|
||||
if (row.directory_full_name) then
|
||||
name = row.directory_full_name;
|
||||
else
|
||||
if (row.directory_full_name) then
|
||||
name = row.effective_caller_id_name;
|
||||
end
|
||||
end
|
||||
if (name) then
|
||||
name_table = explode(" ",name);
|
||||
first_name = name_table[1];
|
||||
last_name = name_table[2];
|
||||
if (first_name) then
|
||||
if (string.len(first_name) > 0) then
|
||||
--freeswitch.consoleLog("notice", "[directory] first_name: --" .. first_name .. "--\n");
|
||||
first_name_digits = dialpad_to_digit(string.sub(first_name, 1, 1))..dialpad_to_digit(string.sub(first_name, 2, 2))..dialpad_to_digit(string.sub(first_name, 3, 3));
|
||||
end
|
||||
end
|
||||
if (last_name) then
|
||||
if (string.len(last_name) > 0) then
|
||||
--freeswitch.consoleLog("notice", "[directory] last_name: --" .. last_name .. "--\n");
|
||||
last_name_digits = dialpad_to_digit(string.sub(last_name, 1, 1))..dialpad_to_digit(string.sub(last_name, 2, 2))..dialpad_to_digit(string.sub(last_name, 3, 3));
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
--add the row to the array
|
||||
table.insert(directory, {extension=row.extension,context=row.user_context,first_name=name_table[1],last_name=name_table[2],first_name_digits=first_name_digits,last_name_digits=last_name_digits,directory_exten_visible=row.directory_exten_visible});
|
||||
|
||||
--increment x
|
||||
x = x + 1;
|
||||
end);
|
||||
|
||||
--call the directory search function
|
||||
if (session:ready()) then
|
||||
directory_search();
|
||||
end
|
||||
|
||||
--notes
|
||||
--session:execute("say", "en name_spelled pronounced mark");
|
||||
--<action application="say" data="en name_spelled iterated ${destination_number}"/>
|
||||
--session:execute("say", "en number iterated 12345");
|
||||
--session:execute("say", "en number pronounced 1001");
|
||||
--session:execute("say", "en short_date_time pronounced [timestamp]");
|
||||
--session:execute("say", "en CURRENT_TIME pronounced CURRENT_TIME");
|
||||
--session:execute("say", "en CURRENT_DATE pronounced CURRENT_DATE");
|
||||
--session:execute("say", "en CURRENT_DATE_TIME pronounced CURRENT_DATE_TIME");
|
||||
155
resources/install/scripts/disa.lua
Normal file
155
resources/install/scripts/disa.lua
Normal file
@@ -0,0 +1,155 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
predefined_destination = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
caller_id_name = session:getVariable("caller_id_name");
|
||||
caller_id_number = session:getVariable("caller_id_number");
|
||||
predefined_destination = session:getVariable("predefined_destination");
|
||||
digit_min_length = session:getVariable("digit_min_length");
|
||||
digit_max_length = session:getVariable("digit_max_length");
|
||||
gateway = session:getVariable("gateway");
|
||||
context = session:getVariable("context");
|
||||
|
||||
--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
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-please_enter_pin_followed_by_pound.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-pin_or_extension_is-invalid.wav");
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-im_sorry.wav");
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/voicemail/vm-goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--if a predefined_destination is provided then set the number to the predefined_destination
|
||||
if (predefined_destination) then
|
||||
destination_number = predefined_destination;
|
||||
else
|
||||
dtmf = ""; --clear dtmf digits to prepare for next dtmf request
|
||||
destination_number = session:playAndGetDigits(digit_min_length, digit_max_length, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-enter_destination_telephone_number.wav", "", "\\d+");
|
||||
--if (string.len(destination_number) == 10) then destination_number = "1"..destination_number; end
|
||||
end
|
||||
|
||||
--set the caller id anme and number
|
||||
if (string.len(destination_number) < 7) then
|
||||
if (caller_id_name) then
|
||||
--caller id name provided do nothing
|
||||
else
|
||||
caller_id_number = session:getVariable("effective_caller_id_name");
|
||||
end
|
||||
if (caller_id_number) then
|
||||
--caller id number provided do nothing
|
||||
else
|
||||
caller_id_number = session:getVariable("effective_caller_id_number");
|
||||
end
|
||||
else
|
||||
if (caller_id_name) then
|
||||
--caller id name provided do nothing
|
||||
else
|
||||
caller_id_number = session:getVariable("outbound_caller_id_name");
|
||||
end
|
||||
if (caller_id_number) then
|
||||
--caller id number provided do nothing
|
||||
else
|
||||
caller_id_number = session:getVariable("outbound_caller_id_number");
|
||||
end
|
||||
end
|
||||
|
||||
--transfer or bridge the call
|
||||
if (string.len(destination_number) < 7) then
|
||||
--local call
|
||||
session:execute("transfer", destination_number .. " XML " .. context);
|
||||
else
|
||||
--remote call
|
||||
if (gateway) then
|
||||
gateway_table = explode(",",gateway);
|
||||
for index,value in pairs(gateway_table) do
|
||||
session:execute("bridge", "{continue_on_fail=true,hangup_after_bridge=true,origination_caller_id_name="..caller_id_name..",origination_caller_id_number="..caller_id_number.."}sofia/gateway/"..value.."/"..destination_number);
|
||||
end
|
||||
else
|
||||
session:execute("set", "effective_caller_id_name="..caller_id_name);
|
||||
session:execute("set", "effective_caller_id_number="..caller_id_number);
|
||||
session:execute("transfer", destination_number .. " XML " .. context);
|
||||
end
|
||||
end
|
||||
|
||||
--alternate method
|
||||
--local session2 = freeswitch.Session("{ignore_early_media=true}sofia/gateway/flowroute.com/"..destination_number);
|
||||
--t1 = os.date('*t');
|
||||
--call_start_time = os.time(t1);
|
||||
--freeswitch.bridge(session, session2);
|
||||
end
|
||||
|
||||
--function HangupHook(s, status, arg)
|
||||
--session:execute("info", "");
|
||||
--freeswitch.consoleLog("NOTICE", "HangupHook: " .. status .. "\n");
|
||||
--end
|
||||
--session:setHangupHook("HangupHook", "");
|
||||
113
resources/install/scripts/eavesdrop.lua
Normal file
113
resources/install/scripts/eavesdrop.lua
Normal file
@@ -0,0 +1,113 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
extension = argv[1];
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--add the file_exists function
|
||||
dofile(scripts_dir.."/resources/functions/file_exists.lua");
|
||||
|
||||
--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
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('switch');
|
||||
end
|
||||
|
||||
--exits the script if we didn't connect properly
|
||||
assert(dbh:connected());
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
domain_name = session:getVariable("domain_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
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--check the database to get the uuid
|
||||
--eavesdrop
|
||||
sql = "select uuid from channels where presence_id = '"..extension.."@"..domain_name.."' ";
|
||||
dbh:query(sql, function(result)
|
||||
for key, val in pairs(result) do
|
||||
freeswitch.consoleLog("NOTICE", "result "..key.." "..val.."\n");
|
||||
end
|
||||
uuid = result.uuid;
|
||||
end);
|
||||
|
||||
end
|
||||
|
||||
--eavesdrop
|
||||
if (uuid) then
|
||||
session:execute("eavesdrop", uuid); --call barge
|
||||
end
|
||||
|
||||
--notes
|
||||
--originate a call
|
||||
--cmd = "originate user/1007@voip.example.com &eavesdrop("..uuid..")";
|
||||
--cmd = "uuid_bridge "..caller_uuid.." "..uuid;
|
||||
--api = freeswitch.API();
|
||||
--result = api:executeString(cmd);
|
||||
88
resources/install/scripts/email.lua
Normal file
88
resources/install/scripts/email.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
-- email.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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
|
||||
--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 email.lua to@domain.com from@domain.com 'subject' 'body'
|
||||
|
||||
--get the argv values
|
||||
script_name = argv[0];
|
||||
to = argv[1];
|
||||
from = argv[2];
|
||||
subject = argv[3];
|
||||
body = argv[4];
|
||||
file = argv[5];
|
||||
delete = argv[6];
|
||||
--convert_cmd = argv[7];
|
||||
--convert_ext = argv[8];
|
||||
|
||||
--replace the ' with a single quote
|
||||
body = body:gsub("'", "'");
|
||||
|
||||
--replace the " with double quote
|
||||
body = body:gsub(""", [["]]);
|
||||
|
||||
--send the email
|
||||
if (file == nil) then
|
||||
freeswitch.email("",
|
||||
"",
|
||||
"To: "..to.."\nFrom: "..from.."\nSubject: "..subject,
|
||||
body
|
||||
);
|
||||
else
|
||||
if (convert_cmd == nil) then
|
||||
freeswitch.email("",
|
||||
"",
|
||||
"To: "..to.."\nFrom: "..from.."\nSubject: "..subject,
|
||||
body,
|
||||
file
|
||||
);
|
||||
else
|
||||
freeswitch.email("",
|
||||
"",
|
||||
"To: "..to.."\nFrom: "..from.."\nSubject: "..subject,
|
||||
body,
|
||||
file,
|
||||
convert_cmd,
|
||||
convert_ext
|
||||
);
|
||||
end
|
||||
end
|
||||
|
||||
--delete the file
|
||||
if (delete == "true") then
|
||||
os.remove(file);
|
||||
end
|
||||
186
resources/install/scripts/fax_retry.lua
Normal file
186
resources/install/scripts/fax_retry.lua
Normal file
@@ -0,0 +1,186 @@
|
||||
--contribtors: Mark J. Crane, James O. Rose
|
||||
|
||||
--set default variables
|
||||
fax_retry_sleep = 30;
|
||||
fax_retry_limit = 4;
|
||||
fax_busy_limit = 3;
|
||||
api = freeswitch.API();
|
||||
|
||||
-- show all channel variables
|
||||
--dat = env:serialize()
|
||||
--freeswitch.consoleLog("INFO","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");
|
||||
fax_success = env:getHeader("fax_success");
|
||||
fax_result_text = env:getHeader("fax_result_text");
|
||||
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");
|
||||
|
||||
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"));
|
||||
|
||||
--set default values
|
||||
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
|
||||
|
||||
--for email
|
||||
email_address = env:getHeader("mailto_address");
|
||||
--email_address = api:execute("system", "/bin/echo -n "..email_address.." | /bin/sed -e s/\,/\\\\,/g");
|
||||
email_address = email_address:gsub(",", "\\,");
|
||||
from_address = env:getHeader("mailfrom_address");
|
||||
--needs to be fixed on lesser operating systems that do not have GNU utils.
|
||||
number_dialed = api:execute("system", "/bin/echo -n "..fax_uri.." | sed -e s,.*/,,g");
|
||||
--do not use apostrophies in message, they are not excaped and the mail will fail.
|
||||
email_message_fail = "We are sorry the fax failed to go through. It has been attached. Please check the number "..number_dialed..", and if it was correct you might consider emailing it instead."
|
||||
email_message_success = "We are happy to report the fax was sent successfully. It has been attached for your records."
|
||||
|
||||
-- send the selected variables to the console
|
||||
freeswitch.consoleLog("INFO","fax_success: '" .. fax_success .. "'\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_retry_attempts: " .. fax_retry_attempts.. "\n");
|
||||
freeswitch.consoleLog("INFO","fax_retry_limit: " .. fax_retry_limit.. "\n");
|
||||
freeswitch.consoleLog("INFO","fax_retry_sleep: " .. fax_retry_sleep.. "\n");
|
||||
freeswitch.consoleLog("INFO","fax_uri: '" .. fax_uri.. "'\n");
|
||||
freeswitch.consoleLog("INFO","origination_caller_id_name: " .. origination_caller_id_name .. "\n");
|
||||
freeswitch.consoleLog("INFO","origination_caller_id_number: " .. origination_caller_id_number .. "\n");
|
||||
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");
|
||||
|
||||
-- if the fax failed then try again
|
||||
if (fax_success == "0") then
|
||||
--DEBUG
|
||||
--email_cmd = "/bin/echo '"..email_message_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 = "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.."'";
|
||||
|
||||
|
||||
if (fax_retry_attempts < fax_retry_limit) then
|
||||
|
||||
--timed out waitng for comm or on first message (busy code?)
|
||||
if (fax_result_code == "2" or fax_result_code == "3" ) then
|
||||
--do nothing. don't want to increment
|
||||
freeswitch.consoleLog("INFO","Last Fax was probably Busy, don't increment retry_attempts. \n");
|
||||
fax_busy_attempts = fax_busy_attempts + 1;
|
||||
freeswitch.msleep(fax_retry_sleep * 1000);
|
||||
|
||||
elseif (fax_retry_attempts < 5 ) then
|
||||
freeswitch.consoleLog("INFO","Last Fax Failed, try a different way. Wait first.\n");
|
||||
freeswitch.msleep(fax_retry_sleep * 500);
|
||||
else
|
||||
freeswitch.consoleLog("INFO","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");
|
||||
fax_retry_attempts = fax_retry_attempts + 1;
|
||||
cmd = "originate {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.."')";
|
||||
|
||||
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");
|
||||
fax_retry_attempts = fax_retry_attempts + 1;
|
||||
cmd = "originate {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");
|
||||
fax_retry_attempts = fax_retry_attempts + 1;
|
||||
|
||||
cmd = "originate {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.."')";
|
||||
|
||||
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");
|
||||
fax_retry_attempts = fax_retry_attempts + 1;
|
||||
|
||||
cmd = "originate {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.."')";
|
||||
|
||||
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\n");
|
||||
|
||||
email_address = email_address:gsub("\\,", ",");
|
||||
|
||||
freeswitch.email("",
|
||||
"",
|
||||
"To: "..email_address.."\nFrom: "..from_address.."\nSubject: Fax to: "..number_dialed.." FAILED",
|
||||
email_message_fail ,
|
||||
fax_file
|
||||
);
|
||||
|
||||
fax_retry_attempts = fax_retry_attempts + 1;
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
api = freeswitch.API();
|
||||
if ( not cmd ) then
|
||||
freeswitch.consoleLog("INFO","Last Fallthrough (5th) of FAX_RETRY.lua: \n");
|
||||
else
|
||||
freeswitch.consoleLog("INFO","retry cmd: " .. cmd .. "\n");
|
||||
reply = api:executeString(cmd);
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
--Huzah! Success!
|
||||
if (fax_retry_attempts == 0) then
|
||||
fax_trial = "fax_use_ecm=false,fax_enable_t38=true,fax_enable_t38_request=true,fax_disable_v17=default";
|
||||
elseif (fax_retry_attempts == 1) then
|
||||
fax_trial = "fax_use_ecm=true,fax_enable_t38=true,fax_enable_t38_request=true,fax_disable_v17=false";
|
||||
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
|
||||
fax_trial = "fax_use_ecm=true,fax_enable_t38=true,fax_enable_t38_request=true,fax_disable_v17=true";
|
||||
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 .. "]\n");
|
||||
email_address = email_address:gsub("\\,", ",");
|
||||
|
||||
freeswitch.email("",
|
||||
"",
|
||||
"To: "..email_address.."\nFrom: "..from_address.."\nSubject: Fax to: "..number_dialed.." SENT",
|
||||
email_message_success ,
|
||||
fax_file
|
||||
);
|
||||
end
|
||||
99
resources/install/scripts/fifo_member.lua
Normal file
99
resources/install/scripts/fifo_member.lua
Normal file
@@ -0,0 +1,99 @@
|
||||
--
|
||||
-- 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
|
||||
-- All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
sounds_dir = "";
|
||||
recordings_dir = "";
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
--session:execute("info", "");
|
||||
user_name = session:getVariable("user_name");
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
queue_name = session:getVariable("queue_name");
|
||||
fifo_simo = session:getVariable("fifo_simo");
|
||||
fifo_timeout = session:getVariable("fifo_timeout");
|
||||
fifo_lag = session:getVariable("fifo_lag");
|
||||
|
||||
--pin_number = "1234"; --for testing
|
||||
--queue_name = "5900@voip.fusionpbx.com";
|
||||
--fifo_simo = 1;
|
||||
--fifo_timeout = 10;
|
||||
--fifo_lag = 10;
|
||||
|
||||
if (pin_number) then
|
||||
digits = session:playAndGetDigits(3, 8, 3, digit_timeout, "#", sounds_dir.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
|
||||
--press 1 to login and 2 to logout
|
||||
menu_selection = session:playAndGetDigits(1, 1, max_tries, digit_timeout, "#", sounds_dir.."/custom/please_enter_the_phone_number.wav", "", "\\d+");
|
||||
freeswitch.consoleLog("NOTICE", "menu_selection: "..menu_selection.."\n");
|
||||
if (menu_selection == "1") then
|
||||
session:execute("set", "fifo_member_add_result=${fifo_member(add "..queue_name.." {fifo_member_wait=nowait}user/"..user_name.." "..fifo_simo.." "..fifo_timeout.." "..fifo_lag.."} )"); --simo timeout lag
|
||||
fifo_member_add_result = session:getVariable("fifo_member_add_result");
|
||||
freeswitch.consoleLog("NOTICE", "fifo_member_add_result: "..fifo_member_add_result.."\n");
|
||||
session:streamFile("ivr/ivr-you_are_now_logged_in.wav");
|
||||
end
|
||||
if (menu_selection == "2") then
|
||||
session:execute("set", "fifo_member_del_result=${fifo_member(del "..queue_name.." {fifo_member_wait=nowait}user/"..user_name.."} )");
|
||||
session:streamFile("ivr/ivr-you_are_now_logged_out.wav");
|
||||
end
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
-- session:sleep(1000);
|
||||
|
||||
session:hangup();
|
||||
|
||||
else
|
||||
session:streamFile(sounds_dir.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
end
|
||||
else
|
||||
|
||||
--pin number is not required
|
||||
|
||||
--press 1 to login and 2 to logout
|
||||
menu_selection = session:playAndGetDigits(1, 1, max_tries, digit_timeout, "#", sounds_dir.."/custom/please_enter_the_phone_number.wav", "", "\\d+");
|
||||
freeswitch.consoleLog("NOTICE", "menu_selection: "..menu_selection.."\n");
|
||||
if (menu_selection == "1") then
|
||||
session:execute("set", "fifo_member_add_result=${fifo_member(add "..queue_name.." {fifo_member_wait=nowait}user/"..user_name.." "..fifo_simo.." "..fifo_timeout.." "..fifo_lag.."} )"); --simo timeout lag
|
||||
fifo_member_add_result = session:getVariable("fifo_member_add_result");
|
||||
freeswitch.consoleLog("NOTICE", "fifo_member_add_result: "..fifo_member_add_result.."\n");
|
||||
session:streamFile("ivr/ivr-you_are_now_logged_in.wav");
|
||||
end
|
||||
if (menu_selection == "2") then
|
||||
session:execute("set", "fifo_member_del_result=${fifo_member(del "..queue_name.." {fifo_member_wait=nowait}user/"..user_name.."} )");
|
||||
session:streamFile("ivr/ivr-you_are_now_logged_out.wav");
|
||||
end
|
||||
|
||||
--wait for the file to be written before proceeding
|
||||
-- session:sleep(1000);
|
||||
|
||||
session:hangup();
|
||||
end
|
||||
end
|
||||
108
resources/install/scripts/huntgroup_originate.lua
Normal file
108
resources/install/scripts/huntgroup_originate.lua
Normal file
@@ -0,0 +1,108 @@
|
||||
--get the argv values
|
||||
domain_name = argv[1];
|
||||
uuid = argv[2];
|
||||
sipuri = argv[3];
|
||||
extension = argv[4];
|
||||
caller_id_name = argv[5];
|
||||
caller_id_number = argv[6];
|
||||
caller_announce = argv[7];
|
||||
|
||||
--variable preparation
|
||||
tmp_sipuri = '';
|
||||
caller_id_name = string.gsub(caller_id_name, "+", " ");
|
||||
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
function originate (domain_name, session, sipuri, extension, caller_announce, caller_id_name, caller_id_number)
|
||||
|
||||
cid = ",origination_caller_id_name="..caller_id_name..",origination_caller_id_number="..caller_id_number;
|
||||
local new_session = freeswitch.Session("{ignore_early_media=true"..cid.."}"..sipuri);
|
||||
new_session:execute("set", "call_timeout=60");
|
||||
new_session:execute("sleep", "1000");
|
||||
|
||||
--if the session is not ready wait longer
|
||||
if ( new_session:ready() ) then
|
||||
--do nothing
|
||||
else
|
||||
new_session:execute("sleep", "1000");
|
||||
end
|
||||
|
||||
if ( new_session:ready() ) then
|
||||
--get the session id
|
||||
uuid = new_session:getVariable("uuid");
|
||||
--set the sounds path for the language, dialect and voice
|
||||
default_language = new_session:getVariable("default_language");
|
||||
default_dialect = new_session:getVariable("default_dialect");
|
||||
default_voice = new_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
|
||||
|
||||
--caller announce
|
||||
if (caller_announce) then
|
||||
new_session:streamFile(caller_announce);
|
||||
end
|
||||
|
||||
--set the sounds directory
|
||||
sounds_dir = new_session:getVariable("sounds_dir");
|
||||
|
||||
--check the fifo status if it is empty hangup the call
|
||||
api = freeswitch.API();
|
||||
cmd = "fifo count "..extension.."@"..domain_name;
|
||||
result = api:executeString(cmd);
|
||||
--freeswitch.consoleLog("notice", "result " .. result .. "\n");
|
||||
result_table = explode(":",result);
|
||||
if (result_table[3] == "0") then
|
||||
--session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
new_session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
|
||||
--prompt user for action
|
||||
dtmf_digits = new_session:playAndGetDigits(1, 1, 2, 3000, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/8000/press_1_to_accept_2_to_reject_or_3_for_voicemail.wav", "", "\\d+");
|
||||
freeswitch.consoleLog("NOTICE", "followme: "..dtmf_digits.."\n");
|
||||
|
||||
if ( dtmf_digits == "1" ) then
|
||||
freeswitch.consoleLog("NOTICE", "followme: call accepted\n");
|
||||
freeswitch.consoleLog("NOTICE", extension.."@"..domain_name.." out nowait\n");
|
||||
new_session:execute("fifo", extension.."@"..domain_name.." out nowait");
|
||||
return true;
|
||||
end
|
||||
if ( dtmf_digits == "2" ) then
|
||||
freeswitch.consoleLog("NOTICE", "followme: call rejected\n");
|
||||
new_session:hangup();
|
||||
return false;
|
||||
end
|
||||
if ( dtmf_digits == "3" ) then
|
||||
freeswitch.consoleLog("NOTICE", "followme: call sent to voicemail\n");
|
||||
cmd = "uuid_transfer "..uuid.." *99"..extension;
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString(cmd);
|
||||
return true;
|
||||
end
|
||||
if ( dtmf_digits == "" ) then
|
||||
freeswitch.consoleLog("NOTICE", "followme: no dtmf detected\n");
|
||||
return false;
|
||||
end
|
||||
else
|
||||
freeswitch.consoleLog("err", "followme: session not ready\n");
|
||||
end
|
||||
end
|
||||
|
||||
sipuri_table = explode(",",sipuri);
|
||||
for index,tmp_sip_uri in pairs(sipuri_table) do
|
||||
freeswitch.consoleLog("NOTICE", "sip_uri: "..tmp_sip_uri.."\n");
|
||||
result = originate (domain_name, session, tmp_sip_uri, extension, caller_announce, caller_id_name, caller_id_number);
|
||||
if (result) then
|
||||
break;
|
||||
--exit;
|
||||
end
|
||||
end
|
||||
127
resources/install/scripts/intercept.lua
Normal file
127
resources/install/scripts/intercept.lua
Normal file
@@ -0,0 +1,127 @@
|
||||
--
|
||||
-- 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
|
||||
-- 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
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--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
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('switch');
|
||||
end
|
||||
|
||||
--exits the script if we didn't connect properly
|
||||
assert(dbh:connected());
|
||||
|
||||
if ( session:ready() ) then
|
||||
--answer the session
|
||||
session:answer();
|
||||
|
||||
--get session variables
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
domain_name = session:getVariable("domain_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
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
--digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_pass:#", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
--session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:streamFile("phrase:voicemail_fail_auth:#");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--check the database to get the uuid of a ringing call
|
||||
sql = "select call_uuid as uuid from channels ";
|
||||
sql = sql .. "where callstate = 'RINGING' ";
|
||||
if (extension) then
|
||||
sql = sql .. "and presence_id = '"..extension.."@"..domain_name.."' ";
|
||||
else
|
||||
if (domain_count > 1) then
|
||||
sql = sql .. "and context = '"..domain_name.."' ";
|
||||
end
|
||||
end
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("NOTICE", "sql "..sql.."\n");
|
||||
end
|
||||
dbh:query(sql, function(result)
|
||||
--for key, val in pairs(result) do
|
||||
-- freeswitch.consoleLog("NOTICE", "result "..key.." "..val.."\n");
|
||||
--end
|
||||
uuid = result.uuid;
|
||||
end);
|
||||
|
||||
end
|
||||
|
||||
--intercept a call that is ringing
|
||||
if (uuid) then
|
||||
session:execute("intercept", uuid);
|
||||
end
|
||||
|
||||
--notes
|
||||
--originate a call
|
||||
--cmd = "originate user/1007@voip.example.com &intercept("..uuid..")";
|
||||
--api = freeswitch.API();
|
||||
--result = api:executeString(cmd);
|
||||
254
resources/install/scripts/ivr_menu.lua
Normal file
254
resources/install/scripts/ivr_menu.lua
Normal file
@@ -0,0 +1,254 @@
|
||||
-- ivr_menu.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2012 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--set the debug options
|
||||
debug["action"] = false;
|
||||
debug["sql"] = false;
|
||||
debug["regex"] = false;
|
||||
debug["dtmf"] = false;
|
||||
debug["tries"] = false;
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--get the variables
|
||||
domain_name = session:getVariable("domain_name");
|
||||
context = session:getVariable("context");
|
||||
ivr_menu_uuid = session:getVariable("ivr_menu_uuid");
|
||||
caller_id_name = session:getVariable("caller_id_name");
|
||||
caller_id_number = session:getVariable("caller_id_number");
|
||||
|
||||
--set default variable(s)
|
||||
tries = 0;
|
||||
|
||||
--add the trim function
|
||||
function trim(s)
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
--check if a file exists
|
||||
function file_exists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
end
|
||||
|
||||
--get the ivr menu from the database
|
||||
sql = [[SELECT * FROM v_ivr_menus
|
||||
WHERE ivr_menu_uuid = ']] .. ivr_menu_uuid ..[['
|
||||
AND ivr_menu_enabled = 'true' ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
ivr_menu_name = row["ivr_menu_name"];
|
||||
--ivr_menu_extension = row["ivr_menu_extension"];
|
||||
ivr_menu_greet_long = row["ivr_menu_greet_long"];
|
||||
ivr_menu_greet_short = row["ivr_menu_greet_short"];
|
||||
ivr_menu_invalid_sound = row["ivr_menu_invalid_sound"];
|
||||
ivr_menu_exit_sound = row["ivr_menu_exit_sound"];
|
||||
ivr_menu_confirm_macro = row["ivr_menu_confirm_macro"];
|
||||
ivr_menu_confirm_key = row["ivr_menu_confirm_key"];
|
||||
ivr_menu_tts_engine = row["ivr_menu_tts_engine"];
|
||||
ivr_menu_tts_voice = row["ivr_menu_tts_voice"];
|
||||
ivr_menu_confirm_attempts = row["ivr_menu_confirm_attempts"];
|
||||
ivr_menu_timeout = row["ivr_menu_timeout"];
|
||||
--ivr_menu_exit_app = row["ivr_menu_exit_app"];
|
||||
--ivr_menu_exit_data = row["ivr_menu_exit_data"];
|
||||
ivr_menu_inter_digit_timeout = row["ivr_menu_inter_digit_timeout"];
|
||||
ivr_menu_max_failures = row["ivr_menu_max_failures"];
|
||||
ivr_menu_max_timeouts = row["ivr_menu_max_timeouts"];
|
||||
ivr_menu_digit_len = row["ivr_menu_digit_len"];
|
||||
ivr_menu_direct_dial = row["ivr_menu_direct_dial"];
|
||||
--ivr_menu_description = row["ivr_menu_description"];
|
||||
ivr_menu_ringback = row["ivr_menu_ringback"];
|
||||
ivr_menu_cid_prefix = row["ivr_menu_cid_prefix"];
|
||||
end);
|
||||
|
||||
--set the caller id name
|
||||
if (caller_id_name) then
|
||||
if (string.len(ivr_menu_cid_prefix) > 0) then
|
||||
caller_id_name = ivr_menu_cid_prefix .. "#" .. caller_id_name;
|
||||
session:setVariable("caller_id_name", caller_id_name);
|
||||
session:setVariable("effective_caller_id_name", caller_id_name);
|
||||
end
|
||||
end
|
||||
|
||||
--get the sounds dir, language, dialect and voice
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
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
|
||||
|
||||
--make the path relative
|
||||
if (string.sub(ivr_menu_greet_long,0,71) == "$${sounds_dir}/${default_language}/${default_dialect}/${default_voice}/") then
|
||||
ivr_menu_greet_long = string.sub(ivr_menu_greet_long,72);
|
||||
end
|
||||
if (string.sub(ivr_menu_greet_short,0,71) == "$${sounds_dir}/${default_language}/${default_dialect}/${default_voice}/") then
|
||||
ivr_menu_greet_short = string.sub(ivr_menu_greet_short,72);
|
||||
end
|
||||
|
||||
--adjust the file path
|
||||
if (ivr_menu_greet_short) then
|
||||
--do nothing
|
||||
else
|
||||
ivr_menu_greet_short = ivr_menu_greet_long;
|
||||
end
|
||||
if (not file_exists(ivr_menu_greet_long)) then
|
||||
if (file_exists(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/"..ivr_menu_greet_long)) then
|
||||
ivr_menu_greet_long = sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/"..ivr_menu_greet_long;
|
||||
end
|
||||
end
|
||||
if (not file_exists(ivr_menu_greet_short)) then
|
||||
if (file_exists(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/"..ivr_menu_greet_short)) then
|
||||
ivr_menu_greet_short = sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/"..ivr_menu_greet_short;
|
||||
end
|
||||
end
|
||||
ivr_menu_invalid_entry = sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-that_was_an_invalid_entry.wav";
|
||||
|
||||
--prepare the api object
|
||||
api = freeswitch.API();
|
||||
|
||||
--define the ivr menu
|
||||
function menu()
|
||||
--increment the tries
|
||||
tries = tries + 1;
|
||||
dtmf_digits = "";
|
||||
min_digits = 1;
|
||||
if (tries == 1) then
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] greet long: " .. ivr_menu_greet_long .. "\n");
|
||||
dtmf_digits = session:playAndGetDigits(min_digits, ivr_menu_digit_len, 1, ivr_menu_timeout, ivr_menu_confirm_key, ivr_menu_greet_long, "", ".*");
|
||||
else
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] greet long: " .. ivr_menu_greet_short .. "\n");
|
||||
dtmf_digits = session:playAndGetDigits(min_digits, ivr_menu_digit_len, ivr_menu_max_timeouts, ivr_menu_timeout, ivr_menu_confirm_key, ivr_menu_greet_short, "", ".*");
|
||||
end
|
||||
if (string.len(dtmf_digits) > 0) then
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] dtmf_digits: " .. dtmf_digits .. "\n");
|
||||
menu_options(session, dtmf_digits);
|
||||
else
|
||||
if (tries <= tonumber(ivr_menu_max_failures)) then
|
||||
--log the dtmf digits
|
||||
if (debug["tries"]) then
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] tries: " .. tries .. "\n");
|
||||
end
|
||||
--run the menu again
|
||||
menu();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function menu_options(session, digits)
|
||||
|
||||
--log the dtmf digits
|
||||
if (debug["dtmf"]) then
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] dtmf: " .. digits .. "\n");
|
||||
end
|
||||
|
||||
--get the ivr menu options
|
||||
sql = [[SELECT * FROM v_ivr_menu_options WHERE ivr_menu_uuid = ']] .. ivr_menu_uuid ..[[' ORDER BY ivr_menu_option_order asc ]];
|
||||
if (debug["sql"]) then
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] SQL: " .. sql .. "\n");
|
||||
end
|
||||
status = dbh:query(sql, function(row)
|
||||
--check for matching options
|
||||
if (tonumber(row.ivr_menu_option_digits) ~= nil) then
|
||||
row.ivr_menu_option_digits = "^"..row.ivr_menu_option_digits.."$";
|
||||
end
|
||||
if (api:execute("regex", digits.."|"..row.ivr_menu_option_digits) == "true") then
|
||||
if (row.ivr_menu_option_action == "menu-exec-app") then
|
||||
--get the action and data
|
||||
pos = string.find(row.ivr_menu_option_param, " ", 0, true);
|
||||
action = string.sub( row.ivr_menu_option_param, 0, pos-1);
|
||||
data = string.sub( row.ivr_menu_option_param, pos+1);
|
||||
|
||||
--check if the option uses a regex
|
||||
regex = string.find(row.ivr_menu_option_digits, "(", 0, true);
|
||||
if (regex) then
|
||||
--get the regex result
|
||||
result = trim(api:execute("regex", digits.."|"..row.ivr_menu_option_digits.."|\$1"));
|
||||
if (debug["regex"]) then
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] regex "..digits.."|"..row.ivr_menu_option_digits.."|\$1\n");
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] result: "..result.."\n");
|
||||
end
|
||||
|
||||
--replace the $1 and the domain name
|
||||
data = data:gsub("$1", result);
|
||||
data = data:gsub("${domain_name}", domain_name);
|
||||
end --if regex
|
||||
end --if menu-exex-app
|
||||
end --if regex match
|
||||
|
||||
--execute
|
||||
if (action) then
|
||||
if (string.len(action) > 0) then
|
||||
--send to the log
|
||||
if (debug["action"]) then
|
||||
freeswitch.consoleLog("notice", "[ivr_menu] action: " .. action .. " data: ".. data .. "\n");
|
||||
end
|
||||
--run the action
|
||||
session:execute(action, data);
|
||||
end
|
||||
else
|
||||
if (ivr_menu_direct_dial == "true") then
|
||||
if (string.len(digits) < 6) then
|
||||
--replace the $1 and the domain name
|
||||
digits = digits:gsub("*", "");
|
||||
--run the action
|
||||
session:execute("transfer", digits.." XML "..context);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--clear the variables
|
||||
action = "";
|
||||
data = "";
|
||||
end); --end results
|
||||
|
||||
--execute
|
||||
if (action) then
|
||||
if (string.len(action) == 0) then
|
||||
session:streamFile(ivr_menu_invalid_entry);
|
||||
menu();
|
||||
end
|
||||
else
|
||||
session:streamFile(ivr_menu_invalid_entry);
|
||||
menu();
|
||||
end
|
||||
end --end function
|
||||
|
||||
--answer the session
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
menu();
|
||||
end
|
||||
92
resources/install/scripts/monitor.lua
Normal file
92
resources/install/scripts/monitor.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
-- monitor.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--define general settings
|
||||
tmp_file = "/usr/local/freeswitch/log/monitor.tmp";
|
||||
|
||||
--used to stop the lua service
|
||||
local file = assert(io.open(tmp_file, "w"));
|
||||
file:write("remove this file to stop the script");
|
||||
|
||||
--add the trim function
|
||||
function trim(s)
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
--check if a file exists
|
||||
function file_exists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
end
|
||||
|
||||
--create the api object
|
||||
api = freeswitch.API();
|
||||
|
||||
--run lua as a service
|
||||
while true do
|
||||
|
||||
--exit the loop when the file does not exist
|
||||
if (not file_exists(tmp_file)) then
|
||||
break;
|
||||
end
|
||||
|
||||
--check to see if the sip profile is running
|
||||
sip_profile = "internal";
|
||||
result = trim(api:execute("sofia", "status profile "..sip_profile));
|
||||
if (result == "Invalid Profile!") then
|
||||
--start the sip profile
|
||||
result = trim(api:execute("sofia", "profile "..sip_profile.." start"));
|
||||
freeswitch.consoleLog("NOTICE", "monitor.lua: "..sip_profile.." is not running starting the sip profile.\n");
|
||||
--run sofia recover
|
||||
api = freeswitch.API();
|
||||
result = api:execute("sofia", "recover");
|
||||
freeswitch.consoleLog("NOTICE", "monitor.lua - sofia recover\n");
|
||||
end
|
||||
result = "";
|
||||
|
||||
--check to see if the sip profile is running
|
||||
sip_profile = "external";
|
||||
result = trim(api:execute("sofia", "status profile "..sip_profile));
|
||||
if (result == "Invalid Profile!") then
|
||||
--start the sip profile
|
||||
result = trim(api:execute("sofia", "profile "..sip_profile.." start"));
|
||||
freeswitch.consoleLog("NOTICE", "monitor.lua: "..sip_profile.." is not running starting the sip profile.\n");
|
||||
--run sofia recover
|
||||
api = freeswitch.API();
|
||||
result = api:execute("sofia", "recover");
|
||||
freeswitch.consoleLog("NOTICE", "monitor.lua - sofia recover\n");
|
||||
end
|
||||
result = "";
|
||||
|
||||
--send a message to the log
|
||||
--freeswitch.consoleLog("NOTICE", "monitor.lua "..result.."\n");
|
||||
|
||||
--slow the loop down
|
||||
os.execute("sleep 3");
|
||||
|
||||
--testing exit immediately
|
||||
--break;
|
||||
end
|
||||
157
resources/install/scripts/page.lua
Normal file
157
resources/install/scripts/page.lua
Normal file
@@ -0,0 +1,157 @@
|
||||
-- page.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
--get the dialplan variables and set them as local variables
|
||||
destination_number = session:getVariable("destination_number");
|
||||
pin_number = session:getVariable("pin_number");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
extension_list = session:getVariable("extension_list");
|
||||
caller_id_name = session:getVariable("caller_id_name");
|
||||
caller_id_number = session:getVariable("caller_id_number");
|
||||
extension_table = explode(",",extension_list);
|
||||
sip_from_user = session:getVariable("sip_from_user");
|
||||
mute = session:getVariable("mute");
|
||||
|
||||
--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
|
||||
|
||||
if (caller_id_name) then
|
||||
--caller id name provided do nothing
|
||||
else
|
||||
effective_caller_id_name = session:getVariable("effective_caller_id_name");
|
||||
caller_id_number = effective_caller_id_name;
|
||||
end
|
||||
|
||||
if (caller_id_number) then
|
||||
--caller id number provided do nothing
|
||||
else
|
||||
effective_caller_id_number = session:getVariable("effective_caller_id_number");
|
||||
caller_id_number = effective_caller_id_number;
|
||||
end
|
||||
|
||||
--set conference flags
|
||||
if (mute) then
|
||||
if (mute == "false") then
|
||||
flags = "flags{}";
|
||||
else
|
||||
flags = "flags{mute}";
|
||||
end
|
||||
else
|
||||
flags = "flags{mute}";
|
||||
end
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
destination_count = 0;
|
||||
api = freeswitch.API();
|
||||
for index,value in pairs(extension_table) do
|
||||
if (string.find(value, "-") == nill) then
|
||||
value = value..'-'..value;
|
||||
end
|
||||
sub_table = explode("-",value);
|
||||
for extension=sub_table[1],sub_table[2] do
|
||||
--extension_exists = "username_exists id "..extension.."@"..domain_name;
|
||||
--reply = trim(api:executeString(extension_exists));
|
||||
--if (reply == "true") then
|
||||
extension_status = "show channels like "..extension.."@";
|
||||
reply = trim(api:executeString(extension_status));
|
||||
if (reply == "0 total.") then
|
||||
--freeswitch.consoleLog("NOTICE", "extension "..extension.." available\n");
|
||||
if (extension == tonumber(sip_from_user)) then
|
||||
--this extension is the caller that initated the page
|
||||
else
|
||||
--originate the call
|
||||
cmd_string = "bgapi originate {sip_auto_answer=true,sip_h_Alert-Info='Ring Answer',hangup_after_bridge=false,origination_caller_id_name='"..caller_id_name.."',origination_caller_id_number="..caller_id_number.."}user/"..extension.."@"..domain_name.." conference:page-"..destination_number.."@page+"..flags.." inline";
|
||||
api:executeString(cmd_string);
|
||||
destination_count = destination_count + 1;
|
||||
end
|
||||
--freeswitch.consoleLog("NOTICE", "cmd_string "..cmd_string.."\n");
|
||||
else
|
||||
--look inside the reply to check for the correct domain_name
|
||||
if string.find(reply, domain_name) then
|
||||
--found: extension number is busy
|
||||
else
|
||||
--not found
|
||||
if (extension == tonumber(sip_from_user)) then
|
||||
--this extension is the caller that initated the page
|
||||
else
|
||||
--originate the call
|
||||
cmd_string = "bgapi originate {sip_auto_answer=true,hangup_after_bridge=false,origination_caller_id_name='"..caller_id_name.."',origination_caller_id_number="..caller_id_number.."}user/"..extension.."@"..domain_name.." conference:page-"..destination_number.."@page+"..flags.." inline";
|
||||
api:executeString(cmd_string);
|
||||
destination_count = destination_count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
--end
|
||||
end
|
||||
end
|
||||
|
||||
--send main call to the conference room
|
||||
if (destination_count > 0) then
|
||||
session:execute("conference", "page-"..destination_number.."@page+flags{endconf}");
|
||||
else
|
||||
session:execute("playback", "tone_stream://%(500,500,480,620);loops=3");
|
||||
end
|
||||
|
||||
end
|
||||
233
resources/install/scripts/park.lua
Normal file
233
resources/install/scripts/park.lua
Normal file
@@ -0,0 +1,233 @@
|
||||
--example usage
|
||||
--basic
|
||||
--condition destination_number 5900
|
||||
--action set park_extension=5901
|
||||
--advanced
|
||||
--condition destination_number ^59(\d{2})$
|
||||
--action set park_extension=$1
|
||||
--additional settings
|
||||
--action set park_range=5
|
||||
--action set park_direction=in (in/out/both)
|
||||
--action set park_announce=true (not implemented yet)
|
||||
--action set park_timeout_seconds=30 (not implemented yet)
|
||||
--action set park_timeout_extension=1001 (not implemented yet)
|
||||
--action set park_music=$${hold_music}
|
||||
--action lua park.lua
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--connect to the database
|
||||
--dbh = freeswitch.Dbh("core:core"); -- when using sqlite
|
||||
dbh = freeswitch.Dbh("sqlite://"..database_dir.."/park.db");
|
||||
--dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
--dbh = database_handle('system');
|
||||
|
||||
--exits the script if we didn't connect properly
|
||||
assert(dbh:connected());
|
||||
--get the session variables
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
park_direction = session:getVariable("park_direction");
|
||||
uuid = session:getVariable("uuid");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
park_extension = session:getVariable("park_extension");
|
||||
park_range = session:getVariable("park_range");
|
||||
park_announce = session:getVariable("park_announce");
|
||||
park_timeout_type = session:getVariable("park_timeout_type");
|
||||
park_timeout_destination = session:getVariable("park_timeout_destination");
|
||||
park_timeout_seconds = session:getVariable("park_timeout_seconds");
|
||||
park_music = session:getVariable("park_music");
|
||||
|
||||
--add the explode function
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
|
||||
--add the trim function
|
||||
function trim(s)
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
--if park_timeout_seconds is not defined set the timeout to 5 minutes
|
||||
if (not park_timeout_seconds) then
|
||||
park_timeout_seconds = 300;
|
||||
end
|
||||
|
||||
--if park_timeout_type is not defined set to transfer
|
||||
if (not park_timeout_type) then
|
||||
park_timeout_type = "transfer";
|
||||
end
|
||||
|
||||
--prepare the api
|
||||
api = freeswitch.API();
|
||||
|
||||
--answer the call
|
||||
session:answer();
|
||||
|
||||
--database
|
||||
--exits the script if we didn't connect properly
|
||||
assert(dbh:connected());
|
||||
|
||||
--create the table if it doesn't exist
|
||||
--pgsql
|
||||
dbh:test_reactive("SELECT * FROM park", "", "CREATE TABLE park (id SERIAL, lot TEXT, domain TEXT, uuid TEXT, CONSTRAINT park_pk PRIMARY KEY(id))");
|
||||
--sqlite
|
||||
dbh:test_reactive("SELECT * FROM park", "", "CREATE TABLE park (id INTEGER PRIMARY KEY, lot TEXT, domain TEXT, uuid TEXT)");
|
||||
--mysql
|
||||
dbh:test_reactive("SELECT * FROM park", "", "CREATE TABLE park (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, lot TEXT, domain TEXT, uuid TEXT)");
|
||||
|
||||
--if park_range is defined then loop through the range to find an available parking lot
|
||||
if (park_range) then
|
||||
park_extension_start = park_extension;
|
||||
park_extension_end = ((park_extension+park_range)-1);
|
||||
extension = park_extension_start;
|
||||
while true do
|
||||
--exit the loop at the end of the range
|
||||
if (tonumber(extension) > park_extension_end) then
|
||||
break;
|
||||
end
|
||||
--check the database for an available slot
|
||||
lot_status = "available";
|
||||
sql = "SELECT count(*) as count FROM park WHERE lot = '"..extension.."' and domain = '"..domain_name.."' ";
|
||||
dbh:query(sql, function(result)
|
||||
--for key, val in pairs(result) do
|
||||
-- freeswitch.consoleLog("NOTICE", "parking result "..key.." "..val.."\n");
|
||||
--end
|
||||
count = result.count;
|
||||
end);
|
||||
--if count is 0 then the parking lot is available end the loop
|
||||
if (count == "0") then
|
||||
lot_status = "available";
|
||||
park_extension = ""..extension;
|
||||
break;
|
||||
end
|
||||
--increment the value
|
||||
extension = extension + 1;
|
||||
end
|
||||
end
|
||||
|
||||
--check the database to see if the slot is available or unavailable
|
||||
lot_status = "available";
|
||||
sql = "SELECT id, lot, uuid FROM park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ";
|
||||
dbh:query(sql, function(row)
|
||||
lot_uuid = row.uuid;
|
||||
lot_status = "unavailable";
|
||||
end);
|
||||
|
||||
--if park direction is set to out then unpark by bridging it to the caller
|
||||
if (park_direction == "out") then
|
||||
if (lot_uuid) then
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..lot_uuid.." park_status unparked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: unparked "..park_extension.."\n");
|
||||
--unpark the call with bridge
|
||||
cmd = "uuid_bridge "..uuid.." "..lot_uuid;
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
else
|
||||
--check if the uuid_exists, if it does not exist then delete the uuid from the db and set presence to terminated
|
||||
if (lot_uuid) then
|
||||
cmd = "uuid_exists "..lot_uuid;
|
||||
result = trim(api:executeString(cmd));
|
||||
if (result == "false") then
|
||||
--set presence out
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", lot_uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--delete from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
--freeswitch.consoleLog("NOTICE", "Park - Affected rows: " .. dbh:affected_rows() .. "\n");
|
||||
|
||||
--set the status to available
|
||||
lot_status = "available";
|
||||
end
|
||||
end
|
||||
|
||||
--check if the parking lot is available, if it is then add it to the db, set presenence to confirmed and park the call
|
||||
if (lot_status == "available") then
|
||||
--park the call
|
||||
cmd = "uuid_park "..uuid;
|
||||
result = trim(api:executeString(cmd));
|
||||
if (park_music) then
|
||||
cmd = "uuid_broadcast "..uuid.." "..park_music.." aleg";
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status parked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: parked "..park_extension.."\n");
|
||||
|
||||
--add to the database
|
||||
dbh:query("INSERT INTO park (lot, domain, uuid) VALUES ('"..park_extension.."', '"..domain_name.."', '"..uuid.."')");
|
||||
|
||||
--set presence in
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip"); --park
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("status", "Active (1 waiting)");
|
||||
event:addHeader("rpid", "unknown");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("event_count", "1");
|
||||
event:addHeader("unique-id", uuid);
|
||||
--event:addHeader("Presence-Call-Direction", "outbound")
|
||||
event:addHeader("answer-state", "confirmed");
|
||||
event:fire();
|
||||
|
||||
else
|
||||
--bridge the current call to the call that is parked
|
||||
--set the presence to terminated
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
--event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--delete the lot from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
--freeswitch.consoleLog("NOTICE", "Park 200- Affected rows: " .. dbh:affected_rows() .. "\n");
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..lot_uuid.." park_status unparked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: unparked "..park_extension.."\n");
|
||||
|
||||
--connect the calls
|
||||
cmd = "uuid_bridge "..uuid.." "..lot_uuid;
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
|
||||
--continue running when the session ends
|
||||
session:setAutoHangup(false);
|
||||
|
||||
--start the fifo monitor on its own so that it doesn't block the script execution
|
||||
api = freeswitch.API();
|
||||
cmd = "luarun park_monitor.lua "..uuid.." "..domain_name.." "..park_extension.." "..park_timeout_type.." "..park_timeout_seconds.." "..park_timeout_destination;
|
||||
result = api:executeString(cmd);
|
||||
end
|
||||
188
resources/install/scripts/park_monitor.lua
Normal file
188
resources/install/scripts/park_monitor.lua
Normal file
@@ -0,0 +1,188 @@
|
||||
-- park_monitor.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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:
|
||||
--if the call has been answered
|
||||
--then send presence terminate, and delete from the database
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--connect to the database
|
||||
--dbh = freeswitch.Dbh("core:core"); -- when using sqlite
|
||||
dbh = freeswitch.Dbh("sqlite://"..database_dir.."/park.db");
|
||||
--dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
|
||||
--get the argv values
|
||||
script_name = argv[0];
|
||||
uuid = argv[1];
|
||||
domain_name = argv[2];
|
||||
park_extension = argv[3];
|
||||
park_timeout_type = argv[4];
|
||||
park_timeout_seconds = argv[5];
|
||||
park_timeout_destination = argv[6];
|
||||
|
||||
--prepare the api
|
||||
api = freeswitch.API();
|
||||
|
||||
--add a trim function
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
--monitor the parking lot if the call has hungup send a terminated event, and delete from the db
|
||||
x = 0
|
||||
while true do
|
||||
--sleep a moment to prevent using unecessary resources
|
||||
freeswitch.msleep(1000);
|
||||
|
||||
if (api:executeString("uuid_exists "..uuid) == "false") then
|
||||
--set the presence to terminated
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status cancelled";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: cancelled\n");
|
||||
|
||||
--delete the lot from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
|
||||
--end the loop
|
||||
break;
|
||||
else
|
||||
cmd = "uuid_getvar "..uuid.." park_status";
|
||||
result = trim(api:executeString(cmd));
|
||||
--freeswitch.consoleLog("notice", "" .. result .. "\n");
|
||||
if (result == "parked") then --_undef_
|
||||
--set presence in
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip"); --park
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("status", "Active (1 waiting)");
|
||||
event:addHeader("rpid", "unknown");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("event_count", "1");
|
||||
event:addHeader("unique-id", uuid);
|
||||
--event:addHeader("Presence-Call-Direction", "outbound")
|
||||
event:addHeader("answer-state", "confirmed");
|
||||
event:fire();
|
||||
else
|
||||
--set the presence to terminated
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--delete the lot from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
--freeswitch.consoleLog("NOTICE", "Affected rows: park ext "..park_extension.." " .. dbh:affected_rows() .. "\n");
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status unparked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: unparked "..park_extension.."\n");
|
||||
|
||||
--end the loop
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
--limit the monitor to watching 60 seconds
|
||||
x = x + 1;
|
||||
if (x > tonumber(park_timeout_seconds)) then
|
||||
--set the presence to terminated
|
||||
event = freeswitch.Event("PRESENCE_IN");
|
||||
event:addHeader("proto", "sip");
|
||||
event:addHeader("event_type", "presence");
|
||||
event:addHeader("alt_event_type", "dialog");
|
||||
event:addHeader("Presence-Call-Direction", "outbound");
|
||||
event:addHeader("state", "Active (1 waiting)");
|
||||
event:addHeader("from", park_extension.."@"..domain_name);
|
||||
event:addHeader("login", park_extension.."@"..domain_name);
|
||||
event:addHeader("unique-id", uuid);
|
||||
event:addHeader("answer-state", "terminated");
|
||||
event:fire();
|
||||
|
||||
--delete the lot from the database
|
||||
dbh:query("DELETE from park WHERE lot = '"..park_extension.."' and domain = '"..domain_name.."' ");
|
||||
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status timeout";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: timeout\n");
|
||||
|
||||
--end the loop
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
--if the timeout was reached transfer the call
|
||||
--get the park status
|
||||
cmd = "uuid_getvar "..uuid.." park_status";
|
||||
park_status = trim(api:executeString(cmd));
|
||||
--get and set the the caller id prefix
|
||||
cmd = "uuid_getvar "..uuid.." park_caller_id_prefix";
|
||||
park_caller_id_prefix = trim(api:executeString(cmd));
|
||||
if (park_caller_id_prefix) then
|
||||
--get the caller id name
|
||||
cmd = "uuid_getvar "..uuid.." effective_caller_id_name";
|
||||
caller_id_name = trim(api:executeString(cmd));
|
||||
--set the caller id name and prefix
|
||||
cmd = "uuid_setvar "..uuid.." effective_caller_id_name '"..park_caller_id_prefix.."#"..caller_id_name.."'";
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
--transfer the call to the timeout destination
|
||||
if (park_timeout_type == "transfer" and park_status == "timeout") then
|
||||
--set the park status
|
||||
cmd = "uuid_setvar "..uuid.." park_status unparked";
|
||||
result = trim(api:executeString(cmd));
|
||||
freeswitch.consoleLog("NOTICE", "Park Status: unparked\n");
|
||||
--transfer the call when it has timed out
|
||||
cmd = "uuid_transfer "..uuid.." "..park_timeout_destination;
|
||||
result = trim(api:executeString(cmd));
|
||||
end
|
||||
67
resources/install/scripts/pin_number.lua
Normal file
67
resources/install/scripts/pin_number.lua
Normal file
@@ -0,0 +1,67 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
|
||||
--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
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_pass:#", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile("phrase:voicemail_fail_auth:#");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
end
|
||||
183
resources/install/scripts/recordings.lua
Normal file
183
resources/install/scripts/recordings.lua
Normal file
@@ -0,0 +1,183 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
--set the variables
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
sounds_dir = "";
|
||||
recordings_dir = "";
|
||||
file_name = "";
|
||||
recording_number = "";
|
||||
recording_slots = "";
|
||||
recording_prefix = "";
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--dtmf call back function detects the "#" and ends the call
|
||||
function onInput(s, type, obj)
|
||||
if (type == "dtmf" and obj['digit'] == '#') then
|
||||
return "break";
|
||||
end
|
||||
end
|
||||
|
||||
--start the recording
|
||||
function begin_record(session, sounds_dir, recordings_dir)
|
||||
|
||||
--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
|
||||
recording_slots = session:getVariable("recording_slots");
|
||||
recording_prefix = session:getVariable("recording_prefix");
|
||||
recording_name = session:getVariable("recording_name");
|
||||
|
||||
--select the recording number
|
||||
if (recording_slots) then
|
||||
min_digits = 1;
|
||||
max_digits = 20;
|
||||
recording_number = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_recording_number.wav", "", "\\d+");
|
||||
recording_name = recording_prefix..recording_number..".wav";
|
||||
end
|
||||
|
||||
--set the default recording name if one was not provided
|
||||
if (recording_name) then
|
||||
--recording name is provided do nothing
|
||||
else
|
||||
--set a default recording_name
|
||||
recording_name = "temp_"..session:get_uuid()..".wav";
|
||||
end
|
||||
|
||||
--prompt for the recording
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/begin_recording.wav");
|
||||
session:execute("set", "playback_terminators=#");
|
||||
|
||||
--begin recording
|
||||
session:execute("record", "'"..recordings_dir.."/"..recording_name.."' 180 200");
|
||||
|
||||
--preview the recording
|
||||
session:streamFile(recordings_dir.."/"..recording_name);
|
||||
|
||||
--approve the recording, to save the recording press 1 to re-record press 2
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "voicemail/vm-save_recording.wav", "", "\\d+");
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "voicemail/vm-press.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "digits/1.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "voicemail/vm-rerecord.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="0" max_digits="1" max_tries = "1"; digit_timeout = "100";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "voicemail/vm-press.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (string.len(digits) == 0) then
|
||||
min_digits="1" max_digits="1" max_tries = "1"; digit_timeout = "5000";
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "digits/2.wav", "", "\\d+");
|
||||
end
|
||||
|
||||
if (digits == "1") then
|
||||
--recording saved, hangup
|
||||
session:streamFile("voicemail/vm-saved.wav");
|
||||
return;
|
||||
elseif (digits == "2") then
|
||||
--delete the old recording
|
||||
os.remove (recordings_dir.."/"..recording_name);
|
||||
--session:execute("system", "rm "..);
|
||||
--make a new recording
|
||||
begin_record(session, sounds_dir, recordings_dir);
|
||||
else
|
||||
--recording saved, hangup
|
||||
session:streamFile("voicemail/vm-saved.wav");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
|
||||
--get the dialplan variables and set them as local variables
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
|
||||
--set the base recordings dir
|
||||
base_recordings_dir = recordings_dir;
|
||||
|
||||
--get the recordings from the config.lua and append the domain_name if the system is multi-tenant
|
||||
if (domain_count > 1) then
|
||||
recordings_dir = recordings_dir .. "/" .. domain_name;
|
||||
end
|
||||
|
||||
--use the recording_dir when the variable is set
|
||||
if (session:getVariable("recordings_dir")) then
|
||||
if (base_recordings_dir ~= session:getVariable("recordings_dir")) then
|
||||
recordings_dir = session:getVariable("recordings_dir");
|
||||
end
|
||||
end
|
||||
|
||||
--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
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
--start recording
|
||||
begin_record(session, sounds_dir, recordings_dir);
|
||||
|
||||
session:hangup();
|
||||
end
|
||||
36
resources/install/scripts/resources/functions/base64.lua
Normal file
36
resources/install/scripts/resources/functions/base64.lua
Normal file
@@ -0,0 +1,36 @@
|
||||
-- Lua 5.1+ base64 v3.0 (c) 2009 by Alex Kloss <alexthkloss@web.de>
|
||||
-- licensed under the terms of the LGPL2
|
||||
base64={}
|
||||
|
||||
-- character table string
|
||||
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
|
||||
-- encoding
|
||||
function base64.enc(data)
|
||||
return ((data:gsub('.', function(x)
|
||||
local r,b='',x:byte()
|
||||
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
|
||||
return r;
|
||||
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
|
||||
if (#x < 6) then return '' end
|
||||
local c=0
|
||||
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
|
||||
return b:sub(c+1,c+1)
|
||||
end)..({ '', '==', '=' })[#data%3+1])
|
||||
end
|
||||
|
||||
-- decoding
|
||||
function base64.dec(data)
|
||||
data = string.gsub(data, '[^'..b..'=]', '')
|
||||
return (data:gsub('.', function(x)
|
||||
if (x == '=') then return '' end
|
||||
local r,f='',(b:find(x)-1)
|
||||
for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
|
||||
return r;
|
||||
end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
|
||||
if (#x ~= 8) then return '' end
|
||||
local c=0
|
||||
for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
|
||||
return string.char(c)
|
||||
end))
|
||||
end
|
||||
12
resources/install/scripts/resources/functions/config.lua
Normal file
12
resources/install/scripts/resources/functions/config.lua
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
--find and return path to the config.lua
|
||||
function config()
|
||||
dofile(scripts_dir.."/resources/functions/file_exists.lua");
|
||||
if (file_exists("/etc/fusionpbx/config.lua")) then
|
||||
return "/etc/fusionpbx/config.lua";
|
||||
elseif (file_exists("/usr/local/etc/fusionpbx/config.lua")) then
|
||||
return "/usr/local/etc/fusionpbx/config.lua";
|
||||
else
|
||||
return scripts_dir.."/resources/config.lua";
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
--connect to the database
|
||||
function database_handle(t)
|
||||
if (t == "system") then
|
||||
return freeswitch.Dbh(database["system"]);
|
||||
elseif (t == "switch") then
|
||||
return freeswitch.Dbh(database["switch"]);
|
||||
end
|
||||
end
|
||||
11
resources/install/scripts/resources/functions/explode.lua
Normal file
11
resources/install/scripts/resources/functions/explode.lua
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
--add the explode function
|
||||
function explode ( seperator, str )
|
||||
local pos, arr = 0, {}
|
||||
for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
|
||||
table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
|
||||
pos = sp + 1 -- jump past current divider
|
||||
end
|
||||
table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
--check if a file exists
|
||||
function file_exists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2013 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--format seconds to 00:00:00
|
||||
function format_seconds(seconds)
|
||||
local seconds = tonumber(seconds);
|
||||
if seconds == 0 then
|
||||
return "00:00:00";
|
||||
else
|
||||
hours = string.format("%02.f", math.floor(seconds/3600));
|
||||
minutes = string.format("%02.f", math.floor(seconds/60 - (hours*60)));
|
||||
seconds = string.format("%02.f", math.floor(seconds - hours*3600 - minutes *60));
|
||||
return string.format("%02d:%02d:%02d", hours, minutes, seconds);
|
||||
end
|
||||
end
|
||||
14
resources/install/scripts/resources/functions/mkdir.lua
Normal file
14
resources/install/scripts/resources/functions/mkdir.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
--add the mkdir function
|
||||
function mkdir(dir)
|
||||
dir = dir:gsub([[\]], "/");
|
||||
if (package.config:sub(1,1) == "/") then
|
||||
--unix
|
||||
cmd = [[mkdir -p "]] .. dir .. [["]];
|
||||
elseif (package.config:sub(1,1) == [[\]]) then
|
||||
--windows
|
||||
cmd = [[mkdir "]] .. dir .. [["]];
|
||||
end
|
||||
os.execute(cmd);
|
||||
return cmd;
|
||||
end
|
||||
7
resources/install/scripts/resources/functions/trim.lua
Normal file
7
resources/install/scripts/resources/functions/trim.lua
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
--add the trim function
|
||||
function trim(s)
|
||||
if (s) then
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
end
|
||||
145
resources/install/scripts/ring_group.lua
Normal file
145
resources/install/scripts/ring_group.lua
Normal file
@@ -0,0 +1,145 @@
|
||||
-- ring_groups.lua
|
||||
-- Part of FusionPBX
|
||||
-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
|
||||
-- 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.
|
||||
|
||||
--include config.lua
|
||||
scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
|
||||
dofile(scripts_dir.."/resources/functions/config.lua");
|
||||
dofile(config());
|
||||
|
||||
--connect to the database
|
||||
dofile(scripts_dir.."/resources/functions/database_handle.lua");
|
||||
dbh = database_handle('system');
|
||||
|
||||
--get the variables
|
||||
if (session:ready()) then
|
||||
domain_name = session:getVariable("domain_name");
|
||||
ring_group_uuid = session:getVariable("ring_group_uuid");
|
||||
caller_id_name = session:getVariable("caller_id_name");
|
||||
caller_id_number = session:getVariable("caller_id_number");
|
||||
recordings_dir = session:getVariable("recordings_dir");
|
||||
uuid = session:getVariable("uuid");
|
||||
end
|
||||
|
||||
--get the extension list
|
||||
sql =
|
||||
[[ SELECT g.ring_group_extension_uuid, e.extension_uuid, e.extension,
|
||||
r.ring_group_strategy, r.ring_group_timeout_sec, r.ring_group_timeout_app, g.extension_delay, g.extension_timeout, r.ring_group_timeout_data, r.ring_group_cid_name_prefix, r.ring_group_ringback
|
||||
FROM v_ring_groups as r, v_ring_group_extensions as g, v_extensions as e
|
||||
where g.ring_group_uuid = r.ring_group_uuid
|
||||
and g.ring_group_uuid = ']]..ring_group_uuid..[['
|
||||
and e.extension_uuid = g.extension_uuid
|
||||
and r.ring_group_enabled = 'true'
|
||||
order by g.extension_delay, e.extension asc ]]
|
||||
--freeswitch.consoleLog("notice", "SQL:" .. sql .. "\n");
|
||||
|
||||
x = 0;
|
||||
dbh:query(sql, function(row)
|
||||
ring_group_timeout_sec = row.ring_group_timeout_sec;
|
||||
ring_group_timeout_app = row.ring_group_timeout_app;
|
||||
ring_group_timeout_data = row.ring_group_timeout_data;
|
||||
ring_group_cid_name_prefix = row.ring_group_cid_name_prefix;
|
||||
ring_group_ringback = row.ring_group_ringback;
|
||||
extension_delay = row.extension_delay;
|
||||
extension_timeout = row.extension_timeout;
|
||||
|
||||
if (ring_group_ringback == "${uk-ring}") then
|
||||
ring_group_ringback = "%(400,200,400,450);%(400,2200,400,450)";
|
||||
end
|
||||
if (ring_group_ringback == "${us-ring}") then
|
||||
ring_group_ringback = "%(2000, 4000, 440.0, 480.0)";
|
||||
end
|
||||
if (ring_group_ringback == "${fr-ring}") then
|
||||
ring_group_ringback = "%(1500, 3500, 440.0, 0.0)";
|
||||
end
|
||||
if (ring_group_ringback == "${rs-ring}") then
|
||||
ring_group_ringback = "%(1000, 4000, 425.0, 0.0)";
|
||||
end
|
||||
session:setVariable("ringback", ring_group_ringback);
|
||||
session:setVariable("transfer_ringback", ring_group_ringback);
|
||||
|
||||
if (string.len(ring_group_cid_name_prefix) > 0) then
|
||||
origination_caller_id_name = ring_group_cid_name_prefix .. "#" .. caller_id_name;
|
||||
else
|
||||
origination_caller_id_name = caller_id_name;
|
||||
end
|
||||
|
||||
delimiter = ",";
|
||||
if (row.ring_group_strategy == "sequence") then
|
||||
delimiter = "|";
|
||||
end
|
||||
if (row.ring_group_strategy == "simultaneous") then
|
||||
delimiter = ",";
|
||||
end
|
||||
if (row.ring_group_strategy == "enterprise") then
|
||||
delimiter = ":_:";
|
||||
end
|
||||
|
||||
if (x == 0) then
|
||||
app_data = ""; --{originate_timeout="..ring_group_timeout_sec.."}";
|
||||
app_data = app_data .. "[sip_invite_domain="..domain_name..",leg_timeout="..extension_timeout..",leg_delay_start="..extension_delay..",origination_caller_id_name="..origination_caller_id_name.."]user/" .. row.extension .. "@" .. domain_name;
|
||||
else
|
||||
app_data = app_data .. delimiter .. "[sip_invite_domain="..domain_name..",leg_timeout="..extension_timeout..",leg_delay_start="..extension_delay..",origination_caller_id_name="..origination_caller_id_name.."]user/" .. row.extension .. "@" .. domain_name;
|
||||
end
|
||||
x = x + 1;
|
||||
end);
|
||||
|
||||
--app_data
|
||||
--freeswitch.consoleLog("notice", "[ring group] app_data: " .. app_data .. "\n");
|
||||
|
||||
--session actions
|
||||
if (session:ready()) then
|
||||
session:preAnswer();
|
||||
session:execute("set", "hangup_after_bridge=true");
|
||||
session:execute("set", "continue_on_fail=true");
|
||||
session:execute("bind_meta_app", "1 ab s execute_extension::dx XML features");
|
||||
session:execute("bind_meta_app", "2 ab s record_session::"..recordings_dir.."}/archive/"..os.date("%Y").."/"..os.date("%m").."/"..os.date("%d").."}/"..uuid..".wav");
|
||||
session:execute("bind_meta_app", "3 ab s execute_extension::cf XML features");
|
||||
session:execute("bind_meta_app", "4 ab s execute_extension::att_xfer XML features");
|
||||
if (app_data) then
|
||||
session:execute("bridge", app_data);
|
||||
else
|
||||
--get the timeout app and data
|
||||
sql = [[SELECT ring_group_timeout_app, ring_group_timeout_data FROM v_ring_groups
|
||||
where ring_group_uuid = ']]..ring_group_uuid..[['
|
||||
and ring_group_enabled = 'true' ]];
|
||||
--freeswitch.consoleLog("notice", "SQL:" .. sql .. "\n");
|
||||
dbh:query(sql, function(row)
|
||||
ring_group_timeout_app = row.ring_group_timeout_app;
|
||||
ring_group_timeout_data = row.ring_group_timeout_data;
|
||||
end);
|
||||
end
|
||||
if (session:getVariable("originate_disposition") == "ALLOTTED_TIMEOUT") then
|
||||
session:execute(ring_group_timeout_app, ring_group_timeout_data);
|
||||
end
|
||||
end
|
||||
|
||||
--actions
|
||||
--ACTIONS = {}
|
||||
--table.insert(ACTIONS, {"set", "hangup_after_bridge=true"});
|
||||
--table.insert(ACTIONS, {"set", "continue_on_fail=true"});
|
||||
--table.insert(ACTIONS, {"bridge", app_data});
|
||||
--table.insert(ACTIONS, {ring_group_timeout_app, ring_group_timeout_data});
|
||||
|
||||
91
resources/install/scripts/roku.lua
Normal file
91
resources/install/scripts/roku.lua
Normal file
@@ -0,0 +1,91 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
predefined_destination = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "5000";
|
||||
port = "8080";
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer( );
|
||||
pin_number = session:getVariable("pin_number");
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
host = session:getVariable("host");
|
||||
|
||||
--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 (default_language) then else default_language = 'en'; end
|
||||
if (default_dialect) then else default_dialect = 'us'; end
|
||||
if (default_voice) then else default_voice = 'callie'; end
|
||||
|
||||
digitmaxlength = 0;
|
||||
timeoutpin = 7500;
|
||||
timeouttransfer = 7500;
|
||||
|
||||
--if the pin number is provided then require it
|
||||
if (pin_number) then
|
||||
min_digits = string.len(pin_number);
|
||||
max_digits = string.len(pin_number)+1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_pin_number.wav", "", "\\d+");
|
||||
if (digits == pin_number) then
|
||||
--pin is correct
|
||||
digits = "";
|
||||
else
|
||||
session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/your_pin_number_is_incorect_goodbye.wav");
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if (session:ready()) then
|
||||
session:answer();
|
||||
min_digits = 1;
|
||||
max_digits = 1;
|
||||
digitmaxlength = 1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/custom/please_enter_the_phone_number.wav", "", "\\d+");
|
||||
|
||||
x = 0;
|
||||
while (session:ready() == true) do
|
||||
if (string.len(digits) == 0) then
|
||||
--getDigits(length, terminators, timeout, digit_timeout, abs_timeout)
|
||||
digits = session:getDigits(1, "#", 40000);
|
||||
end
|
||||
if (string.len(digits) > 0) then
|
||||
--press star to exit
|
||||
if (digits == "*") then
|
||||
break;
|
||||
end
|
||||
--send the command to php
|
||||
session:execute("system","/usr/local/bin/php /usr/local/www/fusionpbx/mod/roku/roku.php "..digits.." "..host.." "..port);
|
||||
end
|
||||
digits = "";
|
||||
if (x > 17500) then
|
||||
break;
|
||||
end
|
||||
end
|
||||
session:hangup("NORMAL_CLEARING");
|
||||
end
|
||||
end
|
||||
203
resources/install/scripts/wakeup.lua
Normal file
203
resources/install/scripts/wakeup.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
--
|
||||
-- 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
|
||||
-- the Initial Developer. All Rights Reserved.
|
||||
--
|
||||
-- Contributor(s):
|
||||
-- Mark J Crane <markjcrane@fusionpbx.com>
|
||||
|
||||
--get the argv values
|
||||
script_name = argv[0];
|
||||
domain_name = argv[1];
|
||||
wakeup_number = argv[2];
|
||||
|
||||
--add the trim function
|
||||
function trim(s)
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
--add is_numeric
|
||||
function is_numeric(text)
|
||||
if type(text)~="string" and type(text)~="number" then return false end
|
||||
return tonumber(text) and true or false
|
||||
end
|
||||
|
||||
--set the default values for the variables
|
||||
pin_number = "";
|
||||
max_tries = "3";
|
||||
digit_timeout = "3000";
|
||||
sounds_dir = "";
|
||||
extension_type = ""; --number,caller_id_number,prompt
|
||||
extension_number = "";
|
||||
|
||||
if (wakeup_number) then
|
||||
--begin the wakeup call
|
||||
if ( session:ready() ) then
|
||||
--prepare the api object
|
||||
api = freeswitch.API();
|
||||
|
||||
--set session settings
|
||||
session:answer();
|
||||
session:setAutoHangup(false);
|
||||
|
||||
--wakeup confirm press 1 to 3
|
||||
min_digits = 1;
|
||||
max_digits = 1;
|
||||
digits = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:wakeup-call", "", "\\d+");
|
||||
|
||||
--reschedule the call for snooze
|
||||
if (digits == "2") then
|
||||
freeswitch.consoleLog("NOTICE", "wakeup call: snooze selected - rescheduled the call\n");
|
||||
api = freeswitch.API();
|
||||
caller_id_name = "wakeup call";
|
||||
caller_id_number = wakeup_number;
|
||||
sched_api_time = "600";
|
||||
cmd_string = "sched_api +"..sched_api_time.." wakeup-call-"..wakeup_number.." originate {hangup_after_bridge=false,origination_caller_id_name='"..caller_id_name.."',origination_caller_id_number="..caller_id_number.."}user/"..wakeup_number.."@"..domain_name.." &lua('wakeup.lua "..domain_name.." "..wakeup_number.."') ";
|
||||
freeswitch.consoleLog("NOTICE", "wakeup: "..cmd_string.."\n");
|
||||
reply = api:executeString(cmd_string);
|
||||
end
|
||||
end
|
||||
else
|
||||
--prompt for the wakeup call information
|
||||
|
||||
if ( session:ready() ) then
|
||||
session:answer();
|
||||
session:setAutoHangup(false);
|
||||
|
||||
--get the dialplan variables and set them as local variables
|
||||
sounds_dir = session:getVariable("sounds_dir");
|
||||
domain_name = session:getVariable("domain_name");
|
||||
extension_number = session:getVariable("extension_number");
|
||||
extension_type = session:getVariable("extension_type");
|
||||
time_zone_offset = session:getVariable("time_zone_offset");
|
||||
sip_number_alias = session:getVariable("sip_number_alias");
|
||||
sip_from_user = session:getVariable("sip_from_user");
|
||||
if (is_numeric(sip_number_alias)) then
|
||||
wakeup_number = sip_number_alias;
|
||||
else
|
||||
wakeup_number = sip_from_user;
|
||||
end
|
||||
|
||||
--get the extension number
|
||||
if (extension_type == "prompt") then
|
||||
min_digits = 1;
|
||||
max_digits = 11;
|
||||
wakeup_time = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:wakeup-get-extension", "", "\\d+");
|
||||
end
|
||||
|
||||
--get the wakeup time
|
||||
min_digits = 4;
|
||||
max_digits = 4;
|
||||
wakeup_time = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:wakeup-greeting", "", "\\d+");
|
||||
freeswitch.consoleLog("NOTICE", "wakeup time: "..wakeup_time.."\n");
|
||||
|
||||
--get the current time
|
||||
current_hours = tonumber(os.date("%H"));
|
||||
current_minutes = tonumber(os.date("%M"));
|
||||
current_seconds = tonumber(os.date("%S"));
|
||||
|
||||
--adjust the time zone offset
|
||||
if (time_zone_offset) then
|
||||
current_hours = time_zone_offset + current_hours;
|
||||
if (current_hours < 0) then
|
||||
current_hours = current_hours + 24;
|
||||
end
|
||||
if (current_hours > 23) then
|
||||
current_hours = current_hours - 24;
|
||||
end
|
||||
end
|
||||
|
||||
--show the current hours minutes and seconds to the log
|
||||
--freeswitch.consoleLog("NOTICE", "Hours: " .. current_hours .. "\n");
|
||||
--freeswitch.consoleLog("NOTICE", "Mins: " .. current_minutes .. "\n");
|
||||
--freeswitch.consoleLog("NOTICE", "Seconds: " .. current_seconds .. "\n");
|
||||
|
||||
--prepare the current time
|
||||
current_time = (current_hours * 100) + current_minutes;
|
||||
|
||||
--get the wakeup hours and minutes
|
||||
wakeup_hours = string.sub(wakeup_time, 1, 2);
|
||||
wakeup_minutes = string.sub(wakeup_time, 3);
|
||||
|
||||
--show the wakeup time, hours, and minutes to the log
|
||||
--freeswitch.consoleLog("NOTICE", "wakeup_time "..wakeup_time.."\n");
|
||||
--freeswitch.consoleLog("NOTICE", "wakeup_hours "..wakeup_hours.."\n");
|
||||
--freeswitch.consoleLog("NOTICE", "wakeup_minutes "..wakeup_minutes.."\n");
|
||||
|
||||
--convert the time, hours and minutes to numbers
|
||||
wakeup_time = tonumber(wakeup_time);
|
||||
wakeup_hours = tonumber(wakeup_hours);
|
||||
wakeup_minutes = tonumber(wakeup_minutes);
|
||||
if (current_time > wakeup_time) then
|
||||
--get the current_time_in_seconds
|
||||
current_time_in_seconds = (current_hours * 3600) + (current_minutes * 60);
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = ("..current_hours.." * 3600) + ("..current_minutes.." * 60)\n");
|
||||
--get the seconds until midnight
|
||||
seconds_until_midnight = (24 * 3600) - current_time_in_seconds;
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = (24 * 3600) - "..current_time_in_seconds.."\n");
|
||||
--get the wakeup_time_in_seconds
|
||||
wakeup_time_in_seconds = (wakeup_hours * 3600) + (wakeup_minutes * 60);
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = ("..wakeup_hours.." * 3600) + ("..wakeup_minutes.." * 60)\n");
|
||||
--add the seconds_until_midnight to the wakeup_time_in_seconds
|
||||
sched_api_time = wakeup_time_in_seconds + seconds_until_midnight;
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = "..wakeup_time_in_seconds.." + "..seconds_until_midnight.."\n");
|
||||
else
|
||||
--get the current_time_in_seconds
|
||||
current_time_in_seconds = (current_hours * 3600) + (current_minutes * 60);
|
||||
--freeswitch.consoleLog("NOTICE", "current_time_in_seconds = ("..current_hours.." * 3600) + ("..current_minutes.." * 60);\n");
|
||||
--get the wakeup_time_in_seconds
|
||||
wakeup_time_in_seconds = (wakeup_hours * 3600) + (wakeup_minutes * 60);
|
||||
--freeswitch.consoleLog("NOTICE", "wakeup_time_in_seconds = ("..wakeup_hours.." * 3600) + ("..wakeup_minutes.." * 60);\n");
|
||||
--subtract the current time from wakeup_time_in_seconds
|
||||
sched_api_time = wakeup_time_in_seconds - current_time_in_seconds;
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time = "..wakeup_time_in_seconds.." - "..current_time_in_seconds.."\n");
|
||||
end
|
||||
--freeswitch.consoleLog("NOTICE", "sched_api_time "..sched_api_time.."\n");
|
||||
|
||||
--wakeup call has been scheduled
|
||||
session:streamFile("phrase:wakeup-scheduled");
|
||||
session:say(wakeup_time, "en", "number", "ITERATED");
|
||||
|
||||
--wakeup confirm press 1 to 3
|
||||
min_digits = 1;
|
||||
max_digits = 1;
|
||||
wakeup_accept = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:wakeup-accept", "", "\\d+");
|
||||
--accept
|
||||
if (wakeup_accept == "1") then
|
||||
--send a message to the console
|
||||
freeswitch.consoleLog("NOTICE", "wakeup: accepted\n");
|
||||
--schedule the wakeup call
|
||||
caller_id_name = "wakeup call";
|
||||
caller_id_number = wakeup_number;
|
||||
cmd_string = "sched_api +"..sched_api_time.." wakeup-call-"..wakeup_number.." originate {hangup_after_bridge=false,origination_caller_id_name='"..caller_id_name.."',origination_caller_id_number="..caller_id_number.."}user/"..wakeup_number.."@"..domain_name.." &lua('wakeup.lua "..domain_name.." "..wakeup_number.."') ";
|
||||
freeswitch.consoleLog("NOTICE", "wakeup: "..cmd_string.."\n");
|
||||
api = freeswitch.API();
|
||||
reply = api:executeString(cmd_string);
|
||||
--hangup
|
||||
session:hangup();
|
||||
end
|
||||
--cancel
|
||||
if (wakeup_accept == "2") then
|
||||
--send a message to the console
|
||||
freeswitch.consoleLog("NOTICE", "wakeup: cancelled\n");
|
||||
--hangup
|
||||
session:hangup();
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user