通过Lua脚本多个网关循环外呼

前情提要:

在文章 freeswitch+freeswitch+语音网关拨打电话 中配置了多个网关。

当前的做法:在/usr/local/freeswitch/conf/dialplan/public.xml使用destination_number的尾号去进行匹配<condition field="destination_number" expression="^(\d*[02468])$">

这种做法存在的问题:

符合规则的尾号不能被同时打,因为一个网关只能支持拨打一个电话

解决方案:

在《FreeSWITCH权威指南》一书中,有一个通过Lua脚本多个网关循环外呼的案例

编写lua脚本

freeswitch/script文件夹下编写auto_retry_gw.lua脚本

lua 复制代码
retries = 0
bridge_hangup_cause = 0
gateways = {
    {
        name = "gw2",                   -- 第一个网关名称
        caller_id_number = "559947",     -- 网关1的主叫号码
        caller_id_name = "559947"        -- 网关1的主叫名称
    },
    {
        name = "gw3",                   -- 第二个网关名称
        caller_id_number = "559948",     -- 网关2的主叫号码
        caller_id_name = "559948"        -- 网关2的主叫名称
    },
    {
        name = "gw4",                   -- 第三个网关名称
        caller_id_number = "559944",     -- 网关3的主叫号码
        caller_id_name = "559944"        -- 网关3的主叫名称
    },
    {
        name = "gw5",                   -- 第四个网关名称
        caller_id_number = "559945",     -- 网关4的主叫号码
        caller_id_name = "559945"        -- 网关4的主叫名称
    },
    {
        name = "gw6",                   -- 第四个网关名称
        caller_id_number = "559946",     -- 网关4的主叫号码
        caller_id_name = "559946"        -- 网关4的主叫名称
    }
    -- ... 可以继续添加更多网关配置
}
-- 呼叫的号码
dest = argv[1]

-- 循环外呼
function call_retry()
    freeswitch.consoleLog("notice", "Calling [" ..dest.. "] FROM lua\n")
    retries = retries + 1
    if not session.ready() then
         return;
    end
    -- 设置主叫号码
    session:setVariable("effective_caller_id_number", gateways[retries].caller_id_number)
    session:setVariable("effective_caller_id_name", gateways[retries].caller_id_name)
    -- 拼接呼叫字符串
    dial_string = "sofia/gateway/" ..gateways[retries].name .. "/" ..dest;
    freeswitch.consoleLog("notice", "Dialing [" ..dial_string.. "]\n");
    session:execute("bridge", dial_string);
    bridge_hangup_cause = session:getVariable("bridge_hangup_cause") or session:getVariable("originate_disposition");
    -- NORMAL_CLEARING 表示除了正常接通,都去循环呼叫
    if(retries < 4 and bridge_hangup_cause ~= "NORMAL_CLEARING") then
        freeswitch.consoleLog("notice", "On calling [" ..dial_string.. "] hangup. Cause:[" ..bridge_hangup_cause.. "].Retry: " ..retries.. "\n");
        session.sleep(1000);
        call_retry();
    else
        freeswitch.consoleLog("notice", "Retry Exceed, Now hangup!\n");
    end
end

session:preAnswer();
-- 有了这两个配置表示一个呼叫失败,继续呼叫下一个
session:setVariable("hangup_after_bridge", "true");
session:setVariable("continue_on_fail", "true");
call_retry();

在fs_cli中测试lua脚本

bash 复制代码
-- 需要使用下面的命令测试
originate {dest=017858661999}loopback/1234 &lua(test.lua)
  • &lua(test.lua 017858661999) 的方式行不通,会接收不到
  • lua test.lua 017858661999 能接收到,但是session会为空
  • 获取dest的方式修改为dest = session:getVariable("dest")

在拨号计划中使用

/usr/local/freeswitch/conf/dialplan/public.xml中的拨号计划配置修改为如下图:

优化方向

把正在通话的号码加入到内存hash中,这样可以减少判断次数

相关推荐
koddnty1 分钟前
c++协程控制流深入剖析
后端·架构
小码哥_常4 分钟前
Spring Boot 集成DFA:打造高效内容安全卫士
后端
砍材农夫5 分钟前
接口限流设计
后端
yhyyht6 分钟前
Spring Data JPA入门记录(一)
后端
SimonKing11 分钟前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员
FastBean19 分钟前
Jackson View Extension Spring Boot Starter
java·后端
武子康1 小时前
大数据-238 离线数仓 - 广告业务 Hive分析实战:ADS 点击率、购买率与 Top100 排名避坑
大数据·后端·apache hive
Victor3562 小时前
MongoDB(23) 如何使用条件查询文档?
后端
摸鱼的春哥2 小时前
Agent教程15:认识LangChain,Agent框架的王(上)
前端·javascript·后端
Victor3562 小时前
MongoDB(22)如何批量插入文档?
后端