diff --git a/includes/install/scripts/app.lua b/includes/install/scripts/app.lua new file mode 100644 index 0000000000..402bcdf16d --- /dev/null +++ b/includes/install/scripts/app.lua @@ -0,0 +1,48 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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/config.lua"); + +--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); \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/index.lua b/includes/install/scripts/app/voicemail/index.lua new file mode 100644 index 0000000000..c65729a770 --- /dev/null +++ b/includes/install/scripts/app/voicemail/index.lua @@ -0,0 +1,315 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 + --ODBC - data source name + if (dsn_name) then + dbh = freeswitch.Dbh(dsn_name,dsn_username,dsn_password); + end + --FreeSWITCH core db handler + if (db_type == "sqlite") then + dbh = freeswitch.Dbh("core:"..db_path.."/"..db_name); + end + +--set the api + api = freeswitch.API(); + +--if the session exists + if (session ~= nil) then + --answer the session + if (session:ready()) then + session:answer(); + end + + --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_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 + domain_uuid = string.lower(domain_uuid); + + --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"); + +--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 + + --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 + end + +--close the database connection + dbh:release(); + +--notes + --record the video + --records audio only + --result = session:execute("set", "enable_file_write_buffering=false"); + --os.execute("mkdir -p " .. 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 + --os.execute("mkdir -p " .. 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,,Send video refresh.,mod_commands + --may be used to clear video buffer before using record_fsv diff --git a/includes/install/scripts/app/voicemail/resources/functions/advanced.lua b/includes/install/scripts/app/voicemail/resources/functions/advanced.lua new file mode 100644 index 0000000000..8485913f67 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/advanced.lua @@ -0,0 +1,90 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/change_password.lua b/includes/install/scripts/app/voicemail/resources/functions/change_password.lua new file mode 100644 index 0000000000..711932681d --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/change_password.lua @@ -0,0 +1,51 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/functions/check_password.lua b/includes/install/scripts/app/voicemail/resources/functions/check_password.lua new file mode 100644 index 0000000000..5170fdcab7 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/check_password.lua @@ -0,0 +1,85 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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"); \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/functions/choose_greeting.lua b/includes/install/scripts/app/voicemail/resources/functions/choose_greeting.lua new file mode 100644 index 0000000000..ad4d6bf286 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/choose_greeting.lua @@ -0,0 +1,110 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/delete_recording.lua b/includes/install/scripts/app/voicemail/resources/functions/delete_recording.lua new file mode 100644 index 0000000000..4588dfcf69 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/delete_recording.lua @@ -0,0 +1,61 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/forward_to_extension.lua b/includes/install/scripts/app/voicemail/resources/functions/forward_to_extension.lua new file mode 100644 index 0000000000..44530cccfd --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/forward_to_extension.lua @@ -0,0 +1,133 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 + os.execute("mkdir -p " .. 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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/get_voicemail_id.lua b/includes/install/scripts/app/voicemail/resources/functions/get_voicemail_id.lua new file mode 100644 index 0000000000..e5c303a179 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/get_voicemail_id.lua @@ -0,0 +1,43 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/functions/listen_to_recording.lua b/includes/install/scripts/app/voicemail/resources/functions/listen_to_recording.lua new file mode 100644 index 0000000000..272bd8dd02 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/listen_to_recording.lua @@ -0,0 +1,137 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/functions/macro.lua b/includes/install/scripts/app/voicemail/resources/functions/macro.lua new file mode 100644 index 0000000000..caaa0f6baf --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/macro.lua @@ -0,0 +1,319 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 + 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 \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/functions/main_menu.lua b/includes/install/scripts/app/voicemail/resources/functions/main_menu.lua new file mode 100644 index 0000000000..a26f72629c --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/main_menu.lua @@ -0,0 +1,115 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/menu_messages.lua b/includes/install/scripts/app/voicemail/resources/functions/menu_messages.lua new file mode 100644 index 0000000000..c3e5adecb9 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/menu_messages.lua @@ -0,0 +1,109 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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) + if (row["new_messages"] == "0") then + --send the message waiting event + local event = freeswitch.Event("message_waiting"); + event:addHeader("MWI-Messages-Waiting", "no"); + event:addHeader("MWI-Message-Account", "sip:"..voicemail_id.."@"..domain_name); + event:fire(); + end + 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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/message_saved.lua b/includes/install/scripts/app/voicemail/resources/functions/message_saved.lua new file mode 100644 index 0000000000..2604684b29 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/message_saved.lua @@ -0,0 +1,56 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/message_waiting.lua b/includes/install/scripts/app/voicemail/resources/functions/message_waiting.lua new file mode 100644 index 0000000000..b8cc6bf7bc --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/message_waiting.lua @@ -0,0 +1,51 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 + 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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/on_dtmf.lua b/includes/install/scripts/app/voicemail/resources/functions/on_dtmf.lua new file mode 100644 index 0000000000..307701e229 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/on_dtmf.lua @@ -0,0 +1,46 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/functions/play_greeting.lua b/includes/install/scripts/app/voicemail/resources/functions/play_greeting.lua new file mode 100644 index 0000000000..bc43ee2a38 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/play_greeting.lua @@ -0,0 +1,44 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/functions/record_greeting.lua b/includes/install/scripts/app/voicemail/resources/functions/record_greeting.lua new file mode 100644 index 0000000000..633eee5c01 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/record_greeting.lua @@ -0,0 +1,96 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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; + os.execute("mkdir -p " .. 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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/record_menu.lua b/includes/install/scripts/app/voicemail/resources/functions/record_menu.lua new file mode 100644 index 0000000000..ff1dc96a7b --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/record_menu.lua @@ -0,0 +1,116 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/record_message.lua b/includes/install/scripts/app/voicemail/resources/functions/record_message.lua new file mode 100644 index 0000000000..cbd1b5371e --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/record_message.lua @@ -0,0 +1,120 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 (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 + + --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 = 30; + silence_threshold = 30; + silence_seconds = 5; + os.execute("mkdir -p " .. 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 minmal 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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/record_name.lua b/includes/install/scripts/app/voicemail/resources/functions/record_name.lua new file mode 100644 index 0000000000..adf4861746 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/record_name.lua @@ -0,0 +1,55 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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; + os.execute("mkdir -p " .. 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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/return_call.lua b/includes/install/scripts/app/voicemail/resources/functions/return_call.lua new file mode 100644 index 0000000000..feb5b0f756 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/return_call.lua @@ -0,0 +1,36 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 diff --git a/includes/install/scripts/app/voicemail/resources/functions/send_email.lua b/includes/install/scripts/app/voicemail/resources/functions/send_email.lua new file mode 100644 index 0000000000..42d098abce --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/functions/send_email.lua @@ -0,0 +1,154 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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_local_after_email == "false") 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 diff --git a/includes/install/scripts/app/voicemail/resources/templates/en/gb/email_body.tpl b/includes/install/scripts/app/voicemail/resources/templates/en/gb/email_body.tpl new file mode 100644 index 0000000000..c4fc58960c --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/templates/en/gb/email_body.tpl @@ -0,0 +1,7 @@ + +Message From "${caller_id_name}" ${caller_id_number}
+
+Created: ${message_date}
+Duration: ${message_duration}
+Account: ${account}@${domain_name}
+
\ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/templates/en/gb/email_subject.tpl b/includes/install/scripts/app/voicemail/resources/templates/en/gb/email_subject.tpl new file mode 100644 index 0000000000..cc19e1ef09 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/templates/en/gb/email_subject.tpl @@ -0,0 +1 @@ +Voicemail from ${caller_id_name} <${caller_id_number}> ${message_duration} \ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/templates/en/us/email_body.tpl b/includes/install/scripts/app/voicemail/resources/templates/en/us/email_body.tpl new file mode 100644 index 0000000000..c4fc58960c --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/templates/en/us/email_body.tpl @@ -0,0 +1,7 @@ + +Message From "${caller_id_name}" ${caller_id_number}
+
+Created: ${message_date}
+Duration: ${message_duration}
+Account: ${account}@${domain_name}
+
\ No newline at end of file diff --git a/includes/install/scripts/app/voicemail/resources/templates/en/us/email_subject.tpl b/includes/install/scripts/app/voicemail/resources/templates/en/us/email_subject.tpl new file mode 100644 index 0000000000..cc19e1ef09 --- /dev/null +++ b/includes/install/scripts/app/voicemail/resources/templates/en/us/email_subject.tpl @@ -0,0 +1 @@ +Voicemail from ${caller_id_name} <${caller_id_number}> ${message_duration} \ No newline at end of file diff --git a/includes/install/scripts/resources/functions/base64.lua b/includes/install/scripts/resources/functions/base64.lua new file mode 100644 index 0000000000..3a8e086170 --- /dev/null +++ b/includes/install/scripts/resources/functions/base64.lua @@ -0,0 +1,36 @@ +-- Lua 5.1+ base64 v3.0 (c) 2009 by Alex Kloss +-- 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 \ No newline at end of file diff --git a/includes/install/scripts/resources/functions/explode.lua b/includes/install/scripts/resources/functions/explode.lua new file mode 100644 index 0000000000..4355a643e8 --- /dev/null +++ b/includes/install/scripts/resources/functions/explode.lua @@ -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 \ No newline at end of file diff --git a/includes/install/scripts/resources/functions/file_exists.lua b/includes/install/scripts/resources/functions/file_exists.lua new file mode 100644 index 0000000000..76a31c5126 --- /dev/null +++ b/includes/install/scripts/resources/functions/file_exists.lua @@ -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 \ No newline at end of file diff --git a/includes/install/scripts/resources/functions/format_seconds.lua b/includes/install/scripts/resources/functions/format_seconds.lua new file mode 100644 index 0000000000..d1422348a7 --- /dev/null +++ b/includes/install/scripts/resources/functions/format_seconds.lua @@ -0,0 +1,37 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--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 \ No newline at end of file diff --git a/includes/install/scripts/resources/functions/trim.lua b/includes/install/scripts/resources/functions/trim.lua new file mode 100644 index 0000000000..ba69f3d477 --- /dev/null +++ b/includes/install/scripts/resources/functions/trim.lua @@ -0,0 +1,5 @@ + +--add the trim function + function trim(s) + return s:gsub("^%s+", ""):gsub("%s+$", "") + end \ No newline at end of file