
IP ATC Asterisk er en kraftfuld platform inden for IP-telefoni. Webgrænsefladen FreePBX, designet til Asterisk, gør opsætningen betydeligt lettere og sænker adgangsbarrieren til systemet.
Hvis du kan forestille dig en opgave relateret til IP-telefoni, så kan det næsten helt sikkert realiseres i Asterisk. Men vær sikker på, at det vil kræve vedholdenhed og tålmodighed fra din side.
Vi stod over for opgaven med at opsætte e-mail-notifikationer om missed calls. Mere præcist at informere via e-mail om de tilfælde, hvor et indgående opkald er gået i kø, men ingen (af agenterne) har besvaret dette indgående opkald.
Overraskende nok fandt vi ikke nogen indbyggede værktøjer til at løse denne opgave i FreePBX. Hvordan vi løste denne opgave, vil jeg fortælle om nedenfor.
Forord
Før vi gik i gang med opgaven direkte, søgte vi selvfølgelig information på internettet, men vi fandt ikke en nøglefærdig løsning (måske søgte vi bare dårligt, men hvad kan man gøre...).
Der er ikke mange færdigheder til direkte arbejde i Asterisk, som man kunne ønske, så den løsning, der blev foreslået, , var ikke helt gennemtænkt og blev forkastet.
Vi kunne lide den løsning, som blev foreslået, , selvom den ikke virkede. Herunder understregede vi, at man skal arbejde i Asterisk i konteksten af køer [ext-queues]. Og da vi arbejder i FreePBX, skal arbejdet ske i konfigurationsfilen «extensions_override_freepbx.conf». Vi lagde mærke til, at det er praktisk at 'fange missed calls' før hangupcall-begivenheden (afslutning af opkaldet).
Efter at have læst diskussionen om, , opstod ideen om, at man skal filtrere CDR-variablen «Disposition» på alle agenter i køen. Og efter at have læst information formede sig ret konkrete skridt til løsningen af den stillede opgave.
Hvad har vi:
Vi har FreePBX 13.0.197, der bruger Asterisk 13.12.1. OS version SHMZ release 6.6 (Final). Distributionen er baseret på CentOS.
I Asterisk er IVR (interaktivt stemmesvar) konfigureret til at fordele indgående opkald til forskellige køer. Hver kø har tildelt agenter, dvs. operatører.
Teori
Hvad sker der i Asterisk
Når et indgående opkald kommer til Asterisk, går opkaldet til IVR. Den der ringer træffer et valg ved at trykke på et bestemt tal på telefonen og havner i en bestemt kø. Herefter modtager alle ledige agenter i køen opkaldet samtidigt.
For bedre at forstå, hvad der sker på dette tidspunkt og hvad der sker derefter, lad os se på Rapport CDR (Fig.1).

Fig.1
Når et indgående opkald kom i kø, blev variablen "Disposition" for alle agenter sat til "NO ANSWER", hvis agenterne på det tidspunkt ikke var optaget. Variablen "Disposition" kunne tage andre værdier (se. ), udover værdien "ANSWERED". I det øjeblik en af agenterne besvarer det indgående opkald, bliver værdien af denne agents "Disposition" lig med "ANSWERED".
Fra Report CDR kan man se, at når opkaldet går i kø (i kolonnen App bliver værdien lig med "Queue"), optræder alle begivenheder med det samme "uniqueid" (kolonne System).
Kort om CDR
Det er vigtigt at forstå, hvad CDR er, og på hvilket tidspunkt dataene, som vi observerer i Report CDR, indtastes i CDR. CDR, i forhold til operativsystemet, er en database, hvor Asterisk registrerer detaljerede opkaldsrapporter (se. ). I vores tilfælde er det en database kaldet asteriskcdrdb, der findes i mysql. Vi har erfaret, at dataene om et opkald med et bestemt "uniqueid" ikke indtastes i asteriskcdrdb med det samme efter en hvilken som helst begivenhed, men efter begivenheden hangupcall (opkaldets afslutning).
Princippet for den oprettede løsning
Da vi har mere viden om bash end om Asterisk, blev hovedideen følgende. Før begivenheden hangupcall skal et bash-script køres. De tre parametre skal sendes til dette script. Den første parameter er "uniqueid" til filtrering af dataene, der hentes fra CDR. Den anden parameter er "CALLERID(num)" (nummeret på den der ringer), for at vide, hvem der skal ringes tilbage. Den tredje parameter er "NODEST" (kønummeret), hvortil opkaldet blev modtaget, for at vide, hvad opkaldet drejede sig om, og hvem der skal modtage e-mail-underretningen om det mistede opkald.
Bash-scriptet skal oprette forbindelse til databasen asteriskcdrdb i mysql og hente alle værdierne af variablen "Disposition" med et bestemt "uniqueid". Fra de indhentede data skal værdierne "NO ANSWER", "BUSY", "FAILED", "UNKNOWN" udelukkes. Resultatet vil være enten "ANSWERED" — opkaldet blev besvaret, eller slet intet — et mistet opkald.
Hvis opkaldet viser sig at være mistet, skal scriptet sende en e-mail underretning.
For at springe frem til det vigtigste punkt, vil jeg nævne, at Asterisk udfører kommandoer rækkefølgen og venter på, at de bliver udført (hvilket er logisk). Og vi vil kalde bash-scriptet, før kommandoen hangupcall bliver udført. Dermed vil der i det øjeblik, hvor scriptet udføres, endnu ikke være indført oplysninger om den "uniqueid", vi søger i CDR. For at løse dette problem vil vi kalde bash-scriptet med parameteren "&", så Asterisk straks kan gå videre til næste trin, dvs. hangupcall. Og indeni bash-scriptet, i starten, vil vi sætte en lille tidsforsinkelse for at give Asterisk tid til at indføre data med den "uniqueid", der interesserer os, i CDR.
Praktik
Før vi går videre til at konfigurere Asterisk og oprette bash-scriptet, skal vi konfigurere afsendelse af e-mail underretninger. Til dette vil vi bruge værktøjet postfix.
Konfiguration af postfix
Vi har e-mail domænet „lucky.ru“, som er placeret i Yandex. Vi vil konfigurere postfix som smtp-klient og sende e-mails fra kontoen asterisk@lucky.ru.
Løsningen er baseret på dette: .
Først installerer/opdaterer/vi kontrollerer tilgængeligheden af pakker:
yum install postfix
yum install mailx
yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plainVi vil ikke overskrive hovedkonfigurationsfilen postfix „/etc/postfix/main.cf“, men lave en backup:
cp /etc/postfix/main.cf /etc/postfix/main.cf.savRediger filen „/etc/postfix/main.cf“ og bring den i følgende form:
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
#####################Ikke hver linje i „/etc/postfix/main.cf“ kan kommenteres. Kommentarer i nogle linjer genkendes ikke af parseren og sendes til behandling, hvilket medfører fejl. Det er bedst at undgå kommentarer inde i denne fil. Du kan eksperimentere med dette ved at køre „tail -f /var/log/messages“ i et nabo vindue.
Jeg vil bemærke linjen „smtputf8_autodetect_classes = all“. Denne indstilling aktiverer utf-8 som standard, hvilket gør det muligt at bruge kyrilliske tegn i både brødteksten og emnet uden yderligere manipulationer (Se. ).
Lad os oprette et katalog til konfigurationsfilerne:
mkdir /etc/postfix/privateRediger filen «/etc/postfix/private/sender_relay». I den skal vi angive, hvilken smtp-server vi skal henvise til, når vi bruger vores maildomæne:
nano /etc/postfix/private/sender_relay
#####################
@lucky.ru smtp.yandex.ru
#####################Rediger filen «/etc/postfix/private/sasl_passwd». Her angiver vi e-mailadressen, som vi vil bruge til at sende mails, samt brugernavn og password til denne konto (brugernavn og password angives med et kolon):
nano /etc/postfix/private/sasl_passwd
#####################
asterisk@lucky.ru asterisk@lucky.ru:password_asterisk
#####################Rediger filen «/etc/postfix/generic». Her angiver vi reglerne for at ændre afsenderadressen (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 oprindelige afsenderadresse afhænger af indholdet i «/etc/hosts» og «/etc/hostname», samt navnet på brugeren, der sender mailen. Det vil sige, selvom vi bruger en smtp-klient og sender mails fra asterisk@lucky.ru, vil postfix alligevel sætte «noget andet» som afsender og det skal rettes med reglerne fra denne konfigurationsfil.
Her er indholdet af 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 er vigtigt, at serveren har et domænenavn (værdien efter punktummet), fordi mail-udnyttelsen «søger» efter domænenavnet i «/etc/hosts», og hvis den «ikke finder» det med det samme, fortsætter den med at søge i flere minutter, før den sender mailen. Det vil sige, hvis domænet ikke er angivet, vil mailen blive sendt med en forsinkelse på flere minutter.
Her er indholdet af min fil «/etc/hostname»:
cat /etc/hostname
#####################
asterisk
#####################Derefter skal vi konvertere de oprettede konfigurationsfiler til indekserede databasetabeller, for dette udfører vi følgende kommando:
postmap /etc/postfix/generic && postmap /etc/postfix/private/{sasl_passwd,sender_relay}Dernæst skal vi hente og placere certifikatet smtp.yandex.ru på serveren, for dette udfører vi følgende kommando:
openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:25 > /etc/postfix/ca.pemMen efter at den tekniske information vises på skærmen, vil teamet «fortsætte med at hænge». Tryk Ctrl+C for at afbryde det.
Lad os nu manuelt fjerne alt unødvendigt fra den resulterende fil og kun bevare certifikatet. Det burde se nogenlunde sådan ud:
nano /etc/postfix/ca.pem
#####################
-----BEGIN CERTIFICATE-----
MIIGazCCBVOgAwIBAgIQcUU9mJXW4OUs5Gf0JfLtsjANBgkqhkiG9w0BAQsFADBf
...
nRG0DfdqYIuPGApFORYe
-----END CERTIFICATE-----
#####################Og til sidst genstarter vi postfix:
service postfix restartSender en test e-mail:
echo "Dette er e-mailens indhold" | mail -s "Dette er emnet" admin@lucky.ruadmin@lucky.ru — destinationsadresse
Nu er konfigurationen af postfix afsluttet.
Skriver et bash-script
Opretter en mappe til opbevaring af bash-scriptet (her hvor det passer bedst):
mkdir /home/asterisk/scriptsOpretter bash-scriptfilen:
touch /home/asterisk/scripts/noanswer.shGiver scriptfilen udførelsesretter:
chmod +x /home/asterisk/scripts/noanswer.shHvis der er tvivl om rettighederne til filen, kan du midlertidigt give fuld adgang til filen under debugging. Men dette er «ikke sikkert».
chmod 777 /home/asterisk/scripts/noanswer.shBash-scriptet tekst:
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="vedrørende et vigtigt spørgsmål"
;;
63100)
address="debian@lucky.ru"
subject="vedrørende linux debian"
;;
63200)
address="windows@lucky.ru"
subject="vedrørende windows"
;;
63300)
address="freebsd@lucky.ru"
subject="vedrørende freebsd"
;;
63400)
address="ubuntu@lucky.ru"
subject="vedrørende linux ubuntu"
;;
63500)
address="centos@lucky.ru"
subject="vedrørende linux centos"
;;
*)
address="admin@lucky.ru"
error_kod=1
;;
esac
case $error_kod in
0)
echo "Mistet opkald fra abonnent $2, der ringede $subject." | mail -s "Mistet opkald fra $2" $address
echo "Mistet opkald til $address fra abonnent $2, der ringede $subject. uid=$1" | mail -s "Mistet opkald fra $2" admin@lucky.ru
;;
1)
echo "Mistet opkald fra $2. Køen er ukendt. uid=$1" | mail -s "Mistet opkald fra $2" admin@lucky.ru
;;
esac
fi
#####################Kort gennemgang af scriptet:
«sleep 7»:
Det er den forsinkelse, jeg nævnte tidligere. Vi har indstillet en forsinkelse på 7 sekunder. Selvom jeg tror, en enkelt sekund ville være tilstrækkelig.
«res_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'"»:MySQL-forespørgslen har vi udskilt i en separat variabel for nemheds skyld.
Here we make a request to MySQL and filter the received output. We remove all options except for "ANSWERED" if it exists. If there are multiple "ANSWERED" values, we should keep only one. In the end, the variable "answer" will contain either "ANSWERED" or an empty string.
If the value of the variable "answer" is not equal to "ANSWERED", then this is a missed call. Depending on the queue number, we will use a case statement to specify the address to which an email notification should be sent, and what to write in that message (the variable part of the message).
Next, we consider the case when the queue is defined in Asterisk but not described in the script. In this case, admin@lucky.ru will receive an email stating that the queue is unknown to the script.
If the queue is described, an email will be sent to the designated recipient, along with a duplicate email sent to admin@lucky.ru indicating the "uniqueid", so that events related to this call can be tracked if necessary.
This concludes the script.
I would like to note that for connecting to MySQL, we used a username and password that we obtained beforehand. In FreePBX, to find out the username for the Asterisk user in MySQL, execute the following command:
cat /etc/amportal.conf | grep AMPDBUSERAnd to find out the password for the Asterisk user in MySQL, execute the following command:
cat /etc/amportal.conf | grep AMPDBPASSSetting up Asterisk
We use FreePBX. In FreePBX, there are different types of configuration files (see ), some of which FreePBX rewrites upon reboot, while others are not rewritten (referred to as custom), as they are specifically intended for the user.
We will work with the configuration file "extensions_override_freepbx.conf" as it belongs to the custom type.
First, let's ensure that the file "/etc/asterisk/extensions.conf" includes the file "extensions_override_freepbx.conf". To do this, execute the following command:
cat /etc/asterisk/extensions.conf | grep extensions_override_freepbx.conf
#####################
#include extensions_override_freepbx.conf
#####################Edit the file "/etc/asterisk/extensions_override_freepbx.conf" and modify it as follows:
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 jeg tidligere nævnte, er symbolet «&» i slutningen obligatorisk. Da vi vil arbejde i bash-scriptet med CDR-data direkte fra MySQL-databasen, og disse data kun gemmes i MySQL efter udførelsen af «exten => h,2,Macro(hangupcall,)», er det nødvendigt ikke at vente på afslutningen af bash-scriptet, men at gå videre til næste skridt i Asterisk. Bash-scriptet skal have en tidsmæssig forsinkelse, før den primære del udføres.
For at ændringerne i konfigurationsfilen «/etc/asterisk/extensions_override_freepbx.conf» træder i kraft, er det nødvendigt at genstarte Asterisk-kernen med følgende kommando:
/usr/sbin/asterisk -rx "core restart now"Dette skal gøres, efter at bash-scriptet er blevet oprettet.
Konklusion
Det må være den 1001. måde at «fange mistede opkald» i Asterisk. Del venligst i kommentarerne, hvordan I løser denne opgave. Og hvad mener du kan forbedres/omarbejdes/optimeres. Vi vil sætte pris på konstruktive idéer.
Kilde: habr.com
