Lua API Reference
关于
本页面提供Lua的FreeSWITCH API文档。
API Sessions
以下的方法可以被应用到已存在的sessions。
session:answer
对一路会话的应答。
session:answer();
session:answered
检查会话是否已经标记为已应答(在应答呼叫后的任何时间都为true)
session:answered();
session:bridged
检查当前会话的channel是否已经桥接到另外一个channel上。
if (session:bridged() == true) do
-- Do something
end
session:check_hangup_hook
session:collectDigits
session:consoleLog
从会话中将某些内容记录到FreeSWITCH记录器中。 参数是日志级别和消息。
session:consoleLog("info", "lua rocks\n");
session:consoleLog("notice", "lua rocks\n");
session:consoleLog("err", "lua rocks\n");
session:consoleLog("debug", "lua rocks\n");
session:consoleLog("warning","lua rocks\n");
session:destroy
销毁会话并释放资源。 这是在脚本结束时完成,但如果你的脚本包含无限循环,则可以使用它来终止会话。
session:execute
session:execute(app, data);
local mySound = "/usr/local/freeswitch/sounds/music/16000/partita-no-3-in-e-major-bwv-1006-1-preludio.wav";
session:execute("playback", mySound);
注意:在一个execute期间,回调无法执行的。
session:flushDigits
session:flushEvents
session:get_uuid
session:get_uuid()
session:getDigits
Get digits:
- getdigits has three arguments: max_digits, terminators, timeout
- max_digits: maximum number of dtmf tones that will be collected
- terminators: buffer of characters that will terminate the digit collection
- timeout: timeout in milliseconds allowed for no input or after last digit is pressed and terminator isn't
- interdigit: if no input is received timeout specified previously will be use, once input is received this becomes the new timeout. (optional default 0)
- return: buffer containing collected digits
- the method blocks until one of the exit criteria is met.**
session:consoleLog("info", "Got dtmf: ".. digits .."\n");
session:getState
获取呼叫状态。例如:"CS_EXECUTE"。呼叫状态在"switch_types.h"头文件中描述。
state=session:getState();
session:getVariable
获取系统参数,例如参数${hold_music}
--[[ events obtained from "switch_channel.c"
regards Monroy from Mexico
]]
session:getVariable("context");
session:getVariable("destination_number");
session:getVariable("caller_id_name");
session:getVariable("caller_id_number");
session:getVariable("network_addr");
session:getVariable("ani");
session:getVariable("aniii");
session:getVariable("rdnis");
session:getVariable("source");
session:getVariable("chan_name");
session:getVariable("uuid");
session:hangup
你可以挂断一个会话,并且提供挂断原因(参照:挂断原因代码表)。
session:hangupCause
您可以找到已应答呼叫(被叫)的挂机原因或主叫发起呼叫未完成的原因。(参照:挂断原因代码表)。
-- Initiate an outbound call
obSession = freeswitch.Session("sofia/192.168.0.4/1002")
-- Check to see if the call was answered
if obSession:ready() then
-- Do something good here
else -- This means the call was not answered ... Check for the reason
local obCause = obSession:hangupCause()
freeswitch.consoleLog("info", "obSession:hangupCause() = " .. obCause )
if ( obCause == "USER_BUSY" ) then -- SIP 486
-- For BUSY you may reschedule the call for later
elseif ( obCause == "NO_ANSWER" ) then
-- Call them back in an hour
elseif ( obCause == "ORIGINATOR_CANCEL" ) then -- SIP 487
-- May need to check for network congestion or problems
else
-- Log these issues
end
end
基于挂断原因的再次呼叫示例。
代码中的是Lua示例,它根据挂断原因重试发起呼叫。 它重试了3次并在两个不同的网关之间交替:
max_retries1 = 3;
retries = 0;
ostr = "";
repeat
retries = retries + 1;
if (retries % 2) then ostr = originate_str1;
else ostr = originate_str12; end
freeswitch.consoleLog("notice", "*********** Dialing Leg1: " .. ostr .. " - Try: "..retries.." ***********\n");
session1 = freeswitch.Session(ostr);
local hcause = session1:hangupCause();
freeswitch.consoleLog("notice", "*********** Leg1: " .. hcause .. " - Try: "..retries.." ***********\n");
until not ((hcause == 'NO_ROUTE_DESTINATION' or hcause == 'RECOVERY_ON_TIMER_EXPIRE' or hcause == 'INCOMPATIBLE_DESTINATION' or hcause == 'CALL_REJECTED' or hcause == 'NORMAL_TEMPORARY_FAILURE') and (retries < max_retriesl1))
注意:originate_str1和originate_str12是2个不同网关的拨号字符串。
session:hangupState
session:insertFile
session:insertFile(<orig_file>, <file_to_insert>, <insertion_sample_point>)
将一个文件插入另一个文件。所有三个参数都是必需的。第三个参数是抽样,并且是要插入file_
to_
insert 的orig_
file 中的样本数。生成的文件将以会话的采样率写入,并将替换orig_
file。因为位置是在样本中给出的,所以您需要知道文件的采样率,以正确计算文件中X秒的样本数。例如,要将文件插入到采样率为8000Hz的.wav文件中两秒钟,您将使用16000作为insertion_
sample_
point参数。
请注意,此方法需要具有有效会话对象的活动channel,因为它需要采样率和会话的编解码器信息。
举例:
-- On a ulaw channel, insert bar.wav one second into foo.wav:
session:insertFile("foo.wav", "bar.wav", 8000)
-- Prepend bar.wav to foo.wav:
session:insertFile("foo.wav", "bar.wav", 0)
-- Append bar.wav to foo.wav:
session:insertFile("bar.wav", "foo.wav", 0)
session:mediaReady
session:originate
session:originate已弃用,请用以下结构代替:
new_session = freeswitch.Session("sofia/gateway/gatewayname/18001234567", session);
下面的代码仅用于历史记录; 请不要继续使用它。
-- this usage of originate is deprecated, use freeswitch.Session(dest, session)
new_session = freeswitch.Session();
new_session.originate(session, dest[, timeout]);
dest:拨号计划目的地址。 例如:“sofia/internal/1000@10.0.0.1”或“sofia/gateway/my_sip_provider/my_dest_number”。
注意:session.originate至少需要2个参数。
session:playAndGetDigits
播放文件并收集DTMF数字。 数字与正则表达式匹配。 不匹配的数字或超时可以触发播放包含错误消息的音频文件。 可选参数允许您在失败时转移到扩展名,并将输入的数字存储到通道变量中。
语法
digits = session:playAndGetDigits (
min_digits, max_digits, max_attempts, timeout, terminators,
prompt_audio_files, input_error_audio_files,
digit_regex, variable_name, digit_timeout,
transfer_on_failure);
参数
参数名 | 描述 |
---|---|
min_digits | 所需的数字最少位数。 |
max_digits | 允许的最大位数。 |
max_attempts | 本函数等待数字的次数(即超时次数),在数字未到达前重复播放prompt_audio_file。 |
timeout | 等待数字的时间(以毫秒为单位)。 |
terminators | 包含导致此函数终止的数字列表的字符串。 |
prompt_audio_file | 要播放的初始音频文件。 如果数字在播放过程中到达,则播放停止。 每次超时后都会重播此文件,超时次数最多为max_attempts。 |
input_error_audio_file | 收到与digit_regex不匹配的数字时播放的音频文件。 播放此文件时,将丢弃接收的数字。 如果未使用此功能,请指定空字符串。 |
digit_regex | 用于验证接收数字的正则表达式。 |
variable_name | (可选)用于存储接收数字的通道变量。 |
digit_timeout | (可选)数字间超时(以毫秒为单位)。 提供后,在输入每个数字后重置超时时钟,从而为移动受限的用户提供缓慢输入数字而不会导致超时的能力。 如果未指定,则digit_timeout设置为timeout。 |
transfer_on_failure | (可选)如果发生故障,此功能会将会话转移到拨号方案中的分机。 语法是“extension-name [dialplan-id [context]]”。 |
争议
- 当所有超时和重试计数都用尽时,此函数返回空字符串。
- 当达到允许的最大位数时,即使未输入终结符,该函数也会立即返回。
- 如果用户忘记按下其中一个终结符,但输入正确,则在下一次超时后返回数字。
- 必须先处理会话才能处理任何数字。 如果您未接听电话,音频仍会播放,但不会收到任何数字。
示例
此示例使FreeSWITCH播放prompt.wav并侦听2到5位数字,以#键结尾。 如果用户没有输入任何内容(或者除了数字之外的其他内容,如*键),则会播放error.wav,并且该过程会再重复2次。
digits = session:playAndGetDigits(2, 5, 3, 3000, "#", "/prompt.wav", "/error.wav", "\\d+");
session:consoleLog("info", "Got DTMF digits: ".. digits .."\n");
这次,我们只需要一个数字,它必须是1,3或4。如果用户在三次尝试后不符合要求,它们将被转移到“default“的XML拨号计划中的操作员扩展名。
如果用户按下正确的键,则该数字返回给调用者,并且将通道变量“digits_received”设置为相同的值。
digits = session:playAndGetDigits(1, 1, 3, 3000, "", "/menu.wav", "/error.wav", "[134]", "digits_received", 3, "operator XML default");
session:consoleLog("info", "Got DTMF digits: ".. digits .."\n");
提醒:如果需要匹配正则表达式中的*键,则必须引用两次:
digits = session:playAndGetDigits(2, 5, 3, 3000, "#", "/sr8k.wav", "", "\\d+|\\*");
session:preAnswer
预先回答会话。
session:preAnswer();
session:read
播放文件并获取数字。
digits = session:read(5, 10, "/sr8k.wav", 3000, "#");
session:consoleLog("info", "Got dtmf: ".. digits .."\n");
session:read有5个参数:<min digits> <max digits> <要播放的文件> <inter-digit timeout> <terminators>
以下显示了如何确定如果有终结器的话,按下的是哪个终结器:
session:setVariable("read_terminator_used", "");
digits = session:read(5, 10, "/sr8k.wav", 3000, "*#");
terminator = session:getVariable("read_terminator_used");
session:consoleLog("info", "Got dtmf: " .. digits .. " terminator: " .. terminator .. "\n");
session:ready
- 检查会话是否仍处于活动状态(在呼叫启动和挂断之间的任何时间都为true)
- 如果正在转移呼叫,ready将返回false。 最重要的是你应该总是检查会话:在任何循环上准备就绪,并在整个脚本中定期,如果返回false则退出。
有关不是ready的详细信息,请参阅 session:hangupCause。
while (session:ready() == true) do
-- do something here
end
session:recordFile
语法是ends_by_silence = session:recordFile(file_name,max_len_secs,silence_threshold,silence_secs);
silence_secs是在结束录制之前容忍的沉默量。
如果录制由其他内容结束,则ends_by_silence为0,例如输入回调获取dtmf
function onInputCBF(s, _type, obj, arg)
local k, v = nil, nil
local _debug = true
if _debug then
for k, v in pairs(obj) do
printSessionFunctions(obj)
print(string.format('obj k-> %s v->%s\n', tostring(k), tostring(v)))
end
if _type == 'table' then
for k, v in pairs(_type) do
print(string.format('_type k-> %s v->%s\n', tostring(k), tostring(v)))
end
end
print(string.format('\n(%s == dtmf) and (obj.digit [%s])\n', _type, obj.digit))
end
if (_type == "dtmf") then
return 'break'
else
return ''
end
end
recording_dir = '/tmp/'
filename = 'myfile.wav'
recording_filename = string.format('%s%s', recording_dir, filename)
if session:ready() then
session:setInputCallback('onInputCBF', '');
-- syntax is session:recordFile(file_name, max_len_secs, silence_threshold, silence_secs)
max_len_secs = 30
silence_threshold = 30
silence_secs = 5
test = session:recordFile(recording_filename, max_len_secs, silence_threshold, silence_secs);
session:consoleLog("info", "session:recordFile() = " .. test )
end
session:sayPhrase
播放语音短语宏。
session:sayPhrase(macro_name [,macro_data] [,language]);
- macro_name:(字符串)要说的说话宏的名称。
- macro_data:(字符串)可选。 要传递给say宏的数据。
- language:(字符串)可选。 要说宏的语言(即“en”或“fr”)。 默认为“en”。
要捕获事件或DTMF,请将其与session:setInputCallback结合使用。
示例:
function key_press(session, input_type, data, args)
if input_type == "dtmf" then
session:consoleLog("info", "Key pressed: " .. data["digit"])
return "break"
end
end
if session:ready() then
session:answer()
session:execute("sleep", "1000")
session:setInputCallback("key_press", "")
session:sayPhrase("voicemail_menu", "1:2:3:#", "en")
end
与setInputCallback一起使用时,返回值和含义如下:
- true或“true”: 使提示继续说话。
- 任何其他字符串值都会中断提示。
session:sendEvent
session:setAutoHangup
默认情况下,lua脚本在执行完毕后会挂断电话。 如果你需要在lua脚本执行完之后在拨号方案中运行下一个操作,则需要将setAutoHangup设置为false。 默认值是true。
session:setAutoHangup(false);
session:setHangupHook
在你的lua代码中,你可以使用setHangupHook来定义会话挂断时要调用的函数。
function myHangupHook(s, status, arg)
freeswitch.consoleLog("NOTICE", "myHangupHook: " .. status .. "\n")
-- close db_conn and terminate
db_conn:close()
error()
end
blah="w00t";
session:setHangupHook("myHangupHook", "blah")
退出脚本的其他可能性(并抛出错误)
return "exit";
或者
return "die";
或者
s:destroy("error message");
session:setInputCallback
function my_cb(s, type, obj, arg)
if (arg) then
io.write("type: " .. type .. "\n" .. "arg: " .. arg .. "\n");
else
io.write("type: " .. type .. "\n");
end
if (type == "dtmf") then
io.write("digit: [" .. obj['digit'] .. "]\nduration: [" .. obj['duration'] .. "]\n");
else
io.write(obj:serialize("xml"));
e = freeswitch.Event("message");
e:add_body("you said " .. obj:get_body());
session:sendEvent(e);
end
end
blah="w00t";
session:answer();
session:setInputCallback("my_cb", "blah");
session:streamFile("/tmp/swimp.raw");
在将文件流式传输到通道之外使用时,返回值“true”或“undefined”被接受为true(继续音频流),其他任何内容都将被评估为false(这将停止流)。
注意:每个返回值都应该是STRING。
返回值 | 影响(流式传输音频时) |
---|---|
"speed" | Unknown |
"volume" | Unknown |
"pause" | 停止音频播放,直到获得下一个输入。 获得另一个输入后,它继续播放。 |
"stop" | Unkown |
"truncate" | Unkown |
"restart" | Unkown |
"seek" | Unkown |
"true" | 等到音频结束。 |
"false" | 立即停止音频。 |
None/NULL | 不要返回None/NULL。 它会造成类型错误问题。 特别是python。 |
session:setVariable
在会话上设置变量:
session:setVariable("varname", "varval");
session:sleep
session:sleep(3000);
- 这将允许回调DTMF,而session:execute(“sleep”,“5000”)则不会。
session:speak
session:set_tts_params("flite", "kal");
session:speak("Please say the name of the person you're trying to contact");
session:say
播放预先录制的声音文件,包括数字,日期,货币等内容。请参阅拨号计划工具say中有关于say的app信息。
参数:<lang><say_type><say_method>
示例:
session:say("12345", "en", "number", "pronounced");
session:streamFile
将文件不停歇地流式传输到会话。
session:streamFile("/tmp/blah.wav");
从sample_count开始,将文件无限流式传输到会话中?(原文此处打了问号)
session:streamFile("/tmp/blah.wav", <sample_count>);
session:transfer
转移当前会话。 参数是extensions,dialplan和context。
session:transfer("3000", "XML", "default");
你执行的lua脚本将立即停止,如果您不希望您的呼叫断开连接,请确保你设置session:setAutoHangup(false)。
如果你执行session:execute(“transfer”,“3000 XML default”),则Lua脚本的执行将继续,即使该调用现在大部分都在您的控制范围之外,并且桥接很可能会失败。