如何向FreeSwitch ESL发送外部事件及实现呼叫等待批准逻辑
呼叫等待音乐与坐席批准触发方案解答
需求场景
呼叫方持续播放等待音乐,直至坐席批准呼叫后由ESL桥接通话,未批准则挂断。
疑问1解答:ESL是否只能通过readEvent轮询,无法接收推送?
这个判断不正确。ESL(Event Socket Library)支持两种核心工作模式,其中Outbound模式就是专门用于事件推送的:
- Inbound模式:应用主动连接FreeSWITCH的Event Socket,通过
readEvent()轮询获取事件(这是你提到的场景)。 - Outbound模式:FreeSWITCH主动将通话的事件流推送至应用,应用可以实时响应事件,无需主动轮询。
针对你想实现的「持续播放等待音乐直到收到中断信号」的需求,有两种更高效的实现方式:
- 利用
uuid_break命令中断播放:
先给呼叫方启动循环播放等待音乐:
当坐席批准时,直接通过ESL发送-- 拨号计划中启动循环播放示例 session:execute("playback", "hold_music.wav loop")uuid_break命令中断播放,再执行桥接:# Python ESL示例代码 import ESL con = ESL.ESLConnection("127.0.0.1", "8021", "ClueCon") con.api("uuid_break", "呼叫方UUID") con.api("bridge", "呼叫方UUID 坐席UUID") - 使用Outbound模式实时监听触发信号:
将通话路由到你的ESL应用(Outbound模式),应用启动播放后,通过readEvent()监听自定义事件或坐席批准的触发事件,收到后立即中断播放并桥接。这种方式不需要轮询数据库,而是实时响应事件。
疑问2解答:外部应用能否通过ESL给特定通话发送事件?
可以,外部应用可以通过Inbound ESL连接直接给指定通话发送命令或自定义事件,实现事件驱动的触发,完全替代数据库轮询方案:
核心实现方式:
- 发送自定义事件:
外部应用(比如坐席审批系统)连接到FreeSWITCH的Event Socket,发送自定义事件到指定通话的UUID:
你的ESL通话处理应用需要提前订阅这个自定义事件:# 外部应用发送自定义事件示例 con = ESL.ESLConnection("127.0.0.1", "8021", "ClueCon") # 发送自定义事件,携带通话UUID和批准标识 con.sendEvent("CUSTOM", ["Event-Subclass: call_approved", "Call-UUID: 呼叫方UUID"])# 通话处理应用订阅自定义事件 con = ESL.ESLConnection("127.0.0.1", "8021", "ClueCon") con.subscribe("CUSTOM", "call_approved") # 监听事件 while True: event = con.readEvent() if event and event.getHeader("Event-Subclass") == "call_approved": call_uuid = event.getHeader("Call-UUID") # 中断播放并桥接 con.api("uuid_break", call_uuid) con.api("bridge", f"{call_uuid} 坐席UUID") break - 直接发送API命令:
坐席批准时,外部应用直接调用FreeSWITCH的API命令,中断等待音乐并桥接通话,这是最直接的事件驱动方式,无需中间事件传递:# 终端命令示例(也可通过ESL库调用) fs_cli -x "uuid_break 呼叫方UUID" fs_cli -x "bridge 呼叫方UUID 坐席UUID"
替代数据库轮询的事件驱动方案总结:
- 优先使用Outbound ESL模式处理通话,实时响应坐席批准信号。
- 外部应用通过Inbound ESL连接发送命令或自定义事件,触发通话流程变更。
- 避免数据库轮询,直接利用FreeSWITCH的事件机制实现低延迟触发。
内容的提问来源于stack exchange,提问作者booleanbuddha
相关产品推荐
相关产品推荐

