[Asterisk-Dev] ANNOUNCE: CLASS-like features for Asterisk

The Traveller traveler at xs4all.nl
Wed Jul 2 11:49:58 MST 2003

Yo all,

As there has been some intrest, here's my updated version:
I post it to "-dev" as well as "-users", as it may be of intrest to

Inspired by the example in the tips & tricks-section of
"http://www.junghanns.net/asterisk/", I built a more elaborate
set of features.  Currently, my implementation supports call-
forward unconditional, on no answer and on busy.  It furthermore
provides each extension with a set of user-definable speed-dials.
It validates if the number entered is actually valid for the current context
and additionally saves this context into the DB and always uses it to
originate the divert from, as you can't expect the forward destination-
number to be available from all caller's contexts.  Only the
speed-dials use the extension's current context, but do save the
context a speed-dial was entered from into the DB anyways.

Some things you need to know:

- No check for forwarding-loops yet.  I haven't tried what happens
when you create one, either.  :-)

- When a call gets forwarded to another local extension and goes to
voicemail from there, voicemail will be left for the extension that
originally forwarded the call, instead of the extension the call was
forwarded to.  This might be seen as a feature.

- The contexts to set the features are to be included into the
context of each extension you want to allow to use them and you
should replace your macro-stdexten with my version (which accepts
some more args than the original version, to allow for passing most
arguments to the "Dial"-application.  This means you have to change
either your extension-entries or the macro, if you're already using

- If you where using my first version, you should remove all related
entries from your ast-DB, as I modified the format somewhat.

- As you can see, it currently uses Festival for it's prompts,
which should obviously be installed and working with Asterisk.
Without it, everything will probably still work, but no prompts,
except the standard "invalid"-recording, which is used when entering
invalid numbers, will be played.

- I'll probably add more features when I have time, and post an
update.  Also, this "stdexten"-macro, like the original one,
assumes everyone has voicemail.  Making a second copy without
voicemail or adding an extra argument to enable / disable VM-
processing should be trivial.


921 + <number>       - Set unconditional forwarding.
921                  - Cancel unconditional forwarding.
9921                 - Check unconditional forwarding.

961 + <number>       - Set forwarding on no answer.
961                  - Cancel forwarding on no answer.
9961                 - Check forwarding on no answer.

967 + <number>       - Set forwarding on busy.
967                  - Cancel forwarding on busy.
9967                 - Check forwarding on busy.

970 - 999 + <number> - Set a personal speed-dial.
970 - 999 + "0"      - Clear a personal speed-dial.
970 - 999            - Call a personal speed-dial, if set.
9970 - 9999          - Check a personal speed-dial.

Note that I choose "9" instead of "*" because a lot of IP-phones
don't allow the user to dial a number containing the "*" or "#".
Nothing stops you from changing it as needed.

Also note that this is almost my first go at it, and I haven't tested it
very heavily.  Comments, suggestions and additions are welcome.  Hope
it's useful to some of you.



; Macros
; Standard extension macro:
;   ${ARG1} - Extension  (we could have used ${MACRO_EXTEN} here as well
;   ${ARG2} - Device(s) to ring
;   ${ARG3} - Timeout
;   ${ARG4} - Other options to app_dial
exten => s,1,DBget(fwdexten=FEAT/${ARG1}/CFWD/CFU)
exten => s,102,Goto(s|4)
exten => s,2,DBget(fwdcontext=FEAT/${ARG1}/CFWD/CFUC)
exten => s,3,Goto(${fwdcontext}|${fwdexten}|1)
exten => s,4,Dial(${ARG2},${ARG3},${ARG4})
exten => s,105,Goto(s|205)
exten => s,5,DBget(fwdexten=FEAT/${ARG1}/CFWD/CFNA)
exten => s,106,Goto(s|8)
exten => s,6,DBget(fwdcontext=FEAT/${ARG1}/CFWD/CFNAC)
exten => s,7,Goto(${fwdcontext}|${fwdexten}|1)
exten => s,8,Answer
exten => s,9,Voicemail2(su${ARG1})
exten => s,10,Hangup
exten => s,205,DBget(fwdexten=FEAT/${ARG1}/CFWD/CFB)
exten => s,306,Goto(s|208)
exten => s,206,DBget(fwdcontext=FEAT/${ARG1}/CFWD/CFBC)
exten => s,207,Goto(${fwdcontext}|${fwdexten}|1)
exten => s,208,Answer
exten => s,209,Voicemail2(sb${ARG1})
exten => s,210,Hangup

; Special features, Call Forwarding, unconditional.
exten => _921X.,1,Answer
exten => _921X.,2,ChanIsAvail(Local/${EXTEN:3}@${CONTEXT})
exten => _921X.,103,Playback(invalid)
exten => _921X.,104,Hangup
exten => _921X.,3,DBput(FEAT/${CALLERIDNUM}/CFWD/CFU=${EXTEN:3})
exten => _921X.,5,Festival(Call-Forward Unconditional: Has been set too: ${EXTEN:3}.)
exten => _921X.,6,Hangup
exten => 921,1,Answer
exten => 921,2,DBdel(FEAT/${CALLERIDNUM}/CFWD/CFU)
exten => 921,3,DBdel(FEAT/${CALLERIDNUM}/CFWD/CFUC)
exten => 921,4,Festival(Call-Forward Unconditional: Has been cleared.)
exten => 921,5,Hangup
exten => 9921,1,Answer
exten => 9921,2,DBget(fwdexten=FEAT/${CALLERIDNUM}/CFWD/CFU)
exten => 9921,103,Festival(Call-Forward Unconditional: Is not set.)
exten => 9921,104,Hangup
exten => 9921,3,Festival(Call-Forward Unconditional: Is set too: ${fwdexten}.)
exten => 9921,4,Hangup

; Special features, Call Forwarding, on no answer.
exten => _961X.,1,Answer
exten => _961X.,2,ChanIsAvail(Local/${EXTEN:3}@${CONTEXT})
exten => _961X.,103,Playback(invalid)
exten => _961X.,104,Hangup
exten => _961X.,3,DBput(FEAT/${CALLERIDNUM}/CFWD/CFNA=${EXTEN:3})
exten => _961X.,5,Festival(Call-Forward on No Answer: Has been set too: ${EXTEN:3}.)
exten => _961X.,6,Hangup
exten => 961,1,Answer
exten => 961,2,DBdel(FEAT/${CALLERIDNUM}/CFWD/CFNA)
exten => 961,3,DBdel(FEAT/${CALLERIDNUM}/CFWD/CFNAC)
exten => 961,4,Festival(Call-Forward on No Answer: Has been cleared.)
exten => 961,5,Hangup
exten => 9961,1,Answer
exten => 9961,2,DBget(fwdexten=FEAT/${CALLERIDNUM}/CFWD/CFNA)
exten => 9961,103,Festival(Call-Forward on No Answer: Is not set.)
exten => 9961,104,Hangup
exten => 9961,3,Festival(Call-Forward on No Answer: Is set too: ${fwdexten}.)
exten => 9961,4,Hangup

; Special features, Call Forwarding, on busy.
exten => _967X.,1,Answer
exten => _967X.,2,ChanIsAvail(Local/${EXTEN:3}@${CONTEXT})
exten => _967X.,103,Playback(invalid)
exten => _967X.,104,Hangup
exten => _967X.,3,DBput(FEAT/${CALLERIDNUM}/CFWD/CFB=${EXTEN:3})
exten => _967X.,5,Festival(Call-Forward on Busy: Has been set too: ${EXTEN:3}.)
exten => _967X.,6,Hangup
exten => 967,1,Answer
exten => 967,2,DBdel(FEAT/${CALLERIDNUM}/CFWD/CFB)
exten => 967,3,DBdel(FEAT/${CALLERIDNUM}/CFWD/CFBC)
exten => 967,4,Festival(Call-Forward on Busy: Has been cleared.)
exten => 967,5,Hangup
exten => 9967,1,Answer
exten => 9967,2,DBget(fwdexten=FEAT/${CALLERIDNUM}/CFWD/CFB)
exten => 9967,103,Festival(Call-Forward on Busy: Is not set.)
exten => 9967,104,Hangup
exten => 9967,3,Festival(Call-Forward on Busy: Is set too: ${fwdexten}.)
exten => 9967,4,Hangup

; Special features, speed-dials.
exten => _9[789]X,1,DBget(sdexten=FEAT/${CALLERIDNUM}/SD/${EXTEN::3}/NR)
exten => _9[789]X,102,Answer
exten => _9[789]X,103,Festival(Speed-dial: ${EXTEN::3}: Is not set.)
exten => _9[789]X,104,Hangup
exten => _9[789]X,2,Goto(${sdexten}|1)
exten => _9[789]X0,1,Answer
exten => _9[789]X0,2,DBdel(FEAT/${CALLERIDNUM}/SD/${EXTEN::3}/NR)
exten => _9[789]X0,3,DBdel(FEAT/${CALLERIDNUM}/SD/${EXTEN::3}/NRC)
exten => _9[789]X0,4,Festival(Speed-dial: ${EXTEN::3}: Has been cleared.)
exten => _9[789]X0,5,Hangup
exten => _9[789]XX.,1,Answer
exten => _9[789]XX.,2,ChanIsAvail(Local/${EXTEN:3}@${CONTEXT})
exten => _9[789]XX.,103,Playback(invalid)
exten => _9[789]XX.,104,Hangup
exten => _9[789]XX.,3,DBput(FEAT/${CALLERIDNUM}/SD/${EXTEN::3}/NR=${EXTEN:3})
exten => _9[789]XX.,4,DBput(FEAT/${CALLERIDNUM}/SD/${EXTEN::3}/NRC=${CONTEXT})
exten => _9[789]XX.,5,Festival(Speed-dial: ${EXTEN::3}: Has been set too: ${EXTEN:3}.)
exten => _9[789]XX.,6,Hangup
exten => _99[789]X,1,Answer
exten => _99[789]X,2,DBget(sdexten=FEAT/${CALLERIDNUM}/SD/${EXTEN:1:3}/NR)
exten => _99[789]X,103,Festival(Speed-dial: ${EXTEN:1:3}: Is not set.)
exten => _99[789]X,104,Hangup
exten => _99[789]X,3,Festival(Speed-dial: ${EXTEN:1:3}: Is set too: ${sdexten}.)
exten => _99[789]X,4,Hangup

On Sun, Jun 29, 2003 at 12:32:33 -0500, Eric Wieling wrote:

> CLASSI v0.01 is a package of sounds, an AGI script, and sample
> extensions.conf file to help users add Custom Calling features to their
> Asterisk installation.  It's a work in progress in the first stages of
> development.  It's buggy and poorly tested, but I'm letting the world
> see it to get feedback and to have it tested in a wider mix of
> environments.
> The following features are currently supported:
>   * Setting the ring pattern for internal calls to be different than
> external calls
>   * Call Back, callback the last number that called you.  Code: *69
>   * Speed Dial 8: Set up to 8 speed dial numbers. Code: *74
> Planned Features:
>   * Call Forward Unconditional
>   * Call Forward Busy
>   * Call Forward No-Answer
>   * Call Forward with Call Rescue
>   * Do-Not-Disturb setting
>   * Remote access to CLASS features.
>   * Speed Dial 30
> I've made a package available at http://www.fnords.org/~eric/asterisk

More information about the asterisk-dev mailing list