Asterisk 11队列来电主叫挂断时HANGUPCAUSE始终为0的解决问询
这个问题在Asterisk 11的队列呼叫场景里确实挺常见的——核心原因是当主叫主动挂断时,队列通道与主叫通道的关联逻辑导致真实的挂断原因没有正确传递到你配置的h上下文,所以才会返回0这个无效值。下面是几个经过验证的可行方案:
利用AGI脚本捕获真实挂断原因
你可以在启动队列前调用一个自定义AGI脚本,让脚本监听呼叫通道的Hangup事件,直接从触发挂断的通道中读取真实的HANGUPCAUSE值,并将其设置为可在主通道中读取的变量。示例配置如下:[from-trunk] exten => s,1,Answer() same => n,AGI(capture_hangup_cause.agi) same => n,Queue(queue-1,rkt,,,30) exten => h,1,Verbose(Effective Hangup Cause: ${AGI_HANGUP_CAUSE})对应的AGI脚本(以Python为例)可以通过监听通道的
hangup事件,获取目标通道的HANGUPCAUSE,再通过set_variable方法将其传递给主通道的AGI_HANGUP_CAUSE变量。通过全局变量传递坐席侧挂断原因
对于坐席挂断的场景,你可以在坐席的接听上下文中,将坐席通道的HANGUPCAUSE存入带全局前缀__的变量中,让主叫通道可以读取到该值。配置示例:
首先是坐席的接听上下文:[agents] exten => 100,1,Answer() same => n,Set(__AGENT_HANGUP_CAUSE=${HANGUPCAUSE}) same => n,Dial(SIP/100,20) same => n,Hangup()然后在主叫的
h上下文里,通过条件判断优先使用坐席侧的挂断原因, fallback到当前的HANGUPCAUSE:[from-trunk] exten => s,1,Answer() same => n,Queue(queue-1,rkt,,,30) exten => h,1,Verbose(Effective Hangup Cause: ${IF($[${AGENT_HANGUP_CAUSE} != ""]?${AGENT_HANGUP_CAUSE}:${HANGUPCAUSE})})这个方法对坐席挂断的场景非常有效,若要覆盖主叫主动挂断的情况,可以结合AGI或AMI的方式补充。
通过AMI监听事件获取挂断原因
如果你的架构允许后台服务介入,可以通过Asterisk Manager Interface(AMI)监听全局的Hangup事件。每个Hangup事件都会包含Channel、Cause和CauseTxt字段,不管是主叫还是坐席触发的挂断,都能拿到真实的原因码。你可以把这些数据存储到数据库或缓存中,在h上下文里通过查询获取对应呼叫的有效挂断原因。这个方案适合需要集中处理呼叫数据的场景。升级到更高版本的Asterisk(若业务允许)
Asterisk 11属于比较老旧的版本,后续的稳定版本(比如13及以上)对队列的挂断原因传递逻辑做了优化,这个问题在新版本中已经被修复。如果业务没有强依赖于11的特定功能,升级到支持的稳定版本是一劳永逸的解决办法。
内容的提问来源于stack exchange,提问作者Jeferson Daniel

