Googling does not helps, so, made own bicycle.
Quick inliner to get variable length in FreeSwitch.
In $1 assuming our variable.
dest_len=${lua(~stream:write(tostring("$1"):len()))}
Showing posts with label lua. Show all posts
Showing posts with label lua. Show all posts
Thursday, October 12, 2017
Wednesday, August 9, 2017
FusionPBX/FreeSWITCH save CLID on transfer
Idea is when call is received, transfer to next destination should come with callerID was received originally, not updated in moment of transfer. Sometimes it's needed for correct CRM integration or peoples just get used to it, cause it's default with blind transfer.
Actually, same ideas that described here, but for use in FusionPBX.
1. Create context save_transfer with order ~85
condition - <empty>
action - export - nolocal:execute_on_answer_1=lua number_save_on_transfer_store.lua
action - export - api_hangup_hook=lua number_save_on_transfer_db_cleanup.lua
2. Create context restore_transfer with order higher, than save_trasfer, ~80
condition - ${db(exists/number_transfer_store/${sip_from_user})} - ^true$
action - set - restored_number_on_transfer=${db(select/number_transfer_store/${sip_from_user})} - inline
action - set - effective_caller_id_number=${restored_number_on_transfer}
action - set - effective_caller_id_name=${restored_number_on_transfer}
action - db - delete/number_transfer_store/${sip_from_user}
condition - ${db(exists/number_transfer_store/${sip_from_user}_name)} - ^true$
action - set - restored_number_on_transfer_name=${db(select/number_transfer_store/${sip_from_user}_name)} - inline
action - set - effective_caller_id_name=${restored_number_on_transfer_name}
action - db - delete/number_transfer_store/${sip_from_user}_name
Lua files:
/usr/share/freeswitch/scripts/number_save_on_transfer_store.lua
-- Save number_answered / original caller_id to database
--api = freeswitch.API()
if (session:ready()) then
answered_extension = session:getVariable("dialed_user")
caller_id = session:getVariable("restored_number_on_transfer")
caller_name = session:getVariable("restored_number_on_transfer_name")
if (caller_id == nil) then
caller_id = session:getVariable("sip_from_user")
end
if (caller_name == nil) then
caller_name = session:getVariable("sip_from_display")
end
if (answered_extension ~= nil and caller_id ~= nil) then
freeswitch.consoleLog("INFO", "[NUMBER_ON_TRANSFER_SAVE] Got answered call from "..caller_id.." to "..answered_extension.."\n")
session:execute('db', 'insert/number_transfer_store/'..answered_extension..'/'..caller_id)
if (caller_name ~= nil) then
session:execute('db', 'insert/number_transfer_store/'..answered_extension..'_name/'..caller_name)
end
end
end
/usr/share/freeswitch/scripts/number_save_on_transfer_db_cleanup.lua
-- Cleanup database
api = freeswitch.API()
sip_to_user = env:getHeader("variable_last_sent_callee_id_number")
if (sip_to_user ~= nil) then
--serialized = env:serialize()
--freeswitch.consoleLog("INFO","[hangup]\n" .. serialized .. "\n")
freeswitch.consoleLog("INFO", "[DB_CLEANUP] Cleaning " .. sip_to_user .. "\n")
api:executeString('db delete/number_transfer_store/'..sip_to_user)
api:executeString('db delete/number_transfer_store/'..sip_to_user..'_name')
end
P.S.: At the end, db is can be easily replaced with hash. As we don't need persistence storage here.
Actually, same ideas that described here, but for use in FusionPBX.
1. Create context save_transfer with order ~85
condition - <empty>
action - export - nolocal:execute_on_answer_1=lua number_save_on_transfer_store.lua
action - export - api_hangup_hook=lua number_save_on_transfer_db_cleanup.lua
2. Create context restore_transfer with order higher, than save_trasfer, ~80
condition - ${db(exists/number_transfer_store/${sip_from_user})} - ^true$
action - set - restored_number_on_transfer=${db(select/number_transfer_store/${sip_from_user})} - inline
action - set - effective_caller_id_number=${restored_number_on_transfer}
action - set - effective_caller_id_name=${restored_number_on_transfer}
action - db - delete/number_transfer_store/${sip_from_user}
condition - ${db(exists/number_transfer_store/${sip_from_user}_name)} - ^true$
action - set - restored_number_on_transfer_name=${db(select/number_transfer_store/${sip_from_user}_name)} - inline
action - set - effective_caller_id_name=${restored_number_on_transfer_name}
action - db - delete/number_transfer_store/${sip_from_user}_name
Lua files:
/usr/share/freeswitch/scripts/number_save_on_transfer_store.lua
-- Save number_answered / original caller_id to database
--api = freeswitch.API()
if (session:ready()) then
answered_extension = session:getVariable("dialed_user")
caller_id = session:getVariable("restored_number_on_transfer")
caller_name = session:getVariable("restored_number_on_transfer_name")
if (caller_id == nil) then
caller_id = session:getVariable("sip_from_user")
end
if (caller_name == nil) then
caller_name = session:getVariable("sip_from_display")
end
if (answered_extension ~= nil and caller_id ~= nil) then
freeswitch.consoleLog("INFO", "[NUMBER_ON_TRANSFER_SAVE] Got answered call from "..caller_id.." to "..answered_extension.."\n")
session:execute('db', 'insert/number_transfer_store/'..answered_extension..'/'..caller_id)
if (caller_name ~= nil) then
session:execute('db', 'insert/number_transfer_store/'..answered_extension..'_name/'..caller_name)
end
end
end
/usr/share/freeswitch/scripts/number_save_on_transfer_db_cleanup.lua
-- Cleanup database
api = freeswitch.API()
sip_to_user = env:getHeader("variable_last_sent_callee_id_number")
if (sip_to_user ~= nil) then
--serialized = env:serialize()
--freeswitch.consoleLog("INFO","[hangup]\n" .. serialized .. "\n")
freeswitch.consoleLog("INFO", "[DB_CLEANUP] Cleaning " .. sip_to_user .. "\n")
api:executeString('db delete/number_transfer_store/'..sip_to_user)
api:executeString('db delete/number_transfer_store/'..sip_to_user..'_name')
end
P.S.: At the end, db is can be easily replaced with hash. As we don't need persistence storage here.
Monday, January 25, 2016
FusionPBX(Freeswitch) HA sync gateways across servers
There was a little task to do.
Assume, we have several FusionPBX in HA (shared database incl. runtime data is on). On "master managing" server we add a gateway to external profile. To add them on other servers we have to go to each server and push rescan on external profile. Eh... To lazy for this.
We will use script, that will subscribe to CUSTOM sofia::gateway_add and gateway_delete event and run sofia profile external rescan over other servers.
We will do this over xmlrpc, so no need to add ssh keys or so.
"Slave" servers:
Assume, we have several FusionPBX in HA (shared database incl. runtime data is on). On "master managing" server we add a gateway to external profile. To add them on other servers we have to go to each server and push rescan on external profile. Eh... To lazy for this.
We will use script, that will subscribe to CUSTOM sofia::gateway_add and gateway_delete event and run sofia profile external rescan over other servers.
We will do this over xmlrpc, so no need to add ssh keys or so.
"Slave" servers:
- Go to Advanced -> Modules and enable XML RPC module
- Go to Advanced -> Settings on each "slave" server and put common data for XMLRPC connection, like username, pass and port
- Restart mod_xml_rpc on each "slave" server
"Master" server
- Create files /usr/local/freeswitch/scripts/app/gateway_states/resources/gateway_states_add.lua and /usr/local/freeswitch/scripts/app/gateway_states/resources/gateway_states_delete.lua
- gateway_states_add.lua
--description
--monitor custom sofia:gateway_* event and run sofia profile external rescan over other servers
--protect xmlrpc using a firewall on the server to limit access by ip address
--iptables
-- /sbin/iptables -I INPUT -j ACCEPT -p tcp --dport 8080 -s x.x.x.x/32
--define the servers running freeswitch do not include local
servers = {}
x = 0;
servers[x] = {}
servers[x]['username'] = "freeswitch";
servers[x]['password'] = "work";
servers[x]['hostname'] = "10.0.0.2";
servers[x]['port'] = "8080";
x = x + 1;
servers[x] = {}
servers[x]['username'] = "freeswitch";
servers[x]['password'] = "work";
servers[x]['hostname'] = "10.0.0.3";
servers[x]['port'] = "8080";
--x = x + 1;
--servers[x] = {}
--servers[x]['username'] = "ccc";
--servers[x]['password'] = "xxxxx";
--servers[x]['hostname'] = "127.0.0.3";
--servers[x]['port'] = "8080";
--subscribe to the events
--events = freeswitch.EventConsumer("all");
events = freeswitch.EventConsumer("CUSTOM", "sofia::gateway_add");
-- events = freeswitch.EventConsumer("CUSTOM", "sofia::gateway_delete");
-- Modify line above to get gateway_states_delete.lua
--prepare the api object
api = freeswitch.API();
--get the events
for event in (function() return events:pop(1) end) do
api_command_argument = "profile%20external%20rescan";
-- event_gateway = event:getHeader("Gateway");
-- api_command_argument = "profile%20external%20killgw%20"..event_gateway;
-- Modify line above to get gateway_states_delete.lua
-- event_gateway = event:getHeader("Gateway");
-- api_command_argument = "profile%20external%20killgw%20"..event_gateway;
-- Modify line above to get gateway_states_delete.lua
for key,row in pairs(servers) do
url = [[http://]]..row.username..[[:]]..row.password..[[@]]..row.hostname..[[:]]..row.port..[[/webapi/sofia?]]..api_command_argument;
response = api:execute("curl", url);
freeswitch.consoleLog("INFO", "[notice] ".. url .. " "..response.."\n");
end
end
- Modify /usr/local/freeswitch/conf/autoload_configs/lua.conf.xml
<param name="startup-script" value="app/gateway_states/resources/gateway_states_add.lua"/>
<param name="startup-script" value="app/gateway_states/resources/gateway_states_delete.lua"/>
- Restart "master" server. At this point, every gateway add or delete will trigger an event, that will go across all our servers and command them pull new config from common database.
This script was modified from memcache.lua, that flushes memcaches over all Fusion servers.
Subscribe to:
Posts (Atom)