如何让Asterisk呼叫文件在未接听等状态下执行Dialplan?
解决Asterisk呼叫文件未接听状态执行指定拨号计划的问题
我来帮你把这个问题理清楚,其实要实现Asterisk呼叫文件在未接听类状态(NO ANSWER、CONGESTION、BUSY、FAILED)触发指定拨号计划,核心是利用呼叫文件的自定义变量加上拨号计划的状态判断逻辑,之前你参考的思路本质也是围绕这两点,我给你拆解成具体可落地的步骤:
第一步:配置呼叫文件,带上自定义识别ID
首先在你的呼叫文件里,除了常规的呼叫参数,一定要添加自定义的CALL_ID变量(用来识别特定呼叫),示例如下:
Channel: SIP/your-trunk/123456789 # 替换成你的实际通道 Context: my_outbound_context # 主拨号计划上下文 Extension: s Priority: 1 Set: CALL_ID=unique_call_001 # 你的自定义识别ID,可根据业务生成唯一值
注意:呼叫文件要设置正确的权限(归属用户为asterisk,权限设为644),否则Asterisk无法读取执行。
第二步:编写拨号计划,处理未接听状态
这里有两种常用的实现方式,你可以根据需求选择:
方式1:利用h(Hangup)扩展(推荐)
h是Asterisk专门用来处理所有呼叫挂断后逻辑的特殊扩展,不管是接听后挂断,还是未接听的状态,都会进入这个扩展。我们可以在这里判断挂断原因,定向执行未接听的处理逻辑:
[my_outbound_context] ; 主呼叫逻辑 exten => s,1,Dial(SIP/your-trunk/123456789,30) ; 30秒呼叫超时 exten => s,n,NoOp(呼叫已接听!CALL_ID: ${CALL_ID}) exten => s,n,Hangup() ; 挂断后触发的统一处理逻辑 exten => h,1,NoOp(挂断原因码:${HANGUPCAUSE}) ; 判断是否为未接听类状态,对应原因码: ; BUSY=17, NO ANSWER=19, CONGESTION=26, FAILED(通道不可用)=21 exten => h,n,GotoIf($[ ${HANGUPCAUSE} = 17 | ${HANGUPCAUSE} = 19 | ${HANGUPCAUSE} = 21 | ${HANGUPCAUSE} = 26 ]?unanswered,1) exten => h,n,Hangup() ; 未接听状态的专属处理逻辑 exten => unanswered,1,NoOp(处理未接听呼叫!CALL_ID: ${CALL_ID}) exten => unanswered,n,AGI(your_custom_script.php,${CALL_ID}) ; 执行你的AGI脚本 ; 也可以添加其他拨号计划动作,比如发送通知、写入数据库等 exten => unanswered,n,Hangup()
方式2:直接在Dial之后判断返回状态
如果不想用h扩展,也可以直接在Dial应用执行后,通过${DIALSTATUS}变量判断呼叫结果,定向跳转:
[my_outbound_context] exten => s,1,Set(CALL_ID=unique_call_001) exten => s,n,Dial(SIP/your-trunk/123456789,30) ; 判断Dial返回的状态:BUSY、NOANSWER、CONGESTION、CHANUNAVAIL(对应FAILED) exten => s,n,GotoIf($["${DIALSTATUS}" = "BUSY" | "${DIALSTATUS}" = "NOANSWER" | "${DIALSTATUS}" = "CONGESTION" | "${DIALSTATUS}" = "CHANUNAVAIL"]?unanswered,1) exten => s,n,NoOp(呼叫已接听!CALL_ID: ${CALL_ID}) exten => s,n,Hangup() ; 未接听处理逻辑,可放到同一上下文或默认上下文 exten => unanswered,1,NoOp(处理未接听呼叫,CALL_ID: ${CALL_ID}) exten => unanswered,n,; 这里添加你需要的拨号计划动作,比如调用外部脚本 exten => unanswered,n,Hangup()
如果要在默认上下文处理未接听逻辑,只需要把unanswered扩展移到[default]里,然后把Goto语句改成Goto(default,unanswered,1)即可。
关键注意事项
CALL_ID变量会在整个呼叫生命周期内有效,所以在后续处理逻辑中可以直接调用,用来识别特定呼叫。- 挂断原因码可能因Asterisk版本或线路配置略有差异,你可以通过
core show hangupecauses命令查看完整的原因码列表,按需调整判断条件。
内容的提问来源于stack exchange,提问作者Jose Figueroa
相关产品推荐
相关产品推荐

