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

相关推荐
言之。3 分钟前
Django REST Framework响应类Response详解
后端·python·django
Abadbeginning11 分钟前
FastSoyAdmin centos7云服务器+宝塔部署
vue.js·后端·python
xuejianxinokok1 小时前
PostgreSQL 18 新功能:虚拟生成列
数据库·后端
未来影子1 小时前
SpringAI(GA):Neo4j向量数据库存储快速上手
后端
武子康1 小时前
大数据-95 Spark 集群 SparkSQL Action与Transformation操作 详细解释与测试案例
大数据·后端·spark
知其然亦知其所以然1 小时前
MySQL8.x 面试高频题:为什么一定要有主键?99%的人答不全
后端·mysql·面试
FE_C_P小麦1 小时前
Git 常用指令
前端·后端·github
某某祺1 小时前
向量存储、检索及 Qdrant 浅析
后端
天天摸鱼的java工程师1 小时前
线上服务无辜假死状态:一次 GC Overhead 的深度排查
java·后端