Feature Codes -- DND, Call Forward, Follow Me
Feature Codes: DND, Call Forward, Follow Me
Let users toggle features from their phone by dialing star codes. State is stored in AstDB so it persists across restarts and can be checked from any context.
Requirements
func_db.somodule loaded (for DB() and DB_DELETE())- A dial-user subroutine or inbound context that checks these DB keys before dialing
Dialplan
[features]
; *78 -- Enable Do Not Disturb
exten => *78,1,NoOp(DND Enable for ${CALLERID(num)})
same => n,Set(DB(DND/${CALLERID(num)})=yes)
same => n,Playback(beep)
same => n,Hangup()
; *79 -- Disable Do Not Disturb
exten => *79,1,NoOp(DND Disable for ${CALLERID(num)})
same => n,Set(DB_DELETE(DND/${CALLERID(num)})=)
same => n,Playback(beep)
same => n,Hangup()
; *72 -- Enable Call Forward (prompts for destination number)
exten => *72,1,NoOp(Call Forward Enable)
same => n,Read(FORWARD_NUM,vm-enter-num-to-call,15)
same => n,GotoIf($["${FORWARD_NUM}" = ""]?cancel)
same => n,Set(DB(CF/${CALLERID(num)})=${FORWARD_NUM})
same => n,Playback(beep)
same => n,SayDigits(${FORWARD_NUM})
same => n,Hangup()
same => n(cancel),Playback(cancelled)
same => n,Hangup()
; *73 -- Disable Call Forward
exten => *73,1,NoOp(Call Forward Disable)
same => n,Set(DB_DELETE(CF/${CALLERID(num)})=)
same => n,Playback(beep)
same => n,Hangup()
; *21 -- Enable Follow Me
exten => *21,1,NoOp(Follow Me Enable)
same => n,Set(DB(FM/${CALLERID(num)})=yes)
same => n,Playback(beep)
same => n,Hangup()
; *22 -- Disable Follow Me
exten => *22,1,NoOp(Follow Me Disable)
same => n,Set(DB_DELETE(FM/${CALLERID(num)})=)
same => n,Playback(beep)
same => n,Hangup()
Checking Features Before Dialing
[dial-user]
exten => s,1,NoOp(Dialing ${ARG1})
; Check DND first
same => n,GotoIf($["${DB(DND/${ARG1})}" = "yes"]?dnd)
same => n,Set(CF=${DB(CF/${ARG1})})
same => n,Set(FM=${DB(FM/${ARG1})})
; Check Call Forward
same => n,GotoIf($["${CF}" != ""]?forward)
same => n,GotoIf($["${FM}" = "yes"]?followme)
same => n,Dial(PJSIP/${ARG1},30,tT)
; ... DIALSTATUS handling ...
same => n,Return()
same => n(dnd),VoiceMail(${ARG1}@default,u)
same => n,Return()
same => n(forward),NoOp(Forwarding to ${CF})
same => n,Dial(PJSIP/${CF},30,tT)
same => n,Return()
same => n(followme),FollowMe(${ARG1},ds)
same => n,Return()
How it works
- AstDB as feature store:
DB(family/key)reads a value from Asterisk's built-in key-value database.DB_DELETE()removes it. The database persists across restarts (stored in SQLite under/var/lib/asterisk/astdb.sqlite3). - Key naming convention:
DND/1001,CF/1001,FM/1001: the family groups related features, the key is the extension number. This makes it easy to query all DND entries withdatabase show DNDon the CLI. - Read() for input:
Read(variable,prompt,maxdigits)plays the prompt file and captures DTMF into the variable. The 15-digit max allows for international numbers. - SayDigits() for confirmation: After setting call forward, the system reads back the number so the user can verify it was entered correctly.
- Priority of checks: DND is checked first (blocks everything), then call forward (redirects), then follow me (rings external). This order matters.
Tips
- Verify AstDB state from the Asterisk CLI:
database show DNDordatabase get DND 1001. - Add BLF (Busy Lamp Field) hints so phone lights indicate when DND or CF is active:
exten => *78,hint,Custom:dnd_${CALLERID(num)}. - For call forward, validate the input is a plausible number before storing:
GotoIf($[${LEN(${FORWARD_NUM})} < 3]?cancel). - Consider adding
*74for "call forward on busy" using a separateCFB/family in AstDB.
User Notes
No notes yet. Be the first to contribute a tip or example.
Contribute a note
Share a tip, gotcha, or practical example. Keep it under 2000 characters. No questions (use the Asterisk community forums for support). Wrap code in backticks.