内线挂断电话后,将外线转到某个IVR的三种实现方法

来源:互联网 发布:国家级精品教材 数据库 编辑:程序博客网 时间:2024/04/29 12:01

说明:内线挂断电话后,将外线转到某个IVR的三种实现方法
作者:张拓
2010-11-9

我们有时候需要实现类似这样的功能,即内线挂断电话后,将外线转到某个IVR节点上,让系统去接管这个通道,播放某个提示音、或者其他。
比如服务评分。
客服MM说 "稍后请您为我的服务评分",然后挂断了电话。这个时候,客户那边就会听到系统录制的评分提示音,如"刚才为您服务的是801,请您为我们的服务打发,灰常满意请按1、满意请按2...."


在asterisk里如何实现呢。

首先,我们看一下内线先挂断电话时,走的哪个拨号规则

-- Executing [s@macro-dial:7] Dial("DAHDI/2-1", "SIP/899||tr") in new stack
    -- Called 899
    -- SIP/899-0886e5c8 is ringing
  == Manager 'admin' logged off from 127.0.0.1
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
    -- SIP/899-0886e5c8 answered DAHDI/2-1
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
  == Manager 'admin' logged off from 127.0.0.1
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
  == Manager 'admin' logged off from 127.0.0.1
    -- Executing [h@macro-dial:1] Macro("DAHDI/2-1", "hangupcall") in new stack
    -- Executing [s@macro-hangupcall:1] ResetCDR("DAHDI/2-1", "w") in new stack
    -- Executing [s@macro-hangupcall:2] NoCDR("DAHDI/2-1", "") in new stack
    -- Executing [s@macro-hangupcall:3] GotoIf("DAHDI/2-1", "1?skiprg") in new stack
    -- Goto (macro-hangupcall,s,6)
    -- Executing [s@macro-hangupcall:6] GotoIf("DAHDI/2-1", "1?skipblkvm") in new stack
    -- Goto (macro-hangupcall,s,9)
    -- Executing [s@macro-hangupcall:9] GotoIf("DAHDI/2-1", "1?theend") in new stack
    -- Goto (macro-hangupcall,s,11)
    -- Executing [s@macro-hangupcall:11] Hangup("DAHDI/2-1", "") in new stack

  == Spawn extension (macro-hangupcall, s, 11) exited non-zero on 'DAHDI/2-1' in macro 'hangupcall'
  == Spawn h extension (macro-dial, h, 1) exited non-zero on 'DAHDI/2-1'
  == Spawn extension (macro-dial, s, 7) exited non-zero on 'DAHDI/2-1' in macro 'dial'
  == Spawn extension (macro-exten-vm, s, 9) exited non-zero on 'DAHDI/2-1' in macro 'exten-vm'
  == Spawn extension (from-did-direct, 899, 1) exited non-zero on 'DAHDI/2-1'
    -- Hungup 'DAHDI/2-1'

 
如上图所示、它跑到了 macro-hangupcall的s里

ok,接下来,开始干

第一种方法
1:我们先建立一个拨号规则,编辑extensions_custom.conf文件,加入下面的这些代码

  1. [bangian-hangup]
  2. exten => s,1,Playback(cn/bangian-hangup)
  3. exten => s,n,Hangup
复制代码


这里,我们让他播放cn目录下面的bangian-hangup提示音:"欢迎致电邦建通讯"....

2:内线挂断电话后,将外线转到上面的拨号规则里,编辑extensions.conf文件

如下
[macro-hangupcall]
exten => s,1,ResetCDR(w)
exten => s,n,NoCDR()

; Cleanup any remaining RG flag
;
exten => s,n,GotoIf($[ "x${USE_CONFIRMATION}" = "x" | "x${RINGGROUP_INDEX}" = "x" | "${CHANNEL}" != "${UNIQCHAN}"]?skiprg)
exten => s,n,Noop(Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL})
exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL})

; Cleanup any remaining BLKVM flag
;
exten => s,n(skiprg),GotoIf($[ "x${BLKVM_BASE}" = "x" | "BLKVM/${BLKVM_BASE}/${CHANNEL}" != "${BLKVM_OVERRIDE}" ]?skipblkvm)
exten => s,n,Noop(Cleaning Up Block VM Flag: ${BLKVM_OVERRIDE})
exten => s,n,DBDel(${BLKVM_OVERRIDE})

; Cleanup any remaining FollowMe DND flags
;
exten => s,n(skipblkvm),GotoIf($[ "x${FMGRP}" = "x" | "x${FMUNIQUE}" = "x" | "${CHANNEL}" != "${FMUNIQUE}" ]?theend)
exten => s,n,DBDel(FM/DND/${FMGRP}/${CHANNEL})

exten => s,n(theend),Goto(bangian-hangup,s,1) ;zhangtuo edit,2010-11-9

;exten => s,n(theend),Hangup  ;zhangtuo edit,2010-11-9


红色的是改动的地方

3:重新加载拨号规则,使用如下命令
  1. localhost*CLI> dialplan reload
复制代码


ok,我们测试一下

-- Executing [s@macro-dial:7] Dial("DAHDI/2-1", "SIP/899||tr") in new stack
    -- Called 899
    -- SIP/899-0890ee48 is ringing
    -- SIP/899-0890ee48 answered DAHDI/2-1
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
  == Manager 'admin' logged off from 127.0.0.1
    -- Executing [h@macro-dial:1] Macro("DAHDI/2-1", "hangupcall") in new stack
    -- Executing [s@macro-hangupcall:1] ResetCDR("DAHDI/2-1", "w") in new stack
    -- Executing [s@macro-hangupcall:2] NoCDR("DAHDI/2-1", "") in new stack
    -- Executing [s@macro-hangupcall:3] GotoIf("DAHDI/2-1", "1?skiprg") in new stack
    -- Goto (macro-hangupcall,s,6)
    -- Executing [s@macro-hangupcall:6] GotoIf("DAHDI/2-1", "1?skipblkvm") in new stack
    -- Goto (macro-hangupcall,s,9)
    -- Executing [s@macro-hangupcall:9] GotoIf("DAHDI/2-1", "1?theend") in new stack
    -- Goto (macro-hangupcall,s,11)
    -- Executing [s@macro-hangupcall:11] Goto("DAHDI/2-1", "bangian-hangup|s|1") in new stack
    -- Goto (bangian-hangup,s,1)
  == Channel 'DAHDI/2-1' jumping out of macro 'hangupcall'
    -- Executing [s@bangian-hangup:1] Playback("DAHDI/2-1", "custom/bangian-hangup") in new stack

    -- <DAHDI/2-1> Playing 'custom/bangian-hangup' (language 'en')
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
  == Manager 'admin' logged off from 127.0.0.1
    -- Executing [s@bangian-hangup:2] Hangup("DAHDI/2-1", "") in new stack
  == Spawn h extension (bangian-hangup, s, 2) exited non-zero on 'DAHDI/2-1'
  == Spawn extension (bangian-hangup, s, 7) exited non-zero on 'DAHDI/2-1' in macro 'dial'
  == Spawn extension (bangian-hangup, s, 7) exited non-zero on 'DAHDI/2-1' in macro 'exten-vm'
  == Spawn extension (bangian-hangup, s, 7) exited non-zero on 'DAHDI/2-1'
    -- Hungup 'DAHDI/2-1'



上面显示了,挂断电话时,外线已经转到了"bangian-hangup,s,1"里去,外线电话里响起了熟悉的声音"欢迎致电邦建通讯...."


测试成功,上面是手动建立的拨号规则。
那,如果使用现有的IVR、公告、等其它在FreePBX里设置的规则呢
请看下文

第二种方法

1:我们通过FreePBX建立一个IVR节点
 
如上图所示,该节点名为voip88_ivr,在这个IVR中,它将播放同名的"voip88_ivr.wav"这个系统录音

2:然后我们在extensions_additional.conf里找一下它对应的拨号规则的“context”叫啥
  1. [ivr-22]
  2. include => ivr-22-custom
  3. include => from-did-direct-ivr
  4. include => app-directory
  5. exten => #,1,dbDel(${BLKVM_OVERRIDE})
  6. exten => #,n,Set(__NODEST=)
  7. exten => #,n,Goto(app-directory,#,1)
  8. exten => h,1,Hangup
  9. exten => s,1,Set(MSG=custom/voip88_ivr)
  10. exten => s,n,Set(LOOPCOUNT=0)
  11. exten => s,n,Set(__DIR-CONTEXT=default)
  12. exten => s,n,Set(_IVR_CONTEXT_${CONTEXT}=${IVR_CONTEXT})
  13. exten => s,n,Set(_IVR_CONTEXT=${CONTEXT})
  14. exten => s,n,GotoIf($["${CDR(disposition)}" = "ANSWERED"]?begin)
  15. exten => s,n,Answer
  16. exten => s,n,Wait(1)
  17. exten => s,n(begin),Set(TIMEOUT(digit)=3)
  18. exten => s,n,Set(TIMEOUT(response)=10)
  19. exten => s,n,Set(__IVR_RETVM=)
  20. exten => s,n,ExecIf($["${MSG}" != ""],Background,${MSG})
  21. exten => s,n,WaitExten(,)
  22. exten => hang,1,Playback(vm-goodbye)
  23. exten => hang,n,Hangup
  24. exten => 1,1,dbDel(${BLKVM_OVERRIDE})
  25. exten => 1,n,Set(__NODEST=)
  26. exten => 1,n,Goto(from-did-direct,801,1)
  27. exten => 2,1,dbDel(${BLKVM_OVERRIDE})
  28. exten => 2,n,Set(__NODEST=)
  29. exten => 2,n,Goto(from-did-direct,802,1)
  30. exten => i,1,Playback(invalid)
  31. exten => i,n,Goto(loop,1)
  32. exten => t,1,Goto(loop,1)
  33. exten => loop,1,Set(LOOPCOUNT=$[${LOOPCOUNT} + 1])
  34. exten => loop,n,GotoIf($[${LOOPCOUNT} > 2]?hang,1)
  35. exten => loop,n,Goto(ivr-22,s,begin)
  36. exten => return,1,Set(MSG=custom/voip88_ivr)
  37. exten => return,n,Set(_IVR_CONTEXT=${CONTEXT})
  38. exten => return,n,Set(_IVR_CONTEXT_${CONTEXT}=${IVR_CONTEXT_${CONTEXT}})
  39. exten => return,n,Goto(ivr-22,s,begin)
  40. exten => fax,1,Goto(ext-fax,in_fax,1)
复制代码
在这里,context是ivr-22,extension是s,priority是1

3:编辑extensions.conf文件

如下
[macro-hangupcall]
exten => s,1,ResetCDR(w)
exten => s,n,NoCDR()

; Cleanup any remaining RG flag
;
exten => s,n,GotoIf($[ "x${USE_CONFIRMATION}" = "x" | "x${RINGGROUP_INDEX}" = "x" | "${CHANNEL}" != "${UNIQCHAN}"]?skiprg)
exten => s,n,Noop(Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL})
exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL})

; Cleanup any remaining BLKVM flag
;
exten => s,n(skiprg),GotoIf($[ "x${BLKVM_BASE}" = "x" | "BLKVM/${BLKVM_BASE}/${CHANNEL}" != "${BLKVM_OVERRIDE}" ]?skipblkvm)
exten => s,n,Noop(Cleaning Up Block VM Flag: ${BLKVM_OVERRIDE})
exten => s,n,DBDel(${BLKVM_OVERRIDE})

; Cleanup any remaining FollowMe DND flags
;
exten => s,n(skipblkvm),GotoIf($[ "x${FMGRP}" = "x" | "x${FMUNIQUE}" = "x" | "${CHANNEL}" != "${FMUNIQUE}" ]?theend)
exten => s,n,DBDel(FM/DND/${FMGRP}/${CHANNEL})

;exten => s,n(theend),Goto(bangian-hangup,s,1) ;zhangtuo edit,2010-11-9
exten => s,n(theend),Goto(ivr-22,s,1) ;zhangtuo edit,2010-11-9

;exten => s,n(theend),Hangup  ;zhangtuo edit,2010-11-9


4:重新加载拨号规则,使用如下命令
  1. localhost*CLI> dialplan reload
复制代码


ok,我们再测试一下

-- Executing [s@macro-dial:7] Dial("DAHDI/2-1", "SIP/899||tr") in new stack
    -- Called 899
    -- SIP/899-088fa4d0 is ringing
    -- SIP/899-088fa4d0 answered DAHDI/2-1
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
  == Manager 'admin' logged off from 127.0.0.1
    -- Executing [h@macro-dial:1] Macro("DAHDI/2-1", "hangupcall") in new stack
    -- Executing [s@macro-hangupcall:1] ResetCDR("DAHDI/2-1", "w") in new stack
    -- Executing [s@macro-hangupcall:2] NoCDR("DAHDI/2-1", "") in new stack
    -- Executing [s@macro-hangupcall:3] GotoIf("DAHDI/2-1", "1?skiprg") in new stack
    -- Goto (macro-hangupcall,s,6)
    -- Executing [s@macro-hangupcall:6] GotoIf("DAHDI/2-1", "1?skipblkvm") in new stack
    -- Goto (macro-hangupcall,s,9)
    -- Executing [s@macro-hangupcall:9] GotoIf("DAHDI/2-1", "1?theend") in new stack
    -- Goto (macro-hangupcall,s,11)
    -- Executing [s@macro-hangupcall:11] Goto("DAHDI/2-1", "ivr-22|s|1") in new stack
    -- Goto (ivr-22,s,1)
  == Channel 'DAHDI/2-1' jumping out of macro 'hangupcall'

    -- Executing [s@ivr-22:1] Set("DAHDI/2-1", "MSG=custom/voip88_ivr") in new stack
    -- Executing [s@ivr-22:2] Set("DAHDI/2-1", "LOOPCOUNT=0") in new stack
    -- Executing [s@ivr-22:3] Set("DAHDI/2-1", "__DIR-CONTEXT=default") in new stack
    -- Executing [s@ivr-22:4] Set("DAHDI/2-1", "_IVR_CONTEXT_ivr-22=ivr-7") in new stack
    -- Executing [s@ivr-22:5] Set("DAHDI/2-1", "_IVR_CONTEXT=ivr-22") in new stack
    -- Executing [s@ivr-22:6] GotoIf("DAHDI/2-1", "0?begin") in new stack
    -- Executing [s@ivr-22:7] Answer("DAHDI/2-1", "") in new stack
    -- Executing [s@ivr-22:8] Wait("DAHDI/2-1", "1") in new stack
    -- Executing [s@ivr-22:9] Set("DAHDI/2-1", "TIMEOUT(digit)=3") in new stack
    -- Digit timeout set to 3
    -- Executing [s@ivr-22:10] Set("DAHDI/2-1", "TIMEOUT(response)=10") in new stack
    -- Response timeout set to 10
    -- Executing [s@ivr-22:11] Set("DAHDI/2-1", "__IVR_RETVM=") in new stack
    -- Executing [s@ivr-22:12] ExecIf("DAHDI/2-1", "1|Background|custom/voip88_ivr") in new stack
    -- <DAHDI/2-1> Playing 'custom/voip88_ivr' (language 'en')

  == Parsing '/etc/asterisk/manager.conf': Found

那一刻...
耳边再次响起了熟悉的声音
"欢迎致电邦建通讯....".....


测试成功,前面我们介绍了手动建立拨号规则、通过freepbx建立拨号规则。
如果我们的拨号规则要经常变,比如今天用voip88_ivr ,明天用bangian_ivr
怎么办?

第三种方法

1:我们在freepbx里建立一个"其它应用",作为统一的入口
 

如上图所示
我们建立一个名为voip88-huangup的应用,功能键是*6688,这个它的入口,至于电话进入后,将去向何方,可以在"目标"一栏中选择
(这正是我们想要的)

2:编辑extensions.conf文件

如下


[macro-hangupcall]
exten => s,1,ResetCDR(w)
exten => s,n,NoCDR()

; Cleanup any remaining RG flag
;
exten => s,n,GotoIf($[ "x${USE_CONFIRMATION}" = "x" | "x${RINGGROUP_INDEX}" = "x" | "${CHANNEL}" != "${UNIQCHAN}"]?skiprg)
exten => s,n,Noop(Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL})
exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL})

; Cleanup any remaining BLKVM flag
;
exten => s,n(skiprg),GotoIf($[ "x${BLKVM_BASE}" = "x" | "BLKVM/${BLKVM_BASE}/${CHANNEL}" != "${BLKVM_OVERRIDE}" ]?skipblkvm)
exten => s,n,Noop(Cleaning Up Block VM Flag: ${BLKVM_OVERRIDE})
exten => s,n,DBDel(${BLKVM_OVERRIDE})

; Cleanup any remaining FollowMe DND flags
;
exten => s,n(skipblkvm),GotoIf($[ "x${FMGRP}" = "x" | "x${FMUNIQUE}" = "x" | "${CHANNEL}" != "${FMUNIQUE}" ]?theend)
exten => s,n,DBDel(FM/DND/${FMGRP}/${CHANNEL})

;exten => s,n(theend),Goto(bangian-hangup,s,1) ;zhangtuo edit,2010-11-9
;exten => s,n(theend),Goto(ivr-22,s,1) ;zhangtuo edit,2010-11-9
exten => s,n(theend),Goto(from-internal,*6688,1) ;zhangtuo edit,2010-11-9

;exten => s,n(theend),Hangup  ;zhangtuo edit,2010-11-9


3:重新加载拨号规则,使用如下命令
  1. localhost*CLI> dialplan reload
复制代码


ok,我们最后测试一下

-- Executing [s@macro-dial:7] Dial("DAHDI/2-1", "SIP/899||tr") in new stack
    -- Called 899
  == Manager 'admin' logged off from 127.0.0.1
    -- SIP/899-0890ee48 is ringing
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
    -- SIP/899-0890ee48 answered DAHDI/2-1
  == Manager 'admin' logged off from 127.0.0.1
  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found
  == Parsing '/etc/asterisk/manager_custom.conf': Found
  == Manager 'admin' logged on from 127.0.0.1
    -- Executing [h@macro-dial:1] Macro("DAHDI/2-1", "hangupcall") in new stack
    -- Executing [s@macro-hangupcall:1] ResetCDR("DAHDI/2-1", "w") in new stack
    -- Executing [s@macro-hangupcall:2] NoCDR("DAHDI/2-1", "") in new stack
    -- Executing [s@macro-hangupcall:3] GotoIf("DAHDI/2-1", "1?skiprg") in new stack
    -- Goto (macro-hangupcall,s,6)
    -- Executing [s@macro-hangupcall:6] GotoIf("DAHDI/2-1", "1?skipblkvm") in new stack
    -- Goto (macro-hangupcall,s,9)
    -- Executing [s@macro-hangupcall:9] GotoIf("DAHDI/2-1", "1?theend") in new stack
    -- Goto (macro-hangupcall,s,11)
   -- Executing [s@macro-hangupcall:11] Goto("DAHDI/2-1", "from-internal|*6688|1") in new stack
    -- Goto (from-internal,*6688,1)
  == Channel 'DAHDI/2-1' jumping out of macro 'hangupcall'
    -- Executing [*6688@from-internal:1] NoOp("DAHDI/2-1", "Running miscapp 2: voip88-hangup") in new stack
    -- Executing [*6688@from-internal:2] Goto("DAHDI/2-1", "ivr-22|s|1") in new stack
    -- Goto (ivr-22,s,1)

    -- Executing [s@ivr-22:1] Set("DAHDI/2-1", "MSG=custom/voip88_ivr") in new stack
    -- Executing [s@ivr-22:2] Set("DAHDI/2-1", "LOOPCOUNT=0") in new stack
    -- Executing [s@ivr-22:3] Set("DAHDI/2-1", "__DIR-CONTEXT=default") in new stack
    -- Executing [s@ivr-22:4] Set("DAHDI/2-1", "_IVR_CONTEXT_ivr-22=ivr-7") in new stack
    -- Executing [s@ivr-22:5] Set("DAHDI/2-1", "_IVR_CONTEXT=ivr-22") in new stack
    -- Executing [s@ivr-22:6] GotoIf("DAHDI/2-1", "0?begin") in new stack
    -- Executing [s@ivr-22:7] Answer("DAHDI/2-1", "") in new stack
    -- Executing [s@ivr-22:8] Wait("DAHDI/2-1", "1") in new stack
  == Manager 'admin' logged off from 127.0.0.1
    -- Executing [s@ivr-22:9] Set("DAHDI/2-1", "TIMEOUT(digit)=3") in new stack
    -- Digit timeout set to 3
    -- Executing [s@ivr-22:10] Set("DAHDI/2-1", "TIMEOUT(response)=10") in new stack
    -- Response timeout set to 10
    -- Executing [s@ivr-22:11] Set("DAHDI/2-1", "__IVR_RETVM=") in new stack
    -- Executing [s@ivr-22:12] ExecIf("DAHDI/2-1", "1|Background|custom/voip88_ivr") in new stack
    -- <DAHDI/2-1> Playing 'custom/voip88_ivr' (language 'en')

  == Parsing '/etc/asterisk/manager.conf': Found
  == Parsing '/etc/asterisk/manager_additional.conf': Found

那一刻...
声音响起
我们眼中闪耀着激动的泪光


总结一下

常言道,工欲善其事,必先找到对应的拨号规则
此例中,拨号规则是 macro-hangupcall
因为,我们就可以从这里面下手,至于后面的实现方法,可谓是条条大路通voip88,花样甚多