We do something similar to ksdpbx, but we utilize the accountcode field for other things, so our dialplan is slightly different.
We don’t give DIDs to every teacher, but this dialplan does in fact work on DID calls that go to an extension with the account code set
One of our typical account codes look like this:
es,abes,cdhsfeeder,ExternalToVM,secretary
ES meaning “elementary school”, ABES meaning the abbreviated name of the location, then the highschool it feeds into, then the external to voicemail code to signify call treatment, then the function of the phone or jobtitle of the user
This way we can use the account code field for different custom functions.
All of this is in our extensions_custom.conf
we override the from-did-direct context to hook in at that point:
; Override for custom dialplan to check account code and send to VM if found
[from-did-direct]
include => ext-direct-to-vm-custom
include => ext-findmefollow
include => ext-local
now the custom context:
[ext-direct-to-vm-custom]
; Direct to voicemail if accountcode field = ExternalToVM
exten => _XXXXX,1,Answer()
same => n,Set(EXTEN_ACCOUNTCODE=${DB(AMPUSER/${EXTEN}/accountcode)})
same => n,NoOp(========== ${EXTEN} ExternalToVM = ${REGEX("ExternalToVM" ${EXTEN_ACCOUNTCODE})} ==========)
same => n,GotoIfTime(08:00-15:00,mon-sun,,?EvalAccountCode:SendToEXT) ; systemwide time of day rule for classroom calls
; determine if account code field contains the string
same => n(EvalAccountCode),GotoIf($["${REGEX("ExternalToVM" ${EXTEN_ACCOUNTCODE})}" = "1"]?Direct2VM:SendToEXT)
; Here's where we send them to voicemail (we use skype for business, which needs a username instead of an extension)
same => n(Direct2VM),Set(username=${ODBC_EXT2UN(${EXTEN})})
same => n,GotoIf($["${username}" == ""]?BackToIVR)
same => n,Dial(PJSIP/${username}@skypeVM)
same => n,Hangup()
; If no ExternalToVM account code, or outside school hours, send the call on ahead
same => n(SendToEXT),Goto(from-internal,${EXTEN},1)
same => n,Hangup()
; In the event that they came from an IVR, send them back, or let the caller know they called someone with no VM assigned.
same => n(BackToIVR),Playback(cdir-sorry-no-entries)
same => n,Goto(${IVR_CONTEXT},-,1)
same => n,Hangup()
Hope this assists you in finding the right way to do it. Our dialplan involves some policy decisions, as we wrestled with the “should we let internal callers through to classrooms during instruction?” and realized that our teachers were so used to using the override code on the restrictions of the previous phone system, they were muscle memory dialing every internal number that way. So we decided that if you’re on a phone in the school system, and calling a number that could be a classroom, you’re probably aware that you’re potentially interrupting instruction, and probably aware when it’s important enough to do so. Thus, we allow internal calls to all extensions at all times.
It’s those pesky parents that inevitably decide to call classrooms during state testing that we wanted to curtail (and kids with cell phones in the back row calling the main number and putting in the extension of the phone in the front of the room).