
IP-PBX Asterisk ist ein leistungsstarker Kombi in der Welt der IP-Telefonie. Die Web-Schnittstelle FreePBX, die fĂŒr Asterisk entwickelt wurde, erleichtert die Konfiguration erheblich und senkt die EinstiegshĂŒrde fĂŒr das System.
Wenn Sie eine Aufgabe im Zusammenhang mit IP-Telefonie vorstellen können, lÀsst sich diese höchstwahrscheinlich in Asterisk umsetzen. Seien Sie jedoch darauf vorbereitet, dass Sie Entschlossenheit und Durchhaltevermögen benötigen.
Wir standen vor der Aufgabe, E-Mail-Benachrichtigungen ĂŒber versĂ€umte Anrufe einzurichten. Genauer gesagt, sollten wir per E-Mail ĂŒber Situationen informiert werden, in denen ein eingehender Anruf in die Warteschlange ĂŒbergegangen ist, aber niemand (von den Agenten) auf diesen Anruf geantwortet hat.
Zu unserer Ăberraschung konnten wir in FreePBX keine integrierten Mittel zur Lösung dieser Aufgabe finden. Wie wir dieses Problem gelöst haben, werde ich im folgenden Abschnitt erklĂ€ren.
Vorwort
Bevor wir die Lösung direkt angegangen sind, haben wir natĂŒrlich im Internet nach Informationen gesucht, aber keine schlĂŒsselfertige Lösung gefunden (vielleicht haben wir nicht gut genug gesucht, aber was sollâsâŠ).
Es gibt nicht so viele FĂ€higkeiten im direkten Umgang mit Asterisk, wie wir uns wĂŒnschen wĂŒrden, daher wurde die angebotene Lösung , nicht vollstĂ€ndig durchdacht und verworfen.
Ich mochte die vorgeschlagene Lösung , obwohl sie nicht funktioniert hat. Dabei wurde betont, dass man in Asterisk im Kontext der Warteschlangen [ext-queues] arbeiten muss. Da wir FreePBX verwenden, erfolgt die Arbeit in der Konfigurationsdatei âextensions_override_freepbx.confâ. Es wurde festgestellt, dass es praktisch ist, âverpasste Anrufe zu erfassenâ vor dem Ereignis hangupcall (Anrufbeendigung).
Nachdem ich die Diskussion gelesen habe , kam die Idee auf, dass die CDR-Variable âDispositionâ fĂŒr alle Agenten in der Warteschlange gefiltert werden sollte. Nach dem Lesen der Informationen haben sich sehr konkrete Schritte zur Lösung der gestellten Aufgabe herausgebildet.
Was wir haben:
Wir haben FreePBX 13.0.197, das Asterisk 13.12.1 verwendet. Die OS-Version ist SHMZ release 6.6 (Final). Die Distribution basiert auf CentOS.
In Asterisk ist ein IVR (Interactive Voice Response) eingerichtet, das eingehende Anrufe auf verschiedene Warteschlangen verteilt. Jeder Warteschlange sind Agenten zugeordnet, d.h. Operatoren.
Theorie
Was in Asterisk passiert
Wenn ein eingehender Anruf bei Asterisk eingeht, landet dieser Anruf im IVR. Der Anrufer wÀhlt eine bestimmte Ziffer auf dem Telefon und gelangt in eine bestimmte Warteschlange. Danach erhalten alle freien Agenten der Warteschlange gleichzeitig den Anruf.
Um besser zu verstehen, was in diesem Moment passiert und wie es weitergeht, werfen wir einen Blick auf den Report CDR (Abb. 1).

Abb. 1
Wenn ein eingehender Anruf in die Warteschlange gelangt, ist der Wert der Variable âDispositionâ fĂŒr alle Agenten gleich âNO ANSWERâ, sofern die Agenten zu diesem Zeitpunkt nicht beschĂ€ftigt sind. Die Variable âDispositionâ konnte auch andere Werte annehmen (siehe ), auĂer dem Wert âANSWEREDâ. In dem Moment, in dem einer der Agenten den eingehenden Anruf entgegennimmt, wird der Wert der Variable âDispositionâ dieses Agenten gleich âANSWEREDâ.
Aus dem Report CDR lĂ€sst sich erkennen, dass, wenn der Anruf in die Warteschlange ĂŒbergeht (in der Spalte App wird der Wert gleich âQueueâ), alle Ereignisse mit der gleichen âuniqueidâ (Spalte System) erscheinen.
Kurzinformation zu CDR
Es ist wichtig zu verstehen, was CDR ist und in welchem Moment die Daten in CDR eingegeben werden, die wir im Report CDR beobachten. CDR ist, relativ zum Betriebssystem, eine Datenbank, in die Asterisk detaillierte Anrufberichte aufzeichnet (siehe ). In unserem Fall handelt es sich um die Datenbank namens asteriskcdrdb, die sich in MySQL befindet. Durch Erfahrung haben wir festgestellt, dass die Anrufdaten mit einer bestimmten âuniqueidâ nicht sofort nach dem Auftreten eines Ereignisses in asteriskcdrdb gespeichert werden, sondern erst nach dem Ereignis hangupcall (Ende des Anrufs).
Funktionsprinzip der entwickelten Lösung
Da wir in Bash mehr Kenntnisse haben als in Asterisk, lautet die grundlegende Idee wie folgt. Vor dem Ereignis hangupcall soll ein Bash-Skript aufgerufen werden. In dieses Skript ĂŒbergeben wir 3 Parameter. Der erste Parameter ist âuniqueidâ, um die aus dem CDR erhaltenen Daten zu filtern. Der zweite Parameter ist âCALLERID(num)â (die Nummer des Anrufers), um zu wissen, wem wir zurĂŒckrufen. Der dritte Parameter ist âNODESTâ (die Nummer der Warteschlange), in die der Anruf einging, um zu wissen, worum es beim Anruf ging, und um die E-Mail-Benachrichtigung ĂŒber den verpassten Anruf zu versenden.
Das Bash-Skript muss sich mit der Datenbank asteriskcdrdb in MySQL verbinden und alle Werte der Variablen âDispositionâ mit einer bestimmten âuniqueidâ abrufen. Aus den erhaltenen Daten mĂŒssen die Werte âNO ANSWERâ, âBUSYâ, âFAILEDâ und âUNKNOWNâ ausgeschlossen werden. Am Ende bleiben entweder âANSWEREDâ â der eingehende Anruf wurde entgegengenommen, oder es bleibt nichts â der Anruf wurde verpasst.
Wenn ein Anruf verpasst wurde, sollte das Skript eine E-Mail-Benachrichtigung senden.
Um einen wichtigen Punkt vorwegzunehmen: Asterisk fĂŒhrt die Befehle nacheinander aus und wartet auf deren Abschluss (was grundsĂ€tzlich logisch ist). Der bash-Skript wird jedoch aufgerufen, bevor der Befehl hangupcall ausgefĂŒhrt wird. Daher wird zum Zeitpunkt der AusfĂŒhrung des Skripts noch keine Information ĂŒber die gesuchte «uniqueid» in den CDR eingetragen sein. Um dieses Problem zu lösen, werden wir den bash-Skript mit dem Parameter «&» aufrufen, damit Asterisk sofort mit dem nĂ€chsten Schritt, also hangupcall, fortfahren kann. Am Anfang des bash-Skripts setzen wir eine kurze Verzögerung, um Asterisk Zeit zu geben, die Daten mit der interessierenden «uniqueid» in den CDR einzutragen.
Praxis
Bevor wir mit der Konfiguration von Asterisk und der Erstellung des bash-Skripts beginnen, mĂŒssen wir die E-Mail-Benachrichtigungen einrichten. Dazu verwenden wir das Dienstprogramm postfix.
Postfix-Konfiguration
Wir haben die Domain «lucky.ru», die bei Yandex gehostet wird. Wir konfigurieren postfix im SMTP-Client-Modus und senden E-Mails von dem Konto asterisk@lucky.ru.
Hierbei handelt es sich um eine Lösung von hier: .
Zuerst installieren/aktualisieren/prĂŒfen wir die VerfĂŒgbarkeit der Pakete:
yum install postfix
yum install mailx
yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plainWir werden die Hauptkonfigurationsdatei von Postfix «/etc/postfix/main.cf» nicht ĂŒberschreiben, sondern eine Sicherungskopie erstellen:
cp /etc/postfix/main.cf /etc/postfix/main.cf.savBearbeiten Sie die Datei «/etc/postfix/main.cf» und bringen Sie sie in die folgende 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
#####################Nicht jede Zeile in «/etc/postfix/main.cf» kann kommentiert werden. Kommentare in einigen Zeilen werden vom Parser nicht erkannt und an die Verarbeitung ĂŒbergeben, was zu Fehlern fĂŒhrt. Es ist besser, auf Kommentare innerhalb dieser Datei zu verzichten. Sie können damit experimentieren, indem Sie in einem anderen Fenster «tail -f /var/log/messages» ausfĂŒhren.
Ich möchte auf die Zeile «smtputf8_autodetect_classes = all» hinweisen. Diese Einstellung aktiviert standardmĂ€Ăig UTF-8, was es ermöglicht, kyrillische Schriftzeichen sowohl im Text als auch im Betreff der E-Mail ohne zusĂ€tzliche Manipulationen zu verwenden (Siehe. ).
Lassen Sie uns ein Verzeichnis fĂŒr die Konfigurationsdateien erstellen:
mkdir /etc/postfix/privateWir bearbeiten die Datei «/etc/postfix/private/sender_relay». Hier geben wir an, auf welchen SMTP-Server verwiesen werden soll, wenn wir unsere Mail-Domain verwenden:
nano /etc/postfix/private/sender_relay
#####################
@lucky.ru smtp.yandex.ru
#####################Wir bearbeiten die Datei «/etc/postfix/private/sasl_passwd». Hier geben wir die E-Mail-Adresse an, die wir zum Versenden von Nachrichten verwenden werden, sowie den Benutzernamen und das Passwort fĂŒr dieses Konto (Benutzername und Passwort durch einen Doppelpunkt trennen):
nano /etc/postfix/private/sasl_passwd
#####################
asterisk@lucky.ru asterisk@lucky.ru:password_asterisk
#####################Wir bearbeiten die Datei «/etc/postfix/generic». Hier schreiben wir die Regeln fĂŒr die Umleitung der Absenderadresse (siehe. ):
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
#####################Die ursprĂŒngliche Absenderadresse hĂ€ngt vom Inhalt von "/etc/hosts" und "/etc/hostname" sowie vom Benutzernamen ab, der die E-Mail senden wird. Das heiĂt, obwohl wir einen SMTP-Client verwenden und E-Mails von asterisk@lucky.ru senden, wird Postfix dennoch anfangs "etwas Eigenes" in die Absenderadresse einfĂŒgen, was ĂŒber die Regeln in dieser Konfigurationsdatei korrigiert werden muss.
Hier ist der Inhalt meiner Datei "/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
#####################Es ist wichtig, dass der Server eine Domain hat (den Wert nach dem Punkt), da das Mail-Utility nach dem Domainnamen in "/etc/hosts" sucht. Wenn es ihn nicht sofort findet, wird es weitere Minuten danach suchen, bevor die E-Mail gesendet wird. Das heiĂt, wenn die Domain nicht eingetragen ist, wird die E-Mail mit mehreren Minuten Verzögerung versendet.
Hier ist der Inhalt meiner Datei "/etc/hostname":
cat /etc/hostname
#####################
asterisk
#####################AnschlieĂend mĂŒssen die erstellten Konfigurationsdateien in indizierte Datenbanken ĂŒberfĂŒhrt werden. Dazu fĂŒhren wir den folgenden Befehl aus:
postmap /etc/postfix/generic && postmap /etc/postfix/private/{sasl_passwd,sender_relay}Als NĂ€chstes mĂŒssen wir das Zertifikat smtp.yandex.ru herunterladen und auf dem Server ablegen. FĂŒhren Sie dazu den folgenden Befehl aus:
openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:25 > /etc/postfix/ca.pemNachdem technische Informationen angezeigt wurden, wird der Befehl "weiterhin hĂ€ngen" bleiben. DrĂŒcken Sie Ctrl+C, um ihn abzubrechen.
Jetzt entfernen wir manuell den gesamten MĂŒll aus der resultierenden Datei und lassen nur das Zertifikat ĂŒbrig. Es sollte etwa wie folgt aussehen:
nano /etc/postfix/ca.pem
#####################
-----BEGIN CERTIFICATE-----
MIIGazCCBVOgAwIBAgIQcUU9mJXW4OUs5Gf0JfLtsjANBgkqhkiG9w0BAQsFADBf
...
nRG0DfdqYIuPGApFORYe
-----END CERTIFICATE-----
#####################Und schlieĂlich starten wir Postfix neu:
service postfix restartWir senden eine Test-E-Mail:
echo "Dies ist der E-Mail-Text" | mail -s "Das ist das Thema" admin@lucky.ruadmin@lucky.ru â Zieladresse
Damit ist die Konfiguration von Postfix abgeschlossen.
Wir schreiben ein Bash-Skript
Erstellen Sie ein Verzeichnis fĂŒr das Bash-Skript (dort, wo es Ihnen am besten gefĂ€llt):
mkdir /home/asterisk/scriptsErstellen Sie die Bash-Skriptdatei:
touch /home/asterisk/scripts/noanswer.shGeben Sie der Skriptdatei AusfĂŒhrungsrechte:
chmod +x /home/asterisk/scripts/noanswer.shWenn Sie Zweifel an den Rechten der Datei haben, können Sie wĂ€hrend der Fehlersuche vorĂŒbergehend vollen Zugriff auf die Datei gewĂ€hren. Aber das ist ânicht sicherâ.
chmod 777 /home/asterisk/scripts/noanswer.shText des Bash-Skripts:
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="zu einem wichtigen Thema"
;;
63100)
address="debian@lucky.ru"
subject="zu Fragen zu Linux Debian"
;;
63200)
address="windows@lucky.ru"
subject="zu Fragen zu Windows"
;;
63300)
address="freebsd@lucky.ru"
subject="zu Fragen zu FreeBSD"
;;
63400)
address="ubuntu@lucky.ru"
subject="zu Fragen zu Linux Ubuntu"
;;
63500)
address="centos@lucky.ru"
subject="zu Fragen zu Linux CentOS"
;;
*)
address="admin@lucky.ru"
error_kod=1
;;
esac
case $error_kod in
0)
echo "Verpasster Anruf von $2, der ĂŒber $subject anrief." | mail -s "Verpasster Anruf von $2" $address
echo "Verpasster Anruf fĂŒr $address von $2, der ĂŒber $subject anrief. uid=$1" | mail -s "Verpasster Anruf von $2" admin@lucky.ru
;;
1)
echo "Verpasster Anruf von $2. Unbekannte Warteschlange. uid=$1" | mail -s "Verpasster Anruf von $2" admin@lucky.ru
;;
esac
fi
#####################Kurze Analyse des Skripts:
âsleep 7â:
Das ist die Zeitverzögerung, von der ich zuvor gesprochen habe. Wir haben eine Verzögerung von 7 Sekunden festgelegt. Ich denke, dass auch eine Sekunde völlig ausreichend wÀre.
âres_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'"â:Wir haben die MySQL-Anfrage in eine separate Variable ausgegliedert, um die Handhabung zu erleichtern.
AnschlieĂend fĂŒhren wir die MySQL-Anfrage aus und filtern die erhaltenen Ergebnisse. Wir entfernen alle Optionen auĂer âANSWEREDâ, sofern verfĂŒgbar. Falls mehrere Werte âANSWEREDâ vorhanden sind, muss nur einer beibehalten werden. Am Ende erhalten wir in der Variable âanswerâ entweder âANSWEREDâ oder einen leeren Wert.
Wenn der Wert der Variable âanswerâ nicht âANSWEREDâ ist, wird dies als verpasster Anruf gewertet. Je nach Warteschennummer legen wir mit dem Falloperator fest, an wen genau die E-Mail-Benachrichtigung gesendet werden muss und was in dieser Nachricht geschrieben werden soll (verĂ€nderlicher Teil der Nachricht).
Im Folgenden betrachten wir den Fall, in dem die Warteschlange in Asterisk definiert ist, aber nicht im Skript beschrieben wird. In diesem Fall erhÀlt admin@lucky.ru eine E-Mail, dass die Warteschlange dem Skript nicht bekannt ist.
Wenn die Warteschlange hingegen beschrieben ist, wird die E-Mail an die vorgesehene Adresse gesendet und eine Kopie an admin@lucky.ru mit dem âuniqueidâ gesendet, damit die Ereignisse fĂŒr diesen Anruf bei Bedarf nachverfolgt werden können.
Damit endet das Skript.
Ich möchte anmerken, dass wir fĂŒr die Verbindung zu MySQL den Benutzernamen und das Passwort verwendet haben, die wir im Voraus herausgefunden haben. In FreePBX können Sie den Benutzernamen fĂŒr Asterisk in MySQL mit folgendem Befehl herausfinden:
cat /etc/amportal.conf | grep AMPDBUSERUm das Passwort fĂŒr den Asterisk-Benutzer in MySQL herauszufinden, verwenden Sie bitte folgenden Befehl:
cat /etc/amportal.conf | grep AMPDBPASSAsterisk-Konfiguration
Wir verwenden FreePBX. In FreePBX gibt es verschiedene Typen von Konfigurationsdateien (siehe ), einige davon werden von FreePBX beim Neustart ĂŒberschrieben, wĂ€hrend andere nicht ĂŒberschrieben werden (diese werden als benutzerdefiniert bezeichnet), da sie speziell fĂŒr den Benutzer vorgesehen sind.
Wir werden mit der Konfigurationsdatei âextensions_override_freepbx.confâ arbeiten, da sie als benutzerdefiniert gilt.
ZunĂ€chst stellen wir sicher, dass die Datei â/etc/asterisk/extensions.confâ die Datei âextensions_override_freepbx.confâ eingebunden hat. FĂŒhren Sie dazu folgenden Befehl aus:
cat /etc/asterisk/extensions.conf | grep extensions_override_freepbx.conf
#####################
#include extensions_override_freepbx.conf
#####################Bearbeiten Sie die Datei â/etc/asterisk/extensions_override_freepbx.confâ und passen Sie sie wie folgt an:
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,)
#####################Wie ich bereits erwĂ€hnt habe, ist das Symbol â&â am Ende erforderlich. Da wir in einem Bash-Skript mit CDR-Daten direkt aus einer MySQL-Datenbank arbeiten werden und diese Daten nur nach der AusfĂŒhrung von âexten => h,2,Macro(hangupcall,)â in MySQL eingefĂŒgt werden, ist es notwendig, nicht auf das Ende der Bash-Skript-AusfĂŒhrung zu warten, sondern zum nĂ€chsten Schritt in Asterisk ĂŒberzugehen. Das Bash-Skript selbst sollte eine zeitliche Verzögerung vor der AusfĂŒhrung seines Hauptteils enthalten.
Um die Ănderungen in der Konfigurationsdatei â/etc/asterisk/extensions_override_freepbx.confâ wirksam zu machen, muss der Asterisk-Kernel mit dem folgenden Befehl neu gestartet werden:
/usr/sbin/asterisk -rx "core restart now"Dies sollte erfolgen, nachdem das Bash-Skript erstellt wurde.
Fazit
Dies ist wahrscheinlich die 1001. Methode zum âAbfangen verpasster Anrufeâ in Asterisk. Teilen Sie in den Kommentaren mit, wie Sie diese Aufgabe lösen. Und was Ihrer Meinung nach verbessert / umgestaltet / optimiert werden kann. Wir wĂŒrden uns ĂŒber konstruktive Ideen freuen.
Quelle: habr.com
