Dialplan overview
Every extension is its own file under the tenant's extensions/ directory. An
extension is an ordered list of steps that runs top to bottom.
extension: "200"
name: "Support follow-me"
steps:
- id: greeting
type: play
file: ../../../sounds/welcome.wav
when:
days: [mon, tue, wed, thu, fri]
hours: "09:00-17:30"
- id: follow-me
type: dial
moh: default
target:
kind: followme
stages:
- targets: ["101"]
timeout: 15s
- targets: ["100", "external:0612345678"]
timeout: 25s
- id: nobody-home
type: play
file: ../../../sounds/closed.wav
- id: done
type: hangup
| Key | Required | Meaning |
|---|---|---|
extension | yes | The number this plan answers for. |
name | no | Label shown in the editor and in logs. |
steps | yes | Ordered steps. |
The execution rules
These five rules explain every dialplan you will ever write:
- Steps run top to bottom.
- A step whose time condition does not match is skipped, and execution continues with the next one.
- A
dialthat nobody answers continues to the next step. This is the whole reason "greet, then follow-me, then announce we are closed" works. - A
dialthat is answered bridges the legs and ends the plan. - A failing step does not kill the plan. The error is logged and execution continues, so a missing sound file still lets the follow-me behind it run.
Execution also stops when a hangup step runs, or when the caller hangs up.
The clock is read once, when the plan starts. Every time condition in that run is evaluated against the same instant, so a call that begins at 17:29:59 does not change behaviour halfway through.
Step types
| Type | Fields | Behaviour |
|---|---|---|
play | file | Answers the call if needed and plays a WAV file. |
dial | target, timeout, moh | Rings a destination and bridges the first answer. |
moh | moh | Plays music on hold until the caller hangs up. |
hangup | — | Ends the call. |
Every step also accepts an optional id (used in logs) and an optional when
time condition. Full details in
Step types.
Common shapes
A simple extension
extension: "100"
name: Alice
steps:
- id: ring
type: dial
timeout: 30s
target: {kind: endpoint, endpoint: "100"}
Office hours, with an out-of-hours announcement
extension: "200"
name: Reception
steps:
- id: open
type: dial
timeout: 25s
when:
days: [mon, tue, wed, thu, fri]
hours: "09:00-17:00"
target: {kind: ring_group, group: reception}
- id: closed
type: play
file: ../../../sounds/closed.wav
- id: done
type: hangup
Out of hours the dial is skipped and the announcement plays. During office
hours the announcement is only reached when nobody picked up — the fall-through
rule doing the work.
Park the caller on hold
extension: "700"
name: Parking
steps:
- id: hold
type: moh
moh: jazz
moh never returns while the call is up, so it is effectively terminal.
Where the numbers come from
An extension file is reached in three ways:
- an inbound route whose destination is this extension;
- a phone in the same tenant dialling the number;
- another extension's
dialstep targeting it.
An extension does not need a matching account. Extension 200 above is an entry
point with no phone behind it. Conversely, a dial target of kind endpoint
must be an account extension — that is what validation checks.