Upgrade 3CX to v18 and get it hosted free!

Asterisk call forwarding

Author image

If you use this setup a phone can dial *21*<number> for immediate redirect or *61*<number> for delayed redirect, and #21# or #61# to cancel the setting.

If you need help understanding how the variables used in these examples work, have a look at Asterisk variables. (Macro arguments can be referenced along with an offset, like so: exten => s,1,Set(CFIM=${DB(CFIM/${ARG1:-4})})).

Abbreviations used

Example 1


  [macro-stdexten]
  ;
  ; Standard extension macro (with call forwarding):
  ; ${ARG1} - Extension(we could have used ${MACRO_EXTEN} here as well
  ; ${ARG2} - Device(s) to ring
  ;
  exten => s,1,((Asterisk cmd DBget|DBget))(temp=CFIM/${ARG1}) ; Get CFIM key, if not existing, goto 102
  exten => s,2,((Asterisk cmd Dial|Dial))(Local/${temp}@pbx/n)   ; Unconditional forward
  exten => s,3,Dial(${ARG2},20) ; 20sec timeout
  exten => s,4,DBget(temp=CFBS/${ARG1})  ; Get CFBS key, if not existing, goto 105
  exten => s,5,Dial(Local/${temp}@pbx/n) ; Forward on busy or unavailable

  ; No CFIM key
  exten => s,102,Goto(s,3)

  ; No CFBS key - voicemail ?
  exten => s,105,Busy

Asterisk 1.2


  [macro-stdexten]
  ; 
  ; Standard extension macro (with call forwarding): 
  ; ${ARG1} - Extension(we could have used ${MACRO_EXTEN} here as well 
  ; ${ARG2} - Device(s) to ring 
  ; 

  exten => s,1,Set(temp=${DB(CFIM/${ARG1})})
  exten => s,n,GotoIf(${temp}?cfim:nocfim)
  exten => s,n(cfim),Dial(Local/${temp}@default/n)   ; Unconditional forward 
  exten => s,n(nocfim),NoOp

  exten => s,n,Dial(${ARG2},15) ; 15sec timeout 

  exten => s,n,Set(temp=${DB(CFBS/${ARG1})})
  exten => s,n,GotoIf(${temp}?cfbs:nocfbs)
  exten => s,n(cfbs),Dial(Local/${temp}@default/n) ; Forward on busy or unavailable 
  exten => s,n(nocfbs),Busy

Notes

  • This macro reads variables stored in the Asterisk database
  • The macro executes ‘Dial(Local/<number>@pbx)’ if a redirection number is found. This implies the number that was selected is dialable from the [pbx] context. You should probably modify this. (If you only want outbound redirect this could be Dial(Zap/1/<number>) for instance)
  • If the DBget does not find a key, it exits with the result code 101, making the next step in the dial plan the current priority+101

Example 2


  [apps]
  ; Unconditional Call Forward
  exten => _*21*X.,1,DBput(CFIM/${CALLERIDNUM}=${EXTEN:4})
  exten => _*21*X.,2,Hangup
  exten => #21#,1,DBdel(CFIM/${CALLERIDNUM})
  exten => #21#,2,Hangup

  ; Call Forward on Busy or Unavailable
  exten => _*61*X.,1,DBput(CFBS/${CALLERIDNUM}=${EXTEN:4})
  exten => _*61*X.,2,Hangup
  exten => #61#,1,DBdel(CFBS/${CALLERIDNUM})
  exten => #61#,2,Hangup

You can’t use use “#” for SIP adapters like Grandstream Handytone, because they will not be sent. These phones and adaptors use # as the character to end the phoneno., so that you don’t have to wait for the timeout. Use something like this for call forward instead:

Example 3


  [apps]
  ;
  ; Unconditional Call Forward
  ;
  ; create call forward
  exten => _*21*X.,1,GotoIf($[${EXTEN:-1} = #]?2:3)
  exten => _*21*X.,2,StripLSD(1)
  exten => _*21*X.,3,DBput(CFIM/${CALLERIDNUM}=${EXTEN:4})
  exten => _*21*X.,4,Hangup
  ;
  ; delete call forward
  exten => **21,1,DBdel(CFIM/${CALLERIDNUM})
  exten => **21,2,Hangup
  ;
  ; delete call forward (with #)
  exten => **21#,1,Goto(**21,1)

If you do it this way, both regular phones and SIP adaptors without dialplan will work the same way (ending the string with #)

Notes

  • This context implements the functionality to set or cancel call forwarding. It needs to be included in the context used for outbound calls
  • The ${EXTEN:4} variable construct takes the current extension and strips the first four characters.
  • This programming does not confirm the setting with an audio prompt. Add this if you want the user to get a confirmation of the new status.

Example 4


  [pbx]
  exten => 7000,1,Macro(stdexten,7000,MGCP/aaln/1@<myphone>)   ; IP10S
  exten => 7001,1,Macro(stdexten,7001,SIP/oej)   ; SIP connection

Note: Don’t forget to include the apps extension in your context.

Example 5

This is for V1.2.x and handles the forwarded call in the expected manner. IE the caller is dropped into the called mailbox rather than the extension that the called exten was forwarded to. IE 20 calls 21 which is forwarded to 22 but 22 doesn’t answer then the mailbox it drops into is 21 not as many examples 22.

The CFIM database entry is set as in the above examples.

== extensions.conf ==


 [macro-stdexten]
 ;
 ; Standard extension macro:
 ;   ${ARG1} - Extension  (we could have used ${MACRO_EXTEN} here as well
 ;   ${ARG2} - Device(s) to ring
 ; Retrieve the Call Forward number if available.
 exten => s,1,Set(CFIM=${DB(CFIM/${ARG1:-4})})
 ;
 ; Dial the appropriate number depending on whether the Call Forward
 exten => s,n,GotoIf($["${vmbox}"!=""]?s-NoCFIM,1)
 exten => s,n,Set(_vmbox=${MACRO_EXTEN:-4})
 exten => s,n,GotoIf($["${CFIM}"!=""]?s-CFIM,1:s-NoCFIM,1)
 ;
 ; Pass call to Voicemail with the appropriate greeting.
 ;exten => s,n,GosubIf($[${DIALSTATUS}=NOANSWER]?s-NOANSWER,1:s-BUSY,1)
 ; Hangup.
 exten => s,n,Hangup
 ;
 ; Dial Call Forward number & return.
 exten => s-CFIM,1,Dial(Local/${CFIM},30,Ttr)
 exten => s-CFIM,n,GosubIf($[${DIALSTATUS}=NOANSWER]?s-NOANSWER,1:s-BUSY,1)
 exten => s-CFIM,n,Hangup
 ; Dial actual extension & return.
 exten => s-NoCFIM,1,Dial(${ARG1},30,Ttr)
 exten =>  s-NoCFIM,n,GosubIf($[${DIALSTATUS}=NOANSWER]?s-NOANSWER,1:s-BUSY,1)
 exten => s-NoCFIM,n,Hangup
 ;
 ; Unavailable voicemail message if there is no answer.
 exten => s-NOANSWER,1,Voicemail(u${vmbox})
 exten => s-NOANSWER,n,Return
 ; Busy voicemail message for any DIALSTATUS other than NOANSWER (or ANSWER).
 exten => s-BUSY,1,Voicemail(b${vmbox})
 exten => s-BUSY,n,Return

Example 6

For version 1.8


exten = _ZX,1,GotoIf(${DB_EXISTS(CFIM/${EXTEN})}?cfim)
exten = _ZX,n,GotoIf(${DB_EXISTS(CFBS/${EXTEN})}?cfbs)
exten = _ZX,n,Dial(SIP/${EXTEN},,${DIALOPTIONS})
exten = _ZX,n,Hangup

exten = _ZX,n(cfbs),Set(temp=${DB(CFBS/${EXTEN})}) ; Get CFBS key
exten = _ZX,n,Dial(SIP/${EXTEN},20,${DIALOPTIONS}) ; 20sec timeout
exten = _ZX,n,Dial(SIP/operator/${temp},,${DIALOPTIONS}) ; Forward on busy or unavailable
exten = _ZX,n,Hangup

exten = _ZX,n(cfim),Set(temp=${DB(CFIM/${EXTEN})}) ; Get CFIM key
exten = _ZX,n,Dial(SIP/operator/${temp},,${DIALOPTIONS}) ; Unconditional forward
exten = _ZX,n,Hangup

exten = _*21*X.,1,Set(DB(CFIM/${CALLERID(num)})=${REPLACE(EXTEN:4,*#-)})
exten = _*21*X.,n,Hangup
exten = **21,1,DBdel(CFIM/${CALLERID(num)})
exten = **21,n,Hangup

exten = _*61*X.,1,Set(DB(CFBS/${CALLERID(num)})=${REPLACE(EXTEN:4,*#-)})
exten = _*61*X.,n,Hangup
exten = **61,1,DBdel(CFBS/${CALLERID(num)})
exten = **61,n,Hangup

I also have a web gui for setting the callfwd as well as from the set. This allows the attendant to cancel or set  forwards.

Because of limitations of this wiki, the above script is not displayed correctly, plz go to this homepage.

See Also


Article Reviews

Write a Review

Your email address will not be published. Required fields are marked *

Required Field. Minimum 5 characters.

Required Field. Minimum 5 characters, maximum 50.

Required field.There is an error with this field.

Required Field.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

There are no reviews for this article. Be the first one to write a review.

Related Posts:

Get 3CX - Absolutely Free!
Link up your team and customers Phone System Live Chat Video Conferencing

Hosted or Self-managed. Up to 10 users free forever. No credit card. Try risk free.

3CX
A 3CX Account with that email already exists. You will be redirected to the Customer Portal to sign in or reset your password if you've forgotten it.