2012-11-08 21:16:32 +01:00
-- directory.lua
-- Part of FusionPBX
-- Copyright (C) 2012 Mark J Crane <markjcrane@fusionpbx.com>
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- 2. Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
2012-11-08 22:07:36 +01:00
--set the defaults
2012-11-08 21:16:32 +01:00
digit_max_length = 3 ;
timeout_pin = 5000 ;
timeout_transfer = 5000 ;
max_tries = 3 ;
digit_timeout = 5000 ;
2013-01-17 02:11:43 +01:00
search_limit = 3 ;
2012-11-08 22:07:36 +01:00
search_count = 0 ;
2012-11-08 21:16:32 +01:00
2015-04-19 00:39:14 +02:00
--include config.lua
2015-08-10 19:50:29 +02:00
scripts_dir = string.sub ( debug.getinfo ( 1 ) . source , 2 , string.len ( debug.getinfo ( 1 ) . source ) - ( string.len ( argv [ 0 ] ) + 1 ) ) ;
dofile ( scripts_dir .. " /resources/functions/config.lua " ) ;
dofile ( config ( ) ) ;
--include config.lua
scripts_dir = string.sub ( debug.getinfo ( 1 ) . source , 2 , string.len ( debug.getinfo ( 1 ) . source ) - ( string.len ( argv [ 0 ] ) + 1 ) ) ;
dofile ( scripts_dir .. " /resources/functions/config.lua " ) ;
dofile ( config ( ) ) ;
2015-04-19 00:41:45 +02:00
--connect to the database
2015-08-10 19:50:29 +02:00
dofile ( scripts_dir .. " /resources/functions/database_handle.lua " ) ;
2015-04-19 00:41:45 +02:00
dbh = database_handle ( ' system ' ) ;
2015-04-19 00:36:26 +02:00
--settings
2015-08-10 19:50:29 +02:00
dofile ( scripts_dir .. " /resources/functions/settings.lua " ) ;
2015-04-19 00:36:26 +02:00
settings = settings ( domain_uuid ) ;
storage_type = " " ;
storage_path = " " ;
if ( settings [ ' voicemail ' ] ~= nil ) then
if ( settings [ ' voicemail ' ] [ ' storage_type ' ] ~= nil ) then
if ( settings [ ' voicemail ' ] [ ' storage_type ' ] [ ' text ' ] ~= nil ) then
storage_type = settings [ ' voicemail ' ] [ ' storage_type ' ] [ ' text ' ] ;
end
end
if ( settings [ ' voicemail ' ] [ ' storage_path ' ] ~= nil ) then
if ( settings [ ' voicemail ' ] [ ' storage_path ' ] [ ' text ' ] ~= nil ) then
storage_path = settings [ ' voicemail ' ] [ ' storage_path ' ] [ ' text ' ] ;
storage_path = storage_path : gsub ( " ${domain_name} " , domain_name ) ;
storage_path = storage_path : gsub ( " ${voicemail_id} " , voicemail_id ) ;
storage_path = storage_path : gsub ( " ${voicemail_dir} " , voicemail_dir ) ;
end
end
end
2013-01-14 20:37:50 +01:00
--debug
debug [ " info " ] = false ;
debug [ " sql " ] = false ;
2012-11-08 21:16:32 +01:00
--prepare the api object
api = freeswitch.API ( ) ;
--get the session variables
if ( session : ready ( ) ) then
--answer the session
session : answer ( ) ;
2013-01-17 02:11:43 +01:00
--give time for the call to be ready
session : streamFile ( " silence_stream://1000 " ) ;
2013-04-10 09:52:17 +02:00
--get the domain info
2012-11-08 21:16:32 +01:00
domain_name = session : getVariable ( " domain_name " ) ;
2013-04-10 09:52:17 +02:00
domain_uuid = session : getVariable ( " domain_uuid " ) ;
2012-11-08 21:16:32 +01:00
--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
2013-01-17 02:11:43 +01:00
2013-01-26 23:15:41 +01:00
--set the sounds path for the language, dialect and voice
ringback = session : getVariable ( " ringback " ) ;
2013-01-27 04:33:34 +01:00
if ( ringback ) then
ringback = ringback : gsub ( " $ " , " " ) ;
ringback = ringback : gsub ( " { " , " " ) ;
ringback = ringback : gsub ( " } " , " " ) ;
end
2013-01-26 23:15:41 +01:00
session : setVariable ( " instant_ringback " , " true " ) ;
session : setVariable ( " ignore_early_media " , " true " ) ;
if ( not ringback ) then
session : execute ( " set " , " ringback=local_stream://default " ) ; --set to ringtone
session : execute ( " set " , " transfer_ringback=local_stream://default " ) ; --set to ringtone
elseif ( ringback == " uk-ring " ) then
session : setVariable ( " ringback " , " %(400,200,400,450);%(400,2200,400,450) " ) ;
session : setVariable ( " transfer_ringback " , " %(400,200,400,450);%(400,2200,400,450) " ) ;
elseif ( ringback == " us-ring " ) then
session : setVariable ( " ringback " , " %(2000, 4000, 440.0, 480.0) " ) ;
session : setVariable ( " transfer_ringback " , " %(2000, 4000, 440.0, 480.0) " ) ;
2014-01-21 19:03:05 +01:00
elseif ( ringback == " pt-ring " ) then
session : setVariable ( " ringback " , " %(1000, 5000, 400.0, 0.0) " ) ;
session : setVariable ( " transfer_ringback " , " %(1000, 5000, 400.0, 0.0) " ) ;
2013-01-26 23:15:41 +01:00
elseif ( ringback == " fr-ring " ) then
session : setVariable ( " ringback " , " %(1500, 3500, 440.0, 0.0) " ) ;
session : setVariable ( " transfer_ringback " , " %(1500, 3500, 440.0, 0.0) " ) ;
elseif ( ringback == " rs-ring " ) then
session : setVariable ( " ringback " , " %(1000, 4000, 425.0, 0.0) " ) ;
session : setVariable ( " transfer_ringback " , " %(1000, 4000, 425.0, 0.0) " ) ;
2014-11-03 12:16:10 +01:00
elseif ( ringback == " it-ring " ) then
session : setVariable ( " ringback " , " %(1000, 4000, 425.0, 0.0) " ) ;
session : setVariable ( " transfer_ringback " , " %(1000, 4000, 425.0, 0.0) " ) ;
2013-01-26 23:15:41 +01:00
else
session : execute ( " set " , " ringback=local_stream://default " ) ; --set to ringtone
session : execute ( " set " , " transfer_ringback=local_stream://default " ) ; --set to ringtone
end
2013-01-17 02:11:43 +01:00
--define the sounds directory
sounds_dir = session : getVariable ( " sounds_dir " ) ;
sounds_dir = sounds_dir .. " / " .. default_language .. " / " .. default_dialect .. " / " .. default_voice ;
2012-11-08 21:16:32 +01:00
end
2013-01-14 20:37:50 +01:00
--get session variables
base_dir = session : getVariable ( " base_dir " ) ;
--set the voicemail_dir
voicemail_dir = base_dir .. " /storage/voicemail/default/ " .. domain_name ;
if ( debug [ " info " ] ) then
freeswitch.consoleLog ( " notice " , " [directory] voicemail_dir: " .. voicemail_dir .. " \n " ) ;
end
2012-11-08 21:16:32 +01:00
--get the domain_uuid
2013-04-10 09:52:17 +02:00
if ( domain_uuid == nil ) then
if ( domain_name ~= nil ) then
sql = " SELECT domain_uuid FROM v_domains " ;
sql = sql .. " WHERE domain_name = ' " .. domain_name .. " ' " ;
if ( debug [ " sql " ] ) then
freeswitch.consoleLog ( " notice " , " [conference] SQL: " .. sql .. " \n " ) ;
end
status = dbh : query ( sql , function ( rows )
domain_uuid = string.lower ( rows [ " domain_uuid " ] ) ;
end ) ;
2012-11-08 21:16:32 +01:00
end
end
2015-08-10 19:50:29 +02:00
--define explode
function explode ( seperator , str )
local pos , arr = 0 , { }
for st , sp in function ( ) return string.find ( str , seperator , pos , true ) end do -- for each divider found
table.insert ( arr , string.sub ( str , pos , st - 1 ) ) -- attach chars left of current divider
pos = sp + 1 -- jump past current divider
end
table.insert ( arr , string.sub ( str , pos ) ) -- attach chars right of last divider
return arr
end
2012-11-08 21:16:32 +01:00
--define a function to convert dialpad letters to numbers
function dialpad_to_digit ( letter )
letter = string.lower ( letter ) ;
if ( letter == " a " or letter == " b " or letter == " c " ) then
digit = " 2 " ;
elseif ( letter == " d " or letter == " e " or letter == " f " ) then
digit = " 3 " ;
elseif ( letter == " g " or letter == " h " or letter == " i " ) then
digit = " 4 " ;
elseif ( letter == " j " or letter == " k " or letter == " l " ) then
digit = " 5 " ;
elseif ( letter == " m " or letter == " n " or letter == " o " ) then
digit = " 6 " ;
elseif ( letter == " p " or letter == " q " or letter == " r " or letter == " s " ) then
digit = " 7 " ;
elseif ( letter == " t " or letter == " u " or letter == " v " ) then
digit = " 8 " ;
elseif ( letter == " w " or letter == " x " or letter == " y " or letter == " z " ) then
digit = " 9 " ;
end
return digit ;
end
--print(dialpad_to_digit("m"));
--define table_count
function table_count ( T )
local count = 0
for _ in pairs ( T ) do count = count + 1 end
return count
end
2015-08-10 19:50:29 +02:00
--define trim
function trim ( s )
return ( string.gsub ( s , " ^%s*(.-)%s*$ " , " %1 " ) )
end
2012-11-08 21:16:32 +01:00
2013-01-14 20:37:50 +01:00
--check if a file exists
2015-08-10 19:50:29 +02:00
function file_exists ( name )
local f = io.open ( name , " r " )
if f ~= nil then io.close ( f ) return true else return false end
end
2013-01-14 20:37:50 +01:00
2012-11-08 22:07:36 +01:00
--define select_entry function
function select_entry ( )
2012-11-08 21:16:32 +01:00
dtmf_digits = " " ;
digit_timeout = " 500 " ;
max_digits = 1 ;
max_tries = 1 ;
2013-01-17 02:11:43 +01:00
dtmf_digits = session : playAndGetDigits ( min_digits , max_digits , max_tries , digit_timeout , " # " , sounds_dir .. " /directory/dir-to_select_entry.wav " , " " , " \\ d+ " ) ;
2012-11-08 21:16:32 +01:00
if ( string.len ( dtmf_digits ) == 0 ) then
2013-01-17 02:11:43 +01:00
dtmf_digits = session : playAndGetDigits ( min_digits , max_digits , max_tries , digit_timeout , " # " , sounds_dir .. " /voicemail/vm-press.wav " , " " , " \\ d+ " ) ;
2012-11-08 21:16:32 +01:00
end
if ( string.len ( dtmf_digits ) == 0 ) then
digit_timeout = " 3000 " ;
2013-01-17 02:11:43 +01:00
dtmf_digits = session : playAndGetDigits ( min_digits , max_digits , max_tries , digit_timeout , " # " , sounds_dir .. " /digits/1.wav " , " " , " \\ d+ " ) ;
2012-11-08 21:16:32 +01:00
end
return dtmf_digits ;
end
2012-11-08 22:07:36 +01:00
--define prompt_for_name function
function prompt_for_name ( )
2012-11-08 21:26:15 +01:00
dtmf_digits = " " ;
min_digits = 0 ; max_digits = 3 ; max_tries = 3 ; digit_timeout = " 5000 " ;
2013-01-17 02:11:43 +01:00
dtmf_digits = session : playAndGetDigits ( min_digits , max_digits , max_tries , digit_timeout , " # " , sounds_dir .. " /directory/dir-enter_person_first_or_last.wav " , " " , " \\ d+ " ) ;
2012-11-08 21:16:32 +01:00
return dtmf_digits ;
end
--define the directory_search function
2012-11-08 22:07:36 +01:00
function directory_search ( )
2012-11-08 21:16:32 +01:00
2012-11-08 22:07:36 +01:00
--get the digits for the name
dtmf_digits = prompt_for_name ( ) ;
2012-11-08 21:16:32 +01:00
2012-11-08 22:07:36 +01:00
--show the dtmf digits
freeswitch.consoleLog ( " notice " , " [directory] first 3 letters of first or last name: " .. dtmf_digits .. " \n " ) ;
2012-11-08 21:16:32 +01:00
2012-11-08 22:07:36 +01:00
--loop through the extensions to find matches
search_dtmf_digits = dtmf_digits ;
found = false ;
for key , row in pairs ( directory ) do
2012-11-08 21:16:32 +01:00
2012-11-08 22:07:36 +01:00
--if (row.first_name and row.last_name) then
-- freeswitch.consoleLog("notice", "[directory] ext: " .. row.extension .. " context " .. row.context .. " name " .. row.first_name .. " "..row.first_name_digits.." ".. row.last_name .. " "..row.last_name_digits.." "..row.directory_exten_visible.."\n");
--else
-- freeswitch.consoleLog("notice", "[directory] ext: " .. row.extension .. " context " .. row.context .. "\n");
2012-11-08 21:16:32 +01:00
--end
2012-11-08 22:07:36 +01:00
if ( search_dtmf_digits == row.last_name_digits ) or ( search_dtmf_digits == row.first_name_digits ) then
if ( row.first_name and row.last_name ) then
2015-04-19 00:36:26 +02:00
--play the recorded name
if ( storage_type == " base64 " ) then
sql = [ [ SELECT * FROM v_voicemails
WHERE domain_uuid = ' ]] .. domain_uuid ..[[ '
AND voicemail_id = ' ]].. row.extension.. [[ ' ] ] ;
2015-04-19 00:51:43 +02:00
if ( debug [ " sql " ] ) then
2015-04-19 00:36:26 +02:00
freeswitch.consoleLog ( " notice " , " [directory] SQL: " .. sql .. " \n " ) ;
2015-04-19 00:51:43 +02:00
end
2015-04-19 00:49:09 +02:00
status = dbh : query ( sql , function ( field )
2015-04-19 00:36:26 +02:00
--add functions
2015-08-10 19:50:29 +02:00
dofile ( scripts_dir .. " /resources/functions/base64.lua " ) ;
2015-04-19 00:36:26 +02:00
--set the voicemail message path
file_location = voicemail_dir .. " / " .. row.extension .. " /recorded_name.wav " ;
--save the recording to the file system
2015-04-19 00:49:09 +02:00
if ( string.len ( field [ " voicemail_name_base64 " ] ) > 32 ) then
2015-04-19 00:36:26 +02:00
local file = io.open ( file_location , " w " ) ;
2015-04-19 00:49:09 +02:00
file : write ( base64.decode ( field [ " voicemail_name_base64 " ] ) ) ;
2015-04-19 00:36:26 +02:00
file : close ( ) ;
end
--play the recorded name
if ( file_exists ( file_location ) ) then
session : streamFile ( file_location ) ;
else
--announce the first and last names
session : execute ( " say " , " en name_spelled iterated " .. row.first_name ) ;
--session:execute("sleep", "500");
session : execute ( " say " , " en name_spelled iterated " .. row.last_name ) ;
end
end ) ;
elseif ( storage_type == " http_cache " ) then
file_location = storage_path .. " / " .. row.extension .. " /recorded_name.wav " ;
if ( file_exists ( file_location ) ) then
session : streamFile ( file_location ) ;
end
else
if ( debug [ " info " ] ) then
freeswitch.consoleLog ( " notice " , " [directory] path: " .. voicemail_dir .. " / " .. row.extension .. " /recorded_name.wav \n " ) ;
end
if ( file_exists ( voicemail_dir .. " / " .. row.extension .. " /recorded_name.wav " ) ) then
session : streamFile ( voicemail_dir .. " / " .. row.extension .. " /recorded_name.wav " ) ;
else
--announce the first and last names
session : execute ( " say " , " en name_spelled iterated " .. row.first_name ) ;
--session:execute("sleep", "500");
session : execute ( " say " , " en name_spelled iterated " .. row.last_name ) ;
end
end
2012-11-08 22:07:36 +01:00
--announce the extension number
if ( row.directory_exten_visible == " false " ) then
--invisible extension number
else
2013-01-17 02:11:43 +01:00
session : streamFile ( sounds_dir .. " /directory/dir-at_extension.wav " ) ;
2013-01-14 20:37:50 +01:00
session : execute ( " say " , " en number iterated " .. row.extension ) ;
2012-11-08 22:07:36 +01:00
end
--select this entry press 1
dtmf_digits = select_entry ( ) ;
--if 1 is pressed then transfer the call
if ( dtmf_digits == " 1 " ) then
session : execute ( " transfer " , row.extension .. " XML " .. row.context ) ;
end
2012-11-08 21:16:32 +01:00
end
2012-11-08 22:07:36 +01:00
found = true ;
2012-11-08 21:16:32 +01:00
end
2012-11-08 22:07:36 +01:00
end
if ( found ~= true ) then
2013-01-17 02:11:43 +01:00
session : streamFile ( sounds_dir .. " /directory/dir-no_matching_results.wav " ) ;
end
search_count = search_count + 1 ;
if ( search_count < search_limit ) then
directory_search ( ) ;
2012-11-08 22:07:36 +01:00
end
end
2012-11-08 21:16:32 +01:00
2012-11-08 22:07:36 +01:00
--get the extensions from the database
sql = " SELECT * FROM v_extensions WHERE domain_uuid = ' " .. domain_uuid .. " ' AND enabled = 'true' AND (directory_visible is null or directory_visible = 'true'); " ;
if ( debug [ " sql " ] ) then
freeswitch.consoleLog ( " notice " , " [directory] SQL: " .. sql .. " \n " ) ;
end
x = 1 ;
directory = { }
dbh : query ( sql , function ( row )
--show all key value pairs
--for key, val in pairs(row) do
-- freeswitch.consoleLog("notice", "[directory] Key: " .. key .. " Value: " .. val .. "\n");
--end
--add the entire row to the directory table array
--directory[x] = row;
--variables
effective_caller_id_name = row.effective_caller_id_name ;
if ( row.directory_full_name ) then
name = row.directory_full_name ;
2012-11-08 21:16:32 +01:00
else
2014-02-09 10:12:05 +01:00
if ( string.len ( effective_caller_id_name ) > 0 ) then
name = effective_caller_id_name ;
2012-11-08 22:07:36 +01:00
end
2012-11-08 21:16:32 +01:00
end
2012-11-08 22:07:36 +01:00
if ( name ) then
name_table = explode ( " " , name ) ;
first_name = name_table [ 1 ] ;
last_name = name_table [ 2 ] ;
if ( first_name ) then
if ( string.len ( first_name ) > 0 ) then
--freeswitch.consoleLog("notice", "[directory] first_name: --" .. first_name .. "--\n");
first_name_digits = dialpad_to_digit ( string.sub ( first_name , 1 , 1 ) ) .. dialpad_to_digit ( string.sub ( first_name , 2 , 2 ) ) .. dialpad_to_digit ( string.sub ( first_name , 3 , 3 ) ) ;
2012-11-08 21:16:32 +01:00
end
2012-11-08 22:07:36 +01:00
end
if ( last_name ) then
if ( string.len ( last_name ) > 0 ) then
--freeswitch.consoleLog("notice", "[directory] last_name: --" .. last_name .. "--\n");
last_name_digits = dialpad_to_digit ( string.sub ( last_name , 1 , 1 ) ) .. dialpad_to_digit ( string.sub ( last_name , 2 , 2 ) ) .. dialpad_to_digit ( string.sub ( last_name , 3 , 3 ) ) ;
2012-11-08 21:16:32 +01:00
end
2012-11-08 22:07:36 +01:00
end
2012-11-08 21:16:32 +01:00
end
2012-11-08 22:07:36 +01:00
--add the row to the array
2014-02-09 10:12:05 +01:00
--freeswitch.consoleLog("notice", "[directory] extension="..row.extension..",context="..row.user_context..",first_name="..name_table[1]..",last_name="..name_table[2]..",first_name_digits="..first_name_digits..",last_name_digits="..last_name_digits..",directory_exten_visible="..row.directory_exten_visible.."\n");
2012-11-08 22:07:36 +01:00
table.insert ( directory , { extension = row.extension , context = row.user_context , first_name = name_table [ 1 ] , last_name = name_table [ 2 ] , first_name_digits = first_name_digits , last_name_digits = last_name_digits , directory_exten_visible = row.directory_exten_visible } ) ;
2012-11-08 21:16:32 +01:00
2012-11-08 22:07:36 +01:00
--increment x
x = x + 1 ;
end ) ;
--call the directory search function
if ( session : ready ( ) ) then
directory_search ( ) ;
end
2012-11-08 21:16:32 +01:00
2015-03-23 06:35:41 +01:00
session : streamFile ( sounds_dir .. " /voicemail/vm-goodbye.wav " ) ;
2012-11-08 22:07:36 +01:00
--notes
--session:execute("say", "en name_spelled pronounced mark");
--<action application="say" data="en name_spelled iterated ${destination_number}"/>
--session:execute("say", "en number iterated 12345");
--session:execute("say", "en number pronounced 1001");
--session:execute("say", "en short_date_time pronounced [timestamp]");
--session:execute("say", "en CURRENT_TIME pronounced CURRENT_TIME");
--session:execute("say", "en CURRENT_DATE pronounced CURRENT_DATE");
--session:execute("say", "en CURRENT_DATE_TIME pronounced CURRENT_DATE_TIME");