
IP ATC Asterisk â en kraftfull lösning för IP-telefoni. WebgrĂ€nssnittet FreePBX, designat för Asterisk, förenklar betydligt konfigurationen och sĂ€nker intrĂ€desbarriĂ€rerna för systemet.
Om du kan tÀnka dig en uppgift relaterad till IP-telefoni, sÄ Àr det nÀstan sÀkert möjligt att genomföra den i Asterisk. Men var beredd pÄ att det kommer att krÀvas uthÄllighet och tÄlamod frÄn din sida.
Vi stod inför uppgiften att konfigurera e-postaviseringar om missade samtal. Mer specifikt att meddela via e-post de fall dÀr ett inkommande samtal gick till kö, men ingen (av agenterna) svarade pÄ det inkommande samtalet.
Ăverraskande nog fann vi inget standardverktyg för att lösa denna uppgift i FreePBX. Hur vi löste detta kommer jag att berĂ€tta om lĂ€ngre ner.
Förord
Innan vi löste uppgiften "rakt pĂ„" letade vi förstĂ„s efter information pĂ„ internet, men vi hittade ingen fĂ€rdig lösning (kanske letade vi dĂ„ligt, men vad ska man göraâŠ).
FÀrdigheterna i att direkt arbeta i Asterisk Àr inte sÄ mÄnga som vi skulle önska, dÀrför var lösningen som föreslogs , inte helt genomtÀnkt och avfÀrdades.
Vi gillade lösningen som föreslogs av , Àven om den inte fungerade. DÀrför betonade vi att man mÄste arbeta i Asterisk i kontexten av köer [ext-queues]. Eftersom vi arbetar med FreePBX, mÄste vi arbeta i konfigurationsfilen "extensions_override_freepbx.conf". Vi noterade att det Àr praktiskt att "fÄnga missade samtal" innan hÀndelsen hangupcall (avslut av samtal).
Efter att ha lÀst diskussionen om , fick vi idén att filtrera variabeln "Disposition" i CDR för alla agenter i kön. Efter att ha lÀst informationen formulerades ganska konkreta steg för att lösa den uppstÀllda uppgiften.
Vad har vi:
Vi har FreePBX 13.0.197 som anvÀnder Asterisk 13.12.1. Operativsystemversion SHMZ release 6.6 (Final). Distributionen baseras pÄ CentOS.
I Asterisk Àr IVR (röstmeny) konfigurerat och dirigerar inkommande samtal till olika köer. Varje kö har tilldelats agenter.
Teori
Vad hÀnder i Asterisk
NÀr Asterisk tar emot ett inkommande samtal, gÄr detta samtal till IVR. Den som ringer vÀljer genom att trycka pÄ en viss siffra pÄ telefonen och kommer till en viss kö. Efter det fÄr alla lediga agenter i köen samtalet samtidigt.
För att bÀttre förstÄ vad som hÀnder i detta ögonblick och vad som hÀnder hÀrnÀst, lÄt oss hÀnvisa till Report CDR (Fig. 1).

Fig. 1
NÀr ett inkommande samtal hamnar i kön, fÄr alla agenter variabeln "Disposition" att vara lika med "NO ANSWER", om agenterna inte Àr upptagna vid det tillfÀllet. Variabeln "Disposition" kan anta andra vÀrden (se. ), förutom vÀrdet "ANSWERED". NÀr en av agenterna svarar pÄ det inkommande samtalet blir vÀrdet pÄ denna agents variabel "Disposition" lika med "ANSWERED".
FrÄn Report CDR kan man mÀrka att nÀr samtalet gÄr in i kön (i kolumnen App blir vÀrdet lika med "Queue"), sÄ visas alla hÀndelser med samma "uniqueid" (kolumnen System).
Kort om CDR
Det Àr viktigt att förstÄ vad CDR Àr, och vid vilken tidpunkt data skrivs in i CDR som vi observerar i Report CDR. CDR, i förhÄllande till operativsystemet, Àr en databas dÀr Asterisk sparar detaljerade samtalsrapporter (se. ). I vÄrt fall handlar det om databasen som kallas asteriskcdrdb, som finns i mysql. Genom erfarenhet har vi faststÀllt att data för ett samtal med ett specifikt "uniqueid" inte skrivs in i asteriskcdrdb omedelbart efter att nÄgon hÀndelse intrÀffar, utan efter hÀndelsen hangupcall (samtalsavslut).
Principen för den skapade lösningen
Eftersom vi har mer kunskap om bash Àn om Asterisk, blev huvudidén följande. Innan hÀndelsen hangupcall ska ett bash-skript anropas. Tre parametrar ska skickas till detta skript. Den första parametern Àr "uniqueid", för att filtrera de data som hÀmtas frÄn CDR. Den andra parametern Àr "CALLERID(num)" (nummer till den som ringer), för att veta vem man ska Äterringa. Den tredje parametern Àr "NODEST" (kö nummer), som samtalet kom till, för att veta vilket Àrende samtalet handlade om, och vem som ska fÄ ett e-postmeddelande om det missade samtalet.
Bash-skriptet ska ansluta till databasen asteriskcdrdb i mysql och hĂ€mta alla vĂ€rden för variabeln "Disposition" med det specifika "uniqueid". Av de erhĂ„llna uppgifterna mĂ„ste vĂ€rdena "NO ANSWER", "BUSY", "FAILED", "UNKNOWN" uteslutas. Som resultat kommer antingen "ANSWERED" â det inkommande samtalet besvarades, eller inget alls â ett missat samtal.
Om samtalet visade sig vara missat, ska skriptet sedan skicka ett e-postmeddelande.
För att gÄ rakt pÄ sak, Àr det viktigt att notera en avgörande punkt. Asterisk utför kommandon sekventiellt och vÀntar pÄ att de ska slutföras (vilket i och för sig Àr logiskt). Men vi kommer att kalla pÄ bash-skriptet innan kommandot hangupcall har utförts. SÄledes, i ögonblicket dÄ skriptet körs, kommer informationen om det önskade 'uniqueid' Ànnu inte att ha registrerats i CDR. För att lösa detta problem kommer vi att kalla pÄ bash-skriptet med parametern '&', sÄ att Asterisk genast gÄr vidare till nÀsta steg, det vill sÀga hangupcall. Inuti bash-skriptet kommer vi i början att sÀtta en liten tidsfördröjning för att ge Asterisk tid att registrera data med det intressanta 'uniqueid' i CDR.
Praxis
Innan vi gÄr vidare till att konfigurera Asterisk och skapa bash-skriptet, mÄste vi stÀlla in e-postaviseringar. För detta kommer vi att anvÀnda programmet postfix.
Konfigurera postfix
Vi har en e-postdomÀn 'lucky.ru' som finns pÄ Yandex. Vi kommer att stÀlla in postfix i SMTP-klientlÀge och skicka e-post frÄn kontot asterisk@lucky.ru.
Vi baserar oss pÄ denna lösning: .
Först installerar/uppdaterar/kontrollerar vi att paketen finns:
yum install postfix
yum install mailx
yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plainVi kommer inte att skriva över huvudkonfigurationsfilen för postfix '/etc/postfix/main.cf', utan skapa en sÀkerhetskopia av den:
cp /etc/postfix/main.cf /etc/postfix/main.cf.savVi redigerar filen '/etc/postfix/main.cf' och gör den till följande:
nano /etc/postfix/main.cf
#####################
relayhost =
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/private/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_type = cyrus
smtp_sasl_mechanism_filter = login
smtp_sender_dependent_authentication = yes
sender_dependent_relayhost_maps = hash:/etc/postfix/private/sender_relay
smtp_generic_maps = hash:/etc/postfix/generic
smtp_tls_CAfile = /etc/postfix/ca.pem
smtp_use_tls = yes
smtputf8_autodetect_classes = all
#####################Inte varje rad i '/etc/postfix/main.cf' kan kommenteras. Kommentarer i vissa rader identifieras inte av parsers och överförs för bearbetning, vilket kan leda till fel. Det Àr bÀttre att avstÄ frÄn kommentarer inom denna fil. Du kan experimentera med detta genom att köra 'tail -f /var/log/messages' i ett intilliggande fönster.
Jag vill sÀrskilt nÀmna raden 'smtputf8_autodetect_classes = all'. Denna instÀllning aktiverar utf-8 som standard, vilket möjliggör anvÀndning av kyrilliska tecken bÄde i e-postens kropp och Àmnesrad utan ytterligare manipulationsÄtgÀrder (Se. ).
Vi skapar en katalog för konfigurationsfiler:
mkdir /etc/postfix/privateRedigera filen «/etc/postfix/private/sender_relay». DÀr anger vi vilken smtp-server som ska refereras till vid anvÀndning av vÄr e-postdomÀn:
nano /etc/postfix/private/sender_relay
#####################
@lucky.ru smtp.yandex.ru
#####################Redigera filen «/etc/postfix/private/sasl_passwd». HÀr anger vi e-postadressen som vi kommer anvÀnda för att skicka meddelanden samt inloggning och lösenord för detta konto (anvÀndarnamn och lösenord anges med kolon):
nano /etc/postfix/private/sasl_passwd
#####################
asterisk@lucky.ru asterisk@lucky.ru:password_asterisk
#####################Redigera filen «/etc/postfix/generic». DÀr skriver vi reglerna för att Àndra avsÀndaradressen (se. ):
nano /etc/postfix/generic
#####################
root asterisk@lucky.ru
root@localhost asterisk@lucky.ru
root@localhost.localdomain asterisk@lucky.ru
root@freepbx asterisk@lucky.ru
root@freepbx.localdomain asterisk@lucky.ru
root@asterisk asterisk@lucky.ru
root@asterisk.localdomain asterisk@lucky.ru
asterisk asterisk@lucky.ru
asterisk@localhost asterisk@lucky.ru
asterisk@localhost.localdomain asterisk@lucky.ru
asterisk@freepbx asterisk@lucky.ru
asterisk@freepbx.localdomain asterisk@lucky.ru
asterisk@asterisk asterisk@lucky.ru
asterisk@asterisk.localdomain asterisk@lucky.ru
root@localdomain.localdomain asterisk@lucky.ru
#####################Den ursprungliga avsÀndaradressen beror pÄ innehÄllet i «/etc/hosts» och «/etc/hostname», sÄvÀl som namnet pÄ anvÀndaren som kommer att skicka meddelandet. Det vill sÀga, trots att vi anvÀnder en smtp-klient och skickar e-post frÄn asterisk@lucky.ru, kommer postfix initialt att sÀtta «nÄgot eget» i avsÀndaradressen och detta mÄste rÀttas till med reglerna i denna konfigurationsfil.
Jag visar innehÄllet i min fil «/etc/hosts»:
cat /etc/hosts
#####################
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 asterisk.localdomain
127.0.0.1 localhost.localdomain localhost
::1 asterisk localhost localhost6
#####################Det Àr viktigt att servern har en domÀn (vÀrdet efter punkten), eftersom programmet mail «letar efter» domÀnnamnet i «/etc/hosts» och om det «inte hittar» det direkt, fortsÀtter det att leta i ytterligare nÄgra minuter innan det skickar meddelandet. Det vill sÀga, om domÀnen inte Àr angiven, kommer meddelandet att skickas med en fördröjning pÄ flera minuter.
Jag visar innehÄllet i min fil «/etc/hostname»:
cat /etc/hostname
#####################
asterisk
#####################DÀrefter Àr det nödvÀndigt att konvertera de skapade konfigurationsfilerna till indexerade databaser, för detta kör vi följande kommando:
postmap /etc/postfix/generic && postmap /etc/postfix/private/{sasl_passwd,sender_relay}DÀrefter behöver vi ladda ner och placera certifikatet för smtp.yandex.ru pÄ servern, för detta kör vi följande kommando:
openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:25 > /etc/postfix/ca.pemMen efter att den tekniska informationen visas pÄ skÀrmen kommer teamet att "fortsÀtta hÀnga". Tryck Ctrl+C för att avbryta.
Nu tar vi bort allt skrÀp frÄn den resulterande filen manuellt och lÀmnar bara certifikatet. Det borde se ut ungefÀr sÄ hÀr:
nano /etc/postfix/ca.pem
#####################
-----BEGIN CERTIFICATE-----
MIIGazCCBVOgAwIBAgIQcUU9mJXW4OUs5Gf0JfLtsjANBgkqhkiG9w0BAQsFADBf
...
nRG0DfdqYIuPGApFORYe
-----END CERTIFICATE-----
#####################Och till sist startar vi om postfix:
service postfix restartVi skickar ett testmeddelande:
echo "Detta Ă€r kroppstexten" | mail -s "Detta Ă€r Ă€mnet" admin@lucky.ruadmin@lucky.ru â mottagarens adress
Nu Àr instÀllningen av postfix klar.
Vi skriver en bash-skript
Vi skapar en katalog för att lagra bash-skriptet (hÀr kan man vÀlja var som helst):
mkdir /home/asterisk/scriptsVi skapar bash-skriptfilen:
touch /home/asterisk/scripts/noanswer.shVi ger skriptfilen rÀttigheter för att köras:
chmod +x /home/asterisk/scripts/noanswer.shOm du Àr osÀker pÄ filrÀttigheterna kan du temporÀrt ge full tillgÄng till filen för felsökning. Men det Àr "inte sÀkert".
chmod 777 /home/asterisk/scripts/noanswer.shTexten i bash-skriptet:
nano /home/asterisk/scripts/noanswer.sh
#####################
#! /bin /bash
sleep 7
res_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'"
answer=`mysql -u freepbxuser -pPassword_freepbxuser -D asteriskcdrdb -B -N -e "$res_sql" | grep -E -v "NO ANSWER|BUSY|FAILED|UNKNOWN" | head -n 1`
error_kod=0
if [ "$answer" != "ANSWERED" ]
then
case $3 in
68800)
address="big_boss@lucky.ru"
subject="i ett viktigt Àrende"
;;
63100)
address="debian@lucky.ru"
subject="om linux debian"
;;
63200)
address="windows@lucky.ru"
subject="om windows"
;;
63300)
address="freebsd@lucky.ru"
subject="om freebsd"
;;
63400)
address="ubuntu@lucky.ru"
subject="om linux ubuntu"
;;
63500)
address="centos@lucky.ru"
subject="om linux centos"
;;
*)
address="admin@lucky.ru"
error_kod=1
;;
esac
case $error_kod in
0)
echo "Missat samtal frÄn abonnenten $2, som ringde $subject." | mail -s "Missat samtal frÄn $2" $address
echo "Missat samtal till $address frÄn abonnenten $2, som ringde $subject. uid=$1" | mail -s "Missat samtal frÄn $2" admin@lucky.ru
;;
1)
echo "Missat samtal frÄn $2. TjÀnsten Àr okÀnd. uid=$1" | mail -s "Missat samtal frÄn $2" admin@lucky.ru
;;
esac
fi
#####################Kort analys av skriptet:
"sleep 7":
Det handlar om den tidsfördröjning jag nÀmnde tidigare. Vi har en fördröjning pÄ 7 sekunder. Jag tror dock att en sekund skulle vara tillrÀckligt.
"res_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'"":SQL-frÄgan i mysql har vi placerat i en separat variabel för enkelhetens skull.
Vi gör sedan en förfrÄgan i mysql och filtrerar den mottagna utdata. Vi tar bort alla alternativ utom "ANSWERED", om det överhuvudtaget finns nÄgot sÄdant. Om det finns flera vÀrden för "ANSWERED", mÄste vi bara behÄlla ett. I slutet kommer variabeln "answer" att innehÄlla antingen "ANSWERED" eller "".
Om vÀrdet pÄ variabeln "answer" inte Àr lika med "ANSWERED" sÄ Àr det ett missat samtal. Beroende pÄ könumret, ska vi med hjÀlp av case-satsen ange adressen till vem e-postaviseringen ska skickas, och vad som ska stÄ i detta meddelande (det förÀnderliga innehÄllet i meddelandet).
Vi övervÀger nu alternativet dÀr kön Àr angiven i Asterisk, men inte beskriven i skriptet. I detta fall fÄr admin@lucky.ru ett mejl om att kön Àr okÀnd för skriptet.
Om kön Àr beskriven kommer ett mejl att skickas dit det ska, samt en duplicerad mejl till admin@lucky.ru med angivelse av "uniqueid", för att det ska vara möjligt att spÄra hÀndelser kring detta samtal vid behov.
HĂ€r slutar skriptet.
Jag vill nÀmna att vi anvÀnde ett anvÀndarnamn och lösenord för att ansluta till mysql, som vi hade fÄtt pÄ förhand. I FreePBX, för att ta reda pÄ anvÀndarnamnet för Asterisk i mysql, utför följande kommando:
cat /etc/amportal.conf | grep AMPDBUSEROch för att ta reda pÄ lösenordet för Asterisk-anvÀndaren i mysql, kör följande kommando:
cat /etc/amportal.conf | grep AMPDBPASSInstÀllning av Asterisk
Vi anvÀnder FreePBX. I FreePBX finns det olika typer av konfigurationsfiler (se. ), nÄgra av dem skriver FreePBX om vid omstart, och andra skriver den inte om (de kallas custom), eftersom de Àr speciellt avsedda för anvÀndaren.
Vi kommer att arbeta med konfigurationsfilen "extensions_override_freepbx.conf", eftersom den tillhör typen custom.
Först kontrollerar vi att filen "\/etc\/asterisk\/extensions.conf" inkluderar filen "extensions_override_freepbx.conf". För detta utför följande kommando:
cat /etc/asterisk/extensions.conf | grep extensions_override_freepbx.conf
#####################
#include extensions_override_freepbx.conf
#####################Vi redigerar filen "\/etc\/asterisk\/extensions_override_freepbx.conf" och gör den till följande:
nano /etc/asterisk/extensions_override_freepbx.conf
#####################
[ext-queues]
exten => h,1,System(/home/asterisk/scripts/noanswer.sh ${CDR(uniqueid)} ${CALLERID(num)} ${NODEST} &)
exten => h,2,Macro(hangupcall,)Som jag nÀmnde tidigare Àr tecknet «&» i slutet obligatoriskt. Eftersom vi arbetar med bash-skript med CDR-data direkt frÄn mysql-databasen, och dessa data lagras i mysql först efter att «exten => h,2,Macro(hangupcall,)» har körts, Àr det nödvÀndigt att inte vÀnta pÄ att bash-skriptet ska slutföras, utan att gÄ vidare till nÀsta steg i Asterisk. Och sjÀlva bash-skriptet ska innehÄlla en tidsfördröjning innan dess huvuddel utförs.
För att Àndringar i konfigurationsfilen «/etc/asterisk/extensions_override_freepbx.conf» ska trÀda i kraft mÄste Asterisk-kÀrnan startas om med följande kommando:
/usr/sbin/asterisk -rx "core restart now"Detta mÄste göras efter att bash-skriptet har skapats.
Slutsats
Detta Àr antagligen det 1001:a sÀttet att "fÄnga upp missade samtal" i Asterisk. Dela gÀrna med dig i kommentarerna hur du löser denna uppgift. Och vad, enligt din Äsikt, kan förbÀttras/Àndras/optimeras. Vi skulle uppskatta konstruktiva idéer.
KĂ€lla: habr.com
