
IP ATC Asterisk ist ein leistungsstarkes KombigerĂ€t im Bereich der IP-Telefonie. Die Webschnittstelle FreePBX, die fĂŒr Asterisk entwickelt wurde, vereinfacht die Konfiguration erheblich und senkt die EinstiegshĂŒrden fĂŒr das System.
Wenn Sie sich irgendeine Aufgabe im Zusammenhang mit IP-Telefonie vorstellen können, ist es fast sicher möglich, diese in Asterisk zu realisieren. Seien Sie jedoch versichert, dass von Ihnen Durchhaltevermögen und Geduld verlangt werden.
Vor uns stand die Aufgabe, E-Mail-Benachrichtigungen ĂŒber verpasste Anrufe einzurichten. Genauer gesagt, sollten wir per E-Mail ĂŒber die FĂ€lle informieren, in denen ein eingehender Anruf in die Warteschlange ging, aber niemand (aus den Agenten) den Anruf entgegengenommen hat.
Ăberraschenderweise fanden wir in FreePBX keine Standardmittel zur Lösung dieser Aufgabe. Wie wir diese Aufgabe gelöst haben, werde ich im Folgenden erlĂ€utern.
Vorwort
Bevor wir die Aufgabe direkt angehen, haben wir natĂŒrlich Informationen im Internet gesucht, aber keine schlĂŒsselfertige Lösung gefunden (vielleicht haben wir schlecht gesucht, aber was sollâsâŠ).
Die Kenntnisse ĂŒber die direkte Arbeit in Asterisk sind nicht so zahlreich, wie wir uns wĂŒnschen wĂŒrden, daher war die vorgeschlagene Lösung , nicht vollstĂ€ndig durchdacht und wurde verworfen.
Die vorgeschlagene Lösung von hat uns gefallen, auch wenn sie nicht funktioniert hat. Daher haben wir betont, dass die Arbeit in Asterisk im Kontext der Warteschlangen [ext-queues] erfolgen muss. Und da wir in FreePBX arbeiten, ist die Arbeit in der Konfigurationsdatei âextensions_override_freepbx.confâ erforderlich. Wir haben auch festgestellt, dass es praktisch ist, âverpasste Anrufeâ vor dem Ereignis hangupcall (Anrufabschluss) zu erfassen.
Nachdem ich die Diskussion von gelesen hatte, kam mir die Idee, die CDR-Variable âDispositionâ fĂŒr alle Agenten in der Warteschlange zu filtern. Nach dem Lesen von bildeten sich ganz konkrete Schritte zur Lösung der gestellten Aufgabe.
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 (SprachmenĂŒ) eingerichtet, das eingehende Anrufe an verschiedene Warteschlangen verteilt. Jede Warteschlange hat Agenten zugewiesen, d. h. Betreiber.
Theorie
Was in Asterisk passiert
Wenn ein eingehender Anruf bei Asterisk eingeht, gelangt dieser Anruf ins IVR. Der Anrufer trifft eine Auswahl, indem er eine bestimmte Taste auf dem Telefon drĂŒckt, und gelangt in die entsprechende Warteschlange. Danach erhalten alle freien Agenten der Warteschlange gleichzeitig einen Anruf.
Um besser zu verstehen, was in diesem Moment passiert und was danach geschieht, wenden wir uns dem Bericht CDR (Abb.1) zu.

Abb.1
Wenn ein eingehender Anruf in die Warteschlange gelangt, wird der Wert der Variablen âDispositionâ fĂŒr alle Agenten auf âNO ANSWERâ gesetzt, sofern die Agenten zu diesem Zeitpunkt nicht beschĂ€ftigt sind. Die Variablen âDispositionâ können auch andere Werte annehmen (siehe. ), auĂer dem Wert âANSWEREDâ. In dem Moment, in dem einer der Agenten den eingehenden Anruf annimmt, wird der Wert der Variablen âDispositionâ dieses Agenten auf âANSWEREDâ gesetzt.
Aus dem CDR-Bericht lĂ€sst sich erkennen, dass, wenn der Anruf in die Warteschlange ĂŒbergeht (in der Spalte App wird der Wert auf âQueueâ gesetzt), alle Ereignisse mit derselben âuniqueidâ (Spalte System) aufgefĂŒhrt sind.
Kurz zu CDR
Es ist wichtig zu verstehen, was CDR ist und in welchem Moment die Daten, die wir im CDR-Bericht beobachten, im CDR erfasst werden. CDR ist, bezĂŒglich des Betriebssystems, eine Datenbank, in die Asterisk detaillierte Anrufberichte aufzeichnet (siehe. ). In unserem Fall handelt es sich um eine Datenbank mit dem Namen asteriskcdrdb, die sich in MySQL befindet. Durch Versuch und Irrtum haben wir festgestellt, dass die Daten ĂŒber einen Anruf mit einer bestimmten âuniqueidâ nicht sofort nach dem Auftreten eines Ereignisses in asteriskcdrdb eingetragen werden, sondern erst nach dem Ereignis hangupcall (Beendigung des Anrufs).
Funktionsprinzip der erstellten Lösung
Da wir mehr Kenntnisse in Bash als in Asterisk haben, lautet die Grundidee folgendermaĂen. Vor dem Ereignis hangupcall wird ein Bash-Skript aufgerufen. In dieses Skript werden 3 Parameter ĂŒbergeben. Der erste Parameter ist âuniqueidâ, zur Filterung der Daten, die aus dem CDR abgerufen werden. Der zweite Parameter ist âCALLERID(num)â (die Rufnummer des Anrufers), um zu wissen, wem wir zurĂŒckrufen. Der dritte Parameter ist âNODESTâ (die Warteschwenummer), in die der Anruf eingegangen ist, um zu wissen, worum es beim Anruf ging und an wen die E-Mail-Benachrichtigung ĂŒber den verpassten Anruf gesendet werden soll.
Das Bash-Skript sollte sich mit der Datenbank asteriskcdrdb in MySQL verbinden und alle Werte der Variablen âDispositionâ mit der bestimmten âuniqueidâ abrufen. Von den erhaltenen Daten sollten die Werte âNO ANSWERâ, âBUSYâ, âFAILEDâ, âUNKNOWNâ ausgeschlossen werden. In der Folge bleiben entweder âANSWEREDâ â der eingehende Anruf wurde angenommen, oder es bleibt gar nichts â ein verpasster Anruf.
Wenn der Anruf verpasst wurde, sollte das Skript eine E-Mail-Benachrichtigung senden.
Vorweg sei ein wichtiger Punkt erwĂ€hnt: Asterisk fĂŒhrt Befehle nacheinander aus und wartet auf deren Vollziehung (was im Grunde genommen logisch ist). Wir werden jedoch das Bash-Skript aufrufen, bevor der Befehl hangupcall ausgefĂŒhrt wird. Somit wird zum Zeitpunkt der direkten AusfĂŒhrung des Skripts noch keine Information ĂŒber die gesuchte âuniqueidâ in die CDR eingetragen sein. Um dieses Problem zu lösen, werden wir das Bash-Skript mit dem Parameter â&â aufrufen, damit Asterisk sofort zum nĂ€chsten Schritt ĂŒbergeht, d. h. hangupcall. Zu Beginn des Bash-Skripts werden wir eine kurze Zeitverzögerung einfĂŒgen, um Asterisk die Zeit zu geben, die Daten mit der uns interessierenden âuniqueidâ in die 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 werden wir das Programm Postfix verwenden.
Postfix-Konfiguration
Wir haben die Domain âlucky.ruâ, die bei Yandex gehostet ist. Wir werden Postfix im Modus eines SMTP-Clients einrichten und E-Mails vom Konto asterisk@lucky.ru senden.
Die Grundlage wird von hier ĂŒbernommen: .
Zuerst installieren/aktualisieren/prĂŒfen wir die vorhandenen 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 davon erstellen:
cp /etc/postfix/main.cf /etc/postfix/main.cf.savWir bearbeiten die Datei â/etc/postfix/main.cfâ und bringen sie in 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 zur Verarbeitung weitergegeben, was zu Fehlern fĂŒhrt. Es ist besser, auf Kommentare innerhalb dieser Datei zu verzichten. Sie können damit experimentieren, indem Sie in einem benachbarten Fenster âtail -f /var/log/messagesâ ausfĂŒhren.
Ich möchte die Zeile âsmtputf8_autodetect_classes = allâ hervorheben. Dieser Eintrag aktiviert standardmĂ€Ăig UTF-8, was es ermöglicht, kyrillische Schrift sowohl im E-Mail-Text als auch im Betreff ohne zusĂ€tzliche Manipulationen zu verwenden (Siehe. ).
Wir erstellen ein Verzeichnis fĂŒr die Konfigurationsdateien:
mkdir /etc/postfix/privateWir bearbeiten die Datei «/etc/postfix/private/sender_relay». Darin mĂŒssen wir angeben, auf welchen SMTP-Server verwiesen werden soll, wenn wir unsere E-Mail-Domain verwenden:
nano /etc/postfix/private/sender_relay
#####################
@lucky.ru smtp.yandex.ru
#####################Wir bearbeiten die Datei «/etc/postfix/private/sasl_passwd». Dort 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 werden durch einen Doppelpunkt getrennt):
nano /etc/postfix/private/sasl_passwd
#####################
asterisk@lucky.ru asterisk@lucky.ru:password_asterisk
#####################Wir bearbeiten die Datei «/etc/postfix/generic». Darin werden wir die Regeln zur Umgehung der Absenderadresse festlegen (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 Nachricht sendet. Das heiĂt, obwohl wir einen SMTP-Client verwenden und Nachrichten von asterisk@lucky.ru senden, wird Postfix trotzdem ursprĂŒnglich eine "eigenes" Absenderadresse einfĂŒgen, und dies muss durch die Regeln in dieser Konfigurationsdatei korrigiert werden.
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 (Wert nach dem Punkt), da das Mail-Tool den Namen der Domain in «/etc/hosts» "sucht". Wenn es ihn nicht sofort findet, wird es noch weitere Minuten fortfahren, dies zu tun, und erst dann die Nachricht versenden. Das heiĂt, wenn die Domain nicht angegeben ist, wird die Nachricht mit einer Verzögerung von mehreren Minuten gesendet.
Hier ist der Inhalt meiner Datei «/etc/hostname»:
cat /etc/hostname
#####################
asterisk
#####################Als nĂ€chstes mĂŒssen die erstellten Konfigurationsdateien in indizierte Datenbanken umgewandelt 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. Dazu fĂŒhren wir den folgenden Befehl aus:
openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:25 > /etc/postfix/ca.pemNachdem die technische Information auf dem Bildschirm angezeigt wird, wird das Team weiterhin "hĂ€ngen". DrĂŒcken Sie Ctrl+C, um es abzubrechen.
Lassen Sie uns jetzt manuell den gesamten MĂŒll aus der resultierenden Datei entfernen und nur das Zertifikat belassen. Das Ergebnis sollte in etwa so 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 â die Zieladresse
Damit ist die Konfiguration von Postfix abgeschlossen.
Wir schreiben ein Bash-Skript
Wir erstellen ein Verzeichnis zum Speichern des Bash-Skripts (wo auch immer es jemandem besser gefÀllt):
mkdir /home/asterisk/scriptsWir erstellen die Datei fĂŒr das Bash-Skript:
touch /home/asterisk/scripts/noanswer.shWir vergeben AusfĂŒhrungsrechte an die Skriptdatei:
chmod +x /home/asterisk/scripts/noanswer.shWenn Sie Zweifel an den Dateirechten haben, können Sie wĂ€hrend der Fehlersuche vorĂŒbergehend vollstĂ€ndigen Zugriff auf die Datei gewĂ€hren. Aber das ist "nicht sicher".
chmod 777 /home/asterisk/scripts/noanswer.shDer Text 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 ĂŒber Linux Debian"
;;
63200)
address="windows@lucky.ru"
subject="zu Fragen ĂŒber Windows"
;;
63300)
address="freebsd@lucky.ru"
subject="zu Fragen ĂŒber FreeBSD"
;;
63400)
address="ubuntu@lucky.ru"
subject="zu Fragen ĂŒber Linux Ubuntu"
;;
63500)
address="centos@lucky.ru"
subject="zu Fragen ĂŒber Linux CentOS"
;;
*)
address="admin@lucky.ru"
error_kod=1
;;
esac
case $error_kod in
0)
echo "Anruf von Abonnent $2, der $subject angerufen hat, verpasst." | mail -s "Anruf von $2 verpasst" $address
echo "Verpasster Anruf fĂŒr $address von Abonnent $2, der $subject angerufen hat. uid=$1" | mail -s "Anruf von $2 verpasst" admin@lucky.ru
;;
1)
echo "Verpasster Anruf von $2. Warteschlange unbekannt. uid=$1" | mail -s "Anruf von $2 verpasst" 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 eingestellt. Ich denke, eine Sekunde wĂŒrde auch ausreichen.
âres_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'â:Die MySQL-Abfrage haben wir zur besseren Handhabung in eine separate Variable ausgelagert.
Als nĂ€chstes stellen wir eine Anfrage an MySQL und filtern die erhaltene Ausgabe. Wir entfernen alle Optionen auĂer âANSWEREDâ, falls eine solche vorhanden ist. Falls es mehrere Werte fĂŒr âANSWEREDâ gibt, sollte nur einer davon bleiben. Am Ende speichern wir in der Variablen âanswerâ entweder âANSWEREDâ oder ââ.
Wenn der Wert der Variablen âanswerâ nicht âANSWEREDâ entspricht, handelt es sich um einen verpassten Anruf. Je nach Warteschlangennummer 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Ă€nderbarer Teil der Nachricht).
Im Folgenden wird der Fall betrachtet, wenn die Warteschlange in Asterisk festgelegt ist, aber im Skript nicht beschrieben ist. In diesem Fall erhÀlt admin@lucky.ru eine E-Mail, dass die Warteschlange dem Skript nicht bekannt ist.
Wenn die Warteschlange jedoch beschrieben ist, wird eine E-Mail an die entsprechende Adresse gesendet sowie eine Kopie an admin@lucky.ru mit der Angabe âuniqueidâ, damit die Ereignisse zu diesem Anruf bei Bedarf nachverfolgt werden können.
An dieser Stelle endet das Skript.
Ich möchte darauf hinweisen, dass wir fĂŒr die Verbindung zu MySQL den Benutzernamen und das Passwort verwendet haben, die wir im Voraus erfahren haben. In FreePBX, um den Benutzernamen von Asterisk in MySQL zu erfahren, fĂŒhren Sie den folgenden Befehl aus:
cat /etc/amportal.conf | grep AMPDBUSERUm das Passwort des Asterisk-Benutzers in MySQL zu erfahren, fĂŒhren Sie den folgenden Befehl aus:
cat /etc/amportal.conf | grep AMPDBPASSAsterisk-Konfiguration
Wir verwenden FreePBX. In FreePBX gibt es verschiedene Arten von Konfigurationsdateien (siehe ), einige davon werden von FreePBX beim Neustart ĂŒberschrieben, wĂ€hrend andere nicht ĂŒberschrieben werden (sie werden als benutzerdefiniert bezeichnet), da sie speziell fĂŒr den Benutzer bestimmt sind.
Wir werden mit der Konfigurationsdatei âextensions_override_freepbx.confâ arbeiten, da sie zur benutzerdefinierten Art gehört.
ZunĂ€chst stellen wir sicher, dass die Datei â/etc/asterisk/extensions.confâ die Datei âextensions_override_freepbx.confâ eingebunden hat. FĂŒhren Sie dazu den 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 bringen Sie sie in die folgende Form:
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 zuvor erwĂ€hnt habe, ist das Zeichen â&â am Ende erforderlich. Da wir in einem Bash-Skript mit CDR-Daten arbeiten werden, die direkt aus der MySQL-Datenbank abgerufen werden und diese Daten nur nach der AusfĂŒhrung von âexten => h,2,Macro(hangupcall,)â in MySQL eingetragen werden, mĂŒssen wir nicht auf das Ende der AusfĂŒhrung des Bash-Skripts warten, sondern können mit dem nĂ€chsten Schritt in Asterisk fortfahren. Das Bash-Skript selbst sollte eine zeitliche Verzögerung vor dem AusfĂŒhren seines Hauptteils enthalten.
Damit die Ănderungen in der Konfigurationsdatei â/etc/asterisk/extensions_override_freepbx.confâ wirksam werden, muss der Asterisk-Kern mit dem folgenden Befehl neu geladen werden:
/usr/sbin/asterisk -rx "core restart now"Dies muss erfolgen, nachdem das Bash-Skript erstellt wurde.
Fazit
Das ist wohl der 1001. Weg, um âverpasste Anrufeâ in Asterisk zu erfassen. Teilen Sie in den Kommentaren, wie Sie diese Aufgabe lösen. Und was Ihrer Meinung nach verbessert/ĂŒberarbeitet/optimiert werden kann. Wir wĂŒrden uns ĂŒber konstruktive Ideen freuen.
Quelle: habr.com
