FreePBX. Einrichtung von Asterisk für E-Mail-Benachrichtigungen über versäumte eingehende Anrufe in der Warteschlange.

FreePBX. Einrichtung von Asterisk für E-Mail-Benachrichtigungen über versäumte eingehende Anrufe in der Warteschlange.
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 hier, nicht vollständig durchdacht und wurde verworfen.

Die vorgeschlagene Lösung von hierhat 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 hiergelesen hatte, kam mir die Idee, die CDR-Variable „Disposition“ für alle Agenten in der Warteschlange zu filtern. Nach dem Lesen von dieser 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.

FreePBX. Einrichtung von Asterisk für E-Mail-Benachrichtigungen über versäumte eingehende Anrufe in der Warteschlange.
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. https://asterisk-pbx.ru/wiki/asterisk/cf/cdr), 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. https://asterisk-pbx.ru/wiki/asterisk/cf/cdr). 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: https://www.dmosk.ru/miniinstruktions.php?mini=postfix-over-yandex.

Zuerst installieren/aktualisieren/prüfen wir die vorhandenen Pakete:

yum install postfix
yum install mailx
yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plain

Wir 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.sav

Wir 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. http://www.postfix.org/SMTPUTF8_README.html).

Wir erstellen ein Verzeichnis für die Konfigurationsdateien:

mkdir /etc/postfix/private

Wir 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. https://wiki.merionet.ru/ip-telephoniya/30/postfix-nastrojka-otpravki-pochty-v-asterisk/):

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.pem

Nachdem 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 restart

Wir senden eine Test-E-Mail:

echo "Dies ist der E-Mail-Text" | mail -s "Das ist das Thema" admin@lucky.ru

admin@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/scripts

Wir erstellen die Datei für das Bash-Skript:

touch /home/asterisk/scripts/noanswer.sh

Wir vergeben Ausführungsrechte an die Skriptdatei:

chmod +x /home/asterisk/scripts/noanswer.sh

Wenn 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.sh

Der 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 AMPDBUSER

Um das Passwort des Asterisk-Benutzers in MySQL zu erfahren, führen Sie den folgenden Befehl aus:

cat /etc/amportal.conf | grep AMPDBPASS

Asterisk-Konfiguration

Wir verwenden FreePBX. In FreePBX gibt es verschiedene Arten von Konfigurationsdateien (siehe https://asterisk-pbx.ru/wiki/freepbx/files), 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

60GB SSD 8Gb DDR4