通过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中,这样可以减少判断次数

相关推荐
计算机学姐7 分钟前
基于SpringBoot的旅游系统的设计与实现
java·vue.js·spring boot·后端·spring·java-ee·旅游
卷心菜的学习路12 分钟前
Spring Boot 多数据源落地:AbstractRoutingDataSource + 注解切面(附源码)
java·spring boot·后端
薄雾晚晴23 分钟前
大模型Skill暴论:所有Skill终将消亡?最新Skill方法论与模型增强开发实战
前端·后端·架构
MacroZheng42 分钟前
面试官皱眉:"你懂 Vibe Coding,那你说superpowers和grill-me怎么选?",我:"小孩才做选择,我全都要!"
java·人工智能·后端
千里码aicood1 小时前
flask-基于注意力机制的异常流量检测与自动防御系统
后端·python·flask
李迟1 小时前
Golang实践录:工程框架实践:搭建工程模板
开发语言·后端·golang
Lynko1 小时前
C语言指针高阶
后端
the局外人1 小时前
学习 FastAPI 的 Day 2:用异步 ORM 完成增删改查
后端·python·fastapi
SamDeepThinking1 小时前
if嵌套最好控制在3层以内
java·后端·程序员
苏渡苇1 小时前
Spring Insight 里上报 Span 为什么用 JDK HttpClient 而不是 RestTemplate
java·后端·spring·spring cloud·springboot·性能监控