Asterisk中检测B方队列坐席接起电话并实现转接的方法
解决Asterisk坐席接起时自动转接呼叫的问题
我之前在做Asterisk外呼队列项目时遇到过几乎一模一样的场景,WaitForSilence和AMD确实不适合这个需求——前者依赖静音触发,坐席接起直接说话根本抓不到;后者是用来识别机器应答的,和人工坐席接起完全不搭。给你几个经过验证的可行方案,按复杂度从低到高排序:
方案1:用Local通道包裹坐席分机,直接触发转接
这是最简单的方法,不需要依赖AMI或AGI,纯Dialplan就能实现。核心思路是不让队列直接呼叫坐席分机,而是呼叫一个Local通道,在这个通道的上下文里直接执行转接逻辑。
步骤1:修改extensions.conf,添加坐席转接上下文
[agent-transfer-context] ; 这个上下文专门处理坐席接起后的转接 exten => s,1,NoOp(Agent picked up, initiating transfer to target extension) ; 把呼叫转接到目标分机(比如2001),这里可以根据需求调整超时时间 exten => s,n,Dial(SIP/2001,20) exten => s,n,Hangup()
步骤2:修改queues.conf,将坐席成员替换为Local通道
原来的坐席成员可能是member => SIP/agent1,现在改成:
member => Local/s@agent-transfer-context
这样当队列分配呼叫给坐席时,会先进入agent-transfer-context的s分机,直接触发转接,坐席接起的瞬间就完成了跳转。
方案2:监听队列成员状态,实时触发转接
如果需要更灵活的控制(比如只有特定坐席接起才转接),可以在公告播放的上下文里循环检测坐席的状态,一旦坐席进入通话状态就立即转接。
Dialplan示例:
[outbound-flow] exten => _X.,1,NoOp(Outbound call to ${EXTEN}) ; g选项确保被叫接听后继续执行后续逻辑 exten => _X.,n,Dial(SIP/${EXTEN},30,g) exten => _X.,n,Goto(queue-with-monitor,s,1) [queue-with-monitor] exten => s,1,NoOp(Entering queue with announcement and agent status check) exten => s,n,Set(TARGET_EXT=2001) ; 目标转接分机 exten => s,n,Set(AGENT_SIP=SIP/agent1) ; 要监控的坐席通道 exten => s,n,Set(ANNOUNCE_FILE=your_announcement.wav) ; 你的公告文件 ; 后台播放公告,同时循环检测坐席状态 exten => s,n,Background(${ANNOUNCE_FILE}) exten => s,n,While(1) ; 获取坐席的状态:idle(空闲)、inuse(通话中)、ringing(振铃) exten => s,n,Set(AGENT_STATUS=${QUEUE_MEMBER_STATUS(your_queue_name,${AGENT_SIP})}) ; 如果坐席进入通话状态,立即停止播放并转接 exten => s,n,If($["${AGENT_STATUS}" = "inuse"]) exten => s,n,StopPlayback() exten => s,n,Dial(SIP/${TARGET_EXT},20) exten => s,n,Hangup() exten => s,n,EndIf exten => s,n,Wait(1) ; 每隔1秒检测一次,避免占用过多资源 exten => s,n,EndWhile
方案3:用AMI监听桥接事件触发转接
如果需要跨场景的全局控制,或者和外部系统联动,用Asterisk Manager Interface(AMI)监听ChannelBridge事件是最可靠的方式。当坐席和B方的通道完成桥接时,立即发送转接命令。
核心逻辑(伪代码):
# 连接到AMI ami = AMIConnection(host='localhost', username='admin', secret='your_ami_secret') ami.login() # 监听ChannelBridge事件 def on_bridge(event): # 识别B方通道和坐席通道(需要根据你的通道命名规则调整) b_channel = [ch for ch in event['channels'] if 'B-party' in ch][0] agent_channel = [ch for ch in event['channels'] if 'agent' in ch][0] if agent_channel: # 发送转接命令,把B方转接到目标分机2001 ami.send_command(f'Redirect({b_channel},2001,default,1)') ami.register_event('ChannelBridge', on_bridge) ami.run_forever()
这个方法的优势是完全不依赖Dialplan的逻辑,只要坐席和B方一接通就触发转接,不会受公告播放或其他Dialplan步骤的影响。
内容的提问来源于stack exchange,提问作者Saqlain Nawaz
相关产品推荐
相关产品推荐

