目录浏览:
freeswitch.API
api = freeswitch.API(); -- get current time in milliseconds time = api:getTime() |
当从拨号计划(dialplan)中调用LUA脚本后,将会得到一个session对象。然而LUA脚本也能在命令行界面(CLI)被调用。无论是那种情况下,在LUA中,当创建完一个API对象后,就可以执行API命令了。
api = freeswitch.API(); reply = api:executeString("version"); |
在以上的代码段中,LUA变量将会从FreeSWTICH中接收到版本号。
也可以做一些复杂的操作,例如:
api = freeswitch.API(); sofia = api:executeString("sofia status"); |
LUA变量sofia将包含sofia status命令的所有输出。
freeswitch.bridge
session1 = freeswitch.Session("sofia/internal/1001%192.168.1.1"); session2 = freeswitch.Session("sofia/internal/1002%192.168.1.1"); freeswitch.bridge(session1, session2); |
freeswitch.consoleCleanLog
|
freeswitch.consoleLog
向FreeSWITCH记录器记录一些数据,参数为log级别,消息
freeswitch.consoleLog("info", "lua rocks\n"); freeswitch.consoleLog("notice", "lua rocks\n"); freeswitch.consoleLog("err", "lua rocks\n"); freeswitch.consoleLog("debug", "lua rocks\n"); freeswitch.consoleLog("warning","lua rocks\n"); |
freeswitch.Dbh
作用:从FreeSWITCH中获得一个ODBC或者sqlite句柄,并且可以在用该句柄执行SQL语句。
这种方法的优点是充分利用了由FreeSWITCH提供的连接池,即当创建的LUASQL env:connect()的TCP连接增加时,对于每个连接的速度不会有太大的影响。
工作流程如下:
local dbh = freeswitch.Dbh("dsn","user","pass") -- when using ODBC (deprecated) -- OR -- local dbh = freeswitch.Dbh("core:my_db") -- when using sqlite (deprecated, if you have to use this to make it work you should upgrade your FS installation) -- OR -- local dbh = freeswitch.Dbh("sqlite://my_db") -- sqlite database in subdirectory "db" -- OR -- local dbh = freeswitch.Dbh("odbc://my_db:uname:passwd") -- connect to ODBC database
assert(dbh:connected()) -- exits the script if we didn't connect properly
dbh:test_reactive("SELECT * FROM my_table", "DROP TABLE my_table", "CREATE TABLE my_table (id INTEGER(8), name VARCHAR(255))")
dbh:query("INSERT INTO my_table VALUES(1, 'foo')") -- populate the table dbh:query("INSERT INTO my_table VALUES(2, 'bar')") -- with some test data
dbh:query("SELECT id, name FROM my_table", function(row) stream:write(string.format("%5s : %s\n", row.id, row.name)) end)
dbh:query("UPDATE my_table SET name = 'changed'") stream:write("Affected rows: " .. dbh:affected_rows() .. "\n")
dbh:release() -- optional |
freeswitch.email
作用:发送一封邮件(可带附件)
需要注意的是,如果要用该功能,需要在服务器上安装MTA,当然还需要在switch.conf.xml中配置mailer-app
语法:
freeswitch.email(to, from, headers, body, file, convert_cmd, convert_ext) |
参数说明:
参数 |
是否必要 |
作用 |
to |
是 |
一个有效的收件人地址 |
from |
是 |
一个有效的发件人地址 |
headers |
是 |
标题名 |
body |
否 |
正文 |
file |
否 |
附件 |
convert_cmd |
否 |
发送前转换成其他格式 |
convert_ext |
否 |
替换文件(file)的拓展名 |
freeswitch.email("[email protected]", "subject: Voicemail from 1234\n", "Hello,\n\nYou've got a voicemail, click the attachment to listen to it.", "message.wav", "mp3enc", "mp3") |
freeswitch.Event
作用:生效(firing)一个普通事件my::event
local event = freeswitch.Event("custom", "my::event"); event:addHeader("My-Header", "test"); event:fire(); -- Send an event MESSAGE to a receiver function FSMan:fire(nameHeader, header, body) local myEvent = freeswitch.Event("MESSAGE"); nameHeader = Utils:trim(nameHeader); header = Utils:trim(header); body = Utils:trim(body); if (nameHeader == false ) then nameHeader="Generic_Name_Header" end if (header == false) then header="Header_Generic" end if (body == false) then body="Body_Generic" end myEvent:addHeader(nameHeader, header); myEvent:addBody(body); myEvent:fire(); end |
freeswitch.EventConsumer
作用:处理(consume)FreeSWITCH的事件
用法:
con = freeswitch.EventConsumer("
-- pop() returns an event or nil if no events con:pop()
-- pop(1) blocks until there is an event con:pop(1)
-- pop(1,500) blocks for max half a second until there is an event con:pop(1,500) |
示例:
con = freeswitch.EventConsumer("all"); session = freeswitch.Session("sofia/default/[email protected]"); while session:ready() do session:execute("sleep", "1000"); for e in (function() return con:pop() end) do print("event\n" .. e:serialize("xml")); end end -- or while session:ready() do for e in (function() return con:pop(1,1000) end) do print("event\n" .. e:serialize("xml")) end end -- You may subscribe to specific events if you want to, and even subclasses con = freeswitch.EventConsumer("CUSTOM"); con = freeswitch.EventConsumer("CUSTOM","conference::maintenance"); -- wait for a specific event but continue after 500 ms function poll() -- create event and listener local event = freeswitch.Event("CUSTOM", "ping::running?") local con = freeswitch.EventConsumer("CUSTOM", "ping::running!") -- add text ad libitum event:addHeader("hi", "there") -- fire event event:fire() -- and wait for reply but not very long if con:pop(1, 500) then print("reply received") return true end print("no reply") return false end |
freeswitch.getGobalVariable
作用:检索一个全局变量
|
freeswitch.IVRMenu
hash = { ["main"] = undef, ["name"] = "top", ["greet_long"] = "phrase:demo_ivr_main_menu", ["greet_short"] = "phrase:demo_ivr_main_menu_short", ["invalid_sound"] = "ivr/ivr-that_was_an_invalid_entry.wav", ["exit_sound"] = "voicemail/vm-goodbye.wav", ["confirm_macro"] = "undef", ["confirm_key"] = "undef", ["confirm_attempts"] = "3", ["inter_digit_timeout"] = "2000", ["digit_len"] = "1", ["timeout"] = "10000", ["max_failures"] = "3" } top = freeswitch.IVRMenu(hash["main"], hash["name"], hash["greet_long"], hash["greet_short"], hash["invalid_sound"], hash["exit_sound"], hash["confirm_macro"], hash["confirm_key"], hash["confirm_attempts"], hash["inter_digit_timeout"], hash["digit_len"], hash["timeout"], hash["max_failures"]); top:bindAction("menu-exec-app", "playback /tmp/swimp.raw", "2"); top:execute(session, "top"); |
当使用”SAY”时,需要设置三个额外的变量,否则你将会得到以下的错误:
> [ERR] mod_lua.cpp:182 Error in IVRMenu expected 16..16 args, got 13 stack traceback: |
这三个变量为:
["tts_engine"] = "flite", ["tts_voice"] = "rms", ["max_timeouts"] = "2" |
freeswitch.msleep
作用:通知脚本休眠一段时间(单位:毫秒)
注意:不要用在基于会话的脚本中,否则坏事将发生
-- Sleep for 500 milliseconds freeswitch.msleep(500); |
freeswitch.Session
作用:创建一个新会话(session)
local session = freeswitch.Session("sofia/10.0.1.100/1001"); session:transfer("3000", "XML", "default"); |
根据变量execute_on_answer创建一个新会话:
|
stream:write
作用:你可以根据LUA FreeSWITCH API命令,在LUA中写FreeSWITCH API命令并运行LUA脚本,还可以带一些参数。然后就可以在命令行中得到你写的流对象对应的结果。例如,在scripts中放入hello.lua脚本,然后在命令行中调用该脚本。
|
在FreeSWITCH的命令行界面执行lua hello.lua即可返回hello world。
或者在拨号计划(dialplan)中调用它:
|
以上命令将信道变量foo设置为hello world
网页交互示例(调用mod_xml_rpc)
-- -- lua/api.lua -- -- enable mod_xml_rpc and try http://127.0.0.1:8080/api/lua?lua/api.lua in your webbrowser -- stream:write("Content-Type: text/html\n\n"); stream:write(" stream:write(" FreeSWITCH Command Portal");stream:write(" ");
command = env:getHeader("command");
if (command) then api = freeswitch.API(); reply = api:executeString(command);
if (reply) then stream:write(" " .. reply .. "\n"); end end
env:addHeader("cool", "true"); stream:write(env:serialize() .. "\n\n");
|
示例:呼叫控制
-- -- call control lua script -- dialA = "sofia/gateway/fs1/9903" dialB = "user/1001" legA = freeswitch.Session(dialA) dispoA = "None" while(legA:ready() and dispoA ~= "ANSWER") do dispoA = legA:getVariable("endpoint_disposition") freeswitch.consoleLog("INFO","Leg A disposition is '" .. dispoA .. "'\n") os.execute("sleep 1") end -- legA while if( not legA:ready() ) then -- oops, lost leg A handle this case freeswitch.consoleLog("NOTICE","It appears that " .. dialA .. " disconnected...\n") else legB = freeswitch.Session(dialB) dispoB = "None" while(legA:ready() and legB:ready() and dispoB ~= "ANSWER") do if ( not legA:ready() ) then -- oops, leg A hung up or got disconnected, handle this case freeswitch.consoleLog("NOTICE","It appears that " .. dialA .. " disconnected...\n") else os.execute("sleep 1") dispoB = legB:getVariable("endpoint_disposition") freeswitch.consoleLog("NOTICE","Leg B disposition is '" .. dispoB .. "'\n") end -- inner if legA ready end -- legB while if ( legA:ready() and legB:ready() ) then freeswitch.bridge(legA,legB) else -- oops, one of the above legs hung up, handle this case freeswitch.consoleLog("NOTICE","It appears that " .. dialA .. " or " .. dialB .. " disconnected...\n") end end -- outter if legA ready
|
SpecialCase:env object(特殊案例:环境对象)
当将LUA脚本当做挂断钩子(hangup hook)调用时,将产生一个包含刚刚失去连接的信道中所有的信道变量的特殊对象——env
添加一个extension来测试这个特性
|
然后添加scripts目录下添加hook-test.lua:
-- hook-test.lua -- demonstrates using env to look at channel variables in hangup hook script
-- See everything dat = env:serialize() freeswitch.consoleLog("INFO","Here's everything:\n" .. dat .. "\n")
-- Grab a specific channel variable dat = env:getHeader("uuid") freeswitch.consoleLog("INFO","Inside hangup hook, uuid is: " .. dat .. "\n")
-- Drop some info into a log file... res = os.execute("echo " .. dat .. " >> /tmp/fax.log") res = os.execute("echo YOUR COMMAND HERE >> /tmp/fax.log")
-- If you created a custom variable you can get it also... dat = env:getHeader("my_custom_var") freeswitch.consoleLog("INFO","my_custom_var is '" .. dat .. "'\n") |
查看FS控制台,拨打1234并挂断,你将看到相关信道的所有变量
翻译出处:https://freeswitch.org/confluence/display/FREESWITCH/mod_lua
注:译者翻译能力有限,欢迎指明