28/12/2012
At forstå og mestre Asterisk's dialplan er kernen i at bygge en kraftfuld og fleksibel telefoniløsning. Dialplanen er hjertet i ethvert Asterisk-system; det er her, du definerer, hvordan indgående og udgående opkald skal håndteres. Fra at afspille en simpel velkomstbesked til at implementere komplekse IVR-menuer (Interactive Voice Response) og betinget opkaldsrouting, giver dialplanen dig fuld kontrol. I denne artikel vil vi dykke ned i de fundamentale byggeklodser og udforske, hvordan du kan gå fra simple kommandoer til avanceret logik for at skabe skræddersyede opkaldsoplevelser.

Grundlæggende Opkaldsstyring: Answer(), Playback() og Hangup()
For at begynde at bygge en dialplan er det essentielt at forstå de mest basale applikationer. Disse tre kommandoer udgør fundamentet for næsten enhver interaktion med en, der ringer ind.
Answer(): At besvare opkaldet korrekt
Som navnet antyder, bruges Answer() applikationen til at besvare et indgående opkald. Spørgsmålet er ofte, hvornår det er nødvendigt at bruge den. En god tommelfingerregel er: Hvis Asterisk skal interagere med den, der ringer (f.eks. afspille lyd, indsamle DTMF-input), skal du bruge Answer() først. Hvis opkaldet blot skal viderestilles direkte til en anden enhed via Dial(), er det som regel unødvendigt og kan endda forsinke opkaldsforbindelsen.
Answer() kan tage en valgfri parameter, som er en forsinkelse i millisekunder. Dette kan være yderst nyttigt for at sikre, at den fjerne ende er klar til at modtage lyd, før du begynder at afspille en prompt. Uden en lille forsinkelse kan de første millisekunder af en lydfil blive 'klippet af'.
Et eksempel i extensions.conf:
exten => 100,1,Answer(500) ; Besvar opkaldet og vent 500msPlayback(): Afspilning af lydfiler
Med Playback() kan du afspille en forudindspillet lydfil for den, der ringer. Applikationen tager filnavnet (uden filtypenavn) som sin primære parameter. Asterisk vil automatisk søge efter filen i de mest kompatible formater (f.eks. .gsm, .wav). Hvis opkaldet ikke allerede er besvaret, vil Playback() som standard gøre det for dig. Dette kan dog undgås ved at tilføje 'noanswer' som en anden parameter.

For at undgå, at starten af en lydfil bliver afklippet, kan du enten bruge Answer() med en forsinkelse som nævnt ovenfor, eller du kan afspille en kort stilhedsfil først. Asterisk kommer med standard stilhedsfiler.
Eksempel på afspilning af en velkomstbesked:
exten => 100,1,Answer() exten => 100,n,Playback(silence/1) ; Afspil 1 sekunds stilhed exten => 100,n,Playback(velkommen-til-os) ; Afspil velkomstbeskedenDu kan også kombinere flere filer på én linje ved at adskille dem med et ampersand (&):
exten => 100,n,Playback(silence/1&velkommen-til-os)Hangup(): Afslutning af opkaldet
Hangup() applikationen gør præcis, hvad den siger: den afslutter det nuværende opkald. Selvom Asterisk automatisk afslutter et opkald, når det løber tør for prioriteter i en extension, er det god praksis at eksplicit inkludere Hangup() som den sidste prioritet. Dette gør din dialplan mere læselig og forhindrer uventet 'fall-through' til andre dele af din konfiguration.
Et komplet, simpelt eksempel kunne se således ud:
exten => 100,1,Answer() exten => 100,n,Playback(tak-for-dit-opkald) exten => 100,n,Hangup()Avanceret Logik med Betinget Viderestilling
Når du har styr på det grundlæggende, kan du begynde at tilføje intelligens til din dialplan. Her kommer betinget logik ind i billedet, hvilket giver Asterisk mulighed for at træffe beslutninger baseret på forskellige kriterier, såsom tidspunkt på dagen, opkalds-ID eller brugerinput.
GotoIf(): Hjertet i beslutningstagning
Den vigtigste applikation til betinget logik er GotoIf(). Den evaluerer et udtryk og sender opkaldet til én af to destinationer, afhængigt af om udtrykket er sandt eller falsk. Syntaksen er som følger:
GotoIf(udtryk ? destination_hvis_sand: destination_hvis_falsk)
I Asterisk's logik evalueres en tom streng og tallet 0 som falsk. Alt andet evalueres som sandt. En destination kan være en etiket (label) inden for den samme extension, eller en helt anden kontekst, extension og prioritet.

Lad os se på et klassisk eksempel: "anti-kæreste-logik". Her tjekker vi opkalds-ID'et (Caller ID) og sender opkaldet til en speciel besked, hvis det matcher et bestemt nummer.
exten => 123,1,NoOp(Nyt opkald fra ${CALLERID(num)}) exten => 123,n,GotoIf($[${CALLERID(num)} = 8885551212]?afvis:tillad) exten => 123,n(tillad),Dial(SIP/medarbejder1) exten => 123,n,Hangup() exten => 123,n(afvis),Playback(nummer-ude-af-drift) exten => 123,n,Hangup()I dette eksempel henter vi nummeret fra den indgående opkalder med funktionen CALLERID(num). Hvis nummeret er '8885551212', hopper dialplanen til etiketten 'afvis' og afspiller en besked. Hvis det er et hvilket som helst andet nummer, hopper den til 'tillad' og forsøger at ringe til 'medarbejder1'. Brugen af Hangup() efter hver gren er afgørende for at sikre, at opkaldet ikke utilsigtet fortsætter til den næste del af koden.
Forståelse af Dial() Applikationen og Dens Mange Muligheder
Dial() er uden tvivl en af de mest anvendte og kraftfulde applikationer i Asterisk. Dens primære funktion er at forbinde det nuværende opkald til en eller flere andre endepunkter. Men dens sande styrke ligger i de utallige valgmuligheder (options), der kan modificere dens adfærd. Disse muligheder tilføjes som argumenter efter timeout og før destinationen.
At gennemgå alle muligheder ville være overvældende, så her er en tabel over nogle af de mest almindelige og nyttige:
| Option | Dansk Navn | Beskrivelse |
|---|---|---|
t | Tillad Overførsel (Kaldt part) | Giver den person, der modtager opkaldet, mulighed for at viderestille opkaldet via DTMF-koder. |
T | Tillad Overførsel (Kaldende part) | Giver den person, der ringer op, mulighed for at viderestille opkaldet. |
m(klasse) | Ventemusik | Afspiller ventemusik for den opkaldende part, indtil opkaldet besvares. Man kan specificere en bestemt musikklasse defineret i musiconhold.conf. |
L(x:y:z) | Tidsbegrænsning for Opkald | Begrænser opkaldets varighed til x millisekunder, afspiller en advarsel ved y ms tilbage, og gentager advarslen hvert z ms. |
g | Fortsæt ved Ophæng | Hvis den kaldte part lægger på, fortsætter eksekveringen af dialplanen for den opkaldende part ved næste prioritet. Nyttigt for f.eks. voicemail. |
r | Angiv Ringetone | Tvinger Asterisk til at afspille en ringetone for den opkaldende part, selvom den kaldte enhed ikke teknisk set ringer endnu. |
U(sub^arg) | Kør Gosub før Svar | Udfører en subrutine (Gosub) på den kaldte kanal, før kanalerne forbindes. Dette er den moderne og mere fleksible erstatning for den ældre 'M' (Macro) option. |
Et eksempel på Dial() med flere muligheder:
exten => 200,1,Dial(SIP/medarbejder2,30,Ttm)I dette eksempel forsøger vi at ringe til 'medarbejder2' i 30 sekunder. Den opkaldende part kan viderestille opkaldet (T), den kaldte part kan viderestille (t), og der afspilles standard ventemusik (m), mens der ventes.

Ofte Stillede Spørgsmål (FAQ)
Hvornår skal jeg bruge Answer() applikationen?
Du bør bruge Answer(), når du har brug for at interagere med den, der ringer, før opkaldet potentielt viderestilles. Dette inkluderer afspilning af lydfiler (Playback()), indsamling af tal (Read()), eller afspilning af menuer. Hvis du blot skal viderestille opkaldet direkte til en anden telefon med Dial(), er det bedst at undlade Answer() for at opnå den hurtigste opkaldsforbindelse.
Hvad er forskellen på en prioritet og en etiket (label)?
En prioritet er et sekventielt trin i en extension. De starter typisk med 1 og fortsætter med 2, 3, osv. Man kan også bruge 'n' for 'næste' prioritet for at gøre det nemmere at indsætte nye trin. En etiket (label), f.eks. n(mylabel), er et navngivet ankerpunkt i din dialplan. Du kan ikke gå til en prioritet direkte, men du kan hoppe til en etiket ved hjælp af applikationer som Goto() og GotoIf(). Dette gør det muligt at skabe loops og komplekse logiske flows.
Hvordan undgår jeg, at starten af min lydfil bliver afklippet?
Dette er et almindeligt problem, især på VoIP-forbindelser. Der er to effektive metoder. Den første er at bruge Answer() med en kort forsinkelse (f.eks. Answer(500)) før din Playback() kommando. Den anden, og ofte foretrukne, metode er at afspille en meget kort stilhedsfil (f.eks. Playback(silence/1)) lige før din primære lydfil. Dette giver kanalen tid til at blive fuldt etableret, før den vigtige lyd afspilles.
Hvis du vil læse andre artikler, der ligner Asterisk Dialplan: Fra Basis til Avanceret Logik, kan du besøge kategorien Sundhed.
