2013-11-20 06:14:18 +00:00
-- conference_center/index.lua
2013-02-27 09:50:57 +00:00
-- Part of FusionPBX
2015-03-20 19:05:49 +00:00
-- Copyright (C) 2013 - 2015 Mark J Crane <markjcrane@fusionpbx.com>
2013-02-27 09:50:57 +00:00
-- 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.
--
2015-10-16 10:34:54 -07:00
-- THIS SOFTWARE IS PROVIDED AS ''IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
2013-02-27 09:50:57 +00:00
-- 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.
2013-11-20 06:14:18 +00:00
--
-- Contributor(s):
-- Mark J Crane <markjcrane@fusionpbx.com>
2016-03-11 13:21:52 +00:00
-- Luis Daniel Lucio Quiroz <dlucio@okay.com.mx>
2013-02-27 09:50:57 +00:00
--set variables
flags = "" ;
max_tries = 3 ;
digit_timeout = 5000 ;
2013-05-31 20:53:16 +00:00
--debug
2014-02-07 19:09:32 +00:00
debug [ "sql" ] = false ;
2013-05-31 20:53:16 +00:00
2013-02-27 09:50:57 +00:00
--connect to the database
2016-11-22 20:41:25 +03:00
local Database = require "resources.functions.database" ;
dbh = Database.new ( 'system' );
--include json library
local json
if ( debug [ "sql" ]) then
json = require "resources.functions.lunajson"
end
2013-02-27 09:50:57 +00:00
--prepare the api object
api = freeswitch.API ();
--general functions
2015-08-11 05:06:33 +03:00
require "resources.functions.base64" ;
require "resources.functions.trim" ;
require "resources.functions.file_exists" ;
require "resources.functions.explode" ;
require "resources.functions.format_seconds" ;
require "resources.functions.mkdir" ;
2013-02-27 09:50:57 +00:00
--get the session variables
uuid = session : getVariable ( "uuid" );
--answer the call
session : answer ();
2017-04-24 18:43:32 -04:00
--get record_ext
record_ext = session : getVariable ( "record_ext" );
if ( not record_ext ) then
record_ext = "wav" ;
end
2013-02-27 09:50:57 +00:00
--define a function to send email
function send_email ( email , attachment , default_language , default_dialect )
--require the email address to send the email
if ( string.len ( email ) > 2 ) then
--format the message length and date
--message_length_formatted = format_seconds(message_length);
--if (debug["info"]) then
-- freeswitch.consoleLog("notice", "[conference_center] message length: " .. message_length .. "\n");
--end
local conference_date_end = os.date ( "%A, %d %b %Y %I:%M %p" );
--os.time();
--prepare the files
file_subject = scripts_dir .. "/app/conference_center/resources/templates/" .. default_language .. "/" .. default_dialect .. "email_subject.tpl" ;
file_body = scripts_dir .. "/app/conference_center/resources/templates/" .. default_language .. "/" .. default_dialect .. "/email_body.tpl" ;
if ( not file_exists ( file_subject )) then
file_subject = scripts_dir .. "/app/conference_center/resources/templates/en/us/email_subject.tpl" ;
file_body = scripts_dir .. "/app/conference_center/resources/templates/en/us/email_body.tpl" ;
end
--get the moderator_pin
2016-11-22 20:41:25 +03:00
local sql = "SELECT moderator_pin FROM v_meetings WHERE meeting_uuid = :meeting_uuid" ;
local params = { meeting_uuid = meeting_uuid }
freeswitch.consoleLog ( "notice" , "[voicemail] sql: " .. sql .. "; params:" .. json.encode ( params ) .. " \n " );
dbh : query ( sql , params , function ( row )
moderator_pin = string.lower ( row [ "moderator_pin" ]);
2013-02-27 09:50:57 +00:00
end );
2016-07-08 20:12:37 +01:00
--get the link_address
link_address = http_protocol .. "://" .. domain_name .. project_path ;
2014-07-08 02:30:57 +00:00
--prepare the headers
headers = '{"X-FusionPBX-Domain-UUID":"' .. domain_uuid .. '",' ;
headers = headers .. '"X-FusionPBX-Domain-Name":"' .. domain_name .. '",' ;
headers = headers .. '"X-FusionPBX-Call-UUID":"na",' ;
headers = headers .. '"X-FusionPBX-Email-Type":"conference"}' ;
2013-02-27 09:50:57 +00:00
--prepare the subject
local f = io.open ( file_subject , "r" );
local subject = f : read ( "*all" );
f : close ();
subject = subject : gsub ( "${moderator_pin}" , moderator_pin );
subject = subject : gsub ( "${conference_date_end}" , conference_date_end );
--subject = subject:gsub("${conference_duration}", message_length_formatted);
subject = subject : gsub ( "${domain_name}" , domain_name );
2016-07-08 20:12:37 +01:00
subject = subject : gsub ( "${link_address}" , link_address );
2013-02-27 09:50:57 +00:00
subject = trim ( subject );
subject = '=?utf-8?B?' .. base64.enc ( subject ) .. '?=' ;
--prepare the body
local f = io.open ( file_body , "r" );
local body = f : read ( "*all" );
f : close ();
body = body : gsub ( "${moderator_pin}" , moderator_pin );
body = body : gsub ( "${conference_date_end}" , conference_date_end );
body = body : gsub ( "${conference_uuid}" , conference_session_uuid );
--body = body:gsub("${conference_duration}", message_length_formatted);
body = body : gsub ( "${domain_name}" , domain_name );
2016-07-08 20:12:37 +01:00
body = body : gsub ( "${link_address}" , link_address );
2013-02-27 09:50:57 +00:00
body = body : gsub ( " " , " " );
body = body : gsub ( "%s+" , "" );
body = body : gsub ( " " , " " );
body = body : gsub ( " \n " , "" );
body = body : gsub ( " \n " , "" );
body = body : gsub ( "'" , "'" );
body = body : gsub ( [["]] , """ );
body = trim ( body );
--send the email
if ( string.len ( attachment ) > 4 ) then
2014-07-08 02:30:57 +00:00
cmd = "luarun email.lua " .. email .. " " .. email .. " '" .. headers .. "' '" .. subject .. "' '" .. body .. "' '" .. attachment .. "'" ;
2013-02-27 09:50:57 +00:00
else
2014-07-08 02:30:57 +00:00
cmd = "luarun email.lua " .. email .. " " .. email .. " '" .. headers .. "' '" .. subject .. "' '" .. body .. "'" ;
2013-02-27 09:50:57 +00:00
end
if ( debug [ "info" ]) then
freeswitch.consoleLog ( "notice" , "[voicemail] cmd: " .. cmd .. " \n " );
end
result = api : executeString ( cmd );
end
end
--define the session hangup
function session_hangup_hook ()
--get the session variables
conference_session_detail_uuid = api : executeString ( "create_uuid" );
--conference_name = session:getVariable("conference_name");
conference_session_uuid = session : getVariable ( "conference_uuid" );
--conference_recording = session:getVariable("conference_recording");
conference_moderator = session : getVariable ( "conference_moderator" );
default_language = session : getVariable ( "default_language" );
default_dialect = session : getVariable ( "default_dialect" );
--recording = session:getVariable("recording");
2015-12-06 13:37:35 -07:00
domain_name = session : getVariable ( "domain_name" );
2013-02-27 09:50:57 +00:00
--set the end epoch
end_epoch = os.time ();
2013-03-27 07:07:00 +00:00
--connect to the database
2016-11-24 20:04:42 +03:00
dbh = Database.new ( 'system' );
2013-03-27 07:07:00 +00:00
2013-02-27 09:50:57 +00:00
--get the conference sessions
2013-04-03 07:38:29 +00:00
if ( conference_session_uuid ) then
2016-11-22 20:41:25 +03:00
local sql = [[SELECT count(*) as num_rows
2013-04-03 07:38:29 +00:00
FROM v_conference_sessions
2016-11-22 20:41:25 +03:00
WHERE conference_session_uuid = :conference_session_uuid]] ;
local params = { conference_session_uuid = conference_session_uuid };
dbh : query ( sql , params , function ( row )
num_rows = string.lower ( row [ "num_rows" ]);
2013-04-03 07:38:29 +00:00
end );
2014-03-05 21:10:58 +00:00
if ( debug [ "sql" ]) then
2016-11-22 20:41:25 +03:00
freeswitch.consoleLog ( "notice" , "[conference center] SQL: " .. sql .. "; params:" .. json.encode ( params ) .. "; Rows: " .. num_rows .. " \n " );
2014-03-05 21:10:58 +00:00
end
2013-04-03 07:38:29 +00:00
if ( tonumber ( num_rows ) == 0 ) then
local sql = {}
table.insert ( sql , "INSERT INTO v_conference_sessions " );
table.insert ( sql , "(" );
table.insert ( sql , "conference_session_uuid, " );
table.insert ( sql , "domain_uuid, " );
table.insert ( sql , "meeting_uuid, " );
--if (conference_recording) then
-- table.insert(sql, "recording, ");
--end
--if (wait_mod) then
-- table.insert(sql, "wait_mod, ");
--end
--table.insert(sql, "start_epoch, ");
table.insert ( sql , "profile " );
table.insert ( sql , ") " );
table.insert ( sql , "VALUES " );
table.insert ( sql , "( " );
2016-11-22 20:41:25 +03:00
table.insert ( sql , ":conference_session_uuid, " );
table.insert ( sql , ":domain_uuid, " );
table.insert ( sql , ":meeting_uuid, " );
2013-04-03 07:38:29 +00:00
--if (conference_recording) then
2016-11-22 20:41:25 +03:00
-- table.insert(sql, ":conference_recording, ");
2013-04-03 07:38:29 +00:00
--end
--if (wait_mod) then
2016-11-22 20:41:25 +03:00
-- table.insert(sql, ":wait_mod, ");
2013-04-03 07:38:29 +00:00
--end
2016-11-22 20:41:25 +03:00
--table.insert(sql, ":start_epoch, ");
table.insert ( sql , ":profile " );
2013-04-03 07:38:29 +00:00
table.insert ( sql , ") " );
2016-11-22 20:41:25 +03:00
sql = table.concat ( sql , " \n " );
local params = {
conference_session_uuid = conference_session_uuid ;
domain_uuid = domain_uuid ;
meeting_uuid = meeting_uuid ;
-- conference_recording = conference_recording;
-- wait_mod = wait_mod;
-- start_epoch = start_epoch;
profile = profile ;
};
dbh : query ( sql , params );
2014-03-05 21:10:58 +00:00
if ( debug [ "sql" ]) then
2016-11-22 20:41:25 +03:00
freeswitch.consoleLog ( "notice" , "[conference center] SQL: " .. sql .. "; params:" .. json.encode ( params ) .. " \n " );
2014-03-05 21:10:58 +00:00
end
2013-04-03 07:38:29 +00:00
end
end
--add the conference sessions details
if ( conference_session_uuid ) then
2013-02-27 09:50:57 +00:00
local sql = {}
2013-04-03 07:38:29 +00:00
table.insert ( sql , "INSERT INTO v_conference_session_details " );
2013-02-27 09:50:57 +00:00
table.insert ( sql , "(" );
2013-04-03 07:38:29 +00:00
table.insert ( sql , "conference_session_detail_uuid, " );
2013-02-27 09:50:57 +00:00
table.insert ( sql , "domain_uuid, " );
2013-04-03 07:38:29 +00:00
table.insert ( sql , "conference_session_uuid, " );
2013-02-27 09:50:57 +00:00
table.insert ( sql , "meeting_uuid, " );
2013-04-03 07:38:29 +00:00
table.insert ( sql , "username, " );
table.insert ( sql , "caller_id_name, " );
table.insert ( sql , "caller_id_number, " );
table.insert ( sql , "network_addr, " );
table.insert ( sql , "uuid, " );
if ( conference_moderator ) then
table.insert ( sql , "moderator, " );
end
table.insert ( sql , "start_epoch, " );
table.insert ( sql , "end_epoch " );
2013-02-27 09:50:57 +00:00
table.insert ( sql , ") " );
table.insert ( sql , "VALUES " );
table.insert ( sql , "( " );
2016-11-22 20:41:25 +03:00
table.insert ( sql , ":conference_session_detail_uuid, " );
table.insert ( sql , ":domain_uuid, " );
table.insert ( sql , ":conference_session_uuid, " );
table.insert ( sql , ":meeting_uuid, " );
table.insert ( sql , ":username, " );
table.insert ( sql , ":caller_id_name, " );
table.insert ( sql , ":caller_id_number, " );
table.insert ( sql , ":network_addr, " );
table.insert ( sql , ":uuid, " );
2013-04-03 07:38:29 +00:00
if ( conference_moderator ) then
2016-11-22 20:41:25 +03:00
table.insert ( sql , ":conference_moderator, " );
2013-04-03 07:38:29 +00:00
end
2016-11-22 20:41:25 +03:00
table.insert ( sql , ":start_epoch, " );
table.insert ( sql , ":end_epoch " );
2013-02-27 09:50:57 +00:00
table.insert ( sql , ") " );
2016-11-22 20:41:25 +03:00
sql = table.concat ( sql , " \n " );
local params = {
conference_session_detail_uuid = conference_session_detail_uuid ;
domain_uuid = domain_uuid ;
conference_session_uuid = conference_session_uuid ;
meeting_uuid = meeting_uuid ;
username = username ;
caller_id_name = caller_id_name ;
caller_id_number = caller_id_number ;
network_addr = network_addr ;
uuid = uuid ;
conference_moderator = conference_moderator ;
start_epoch = start_epoch ;
end_epoch = end_epoch ;
};
dbh : query ( sql , params );
2013-02-27 09:50:57 +00:00
end
--if the conference is empty
2013-04-03 07:38:29 +00:00
if ( conference_session_uuid ) then
2017-04-17 17:01:04 +02:00
cmd = "conference " .. meeting_uuid .. "@" .. domain_name .. " xml_list" ;
2013-04-03 07:38:29 +00:00
result = trim ( api : executeString ( cmd ));
if ( string.sub ( result , - 9 ) == "not found" ) then
--get the conference start_epoch
2016-11-22 20:41:25 +03:00
local sql = [[SELECT start_epoch
2013-04-03 07:38:29 +00:00
FROM v_conference_session_details
2016-11-22 20:41:25 +03:00
WHERE conference_session_uuid = :conference_session_uuid
2013-04-03 07:38:29 +00:00
ORDER BY start_epoch ASC
LIMIT 1]] ;
2016-11-22 20:41:25 +03:00
local params = { conference_session_uuid = conference_session_uuid };
dbh : query ( sql , params , function ( row )
start_epoch = string.lower ( row [ "start_epoch" ]);
2013-04-03 07:38:29 +00:00
end );
2016-11-22 20:41:25 +03:00
--freeswitch.consoleLog("notice", "[conference center] <conference_start_epoch> sql: " .. sql .. "; params:" .. json.encode(params) .. "\n");
2013-04-03 07:38:29 +00:00
--set the conference_recording
2015-05-30 20:19:36 +00:00
conference_recording = recordings_dir .. "/archive/" .. os.date ( "%Y" , start_epoch ) .. "/" .. os.date ( "%b" , start_epoch ) .. "/" .. os.date ( "%d" , start_epoch ) .. "/" .. conference_session_uuid ;
2015-05-28 18:41:43 +00:00
freeswitch.consoleLog ( "notice" , "[conference center] conference_recording: " .. conference_recording .. " \n " );
2013-04-03 07:38:29 +00:00
--conference has ended set the end_epoch
local sql = {}
table.insert ( sql , "update v_conference_sessions set " );
2016-11-22 20:41:25 +03:00
table.insert ( sql , "recording = :conference_recording, " );
table.insert ( sql , "start_epoch = :start_epoch, " );
table.insert ( sql , "end_epoch = :end_epoch " );
table.insert ( sql , "where conference_session_uuid = :conference_session_uuid " );
sql = table.concat ( sql , " \n " );
local params = {
conference_recording = conference_recording ;
start_epoch = start_epoch ;
end_epoch = end_epoch ;
conference_session_uuid = conference_session_uuid ;
};
2014-03-05 21:10:58 +00:00
if ( debug [ "sql" ]) then
2016-11-22 20:41:25 +03:00
freeswitch.consoleLog ( "notice" , "[conference center] SQL: " .. sql .. "; params:" .. json.encode ( params ) .. " \n " );
2014-03-05 21:10:58 +00:00
end
2016-11-22 20:41:25 +03:00
dbh : query ( sql , params );
2013-04-03 07:38:29 +00:00
--convert the wav to an mp3
if ( record == "true" ) then
--cmd = "sox "..conference_recording..".wav -r 16000 -c 1 "..conference_recording..".mp3";
cmd = "/usr/bin/lame -b 32 --resample 8 -a " .. conference_recording .. ".wav " .. conference_recording .. ".mp3" ;
2014-01-03 21:04:37 +00:00
freeswitch.consoleLog ( "notice" , "[conference center] cmd: " .. cmd .. " \n " );
2013-04-03 07:38:29 +00:00
os.execute ( cmd );
--if (file_exists(conference_recording..".mp3")) then
-- cmd = "rm "..conference_recording..".wav";
-- os.execute(cmd);
--end
end
--send the email addresses
2016-04-14 10:40:25 -06:00
--sql = [[SELECT c.contact_email FROM v_users as u, v_meeting_users as m, v_contacts as c
-- WHERE m.domain_uuid = ']] .. domain_uuid ..[['
-- AND u.user_uuid = m.user_uuid
-- AND m.meeting_uuid = ']] .. meeting_uuid ..[['
-- and u.contact_uuid = c.contact_uuid]];
--if (debug["sql"]) then
-- freeswitch.consoleLog("notice", "[conference center] <email> SQL: " .. sql .. "\n");
--end
--status = dbh:query(sql, function(row)
-- if (row["contact_email"] ~= nil) then
-- contact_email = string.lower(row["contact_email"]);
-- if (string.len(contact_email) > 3) then
-- freeswitch.consoleLog("notice", "[conference center] contact_email: " .. contact_email .. "\n");
-- if (record == "true") then
-- if (file_exists(conference_recording..".wav")) then
-- send_email(contact_email, "", default_language, default_dialect);
-- end
-- end
-- end
-- end
--end);
2013-04-03 07:38:29 +00:00
end
2013-02-27 09:50:57 +00:00
end
2013-03-27 07:07:00 +00:00
--close the database connection
2013-04-03 07:38:29 +00:00
if ( conference_session_uuid ) then
dbh : release ();
end
2013-02-27 09:50:57 +00:00
end
--make sure the session is ready
if ( session : ready ()) then
2013-03-15 17:12:13 +00:00
2013-11-20 06:14:18 +00:00
--answer the call
session : preAnswer ();
2013-03-15 17:12:13 +00:00
2014-12-05 02:40:21 +00:00
--set the session sleep
session : sleep ( 1000 );
2013-03-15 17:12:13 +00:00
--get session variables
sounds_dir = session : getVariable ( "sounds_dir" );
hold_music = session : getVariable ( "hold_music" );
domain_name = session : getVariable ( "domain_name" );
pin_number = session : getVariable ( "pin_number" );
2014-01-04 00:11:09 +00:00
domain_uuid = session : getVariable ( "domain_uuid" );
2013-11-20 06:14:18 +00:00
destination_number = session : getVariable ( "destination_number" );
caller_id_number = session : getVariable ( "caller_id_number" );
2014-03-05 21:10:58 +00:00
--freeswitch.consoleLog("notice", "[conference center] destination_number: " .. destination_number .. "\n");
--freeswitch.consoleLog("notice", "[conference center] caller_id_number: " .. caller_id_number .. "\n");
2013-02-27 09:50:57 +00:00
2015-12-06 13:37:35 -07:00
--add the domain name to the recordings directory
recordings_dir = recordings_dir .. "/" .. domain_name ;
2015-01-29 10:07:50 +00: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-02-27 09:50:57 +00:00
--get the domain_uuid
2014-01-04 00:11:09 +00:00
if ( domain_name ~= nil and domain_uuid == nil ) then
2016-11-22 20:41:25 +03:00
local sql = "SELECT domain_uuid FROM v_domains " ;
sql = sql .. "WHERE domain_name = :domain_name " ;
local params = { domain_name = domain_name };
2013-02-27 09:50:57 +00:00
if ( debug [ "sql" ]) then
2016-11-22 20:41:25 +03:00
freeswitch.consoleLog ( "notice" , "[conference center] SQL: " .. sql .. "; params:" .. json.encode ( params ) .. " \n " );
2013-02-27 09:50:57 +00:00
end
2016-11-22 20:41:25 +03:00
dbh : query ( sql , params , function ( rows )
2013-02-27 09:50:57 +00:00
domain_uuid = string.lower ( rows [ "domain_uuid" ]);
end );
end
2014-03-05 21:10:58 +00:00
--conference center details
2016-11-22 20:41:25 +03:00
local sql = [[SELECT * FROM v_conference_centers
WHERE domain_uuid = :domain_uuid
AND conference_center_extension = :destination_number]] ;
local params = { domain_uuid = domain_uuid , destination_number = destination_number };
dbh : query ( sql , params , function ( row )
2014-03-05 21:10:58 +00:00
conference_center_uuid = string.lower ( row [ "conference_center_uuid" ]);
2015-03-20 19:05:49 +00:00
conference_center_greeting = row [ "conference_center_greeting" ];
2014-03-05 21:10:58 +00:00
end );
2015-01-29 10:07:50 +00:00
if ( conference_center_greeting == '' ) then
2014-12-05 02:40:21 +00:00
conference_center_greeting = sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/conference/conf-pin.wav" ;
2014-03-05 21:10:58 +00:00
end
2014-01-03 21:02:21 +00:00
--connect to the switch database
2016-11-22 20:41:25 +03:00
local dbh_switch = Database.new ( 'switch' )
2014-01-03 21:02:21 +00:00
2013-11-20 06:14:18 +00:00
--check if someone has already joined the conference
2015-10-16 10:34:54 -07:00
local_hostname = trim ( api : execute ( "switchname" , "" ));
2014-01-03 21:04:37 +00:00
freeswitch.consoleLog ( "notice" , "[conference center] local_hostname is " .. local_hostname .. " \n " );
2016-11-22 20:41:25 +03:00
sql = "SELECT hostname FROM channels WHERE application = 'conference' "
.. "AND dest = :destination_number AND cid_num <> :caller_id_number LIMIT 1" ;
params = { destination_number = destination_number , caller_id_number = caller_id_number };
2013-11-20 06:14:18 +00:00
if ( debug [ "sql" ]) then
2016-11-22 20:41:25 +03:00
freeswitch.consoleLog ( "notice" , "[conference center] SQL: " .. sql .. "; params:" .. json.encode ( params ) .. " \n " );
2013-11-20 06:14:18 +00:00
end
2016-11-22 20:41:25 +03:00
dbh_switch : query ( sql , params , function ( rows )
2014-10-03 06:19:03 +00:00
conference_hostname = rows [ "hostname" ];
2013-11-20 06:14:18 +00:00
end );
2016-11-22 20:41:25 +03:00
--close the database connection
dbh_switch : release ();
2014-01-03 21:02:21 +00:00
--if conference hosntame exist, then we bridge there
if ( conference_hostname ~= nil ) then
freeswitch.consoleLog ( "notice" , "[conference center] conference_hostname is " .. conference_hostname .. " \n " );
if ( conference_hostname ~= local_hostname ) then
session : execute ( "bridge" , "sofia/internal/" .. destination_number .. "@" .. domain_name .. ";fs_path=sip:" .. conference_hostname );
end
2013-11-20 07:35:38 +00:00
end
2013-11-20 06:14:18 +00:00
2013-11-20 07:35:38 +00:00
--call not bridged, so we answer
2013-11-20 06:14:18 +00:00
session : answer ();
--set the hangup hook function
session : setHangupHook ( "session_hangup_hook" );
2013-02-27 09:50:57 +00:00
--add the domain to the recording directory
2015-05-28 18:41:43 +00:00
freeswitch.consoleLog ( "notice" , "[conference center] domain_count: " .. domain_count .. " \n " );
2013-02-27 09:50:57 +00:00
--sounds
2013-03-15 17:12:13 +00:00
enter_sound = "tone_stream://v=-20;%(100,1000,100);v=-20;%(90,60,440);%(90,60,620)" ;
exit_sound = "tone_stream://v=-20;%(90,60,620);/%(90,60,440)" ;
2013-02-27 09:50:57 +00:00
--get the variables
username = session : getVariable ( "username" );
caller_id_name = session : getVariable ( "caller_id_name" );
caller_id_number = session : getVariable ( "caller_id_number" );
callee_id_name = session : getVariable ( "callee_id_name" );
callee_id_number = session : getVariable ( "callee_id_number" );
dialplan = session : getVariable ( "dialplan" );
network_addr = session : getVariable ( "network_addr" );
uuid = session : getVariable ( "uuid" );
--context = session:getVariable("context");
chan_name = session : getVariable ( "chan_name" );
2013-05-31 20:53:16 +00:00
--define the function get_pin_number
2014-12-05 02:40:21 +00:00
function get_pin_number ( domain_uuid , prompt_audio_file )
2013-02-27 09:50:57 +00:00
--if the pin number is provided then require it
2016-03-11 13:21:52 +00:00
if ( not pin_number ) then
2014-10-17 20:39:56 +00:00
min_digits = 2 ;
max_digits = 20 ;
2013-02-27 09:50:57 +00:00
max_tries = 1 ;
digit_timeout = 5000 ;
2014-12-05 02:40:21 +00:00
pin_number = session : playAndGetDigits ( min_digits , max_digits , max_tries , digit_timeout , "#" , prompt_audio_file , "" , " \\ d+" );
2013-02-27 09:50:57 +00:00
end
2016-10-17 17:58:06 -06:00
--use the pin_number to find the conference room
if ( pin_number ~= "" ) then
2016-11-22 20:41:25 +03:00
local sql = [[SELECT * FROM v_conference_rooms as r, v_meetings as m
WHERE r.domain_uuid = :domain_uuid
2016-10-17 17:58:06 -06:00
AND r.meeting_uuid = m.meeting_uuid
2016-11-22 20:41:25 +03:00
AND m.domain_uuid = :domain_uuid
AND (m.moderator_pin = :pin_number or m.participant_pin = :pin_number)
2016-10-17 17:58:06 -06:00
AND r.enabled = 'true'
AND m.enabled = 'true'
AND (
2016-11-22 20:41:25 +03:00
( r.start_datetime <> '' AND r.start_datetime is not null AND r.start_datetime <= :timestam ) OR
2016-10-17 17:58:06 -06:00
( r.start_datetime = '' OR r.start_datetime is null )
)
AND (
2016-11-22 20:41:25 +03:00
( r.stop_datetime <> '' AND r.stop_datetime is not null AND r.stop_datetime > :timestam ) OR
2016-10-17 17:58:06 -06:00
( r.stop_datetime = '' OR r.stop_datetime is null )
) ]] ;
2016-11-22 20:41:25 +03:00
local params = {
domain_uuid = domain_uuid ;
pin_number = pin_number ;
timestam = os.date ( "%Y-%m-%d %X" );
};
2016-10-17 17:58:06 -06:00
if ( debug [ "sql" ]) then
2016-11-22 20:41:25 +03:00
freeswitch.consoleLog ( "notice" , "[conference center] SQL: " .. sql .. "; params:" .. json.encode ( params ) .. " \n " );
2016-10-17 17:58:06 -06:00
end
2016-11-22 20:41:25 +03:00
dbh : query ( sql , params , function ( row )
2016-10-17 17:58:06 -06:00
conference_room_uuid = string.lower ( row [ "conference_room_uuid" ]);
end );
end
--if the conference room was not found then return nil
if ( conference_room_uuid == nil ) then
return nil ;
else
return pin_number ;
2013-02-27 09:50:57 +00:00
end
end
2013-03-15 17:12:13 +00:00
--get the pin
2014-12-05 02:45:56 +00:00
pin_number = session : getVariable ( "pin_number" );
2016-10-17 17:58:06 -06:00
pin_number = get_pin_number ( domain_uuid , conference_center_greeting );
2013-03-15 17:12:13 +00:00
if ( pin_number == nil ) then
2014-12-05 02:40:21 +00:00
pin_number = get_pin_number ( domain_uuid , conference_center_greeting );
2013-03-15 17:12:13 +00:00
end
2013-02-27 09:50:57 +00:00
if ( pin_number == nil ) then
session : streamFile ( sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/conference/conf-bad-pin.wav" );
2014-12-05 02:40:21 +00:00
pin_number = get_pin_number ( domain_uuid , conference_center_greeting );
2013-02-27 09:50:57 +00:00
end
if ( pin_number == nil ) then
session : streamFile ( sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/conference/conf-bad-pin.wav" );
2014-12-05 02:40:21 +00:00
pin_number = get_pin_number ( domain_uuid , conference_center_greeting );
2013-02-27 09:50:57 +00:00
end
if ( pin_number ~= nil ) then
2016-11-22 20:41:25 +03:00
local sql = [[SELECT * FROM v_conference_rooms as r, v_meetings as m
WHERE r.domain_uuid = :domain_uuid
2013-04-16 07:39:31 +00:00
AND r.meeting_uuid = m.meeting_uuid
2016-11-22 20:41:25 +03:00
AND r.conference_center_uuid = :conference_center_uuid
AND m.domain_uuid = :domain_uuid
AND (m.moderator_pin = :pin_number or m.participant_pin = :pin_number)
2016-03-11 13:21:52 +00:00
AND r.enabled = 'true'
2015-12-22 21:30:36 -07:00
AND m.enabled = 'true'
2016-11-22 20:41:25 +03:00
]] ;
local params = {
domain_uuid = domain_uuid ;
conference_center_uuid = conference_center_uuid ;
pin_number = pin_number ;
};
2013-02-27 09:50:57 +00:00
if ( debug [ "sql" ]) then
2016-11-22 20:41:25 +03:00
freeswitch.consoleLog ( "notice" , "[conference center] SQL: " .. sql .. "; params:" .. json.encode ( params ) .. " \n " );
2013-02-27 09:50:57 +00:00
end
2016-11-22 20:41:25 +03:00
dbh : query ( sql , params , function ( row )
2013-02-27 09:50:57 +00:00
conference_room_uuid = string.lower ( row [ "conference_room_uuid" ]);
meeting_uuid = string.lower ( row [ "meeting_uuid" ]);
record = string.lower ( row [ "record" ]);
profile = string.lower ( row [ "profile" ]);
max_members = row [ "max_members" ];
wait_mod = row [ "wait_mod" ];
2013-05-31 20:53:16 +00:00
moderator_pin = row [ "moderator_pin" ];
participant_pin = row [ "participant_pin" ];
2013-02-27 09:50:57 +00:00
announce = row [ "announce" ];
mute = row [ "mute" ];
sounds = row [ "sounds" ];
created = row [ "created" ];
created_by = row [ "created_by" ];
enabled = row [ "enabled" ];
description = row [ "description" ];
return pin_number ;
end );
freeswitch.consoleLog ( "INFO" , "conference_room_uuid: " .. conference_room_uuid .. " \n " );
end
2013-05-31 20:53:16 +00:00
--set the member type
if ( pin_number == moderator_pin ) then
member_type = "moderator" ;
end
if ( pin_number == participant_pin ) then
member_type = "participant" ;
end
2013-03-27 07:07:00 +00:00
--close the database connection
dbh : release ();
2013-02-27 09:50:57 +00:00
--set the meeting uuid
2013-04-03 07:38:29 +00:00
if ( meeting_uuid ) then
session : setVariable ( "meeting_uuid" , meeting_uuid );
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
if ( meeting_uuid == nil ) then
2013-02-27 09:50:57 +00:00
--invalid pin number
session : streamFile ( sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/conference/conf-bad-pin.wav" );
session : hangup ( "NORMAL_CLEARING" );
else
2014-03-05 21:10:58 +00:00
if ( meeting_uuid ) then
--check if the conference exists
2017-04-17 17:01:04 +02:00
cmd = "conference " .. meeting_uuid .. "@" .. domain_name .. " xml_list" ;
2014-03-05 21:10:58 +00:00
result = trim ( api : executeString ( cmd ));
if ( string.sub ( result , - 9 ) == "not found" ) then
conference_exists = false ;
else
conference_exists = true ;
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--check if the conference is locked
if ( string.find ( result , [[locked="true"]] ) == nil ) then
conference_locked = false ;
else
conference_locked = true ;
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--set a conference parameter
if ( max_members ~= nil ) then
if ( tonumber ( max_members ) > 0 ) then
--max members must be 2 or more
session : execute ( "set" , "conference_max_members=" .. max_members );
if ( conference_exists ) then
2017-04-17 17:01:04 +02:00
cmd = "conference " .. meeting_uuid .. "@" .. domain_name .. " get count" ;
2014-03-05 21:10:58 +00:00
count = trim ( api : executeString ( cmd ));
if ( count ~= nil ) then
if ( tonumber ( count ) >= tonumber ( max_members )) then
session : execute ( "playback" , sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/conference/conf-locked.wav" );
session : hangup ( "CALL_REJECTED" );
end
2013-02-27 09:50:57 +00:00
end
end
end
end
2014-03-05 21:10:58 +00:00
--announce the caller
if ( conference_locked ) then
announce = "false" ;
end
if ( announce == "true" ) then
--prompt for the name of the caller
session : execute ( "playback" , sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/ivr/ivr-say_name.wav" );
session : execute ( "playback" , "tone_stream://v=-7;%%(500,0,500.0)" );
--record the response
max_len_seconds = 5 ;
silence_threshold = "500" ;
silence_secs = "3" ;
2015-08-07 12:11:27 +04:00
session : recordFile ( temp_dir : gsub ( " \\ " , "/" ) .. "/conference-" .. uuid .. ".wav" , max_len_seconds , silence_threshold , silence_secs );
2014-03-05 21:10:58 +00:00
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--play a message that the conference is being a recorded
--if (record == "true") then
--session:execute("playback", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-recording_started.wav");
--end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--wait for moderator
if ( wait_mod == "true" ) then
if ( conference_exists ) then
--continue
else
if ( member_type == "participant" ) then
profile = "wait-mod" ;
end
2013-02-27 09:50:57 +00:00
end
end
2014-03-05 21:10:58 +00:00
--set the exit sound
if ( sounds == "true" ) then
session : execute ( "set" , "conference_exit_sound=" .. exit_sound );
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--set flags and moderator controls
if ( wait_mod == "true" ) then
if ( member_type == "participant" ) then
flags = flags .. "wait-mod" ;
end
2013-02-27 09:50:57 +00:00
end
2014-03-05 21:10:58 +00:00
if ( mute == "true" ) then
if ( member_type == "participant" ) then
flags = flags .. "|mute" ;
end
end
if ( member_type == "moderator" ) then
--set as the moderator
flags = flags .. "|moderator" ;
--when the moderator leaves end the conference
--flags = flags .. "|endconf";
--set the moderator controls
session : execute ( "set" , "conference_controls=moderator" );
2013-02-27 09:50:57 +00:00
end
2014-03-05 21:10:58 +00:00
--get the conference xml_list
2017-04-17 17:01:04 +02:00
cmd = "conference " .. meeting_uuid .. "@" .. domain_name .. " xml_list" ;
2014-03-05 21:10:58 +00:00
freeswitch.consoleLog ( "INFO" , "" .. cmd .. " \n " );
result = trim ( api : executeString ( cmd ));
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--get the content to the <conference> tag
result = string.match ( result , [[<conference (.-)>]] , 1 );
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--get the uuid out of the xml tag contents
if ( result ~= nil ) then
conference_session_uuid = string.match ( result , [[uuid="(.-)"]] , 1 );
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--log entry
if ( conference_session_uuid ~= nil ) then
freeswitch.consoleLog ( "INFO" , "conference_session_uuid: " .. conference_session_uuid .. " \n " );
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--set the start epoch
start_epoch = os.time ();
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--set the recording variable
if ( conference_session_uuid ~= nil ) then
if ( record == "true" ) then
2015-05-30 20:19:36 +00:00
recordings_dir_2 = recordings_dir .. "/archive/" .. os.date ( "%Y" , start_epoch ) .. "/" .. os.date ( "%b" , start_epoch ) .. "/" .. os.date ( "%d" , start_epoch );
mkdir ( recordings_dir_2 );
recording = recordings_dir_2 .. "/" .. conference_session_uuid ;
2014-03-05 21:10:58 +00:00
session : execute ( "set" , "recording=" .. recording );
2015-05-28 18:41:43 +00:00
session : execute ( "set" , "conference_session_uuid=" .. conference_session_uuid );
2014-03-05 21:10:58 +00:00
end
2013-03-15 17:12:13 +00:00
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--record the conference
if ( record == "true" ) then
--play a message that the conference is being a recorded
session : execute ( "playback" , sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/ivr/ivr-recording_started.wav" );
--play a message that the conference is being a recorded
2017-04-17 17:01:04 +02:00
--cmd = "conference "..meeting_uuid.."@"..domain_name.." play "..sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-recording_started.wav";
2014-03-05 21:10:58 +00:00
--freeswitch.consoleLog("notice", "[conference center] ".. cmd .."\n");
--response = api:executeString(cmd);
end
2013-02-27 09:50:57 +00:00
2014-03-05 21:10:58 +00:00
--announce the caller
if ( announce == "true" ) then
--announce the caller - play the recording
2017-04-17 17:01:04 +02:00
cmd = "conference " .. meeting_uuid .. "@" .. domain_name .. " play " .. temp_dir : gsub ( " \\ " , "/" ) .. "/conference-" .. uuid .. ".wav" ;
2014-03-05 21:10:58 +00:00
--freeswitch.consoleLog("notice", "[conference center] ".. cmd .."\n");
response = api : executeString ( cmd );
--play has entered the conference
2017-04-17 17:01:04 +02:00
cmd = "conference " .. meeting_uuid .. "@" .. domain_name .. " play " .. sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/conference/conf-has_joined.wav" ;
2014-03-05 21:10:58 +00:00
--freeswitch.consoleLog("notice", "[conference center] ".. cmd .."\n");
2013-02-27 09:50:57 +00:00
response = api : executeString ( cmd );
2014-03-05 21:10:58 +00:00
else
if ( not conference_locked ) then
if ( sounds == "true" ) then
2017-04-17 17:01:04 +02:00
cmd = "conference " .. meeting_uuid .. "@" .. domain_name .. " play " .. enter_sound ;
2014-03-05 21:10:58 +00:00
response = api : executeString ( cmd );
end
2013-02-27 09:50:57 +00:00
end
end
2013-02-28 18:55:36 +00:00
2014-03-05 21:10:58 +00:00
--get the conference member count
2017-04-17 17:01:04 +02:00
cmd = "conference " .. meeting_uuid .. "@" .. domain_name .. " list count" ;
2014-03-05 21:10:58 +00:00
--freeswitch.consoleLog("notice", "[conference center] cmd: ".. cmd .."\n");
member_count = api : executeString ( cmd );
if ( string.sub ( trim ( member_count ), - 9 ) == "not found" ) then
member_count = "0" ;
end
2014-02-28 17:14:15 +00:00
2014-03-05 21:10:58 +00:00
--play member count
if ( member_count == "1" ) then
--there is one other member in this conference
session : execute ( "playback" , sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/conference/conf-one_other_member_conference.wav" );
elseif ( member_count == "0" ) then
2015-12-07 16:30:03 -07:00
--conference profile defines the alone sound file
2014-03-05 21:10:58 +00:00
else
--say the count
session : execute ( "say" , default_language .. " number pronounced " .. member_count );
--members in this conference
session : execute ( "playback" , sounds_dir .. "/" .. default_language .. "/" .. default_dialect .. "/" .. default_voice .. "/conference/conf-members_in_conference.wav" );
end
2015-05-30 20:19:36 +00:00
--record the conference
if ( record == "true" ) then
2017-09-28 12:35:44 +10:00
cmd = "sched_api +5 none lua " .. scripts_dir .. "/app/conference_center/resources/scripts/start_recording.lua " .. meeting_uuid .. " " .. domain_name .. " " .. record_ext ;
2015-05-30 20:19:36 +00:00
api : executeString ( cmd );
end
2014-03-05 21:10:58 +00:00
--send the call to the conference
2017-04-17 17:01:04 +02:00
cmd = meeting_uuid .. "@" .. domain_name .. "@" .. profile .. "+flags{" .. flags .. "}" ;
2015-02-13 18:51:19 +00:00
freeswitch.consoleLog ( "INFO" , "[conference center] conference " .. cmd .. " \n " );
2014-03-05 21:10:58 +00:00
session : execute ( "conference" , cmd );
end
2013-02-27 09:50:57 +00:00
end
2015-02-13 18:51:19 +00:00
end