FreeSWITCH脚本与自动化:从入门到实战的进阶指南

FreeSWITCH脚本与自动化:从入门到实战的进阶指南

一、脚本语言选择与核心语法解析

FreeSWITCH支持Lua、Perl、Python等多种脚本语言,其中Lua因其轻量级、高效性和与FreeSWITCH核心的深度集成成为首选。Lua脚本通过mod_lua模块加载,执行环境与FreeSWITCH事件系统无缝对接。

1.1 Lua脚本基础结构

一个典型的Lua脚本包含以下要素:

  1. -- 初始化会话变量
  2. session:answer()
  3. local caller_id = session:getVariable("caller_id_number")
  4. -- 条件分支处理
  5. if caller_id == "1001" then
  6. session:streamFile("/var/lib/freeswitch/sounds/vip_welcome.wav")
  7. else
  8. session:streamFile("/var/lib/freeswitch/sounds/standard_welcome.wav")
  9. end
  10. -- 挂断前执行
  11. session:hangup("NORMAL_CLEARING")

关键API方法包括:

  • session:answer():应答呼叫
  • session:getVariable():获取通道变量
  • session:streamFile():播放音频文件
  • session:execute():执行拨号计划命令

1.2 XML脚本与Dialplan集成

XML脚本通过<action>标签定义处理逻辑,与拨号计划(Dialplan)深度集成:

  1. <extension name="office_hours">
  2. <condition field="destination_number" expression="^1000$">
  3. <action application="answer"/>
  4. <action application="lua" data="check_time.lua"/>
  5. <action application="bridge" data="user/1001@$${domain}"/>
  6. </condition>
  7. </extension>

XML脚本的优势在于可视化配置和复杂条件组合,适合构建标准化的IVR流程。

二、自动化场景设计与实现

2.1 呼叫中心自动化

通过脚本实现ACD(自动呼叫分配)逻辑:

  1. -- 技能组路由示例
  2. local skills = {
  3. ["sales"] = {priority=1, agents={"1001","1002"}},
  4. ["support"] = {priority=2, agents={"1003","1004"}}
  5. }
  6. function route_call(skill)
  7. local group = skills[skill]
  8. for _, agent in ipairs(group.agents) do
  9. if freeswitch.API():execute("sofia", "contact "..agent.."@"..freeswitch.getGlobalVariable("domain")) ~= "" then
  10. session:execute("bridge", "user/"..agent.."@"..freeswitch.getGlobalVariable("domain"))
  11. return true
  12. end
  13. end
  14. return false
  15. end

关键优化点:

  • 实时状态检查(sofia contact
  • 多级技能组回退机制
  • 负载均衡算法集成

2.2 IVR系统自动化

构建动态IVR菜单系统:

  1. -- 多级菜单实现
  2. local menu_tree = {
  3. ["1"] = {file="/sounds/menu_sales.wav", action="sales_queue"},
  4. ["2"] = {file="/sounds/menu_support.wav", action="support_queue"},
  5. ["#"] = {file="/sounds/menu_repeat.wav", action="repeat"}
  6. }
  7. function play_menu()
  8. while true do
  9. session:streamFile("/sounds/main_menu.wav")
  10. local digits = session:getDigits(5, "#", 3000)
  11. if menu_tree[digits] then
  12. if digits == "#" then
  13. continue
  14. else
  15. session:streamFile(menu_tree[digits].file)
  16. if menu_tree[digits].action == "sales_queue" then
  17. session:execute("enqueue", "sales_queue")
  18. break
  19. end
  20. end
  21. else
  22. session:streamFile("/sounds/invalid_entry.wav")
  23. end
  24. end
  25. end

高级功能实现:

  • TTS动态内容生成
  • DTMF超时处理
  • 菜单选项动态加载

三、性能优化与调试技巧

3.1 脚本执行效率优化

  • 预加载常用资源:
    1. local preloaded_sounds = {
    2. welcome = freeswitch.Sound():new("/sounds/welcome.wav"),
    3. hold = freeswitch.Sound():new("/sounds/hold_music.wav")
    4. }
  • 异步操作处理:
    1. -- 使用freeswitch.AsyncAPI进行非阻塞操作
    2. local async = freeswitch.AsyncAPI()
    3. async:execute("sleep", "5000", function()
    4. session:streamFile("/sounds/after_delay.wav")
    5. end)

3.2 调试与日志系统

  • 日志分级输出:
    1. freeswitch.consoleLog("INFO", "Call from: "..caller_id.."\n")
    2. freeswitch.consoleLog("ERR", "Bridge failed: "..tostring(err).."\n")
  • 实时变量监控:
    1. # 在FS CLI中执行
    2. fs_cli -x "sofia status profile internal reg"
    3. fs_cli -x "show channels"

四、实战案例:智能路由系统

4.1 系统架构设计

  1. [SIP Trunk] [FreeSWITCH] [Lua Router] [Agent Groups]
  2. [DB Lookup]

4.2 核心代码实现

  1. -- 数据库连接配置
  2. local dbh = freeswitch.DBH("mysql", "host=localhost;dbname=callcenter;user=fsuser;password=fspass")
  3. function get_agent_by_skill(skill)
  4. local stmt = dbh:prepare("SELECT extension FROM agents WHERE skill = ? AND status = 'available' ORDER BY priority LIMIT 1")
  5. stmt:execute(skill)
  6. local row = stmt:fetch({}, "a")
  7. stmt:finalize()
  8. return row and row.extension or nil
  9. end
  10. -- 主处理函数
  11. function main(session, args)
  12. local number = session:getVariable("destination_number")
  13. local skill = determine_skill(number) -- 自定义技能判断逻辑
  14. local agent = get_agent_by_skill(skill)
  15. if agent then
  16. session:execute("bridge", "user/"..agent.."@"..freeswitch.getGlobalVariable("domain"))
  17. else
  18. session:execute("playback", "/sounds/no_agents.wav")
  19. session:hangup("NO_ANSWER")
  20. end
  21. end

4.3 部署注意事项

  1. 数据库连接池配置
  2. 脚本缓存策略(mod_lualua_script_cache参数)
  3. 错误处理机制(重试次数、fallback路由)

五、进阶方向与资源推荐

5.1 高级主题探索

  • 事件套接字(Event Socket)编程
  • 与Web框架集成(如Flask+FreeSWITCH ESL)
  • 机器学习驱动的路由决策

5.2 学习资源

  • 官方文档:mod_lua章节
  • 社区项目:SignalWire/FSLua示例库
  • 书籍推荐:《FreeSWITCH Cookbook》第5章

通过系统掌握脚本编程与自动化技术,开发者能够构建出高效、灵活的通信解决方案。建议从简单IVR系统入手,逐步扩展到复杂路由场景,最终实现全流程自动化。